隐藏一个通知并将其从DLL中带回
Hiding a winform & bringing it back from a DLL
在我的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
[编辑1]
Hans Passant说:
您收到的链接器错误消息ShowWindow()尝试也是强烈提示您当前代码的原因不起作用。您忘记添加错误检查代码,GetProcAddress()可以失败并将返回一个NULL指针。会的,函数不会导出以"隐藏者"的名字命名。在32位生成,它将导出为"_hidme",注意下划线。哪一个添加以表示函数使用__cdecl调用习俗上的链接器错误ShowWindow演示C++名称装饰,你忘了#includewindows。h并自己制作,ShowWindow的声明不正确。
这不是正确的做法,您应该只设置Visible属性设置为false。就像你试过的那样。为什么?你不能把它还原为真的很难找到。
你说的话对我来说毫无意义,原因有几个。
1)
winform:的导入
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <stdio.h>
正如你所知,windows.h在里面。
2) ShowWindor错误不在DLL中,我可以称之为fine,它在WinForm代码中。
3) 我从未导出过ShowWindow,只是导出了我自己的函数。
[/EDIT1]
[编辑2]Uwe Keim说:
为什么你需要一个额外的DLL只是另一个DLL的包装器作用
我会像在C#中那样使用PInvoke来自您的托管C++应用的签名SendMessage将是(在C#中):
正如评论者所说,PInvoke的东西毫无意义。
至于DLL,它需要是一个DLL,因为我需要一个全局挂钩来响应我的热键&WH_CBT。在这种情况下,我希望程序启动隐藏&只需在按下组合键时显示设置屏幕。
程序中的一切都如预期的那样工作,热键的工作方式就像一个魅力,唯一我做不到的是显示应用程序,从DLL触发。[/EDIT2]
[编辑3]示例代码位于:http://www.nickkusters.com/CPP_PROBLEM_Demo-NOBIN.zip[/EDIT3]
您在ShowWindow()尝试中收到的链接器错误消息也是当前代码无法工作的有力提示。您忘记添加错误检查代码,GetProcAddress()可能会失败并返回NULL指针。会的,函数不会以"隐藏"名称导出。在32位构建中,它将被导出为"_hidme",请注意下划线。添加它是为了指示该函数使用__cdecl调用约定。ShowWindow上的链接器错误演示了C++名称修饰,您忘记了#includewindows.h,并为ShowWindow编写了自己的错误声明。
这不是正确的方法,您应该将Visible属性设置为false。就像你试过的那样。你为什么不能把它还原成真的,这是完全不可辩驳的。
为什么需要一个额外的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);
- 挂起和取消挂起一个文件DLL
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 导入库可以跨dll版本工作吗
- 从C++dll访问C#中的一行主要参数
- 链接到自行创建的dll失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 如何指定我希望我的LIB链接到的DLL文件?-Visual Studio 2019
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- C++:将外部库链接到dll库
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 不同的Visual Studio版本中缺少.dll
- 从DLL中删除类的实例
- 如何包装第三方DLL在R中使用
- 使用c#访问c++dll中带有char*参数的函数时发生AccessViolationException
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 为什么导入Mixed native/CLR lib.dll的本机C++应用程序没有在Mixed lib.dll中的外部变
- 在DLL中使用的最简单的C++PUSH通知/POST解决方案
- 如何通知调试器运行时链接的 DLL 文件的位置
- 隐藏一个通知并将其从DLL中带回