隐藏一个winform&从DLL中恢复它

时间:2011-05-28 14:29:30

标签: c++ winforms dll name-decoration

在我的DDL中,我定义了以下功能:

extern "C" __declspec(dllexport) void hideme(HWND h) {
    //ShowWindow(h, SW_HIDE);
    SendMessage(h, WM_SHOWWINDOW, FALSE, 0);
}

正如你所看到的,我已经尝试过多种方法来实现这个目标......

我在winform中声明如下:

typedef void (*HideMe)(HWND); 

在我的System :: Windows :: Forms :: Form Load事件中,我有以下代码:

...
HINSTANCE hinst = LoadLibrary(_T("My.dll"));
if (hinst == NULL)
    System::Diagnostics::Debug::WriteLine("null hinst"); 
else
    hideme = (HideMe) GetProcAddress(hinst, "hideme");
...

在我的System :: Windows :: Forms :: Form Shown事件中,我有以下代码:

...
hideme((HWND)this->Handle.ToPointer());
...

我认为问题必然在于我通过HWND发送的方式,但我一整天都在搜索,找不到替代方案。

我也试过设置这个 - > Visible = false;但后来我无法弄清楚如何从DLL中触发它(滥用sendmessage?)。

我不是C ++程序员,我通常只使用托管语言编程,所以任何帮助(并且耐心都受到赞赏。

谢谢,

尼克。

N.B。

我无法解释的一个奇怪的事情是我不能从WinForm本身调用ShowWindow。它会抛出这个宝石:

Error   2   error LNK2028: unresolved token (0A00001E) "extern "C" int __stdcall ShowWindow(struct HWND__ *,int)" (?ShowWindow@@$$J18YGHPAUHWND__@@H@Z) referenced in function "private: void __clrcall CheckMSNCpp::frmMain::frmMain_Shown(class System::Object ^,class System::EventArgs ^)" (?frmMain_Shown@frmMain@CheckMSNCpp@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
Error   3   error LNK2019: unresolved external symbol "extern "C" int __stdcall ShowWindow(struct HWND__ *,int)" (?ShowWindow@@$$J18YGHPAUHWND__@@H@Z) referenced in function "private: void __clrcall CheckMSNCpp::frmMain::frmMain_Shown(class System::Object ^,class System::EventArgs ^)" (?frmMain_Shown@frmMain@CheckMSNCpp@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
Error   4   error LNK1120: 2 unresolved externals

[EDIT1]

汉斯帕斯特说:

  

您上传的链接器错误消息   ShowWindow()尝试也是一个   强烈暗示你当前代码的原因   不工作你忘了添加错误   检查代码,GetProcAddress()可以   失败并将返回NULL指针。   它将,该功能不会导出   以“hideme”的名字命名。在一个32位   build,它将被导出为   “_hideme”,请注意下划线。哪一个   被添加以表明该   function使用__cdecl调用   惯例。链接器错误   ShowWindow演示了C ++名称   装修,你忘了#include   windows.h并自己编写,   不正确,ShowWindow声明。

     

这不是正确的做法,   你应该设置Visible   财产到假。就像你试过的那样为什么   你不能把它设置回真实的是   非常不可思议。

你说的话根本没有任何意义。

1)

winform的导入:

#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <stdio.h>

正如你所知,windows.h就在那里。

2)ShowWindor错误不在DLL中,我可以调用它,它在WinForm代码中。

3)我从未导出过ShowWindow,只是我自己的函数。

[/ EDIT1]

[EDIT2] Uwe Keim说:

  

为什么需要额外的DLL   只是另一个DLL的包装器   功能

     

我会像在例如C#使用   来自托管C ++的PInvoke   应用。签名   SendMessage将是(在C#中):

PInvoke的东西没有任何意义,就像评论者说的那样。

至于DLL,它需要是一个DLL,因为我需要一个全局钩子来响应我的热键&amp; WH_CBT。在这种情况下,我希望程序启动隐藏&amp;按键组合时只显示设置屏幕。

程序中的所有内容都按预期工作,热键就像一个魅力,唯一的瘦我无法正确,正在显示从DLL触发的应用程序。 [/ EDIT2]

[EDIT3] 示例代码:http://www.nickkusters.com/CPP_PROBLEM_Demo-NOBIN.zip [/ EDIT3]

2 个答案:

答案 0 :(得分:1)

您在ShowWindow()尝试中获得的链接器错误消息也强烈暗示您当前代码无效的原因。您忘记添加错误检查代码,GetProcAddress()可能会失败并返回NULL指针。它将,该函数不会被“hideme”名称导出。在32位版本中,它将被导出为“_hideme”,请注意下划线。添加了哪个表示该函数使用__cdecl调用约定。 ShowWindow上的链接器错误演示了C ++名称修饰,你忘了#include windows.h并为ShowWindow编写了你自己的错误声明。

这不是正确的方法,您应该将Visible属性设置为false。就像你试过的那样为什么你不能把它恢复为真是非常不可思议的。

答案 1 :(得分:-1)

为什么需要一个额外的DLL,它只是另一个DLL函数的包装器?

我会像在例如C#by using PInvoke from your managed C++ applicationSendMessage的签名是(在C#中):

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(
    IntPtr hWnd, 
    UInt32 Msg, 
    IntPtr wParam, 
    IntPtr lParam);