《Windows via C/C++》中示例程序DIPS的问题

  前一阶段重温了Windows中的HOOK,由此参考了《Windows via C/C++》中的示例程序——DIPS,但是我发现了一个有趣的问题。
  默认情况下,链接器并不会将支持XP或Vista的manifest链接到程序上,因此,生成的应用程序运行时的控件风格是经典Windows样式,此时,DIPS小工具运行正常。
  但是,当加上如下这段代码(适用于x86 CPU),问题就产生了。
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
  这意味着链接器将会把新的XP或Vista的manifest链接到程序上,使应用程序具有XP或Vista的控件样式。这时,问题产生了。
  这里我贴出程序的主函数代码:
int WINAPI _tWinMain(HINSTANCE hInstExe, HINSTANCE, PTSTR pszCmdLine, int{

   
// Convert command-line character to uppercase.
   CharUpperBuff(pszCmdLine, 1);
   TCHAR cWhatToDo 
= pszCmdLine[0];

   
if ((cWhatToDo != TEXT('S')) && (cWhatToDo != TEXT('R'))) {

      
// An invalid command-line argument; prompt the user.
      cWhatToDo = 0;
   }


   
if (cWhatToDo == 0{
      
// No command-line argument was used to tell us what to
      
// do; show usage dialog box and prompt the user.
      switch (DialogBox(hInstExe, MAKEINTRESOURCE(IDD_DIPS), NULL, Dlg_Proc)) {
         
case IDC_SAVE:    
            cWhatToDo 
= TEXT('S'); 
            
break;

         
case IDC_RESTORE: 
            cWhatToDo 
= TEXT('R');
            
break;
      }

   }


   
if (cWhatToDo == 0{
      
// The user doesn't want to do anything.
      return(0);
   }

   
   
// The Desktop ListView window is the grandchild of the ProgMan window.
   HWND hWndLV = GetFirstChild(GetFirstChild(
      FindWindow(TEXT(
"ProgMan"), NULL)));
   chASSERT(IsWindow(hWndLV));

   
// Set hook that injects our DLL into the Explorer's address space. After 
   
// setting the hook, the DIPS hidden modeless dialog box is created. We 
   
// send messages to this window to tell it what we want it to do.
   chVERIFY(SetDIPSHook(GetWindowThreadProcessId(hWndLV, NULL)));

   
// Wait for the DIPS server window to be created.
   MSG msg;
   GetMessage(
&msg, NULL, 00);      // 请注意这里

   
// Find the handle of the hidden dialog box window.
   HWND hWndDIPS = FindWindow(NULL, TEXT("Wintellect DIPS"));

   
// Make sure that the window was created.
   chASSERT(IsWindow(hWndDIPS));

   
// Tell the DIPS window which ListView window to manipulate
   
// and whether the items should be saved or restored.
   BOOL bSave = (cWhatToDo == TEXT('S'));
   SendMessage(hWndDIPS, WM_APP, (WPARAM) hWndLV, bSave);

   
// Tell the DIPS window to destroy itself. Use SendMessage 
   
// instead of PostMessage so that we know the window is 
   
// destroyed before the hook is removed.
   SendMessage(hWndDIPS, WM_CLOSE, 00);

   
// Make sure that the window was destroyed.
   chASSERT(!IsWindow(hWndDIPS));

   
// Unhook the DLL, removing the DIPS dialog box procedure 
   
// from the Explorer's address space.
   SetDIPSHook(0);  

   
return(0);
}

  看到上面代码中的GetMessage函数(加红色注释那行),该函数是在接收一个来自explorer.exe进程的消息,这个消息是在挂钩DLL注入之后,由挂钩过滤函数发送的。挂钩过滤函数代码如下:
LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) {

   
static BOOL bFirstTime = TRUE;

   
if (bFirstTime) {
      
// The DLL just got injected.
      bFirstTime = FALSE;

      
// Uncomment the line below to invoke the debugger 
      
// on the process that just got the injected DLL.
      
// ForceDebugBreak();

      
// Create the DIPS Server window to handle the client request.
      CreateDialog(g_hInstDll, MAKEINTRESOURCE(IDD_DIPS), NULL, Dlg_Proc);

      
// Tell the DIPS application that the server is up 
      
// and ready to handle requests.
      PostThreadMessage(g_dwThreadIdDIPS, WM_NULL, 00);
   }


   
return(CallNextHookEx(g_hHook, nCode, wParam, lParam));
}

  明显地,这里发送了一个WM_NULL消息给DIPS进程,当使用经典样式的控件时一切安好,经调试得到的MSG结构中的各个字段为正确的值。但是加上了上面那行链接命令后,调试得到的MSG结构的字段压根就不是WM_NULL、0、0,而是一个数值为49211的消息,这样导致了DIPS主线程唤醒,随后的FindWindow可能会返回一个NULL,因为该消息并不是挂钩过滤函数的发送的消息。当然,如果在这里Sleep一下,可以得到正确的窗口句柄,我在GetMessage函数上加了一个do-while循环,结果也的确是这样,几次循环之后可以收到消息为WM_NULL的消息,且参数均为0。
  但是我不明白为什么加上了一条链接命令会这样?不妨大家都试试看,我用的IDE是VS2005。
  哪位高手可以来指导我一下呢?

posted on 2009-06-13 13:37 小虎无忧 阅读(1695) 评论(3)  编辑 收藏 引用 所属分类: DLL

评论

# re: 《Windows via C/C++》中示例程序DIPS的问题 2009-06-17 17:21 Zxjay

我也想知道原因  回复  更多评论   

# re: 《Windows via C/C++》中示例程序DIPS的问题 2009-06-22 13:45 小虎无忧

呵呵,楼上的也调试过了么?是不是我所说的问题啊?  回复  更多评论   

# re: 《Windows via C/C++》中示例程序DIPS的问题 2009-06-22 13:45 小虎无忧

@Zxjay
呵呵,楼上的也调试过了么?是不是我所说的问题啊?  回复  更多评论   


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2009年8月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
303112345

导航

统计

常用链接

留言簿

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜