![]() |
If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below. |
|
|
Thread Tools | Search this Thread | Display Modes |
#1
|
|||
|
|||
![]()
Our VB6.0 Outlook addin loads a panel (written in VC++) containing an
internet explorer control in both the inspector and explorer views. The internet explorer control displays an HTML file with a simple text input. We faced similar issues with the backspace and delete key events being eaten up by Outlook and not forwarded to the text input. So we tried out a solution similar to the one posted by you, where we used SetWindowsHookEx to catch the delete and backspace keypress events and send appropriate messages to the panel window. While this does seem to work for backspace in both the explorer and inspector views, the delete keypress event *still* seems to be eaten up by Outlook. This is what our callback for the SetWindowsHookEx looks like : LRESULT CALLBACK LowLevelKeyboardProc(INT nCode, WPARAM wParam, LPARAM lParam){ LRESULT lRes; KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *) lParam; if ( pkbhs-vkCode == VK_DELETE || pkbhs-vkCode == VK_BACK) { if(outlook_mainwindow_Handle) { HWND panel = FindWindowEx(outlook_mainwindow_Handle, NULL, NULL, _T ("PanelDialog")); if (panel) { HWND hWndCtl = ::GetFocus(); if(::IsChild(panel, hWndCtl)) { if (wParam == WM_KEYDOWN) { ::SendMessage(hWndCtl, WM_KEYDOWN, pkbhs-vkCode, 0); } return 1; } } } } lRes = CallNextHookEx (0, nCode, wParam, lParam); return lRes; } Any idea how we can get the delete key working? |
Ads |
#2
|
|||
|
|||
![]()
I have no problem with the following hook in Outlook (Delphi):
initialization g_hook := SetWindowsHookEx(WH_GETMESSAGE, RAHLEditorHookProc, 0, GetCurrentThreadId()); finalization UnhookWindowsHookEx(g_hook); end. var g_hook : HHOOK; function RAHLEditorHookProc(Code : integer; wParam : WPARAM; lParam : LPARAM):LResult;stdcall; var pMsg : ^TMsg; //ClassName:string; Ctrl{, NextCtrl} : TWinControl; ParentFrm : TCustomForm; begin pMsg:=pointer(lParam); if ((wParam and PM_REMOVE) = PM_REMOVE) then begin if (pMsg.message = WM_KEYFIRST) and (pMsg.message = WM_KEYLAST) then begin if ((pMsg.message = WM_KEYDOWN) or (pMsg.message = WM_KEYUP)) and (pMsg.wParam VK_RETURN) and //ignore "Return" keys ((pMsg.wParam = VK_BACK) or (pMsg.wParam = VK_DELETE) or (pMsg.wParam = VK_TAB) or (pMsg.wParam = VK_SPACE) or //(pMsg.wParam = VK_LEFT) or (pMsg.wParam = VK_RIGHT) or (GetKeyState(VK_CONTROL) 0) or //Control key (GetKeyState(VK_MENU) 0) or //Alt key ((pMsg.lParam and (1 shl 24)) 0) or //extended key {(pMsg.wParam = VK_RETURN) or} (pMsg.wParam = VK_UP) or (pMsg.wParam = VK_DOWN)) then begin //SetLength(ClassName, 1024); //SetLength(ClassName, GetClassName(pMsg.hwnd, PChar(ClassName), Length(ClassName))); //if (ClassName = 'TRAHLEditor') then begin Ctrl:=FindDelphiControl(pMsg.hwnd); if Ctrl nil then begin //is it a Delphi control? if (pMsg.wParam = VK_TAB) then begin if (pMsg.message = WM_KEYDOWN) then begin ParentFrm:=GetParentForm(Ctrl); if ParentFrm nil then begin TCheatControl(ParentFrm).SelectNext(Ctrl, true, true); //PostMessage(ParentFrm.Handle, WM_NEXTDLGCTL, 0, 0); end; end; end else begin TranslateMessage(pMsg^); SendMessage(pMsg.hwnd, pMsg.message, pMsg.wParam, pMsg.lParam); end; pMsg.message :=WM_NULL; end; end end end; Result:=CallNextHookEx(g_hook, Code, wParam, lParam); end; -- Dmitry Streblechenko (MVP) http://www.dimastr.com/ OutlookSpy - Outlook, CDO and MAPI Developer Tool - "Reinwald" wrote in message ... Our VB6.0 Outlook addin loads a panel (written in VC++) containing an internet explorer control in both the inspector and explorer views. The internet explorer control displays an HTML file with a simple text input. We faced similar issues with the backspace and delete key events being eaten up by Outlook and not forwarded to the text input. So we tried out a solution similar to the one posted by you, where we used SetWindowsHookEx to catch the delete and backspace keypress events and send appropriate messages to the panel window. While this does seem to work for backspace in both the explorer and inspector views, the delete keypress event *still* seems to be eaten up by Outlook. This is what our callback for the SetWindowsHookEx looks like : LRESULT CALLBACK LowLevelKeyboardProc(INT nCode, WPARAM wParam, LPARAM lParam){ LRESULT lRes; KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *) lParam; if ( pkbhs-vkCode == VK_DELETE || pkbhs-vkCode == VK_BACK) { if(outlook_mainwindow_Handle) { HWND panel = FindWindowEx(outlook_mainwindow_Handle, NULL, NULL, _T ("PanelDialog")); if (panel) { HWND hWndCtl = ::GetFocus(); if(::IsChild(panel, hWndCtl)) { if (wParam == WM_KEYDOWN) { ::SendMessage(hWndCtl, WM_KEYDOWN, pkbhs-vkCode, 0); } return 1; } } } } lRes = CallNextHookEx (0, nCode, wParam, lParam); return lRes; } Any idea how we can get the delete key working? |
#3
|
|||
|
|||
![]()
Hey,
We tried using TranslateMessage(message) and then calling sendmessage ,but it stills doesnt work. Using spy ++ i monitored the keystrokes and i clearly see the after installing our hook the delete message goes to the appropriate window but somehow i feel outlook is eating up the delete key. To confirm my doubt i even mapped the delete key to another key say "?" and when i press the delete key the "?" symbol gets printed . As i mentioned before this hook works for the backspace key which prior to this wasnt working.Any other suggestion to get the delete key working? Thanks "Dmitry Streblechenko" wrote: I have no problem with the following hook in Outlook (Delphi): initialization g_hook := SetWindowsHookEx(WH_GETMESSAGE, RAHLEditorHookProc, 0, GetCurrentThreadId()); finalization UnhookWindowsHookEx(g_hook); end. var g_hook : HHOOK; function RAHLEditorHookProc(Code : integer; wParam : WPARAM; lParam : LPARAM):LResult;stdcall; var pMsg : ^TMsg; //ClassName:string; Ctrl{, NextCtrl} : TWinControl; ParentFrm : TCustomForm; begin pMsg:=pointer(lParam); if ((wParam and PM_REMOVE) = PM_REMOVE) then begin if (pMsg.message = WM_KEYFIRST) and (pMsg.message = WM_KEYLAST) then begin if ((pMsg.message = WM_KEYDOWN) or (pMsg.message = WM_KEYUP)) and (pMsg.wParam VK_RETURN) and //ignore "Return" keys ((pMsg.wParam = VK_BACK) or (pMsg.wParam = VK_DELETE) or (pMsg.wParam = VK_TAB) or (pMsg.wParam = VK_SPACE) or //(pMsg.wParam = VK_LEFT) or (pMsg.wParam = VK_RIGHT) or (GetKeyState(VK_CONTROL) 0) or //Control key (GetKeyState(VK_MENU) 0) or //Alt key ((pMsg.lParam and (1 shl 24)) 0) or //extended key {(pMsg.wParam = VK_RETURN) or} (pMsg.wParam = VK_UP) or (pMsg.wParam = VK_DOWN)) then begin //SetLength(ClassName, 1024); //SetLength(ClassName, GetClassName(pMsg.hwnd, PChar(ClassName), Length(ClassName))); //if (ClassName = 'TRAHLEditor') then begin Ctrl:=FindDelphiControl(pMsg.hwnd); if Ctrl nil then begin //is it a Delphi control? if (pMsg.wParam = VK_TAB) then begin if (pMsg.message = WM_KEYDOWN) then begin ParentFrm:=GetParentForm(Ctrl); if ParentFrm nil then begin TCheatControl(ParentFrm).SelectNext(Ctrl, true, true); //PostMessage(ParentFrm.Handle, WM_NEXTDLGCTL, 0, 0); end; end; end else begin TranslateMessage(pMsg^); SendMessage(pMsg.hwnd, pMsg.message, pMsg.wParam, pMsg.lParam); end; pMsg.message :=WM_NULL; end; end end end; Result:=CallNextHookEx(g_hook, Code, wParam, lParam); end; -- Dmitry Streblechenko (MVP) http://www.dimastr.com/ OutlookSpy - Outlook, CDO and MAPI Developer Tool - "Reinwald" wrote in message ... Our VB6.0 Outlook addin loads a panel (written in VC++) containing an internet explorer control in both the inspector and explorer views. The internet explorer control displays an HTML file with a simple text input. We faced similar issues with the backspace and delete key events being eaten up by Outlook and not forwarded to the text input. So we tried out a solution similar to the one posted by you, where we used SetWindowsHookEx to catch the delete and backspace keypress events and send appropriate messages to the panel window. While this does seem to work for backspace in both the explorer and inspector views, the delete keypress event *still* seems to be eaten up by Outlook. This is what our callback for the SetWindowsHookEx looks like : LRESULT CALLBACK LowLevelKeyboardProc(INT nCode, WPARAM wParam, LPARAM lParam){ LRESULT lRes; KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *) lParam; if ( pkbhs-vkCode == VK_DELETE || pkbhs-vkCode == VK_BACK) { if(outlook_mainwindow_Handle) { HWND panel = FindWindowEx(outlook_mainwindow_Handle, NULL, NULL, _T ("PanelDialog")); if (panel) { HWND hWndCtl = ::GetFocus(); if(::IsChild(panel, hWndCtl)) { if (wParam == WM_KEYDOWN) { ::SendMessage(hWndCtl, WM_KEYDOWN, pkbhs-vkCode, 0); } return 1; } } } } lRes = CallNextHookEx (0, nCode, wParam, lParam); return lRes; } Any idea how we can get the delete key working? |
#4
|
|||
|
|||
![]()
Hey,
The code we tried out after reading your suggestion llKeyHook = SetWindowsHookEx(WH_GETMESSAGE, GetMessageProc, 0, GetCurrentThreadId()); LRESULT CALLBACK GetMessageProc(int code, WPARAM wParam, LPARAM lParam) { const MSG *pMsg = (MSG *) lParam; HWND panel = FindWindowEx(application_Handle, NULL, NULL, _T("PanelDialog")); if (panel) { HWND hWndCtl = ::GetFocus(); if(::IsChild(panel, hWndCtl)) { if (wParam & PM_REMOVE) { if (pMsg-message = WM_KEYFIRST && pMsg-message = WM_KEYLAST) { if (pMsg-message == WM_KEYDOWN && (pMsg-wParam == VK_BACK || pMsg-wParam == VK_DELETE)) { ::TranslateMessage(pMsg); return ::SendMessage(hWndCtl, pMsg-message, pMsg-wParam, pMsg-lParam); } } } } } return ::CallNextHookEx(0, code, wParam, lParam); } As i mentioned before this hook works for the backspace key.Any other suggestion to get the delete key working? "Dmitry Streblechenko" wrote: I have no problem with the following hook in Outlook (Delphi): initialization g_hook := SetWindowsHookEx(WH_GETMESSAGE, RAHLEditorHookProc, 0, GetCurrentThreadId()); finalization UnhookWindowsHookEx(g_hook); end. var g_hook : HHOOK; function RAHLEditorHookProc(Code : integer; wParam : WPARAM; lParam : LPARAM):LResult;stdcall; var pMsg : ^TMsg; //ClassName:string; Ctrl{, NextCtrl} : TWinControl; ParentFrm : TCustomForm; begin pMsg:=pointer(lParam); if ((wParam and PM_REMOVE) = PM_REMOVE) then begin if (pMsg.message = WM_KEYFIRST) and (pMsg.message = WM_KEYLAST) then begin if ((pMsg.message = WM_KEYDOWN) or (pMsg.message = WM_KEYUP)) and (pMsg.wParam VK_RETURN) and //ignore "Return" keys ((pMsg.wParam = VK_BACK) or (pMsg.wParam = VK_DELETE) or (pMsg.wParam = VK_TAB) or (pMsg.wParam = VK_SPACE) or //(pMsg.wParam = VK_LEFT) or (pMsg.wParam = VK_RIGHT) or (GetKeyState(VK_CONTROL) 0) or //Control key (GetKeyState(VK_MENU) 0) or //Alt key ((pMsg.lParam and (1 shl 24)) 0) or //extended key {(pMsg.wParam = VK_RETURN) or} (pMsg.wParam = VK_UP) or (pMsg.wParam = VK_DOWN)) then begin //SetLength(ClassName, 1024); //SetLength(ClassName, GetClassName(pMsg.hwnd, PChar(ClassName), Length(ClassName))); //if (ClassName = 'TRAHLEditor') then begin Ctrl:=FindDelphiControl(pMsg.hwnd); if Ctrl nil then begin //is it a Delphi control? if (pMsg.wParam = VK_TAB) then begin if (pMsg.message = WM_KEYDOWN) then begin ParentFrm:=GetParentForm(Ctrl); if ParentFrm nil then begin TCheatControl(ParentFrm).SelectNext(Ctrl, true, true); //PostMessage(ParentFrm.Handle, WM_NEXTDLGCTL, 0, 0); end; end; end else begin TranslateMessage(pMsg^); SendMessage(pMsg.hwnd, pMsg.message, pMsg.wParam, pMsg.lParam); end; pMsg.message :=WM_NULL; end; end end end; Result:=CallNextHookEx(g_hook, Code, wParam, lParam); end; -- Dmitry Streblechenko (MVP) http://www.dimastr.com/ OutlookSpy - Outlook, CDO and MAPI Developer Tool - "Reinwald" wrote in message ... Our VB6.0 Outlook addin loads a panel (written in VC++) containing an internet explorer control in both the inspector and explorer views. The internet explorer control displays an HTML file with a simple text input. We faced similar issues with the backspace and delete key events being eaten up by Outlook and not forwarded to the text input. So we tried out a solution similar to the one posted by you, where we used SetWindowsHookEx to catch the delete and backspace keypress events and send appropriate messages to the panel window. While this does seem to work for backspace in both the explorer and inspector views, the delete keypress event *still* seems to be eaten up by Outlook. This is what our callback for the SetWindowsHookEx looks like : LRESULT CALLBACK LowLevelKeyboardProc(INT nCode, WPARAM wParam, LPARAM lParam){ LRESULT lRes; KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *) lParam; if ( pkbhs-vkCode == VK_DELETE || pkbhs-vkCode == VK_BACK) { if(outlook_mainwindow_Handle) { HWND panel = FindWindowEx(outlook_mainwindow_Handle, NULL, NULL, _T ("PanelDialog")); if (panel) { HWND hWndCtl = ::GetFocus(); if(::IsChild(panel, hWndCtl)) { if (wParam == WM_KEYDOWN) { ::SendMessage(hWndCtl, WM_KEYDOWN, pkbhs-vkCode, 0); } return 1; } } } } lRes = CallNextHookEx (0, nCode, wParam, lParam); return lRes; } Any idea how we can get the delete key working? |
#5
|
|||
|
|||
![]()
So you do see the message and it gets forwarded, right?
-- Dmitry Streblechenko (MVP) http://www.dimastr.com/ OutlookSpy - Outlook, CDO and MAPI Developer Tool - "Reinwald" wrote in message ... Hey, The code we tried out after reading your suggestion llKeyHook = SetWindowsHookEx(WH_GETMESSAGE, GetMessageProc, 0, GetCurrentThreadId()); LRESULT CALLBACK GetMessageProc(int code, WPARAM wParam, LPARAM lParam) { const MSG *pMsg = (MSG *) lParam; HWND panel = FindWindowEx(application_Handle, NULL, NULL, _T("PanelDialog")); if (panel) { HWND hWndCtl = ::GetFocus(); if(::IsChild(panel, hWndCtl)) { if (wParam & PM_REMOVE) { if (pMsg-message = WM_KEYFIRST && pMsg-message = WM_KEYLAST) { if (pMsg-message == WM_KEYDOWN && (pMsg-wParam == VK_BACK || pMsg-wParam == VK_DELETE)) { ::TranslateMessage(pMsg); return ::SendMessage(hWndCtl, pMsg-message, pMsg-wParam, pMsg-lParam); } } } } } return ::CallNextHookEx(0, code, wParam, lParam); } As i mentioned before this hook works for the backspace key.Any other suggestion to get the delete key working? "Dmitry Streblechenko" wrote: I have no problem with the following hook in Outlook (Delphi): initialization g_hook := SetWindowsHookEx(WH_GETMESSAGE, RAHLEditorHookProc, 0, GetCurrentThreadId()); finalization UnhookWindowsHookEx(g_hook); end. var g_hook : HHOOK; function RAHLEditorHookProc(Code : integer; wParam : WPARAM; lParam : LPARAM):LResult;stdcall; var pMsg : ^TMsg; //ClassName:string; Ctrl{, NextCtrl} : TWinControl; ParentFrm : TCustomForm; begin pMsg:=pointer(lParam); if ((wParam and PM_REMOVE) = PM_REMOVE) then begin if (pMsg.message = WM_KEYFIRST) and (pMsg.message = WM_KEYLAST) then begin if ((pMsg.message = WM_KEYDOWN) or (pMsg.message = WM_KEYUP)) and (pMsg.wParam VK_RETURN) and //ignore "Return" keys ((pMsg.wParam = VK_BACK) or (pMsg.wParam = VK_DELETE) or (pMsg.wParam = VK_TAB) or (pMsg.wParam = VK_SPACE) or //(pMsg.wParam = VK_LEFT) or (pMsg.wParam = VK_RIGHT) or (GetKeyState(VK_CONTROL) 0) or //Control key (GetKeyState(VK_MENU) 0) or //Alt key ((pMsg.lParam and (1 shl 24)) 0) or //extended key {(pMsg.wParam = VK_RETURN) or} (pMsg.wParam = VK_UP) or (pMsg.wParam = VK_DOWN)) then begin //SetLength(ClassName, 1024); //SetLength(ClassName, GetClassName(pMsg.hwnd, PChar(ClassName), Length(ClassName))); //if (ClassName = 'TRAHLEditor') then begin Ctrl:=FindDelphiControl(pMsg.hwnd); if Ctrl nil then begin //is it a Delphi control? if (pMsg.wParam = VK_TAB) then begin if (pMsg.message = WM_KEYDOWN) then begin ParentFrm:=GetParentForm(Ctrl); if ParentFrm nil then begin TCheatControl(ParentFrm).SelectNext(Ctrl, true, true); //PostMessage(ParentFrm.Handle, WM_NEXTDLGCTL, 0, 0); end; end; end else begin TranslateMessage(pMsg^); SendMessage(pMsg.hwnd, pMsg.message, pMsg.wParam, pMsg.lParam); end; pMsg.message :=WM_NULL; end; end end end; Result:=CallNextHookEx(g_hook, Code, wParam, lParam); end; -- Dmitry Streblechenko (MVP) http://www.dimastr.com/ OutlookSpy - Outlook, CDO and MAPI Developer Tool - "Reinwald" wrote in message ... Our VB6.0 Outlook addin loads a panel (written in VC++) containing an internet explorer control in both the inspector and explorer views. The internet explorer control displays an HTML file with a simple text input. We faced similar issues with the backspace and delete key events being eaten up by Outlook and not forwarded to the text input. So we tried out a solution similar to the one posted by you, where we used SetWindowsHookEx to catch the delete and backspace keypress events and send appropriate messages to the panel window. While this does seem to work for backspace in both the explorer and inspector views, the delete keypress event *still* seems to be eaten up by Outlook. This is what our callback for the SetWindowsHookEx looks like : LRESULT CALLBACK LowLevelKeyboardProc(INT nCode, WPARAM wParam, LPARAM lParam){ LRESULT lRes; KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *) lParam; if ( pkbhs-vkCode == VK_DELETE || pkbhs-vkCode == VK_BACK) { if(outlook_mainwindow_Handle) { HWND panel = FindWindowEx(outlook_mainwindow_Handle, NULL, NULL, _T ("PanelDialog")); if (panel) { HWND hWndCtl = ::GetFocus(); if(::IsChild(panel, hWndCtl)) { if (wParam == WM_KEYDOWN) { ::SendMessage(hWndCtl, WM_KEYDOWN, pkbhs-vkCode, 0); } return 1; } } } } lRes = CallNextHookEx (0, nCode, wParam, lParam); return lRes; } Any idea how we can get the delete key working? |
#6
|
|||
|
|||
![]()
Hey,
In spy ++ when I spied on the internet browser inside our panel I observed that the keypresses were getting logged On checking these articles http://209.85.153.132/translate_c?hl...TZqLfQwGM4i3zQ http://209.85.153.132/translate_c?hl...TZqLfQwGM4i3zQ http://social.msdn.microsoft.com/For...f-5f22b66bcd5a Any idea how to go about this ??? "Dmitry Streblechenko" wrote: So you do see the message and it gets forwarded, right? -- Dmitry Streblechenko (MVP) http://www.dimastr.com/ OutlookSpy - Outlook, CDO and MAPI Developer Tool - "Reinwald" wrote in message ... Hey, The code we tried out after reading your suggestion llKeyHook = SetWindowsHookEx(WH_GETMESSAGE, GetMessageProc, 0, GetCurrentThreadId()); LRESULT CALLBACK GetMessageProc(int code, WPARAM wParam, LPARAM lParam) { const MSG *pMsg = (MSG *) lParam; HWND panel = FindWindowEx(application_Handle, NULL, NULL, _T("PanelDialog")); if (panel) { HWND hWndCtl = ::GetFocus(); if(::IsChild(panel, hWndCtl)) { if (wParam & PM_REMOVE) { if (pMsg-message = WM_KEYFIRST && pMsg-message = WM_KEYLAST) { if (pMsg-message == WM_KEYDOWN && (pMsg-wParam == VK_BACK || pMsg-wParam == VK_DELETE)) { ::TranslateMessage(pMsg); return ::SendMessage(hWndCtl, pMsg-message, pMsg-wParam, pMsg-lParam); } } } } } return ::CallNextHookEx(0, code, wParam, lParam); } As i mentioned before this hook works for the backspace key.Any other suggestion to get the delete key working? "Dmitry Streblechenko" wrote: I have no problem with the following hook in Outlook (Delphi): initialization g_hook := SetWindowsHookEx(WH_GETMESSAGE, RAHLEditorHookProc, 0, GetCurrentThreadId()); finalization UnhookWindowsHookEx(g_hook); end. var g_hook : HHOOK; function RAHLEditorHookProc(Code : integer; wParam : WPARAM; lParam : LPARAM):LResult;stdcall; var pMsg : ^TMsg; //ClassName:string; Ctrl{, NextCtrl} : TWinControl; ParentFrm : TCustomForm; begin pMsg:=pointer(lParam); if ((wParam and PM_REMOVE) = PM_REMOVE) then begin if (pMsg.message = WM_KEYFIRST) and (pMsg.message = WM_KEYLAST) then begin if ((pMsg.message = WM_KEYDOWN) or (pMsg.message = WM_KEYUP)) and (pMsg.wParam VK_RETURN) and //ignore "Return" keys ((pMsg.wParam = VK_BACK) or (pMsg.wParam = VK_DELETE) or (pMsg.wParam = VK_TAB) or (pMsg.wParam = VK_SPACE) or //(pMsg.wParam = VK_LEFT) or (pMsg.wParam = VK_RIGHT) or (GetKeyState(VK_CONTROL) 0) or //Control key (GetKeyState(VK_MENU) 0) or //Alt key ((pMsg.lParam and (1 shl 24)) 0) or //extended key {(pMsg.wParam = VK_RETURN) or} (pMsg.wParam = VK_UP) or (pMsg.wParam = VK_DOWN)) then begin //SetLength(ClassName, 1024); //SetLength(ClassName, GetClassName(pMsg.hwnd, PChar(ClassName), Length(ClassName))); //if (ClassName = 'TRAHLEditor') then begin Ctrl:=FindDelphiControl(pMsg.hwnd); if Ctrl nil then begin //is it a Delphi control? if (pMsg.wParam = VK_TAB) then begin if (pMsg.message = WM_KEYDOWN) then begin ParentFrm:=GetParentForm(Ctrl); if ParentFrm nil then begin TCheatControl(ParentFrm).SelectNext(Ctrl, true, true); //PostMessage(ParentFrm.Handle, WM_NEXTDLGCTL, 0, 0); end; end; end else begin TranslateMessage(pMsg^); SendMessage(pMsg.hwnd, pMsg.message, pMsg.wParam, pMsg.lParam); end; pMsg.message :=WM_NULL; end; end end end; Result:=CallNextHookEx(g_hook, Code, wParam, lParam); end; -- Dmitry Streblechenko (MVP) http://www.dimastr.com/ OutlookSpy - Outlook, CDO and MAPI Developer Tool - "Reinwald" wrote in message ... Our VB6.0 Outlook addin loads a panel (written in VC++) containing an internet explorer control in both the inspector and explorer views. The internet explorer control displays an HTML file with a simple text input. We faced similar issues with the backspace and delete key events being eaten up by Outlook and not forwarded to the text input. So we tried out a solution similar to the one posted by you, where we used SetWindowsHookEx to catch the delete and backspace keypress events and send appropriate messages to the panel window. While this does seem to work for backspace in both the explorer and inspector views, the delete keypress event *still* seems to be eaten up by Outlook. This is what our callback for the SetWindowsHookEx looks like : LRESULT CALLBACK LowLevelKeyboardProc(INT nCode, WPARAM wParam, LPARAM lParam){ LRESULT lRes; KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *) lParam; if ( pkbhs-vkCode == VK_DELETE || pkbhs-vkCode == VK_BACK) { if(outlook_mainwindow_Handle) { HWND panel = FindWindowEx(outlook_mainwindow_Handle, NULL, NULL, _T ("PanelDialog")); if (panel) { HWND hWndCtl = ::GetFocus(); if(::IsChild(panel, hWndCtl)) { if (wParam == WM_KEYDOWN) { ::SendMessage(hWndCtl, WM_KEYDOWN, pkbhs-vkCode, 0); } return 1; } } } } lRes = CallNextHookEx (0, nCode, wParam, lParam); return lRes; } Any idea how we can get the delete key working? |
#7
|
|||
|
|||
![]()
Hey,
Well this article helped me also and now the keystrokes work on the internet explorer control. Also thanks Dmitry for the help. ------------i have pasted the article below -------------------------------- ATL and Standard C++ When hosting the WebBrowser control in either an ATL application or one written in standard C++, the solution is sometimes rather simple. All you have to do is query the WebBrowser control for the IOleInPlaceActiveObject interface and call its TranslateAccelerator method. Typically, you call this method in your handler function for the WM_KEYDOWN message. Figure 2 contains ATL and standard C++ code that shows how to call the TranslateAccelerator method to fix the keystroke problem. Sometimes your application will not automatically be sent WM_KEYDOWN messages for accelerator keys. In this case, you must manually send this message to your window. Here is a sample message pump that sends all keyboard messages to the window of your application: while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); // Send all keyboard messages to the window of your // application. hwndApp is the window handle of // your application. // if (msg.message = WM_KEYFIRST && msg.message = WM_KEYLAST) ::SendMessage(hwndApp, msg.message, msg.wParam, msg.lParam); DispatchMessage(&msg); } Win32 SDK Modal Dialogs The Win32? dialog box functions (DialogBox, DialogBoxIndirect, DialogBoxIndirectParam, and DialogBoxParam) are very helpful when creating modal dialog boxes. They take care of handling the message pump for your application. However, this creates a problem when you are trying to fix these keystroke problems. Where do you put the call to TranslateAccelerator? Unfortunately, if you need to host the WebBrowser control in a dialog, it is not a good idea to use these functions to create the modal dialog. The reason for this is simple. When focus is set to a control on a dialog, the control is sent the WB_GETDLGCODE message. Controls typically respond to this message by returning DLGC_WANTALLKEYS. Then the control is given a chance to handle all keys entered by the user. The WebBrowser control returns DLGC_WANTARROWS| DLGC_WANTCHARS in response to the WM_GETDLGCODE message. This means that it will not handle certain keys such as Tab and Delete. Therefore, to work around these keystroke problems, you need to have control of the message pump so that you can call TranslateAccelerator. For these reasons, I recommend that you do not use the Win32 dialog box functions to create your modal dialog box. Create the dialog window yourself so you have control of the message pump. You can use MFC or ATL to create this dialog. In addition, if you just need a modal dialog that displays a Web page, you can use the DHTML showModalDialog function provided by Microsoft Internet Explorer. There is one other option you can use to fix these problems, instead of creating the dialog window manually. You can use a Windows hook. This will enable you to retrieve all keyboard messages for the current thread and then call TranslateAccelerator so that accelerator keys will be processed. There is one problem with this approach, however. When the focus is on the WebBrowser control and you attempt to change focus between controls on the Web page by pressing tab, the focus will never leave the WebBrowser window. This means that you can Tab between controls on the Web page or between controls in your application, but not both. There are four steps required to set up a Windows hook to work around the keystroke problems in a Win32 SDK dialog. First, declare your hook procedure in your header file. static LRESULT CALLBACK GetMsgHookProc(int nCode, WPARAM wParam, LPARAM lParam); Next, set your hook procedure during initialization by calling SetWindowsHookEx. Also, make sure to save the returned hook handle so that you can unhook the procedure when you are shutting down or when it is no longer needed. // Declare this global handle in one of your project files. HHOOK g_hook; // Place this code inside an initialization // method in your implementation file (.cpp) g_hook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgHookProc, NULL, GetCurrentThreadId()); After that, implement your hook procedure and call TranslateAccelerator. LRESULT CALLBACK CYourClass::GetMsgHookProc(int nCode, WPARAM wParam, LPARAM lParam) { LPCKFSEARCH pThis = (LPCKFSEARCH)GetWindowLong(hwndMain, DWL_USER); if (pThis && nCode = 0) { MSG* pMsg = (MSG*)lParam; // m_pOleInPlaceActObj is an IOleInPlaceActiveObject // data member of the view class that is initialized // after the WebBrowser control is loaded. if (pThis-m_pOleInPlaceActObj) pThis-m_pOleInPlaceActObj-TranslateAccelerator(pMsg); // This causes the tab to work in the WebBrowser window. If you do not do // this, tabbing will happen in the dialog only. You have the choice of // tabbing in the dialog or the WebBrowser window, not both. if (pMsg-wParam == VK_TAB) ZeroMemory(pMsg, sizeof(MSG)); } return CallNextHookEx(g_hook, nCode, wParam, lParam); } Finally, when your application is shutting down or when you no longer need the hook, unhook the procedure. UnhookWindowsHookEx(g_hook); "Dmitry Streblechenko" wrote: So you do see the message and it gets forwarded, right? -- Dmitry Streblechenko (MVP) http://www.dimastr.com/ OutlookSpy - Outlook, CDO and MAPI Developer Tool - "Reinwald" wrote in message ... Hey, The code we tried out after reading your suggestion llKeyHook = SetWindowsHookEx(WH_GETMESSAGE, GetMessageProc, 0, GetCurrentThreadId()); LRESULT CALLBACK GetMessageProc(int code, WPARAM wParam, LPARAM lParam) { const MSG *pMsg = (MSG *) lParam; HWND panel = FindWindowEx(application_Handle, NULL, NULL, _T("PanelDialog")); if (panel) { HWND hWndCtl = ::GetFocus(); if(::IsChild(panel, hWndCtl)) { if (wParam & PM_REMOVE) { if (pMsg-message = WM_KEYFIRST && pMsg-message = WM_KEYLAST) { if (pMsg-message == WM_KEYDOWN && (pMsg-wParam == VK_BACK || pMsg-wParam == VK_DELETE)) { ::TranslateMessage(pMsg); return ::SendMessage(hWndCtl, pMsg-message, pMsg-wParam, pMsg-lParam); } } } } } return ::CallNextHookEx(0, code, wParam, lParam); } As i mentioned before this hook works for the backspace key.Any other suggestion to get the delete key working? "Dmitry Streblechenko" wrote: I have no problem with the following hook in Outlook (Delphi): initialization g_hook := SetWindowsHookEx(WH_GETMESSAGE, RAHLEditorHookProc, 0, GetCurrentThreadId()); finalization UnhookWindowsHookEx(g_hook); end. var g_hook : HHOOK; function RAHLEditorHookProc(Code : integer; wParam : WPARAM; lParam : LPARAM):LResult;stdcall; var pMsg : ^TMsg; //ClassName:string; Ctrl{, NextCtrl} : TWinControl; ParentFrm : TCustomForm; begin pMsg:=pointer(lParam); if ((wParam and PM_REMOVE) = PM_REMOVE) then begin if (pMsg.message = WM_KEYFIRST) and (pMsg.message = WM_KEYLAST) then begin if ((pMsg.message = WM_KEYDOWN) or (pMsg.message = WM_KEYUP)) and (pMsg.wParam VK_RETURN) and //ignore "Return" keys ((pMsg.wParam = VK_BACK) or (pMsg.wParam = VK_DELETE) or (pMsg.wParam = VK_TAB) or (pMsg.wParam = VK_SPACE) or //(pMsg.wParam = VK_LEFT) or (pMsg.wParam = VK_RIGHT) or (GetKeyState(VK_CONTROL) 0) or //Control key (GetKeyState(VK_MENU) 0) or //Alt key ((pMsg.lParam and (1 shl 24)) 0) or //extended key {(pMsg.wParam = VK_RETURN) or} (pMsg.wParam = VK_UP) or (pMsg.wParam = VK_DOWN)) then begin //SetLength(ClassName, 1024); //SetLength(ClassName, GetClassName(pMsg.hwnd, PChar(ClassName), Length(ClassName))); //if (ClassName = 'TRAHLEditor') then begin Ctrl:=FindDelphiControl(pMsg.hwnd); if Ctrl nil then begin //is it a Delphi control? if (pMsg.wParam = VK_TAB) then begin if (pMsg.message = WM_KEYDOWN) then begin ParentFrm:=GetParentForm(Ctrl); if ParentFrm nil then begin TCheatControl(ParentFrm).SelectNext(Ctrl, true, true); //PostMessage(ParentFrm.Handle, WM_NEXTDLGCTL, 0, 0); end; end; end else begin TranslateMessage(pMsg^); SendMessage(pMsg.hwnd, pMsg.message, pMsg.wParam, pMsg.lParam); end; pMsg.message :=WM_NULL; end; end end end; Result:=CallNextHookEx(g_hook, Code, wParam, lParam); end; -- Dmitry Streblechenko (MVP) http://www.dimastr.com/ OutlookSpy - Outlook, CDO and MAPI Developer Tool - "Reinwald" wrote in message ... Our VB6.0 Outlook addin loads a panel (written in VC++) containing an internet explorer control in both the inspector and explorer views. The internet explorer control displays an HTML file with a simple text input. We faced similar issues with the backspace and delete key events being eaten up by Outlook and not forwarded to the text input. So we tried out a solution similar to the one posted by you, where we used SetWindowsHookEx to catch the delete and backspace keypress events and send appropriate messages to the panel window. While this does seem to work for backspace in both the explorer and inspector views, the delete keypress event *still* seems to be eaten up by Outlook. This is what our callback for the SetWindowsHookEx looks like : LRESULT CALLBACK LowLevelKeyboardProc(INT nCode, WPARAM wParam, LPARAM lParam){ LRESULT lRes; KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *) lParam; if ( pkbhs-vkCode == VK_DELETE || pkbhs-vkCode == VK_BACK) { if(outlook_mainwindow_Handle) { HWND panel = FindWindowEx(outlook_mainwindow_Handle, NULL, NULL, _T ("PanelDialog")); if (panel) { HWND hWndCtl = ::GetFocus(); if(::IsChild(panel, hWndCtl)) { if (wParam == WM_KEYDOWN) { ::SendMessage(hWndCtl, WM_KEYDOWN, pkbhs-vkCode, 0); } return 1; } } } } lRes = CallNextHookEx (0, nCode, wParam, lParam); return lRes; } Any idea how we can get the delete key working? |
Thread Tools | Search this Thread |
Display Modes | |
|
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
Capturing user Keypress in Outlook VBA | Praveen Mishra | Outlook and VBA | 3 | April 1st 08 01:42 PM |
Stop baby eating in CHINA | LPC | Outlook - Using Forms | 0 | January 29th 08 03:35 PM |
Stop baby eating in CHINA | LPC | Outlook - Calandaring | 0 | January 29th 08 03:25 PM |
Keypress and OLKCombobox on form region | shubhangi | Outlook and VBA | 1 | October 23rd 07 04:14 PM |
Outlook 2007, proofing options greyed out in Editing Options dialog | Rojo Habe | Outlook - General Queries | 4 | October 8th 07 11:33 PM |