在一个DLL文件里有这么一段代码:
LRESULT CALLBACK HookWinampWnd(
  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
);WNDPROC pOrigProc;
pOrigProc = (WNDPROC)SetWindowLong(plugin.hwndParent/*HWND类型*/, GWL_WNDPROC, (LONG)HookWinampWnd/*回调函数*/); //调用SetWindowLong函数,为什么要用会掉函数作为第四个参数呢?
CWnd wndTemp; //定义临时变量wndTemp
wndTemp.Attach(plugin.hwndParent);m_MainWnd.Create(&wndTemp);//创建m_MainWnd主窗口,该变量已定义CMyMainWnd,作为DLL文件里的主窗口,然后再根据wndTemp输入参数注册窗口,并调用CreateEx()函数创建(HWND hwndParent输入参数为wndTemp->GetSafeHwnd())。主窗口能够显示出来,但是在调用GetParent()函数获得其父亲指针时就出错了,请问是什么原因?

解决方案 »

  1.   

    以上就是DLL文件里的代码,我在程序里掉用了这个文件,结果出错,出错的原因可能是因为指向父亲类的指针为空,对于DLL文件来说,怎样才能获得调用它的那个客户程序(父亲窗口类)的句柄呢?是不是就调用SetWindowLong(plugin.hwndParent/*HWND类型*/, GWL_WNDPROC, (LONG)HookWinampWnd/*回调函数*/);函数?最后一个参数应该怎样设置?在这里用了一个回调函数HookWinampWnd,这样做是什么原因呢?
     
      

  2.   

    SetWIndowLong 函数可用于实现窗口子类化:窗口子类化方法  应用程序为了登记一个窗口类,首先要填写好一个WNDCLASS结构,其中的结构参数lpfnWndProc就是该类窗口函数的地址,接着调用RegisterClass()函数向Windows系统申请登记这个窗口类。这时Windows会为其分配一块内存来存放该类的全部信息,这个内存块称为窗口类内存块。  当应用程序要创建一个属于某一已登记窗口类的窗口时,Windows便为这个窗口分配一块内存,即窗口内存块,用来存放与该窗口有关的专用信息。这些信息一部分来自传递给窗口创建函数CreateWindow()或CreateWindowEx()的参数信息,另一部分则来自所属窗口类的窗口类内存块,其中参数lpfnWndProc便被Windows从窗口类内存块复制到为新创建窗口分配的窗口内存块中。当有消息被发送到这个窗口时,Windows检查该窗口内存块中的窗口函数地址(lpfnWndProc),并调用该地址上的函数来处理这些消息。  所谓窗口子类化,实际上就是改变窗口内存块中的有关参数。由于这种修改只涉及到一个窗口的窗口内存块,因此它不会影响到属于同一窗口类的其它窗口的功能和表现。窗口子类化中最常见的是修改窗口内存块中的窗口函数地址(lpfnWndProc),使其指向一个新的窗口函数,从而改变原窗口函数的处理方法,改进其功能。其基本步骤如下:  (1)编写子类化窗口函数。该函数必须为标准的窗口函数格式即:  LRESULT CALLBACK SubClassWndProc ( HWND , UINT , WPARAM , LPARAM ) ;  在这个函数中对感兴趣的消息进行处理,而把未处理或者需要原窗口函数进一步处理的消息传送给原窗口函数;  (2)利用待子类化窗口的句柄hWnd,调用GetWindowLong ( hWnd , GWL_WNDPROC ) 函数获得原窗口函数的地址并保存起来;  (3)调用SetWIndowLong ( hWnd , GWL_WNDPROC , SubClassWndProc ) 把窗口函数设置成子类化窗口函数,完成窗口子类化。详细资料可参看http://www.vcfan.com/vc/example/0601/60117.htm在你的程序里无法获得父亲类指针,问题可能不是出现在这里,plugin.hwndParent从何而来呢?