Link to home
Start Free TrialLog in
Avatar of josekv
josekv

asked on

Bringing a window to the foreground from Win32 DLL

I have installed a keyboard hook thru Win32 DLL.
My application that uses the hook is based on SDI FormView.

I am sending a WM_SETTEXT message from the Hook Filter function to one of the edit controls in the formview.

I pass the Edit control's window handle as well as the the mainframe window handle to the dll when I install the hook for the first time.

Now the problem is, if my application's frame window has the focus, the message from the dll is processed.
If some other application has the focus this message is not
processed. I used the SetForeGroundWindow and ShowWindow
APIs before sending the message but failed.

It seems that that once the application looses the input focus, the Handles I pass as parameters becomes NULL.

How to bring an application to the foreground and also how to popup a hidden window from a Win32 DLL?



Avatar of migel
migel

Hi!
You must declare shared section in the your dll. see PAQ there are many question  about this
Avatar of josekv

ASKER

I already have declared the handles in the shard section
even though there is only one instance of the application
running.

When the application is in the foreground, I get no problem. When it goes to the background, I am not able
to bring it to the foreground using the APIs. ex.SetForeGroundWindow etc..  When I debug, I find the
value of Handle parameter becomes zero. Once I bring the application to the foreground using mouse, again the original value of the Handle is restored.  

Since I am using a Win32 DLL I can't call mfc equivalents.

regards




>I pass the Edit control's window handle as well as the the mainframe window handle to the dll when I install the hook for the first time.
You passed the handles to DLL only once at the beggining of your programming running, right? And the value in the DLL actually changes to NULL sometimes and change back to normal when its running? Sounds very weird. Better post some related codes here.
Avatar of josekv

ASKER

I am posting the entire code as it is. Pl look into it.


#include "windows.h"
#include "stdio.h"

#define DllExport __declspec(dllexport)
DllExport void WINAPI InstallHook (HWND hWnd,HWND hFrameWnd);
LRESULT CALLBACK KeyboardHook (int nCode, WORD wPAram,DWORD lPAram,HWND hMainFrameWnd,HWND hWnd);

HANDLE hDLLInst = 0;

#pragma data_seg ( "CommMem")
       HHOOK hHook = NULL;
         HWND hWndMain = NULL;
       HWND hMainFrameWnd = NULL;
#pragma data_seg()

BOOL WINAPI DllMain (HANDLE hModule, DWORD dwFunction, LPVOID lpNot)
{
      hDLLInst =hModule;
      switch (dwFunction)
      {
      case DLL_PROCESS_ATTACH:
      case DLL_PROCESS_DETACH:
      default:
            break;
    }
      return TRUE;

}

DllExport void WINAPI InstallHook (HWND hWnd, HWND hFrameWnd)
{
      hWndMain = hWnd; // handle to Edit Window
      hMainFrameWnd = hFrameWnd; //handle to Mainframe  
                                    //Window
if (hHook == NULL)
            hHook =
   (HHOOK) SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardHook,hDLLInst,0);
      else
            {
            UnhookWindowsHookEx(hHook);
          hHook = NULL;
            }
}

LRESULT CALLBACK KeyboardHook (int nCode, WORD wParam, DWORD lParam,HWND hMainFrameWnd,HWND hWnd)
{
      BOOL ret;
      char Buf[50];
      LRESULT lResult = 0;
      if (nCode == HC_ACTION)
      {
    if (wParam == 'B' &&  GetKeyState(VK_CONTROL) && (lParam & 0x80000000))
         {
            lResult = 1;

            ret = SetForegroundWindow(hMainFrameWnd);
            //if (ret!=FALSE)
            //         MessageBox(NULL,"Window Brought to Foreground",NULL,0);
            //BringWindowToTop(hMainFrameWnd);
            //ShowWindow(hMainFrameWnd,SW_SHOW);
            SetActiveWindow(hMainFrameWnd);
       
            //SendMessage(hMainFrameWnd,WM_SHOWWINDOW,TRUE,0);
            //SendMessage(hMainFrameWnd,WM_SETFOCUS,0,0);
            SendMessage(hWndMain,WM_SETFOCUS,0,0);
            SendMessage(hWndMain,WM_SETTEXT,0,(LPARAM) "Set BookMark");
            SendMessage(hWndMain,WM_SETTEXT,0,(LPARAM) "Set BookMark");
            return lResult;
            }
      
      if (wParam == 'D' &&  GetKeyState(VK_CONTROL) && (lParam & 0x80000000))
         {
            lResult = 1;
//              MessageBox(NULL,"Control D is pressed",NULL,0);
            ShowWindow(hMainFrameWnd,SW_SHOW);
//            ShowWindow(hWndMain,SW_SHOW);
            SendMessage(hWndMain,WM_SETTEXT,0,(LPARAM) "Remove BookMark");
            return lResult;
            }
      }
 return (int) CallNextHookEx(hHook, nCode, wParam, lParam);
}




Did you also set the shared data segment in your DEF file?

MS article Q125677 has details on how to share data in a DLL. An excerpt is below.

Sample Code

   #pragma data_seg(".shared")
   int iSharedVar = 0;
   #pragma data_seg()

The first line directs the compiler to place all the data declared in this section into the .shared data segment. Therefore, the iSharedVar variable is stored in the .shared segment. By default, data is not shared. Note that you must initialize all data in the named section. The data_seg pragma applies only to initialized data. The third line, #pragma data_seg(), resets allocation to the default data section.
If one application makes any changes to variables in the shared data section, all mappings of this DLL will reflect the same changes, so you need to be careful when dealing with shared data in applications or DLLs.

You must also tell the linker that the variables in the section you defined are to be shared by modifying your .DEF file to include a SECTIONS section or by specifying /SECTION:.shared,RWS in your link line. Here's an example SECTIONS section:


   SECTIONS
   .shared   READ WRITE SHARED

Alternatively, some compilers allow you to set the linker switch in your code so that if your file is ever copied to another project, the linker switch goes with it. To do this, include the following line in your code preferably near the #pragma data_seg(".shared") line:

   #pragma comment(linker, "/SECTION:.shared,RWS")

Be careful not to include any extraneous spaces inside the quotation marks because this may cause the linker to misinterpret the directive. In the case of a typical hook DLL, the HHOOK, HINSTDLL, and other variables can go into the shared data section.

Avatar of josekv

ASKER

Oh no!! I am not using a DEF file at all!!!...

Avatar of josekv

ASKER

rberg, u r God Sent for me!!!

Pl go ahead and answer the question.

I forgot to remember that HOOK DLLS are attached to
all processes. I did not care to define the DEF file.

Thanks a lot.....


ASKER CERTIFIED SOLUTION
Avatar of rberg
rberg

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial