0

在我的 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 发送的方式上,但是我一直在搜索一整天,找不到替代方法。

我也试过设置 this->Visible = false; 但后来我不知道如何触发它从 DLL 中恢复可见(滥用 sendmessage?)。

我不是 C++ 程序员,我通常只用托管语言编程,所以任何帮助(和耐心表示赞赏。

谢谢,

缺口。

注意

我无法解释的一件奇怪的事情是我不能从 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

[编辑1]

汉斯帕桑特说:

您在 ShowWindow() 尝试中收到的链接器错误消息也是您当前代码无法正常工作的强烈暗示。您忘记添加错误检查代码,GetProcAddress() 可能会失败并返回 NULL 指针。它将,该功能不会由“hideme”名称导出。在 32 位版本中,它将导出为“_hideme”,请注意下划线。添加它以指示该函数使用 __cdecl 调用约定。ShowWindow 上的链接器错误演示了 C++ 名称修饰,您忘记了 #include windows.h 并为 ShowWindow 编造了您自己的不正确声明。

这不是正确的方法,您应该将 Visible 属性设置为 false。就像你试过的那样。为什么你不能将它设置回 true 是非常难以猜测的。

你说的话对我来说毫无意义,有几个原因。

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,因为我需要一个全局挂钩来响应我的热键和 WH_CBT。在这种情况下,我希望程序开始隐藏并在按下组合键时显示设置屏幕。

程序中的一切都按预期工作,热键就像一个魅力,唯一我不能正确的,是显示应用程序,从 DLL 触发。[/EDIT2]

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

4

2 回答 2

1

您在 ShowWindow() 尝试中收到的链接器错误消息也是您当前代码无法正常工作的强烈暗示。您忘记添加错误检查代码,GetProcAddress() 可能会失败并返回 NULL 指针。它将,该功能不会由“hideme”名称导出。在 32 位版本中,它将导出为“_hideme”,请注意下划线。添加它以指示该函数使用 __cdecl 调用约定。ShowWindow 上的链接器错误演示了 C++ 名称修饰,您忘记了 #include windows.h 并为 ShowWindow 编造了您自己的不正确声明。

这不是正确的方法,您应该将 Visible 属性设置为 false。就像你试过的那样。为什么你不能将它设置回 true 是非常难以猜测的。

于 2011-05-28T14:46:41.197 回答
-1

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

我会像在 C# 中那样使用托管 C++ 应用程序中的 PInvoke。的签名SendMessage将是(在 C# 中):

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(
    IntPtr hWnd, 
    UInt32 Msg, 
    IntPtr wParam, 
    IntPtr lParam);
于 2011-05-28T14:43:13.637 回答