Tommy 碎碎念

Tommy Wu's blog

« 上一篇 | 下一篇 »

Delphi 中使用 WebBrowser 元件時對按鍵的處理
post by tommy @ 25 八月, 2016 12:13

我們某些系統是使用古老的 Delphi3 開發的, 所以.... 不支援 unicode 也是正常的. 就算在資料庫中加上了 nchar/nvarchar 的欄位, 還是無法正常的顯示 (其實連存取都有點麻煩, 因為 BDE 不支援 unicode, 要動些手腳才可以).由於 web 上頭對於 unicode 的處理十分容易, 所以... 打算把兩者混在一起使用.

Microsoft 有提供一個 IE 的 ActiveX 元件, 所以, 在 Delphi3 可以簡單的把它加進來 (會多 WebBrowser 與 WebBrowser_V1 兩個元件可以用, V1 據說是 IE3 的版本, 所以... 我們通常直接用 WebBrowser 那個).

為了安全起見, 我們是透過 database 來處理 Delphi 與 WebBrowser 之間的 session, 在開啟 WebBrowser 的 form 之前, 會把相關的參數與登入的帳號寫到資料庫, 用一個 hash 當 key, 然後在 WebBrowser form 開啟時, 用 post 的方式把那個 hash 傳過去, 在 web server 端依據那個 key 去查資料庫取得登入的帳號與參數, 如果不正確或 hash 不存在就拒絕存取.

透過這種方式, 使用者不需要離開原本的系統, 也不會知道那個 form 打開來實際上是個瀏覽器, 又能正確處理 unicode 的字元.

不過, 在 Delphi 中使用 WebBrowser 元件會有個問題就是某些按鍵會沒作用, 例如: 無法用 tab 切換輸入的欄位, 也沒辦法用 ctrl-c/ctrl-v 之類的按鍵複製與貼上.

這些可以透過下面的方法來處理 (在 WebBrowser 元件放的那個 form 的 .pas):

  • uses 加上 ActiveX (才能用 OleInitialize 與 OleUninitialize 函式)
  • end. 之前加上這幾行 (可以讓滑鼠操作的複製貼上有作用)
initialization
OleInitialize(nil);
 
finalization
OleUninitialize;
 
 
end.
  • 寫一個 message 處理的函式來處理

var
FOleInPlaceActiveObject: IOleInPlaceActiveObject;
SaveMessageHandler: TMessageEvent;
 
procedure TForm_webbrowser.MyMessageHandler(var Msg: TMsg; var Handled: Boolean);
var iOIPAO: IOleInPlaceActiveObject;
Dispatch: IDispatch;
begin
if WebBrowser1 = nil then
begin
Handled := False;
Exit;
end;
 
Handled:=(IsDialogMessage(WebBrowser1.Handle, Msg) = True);
 
if (Handled) and (not WebBrowser1.Busy) then
begin
if FOleInPlaceActiveObject = nil then
begin
Dispatch := WebBrowser1.Application;
if Dispatch <> nil then
begin
Dispatch.QueryInterface(IOleInPlaceActiveObject, iOIPAO);
if iOIPAO <> nil then
FOleInPlaceActiveObject := iOIPAO;
end;
end;
 
if FOleInPlaceActiveObject <> nil then
if ((Msg.message = WM_KEYDOWN) or (Msg.message = WM_KEYUP)) and
((Msg.wParam = VK_BACK) or (Msg.wParam = VK_LEFT) or (Msg.wParam = VK_RIGHT)) then
//nothing - do not pass on Backspace, Left or Right arrows
else
FOleInPlaceActiveObject.TranslateAccelerator(Msg);
end;
end;
 
procedure TForm_webbrowser.FormActivate(Sender: TObject);
begin
SaveMessageHandler := Application.OnMessage;
Application.OnMessage := MyMessageHandler;
end;
 
procedure TForm_webbrowser.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
Application.OnMessage := SaveMessageHandler;
FOleInPlaceActiveObject := nil;
end;
 
procedure TForm_webbrowser.FormDeactivate(Sender: TObject);
begin
Application.OnMessage := SaveMessageHandler;
end;

透過這樣子的處理, 就能使用 tab, ctrl-c/ctrl-v 等按鍵了.

Del.icio.us Furl HEMiDEMi Technorati MyShare
迴響
暱稱:
標題:
個人網頁:
電子郵件:
authimage

迴響

  

Bad Behavior 已經阻擋了 46 個過去 7 天試圖闖關的垃圾迴響與引用。
Power by LifeType. Template design by JamesHuang. Valid XHTML and CSS