简体   繁体   English

隐藏 winform 并从 DLL 中恢复

[英]Hiding a winform & bringing it back from a DLL

In my DDL, I have the following function defined:在我的 DDL 中,我定义了以下 function:

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

As you can see, I've tried multiple things to get this working...如您所见,我已经尝试了多种方法来使其正常工作...

I have it declared in my winform as followed:我在我的winform中声明如下:

typedef void (*HideMe)(HWND); 

In my System::Windows::Forms::Form Load event, I have the following code:在我的 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");
...

In my System::Windows::Forms::Form Shown event, I have the following code:在我的 System::Windows::Forms::Form 显示的事件中,我有以下代码:

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

I think the problem must lie in the way I send over the HWND, but I've been searching all day, and can't find an alternative.我认为问题一定出在我通过 HWND 发送的方式上,但是我一直在搜索一整天,找不到替代方法。

I've also tried setting this->Visible = false;我也试过设置 this->Visible = false; but then I can't figure out how to trigger it back to visible from the DLL (abuse sendmessage?).但后来我不知道如何从 DLL 将其触发回可见(滥用发送消息?)。

I'm not a C++ programmer, I normally only program in managed languages, so any help (and patience is appreciated.我不是 C++ 程序员,我通常只用托管语言编程,所以任何帮助(和耐心表示赞赏。

Thanks,谢谢,

Nick.缺口。

NB注意

One weird thing I can't explain is that I can't call ShowWindow from the WinForm itself.我无法解释的一件奇怪的事情是我不能从 WinForm 本身调用 ShowWindow。 It will throw up this gem:它会抛出这个宝石:

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] [编辑1]

Hans Passant said:汉斯帕桑特说:

The linker error message you got on the ShowWindow() attempt is also a strong hint why your current code is not working.您在 ShowWindow() 尝试中收到的 linker 错误消息也是您当前代码无法正常工作的强烈提示。 You forgot to add error checking code, GetProcAddress() can fail and will return a NULL pointer.您忘记添加错误检查代码,GetProcAddress() 可能会失败并返回 NULL 指针。 It will, the function isn't exported by the "hideme" name.它会,function 不会由“隐藏”名称导出。 In a 32-bit build, it will be exported as "_hideme", note the underscore.在 32 位版本中,它将导出为“_hideme”,请注意下划线。 Which was added to indicate that the function uses the __cdecl calling convention.添加它以表明 function 使用 __cdecl 调用约定。 The linker error on ShowWindow demonstrates C++ name decoration, you forgot to #include windows.h and made up your own, incorrect, declaration for ShowWindow. ShowWindow 上的 linker 错误演示了 C++ 名称装饰,您忘记了 #include windows.h 并为 ShowWindow 编写了自己的不正确声明。

This is not the right way to do it, you should just set the Visible property to false.这不是正确的方法,您应该将 Visible 属性设置为 false。 Like you tried.就像你试过的那样。 Why you cannot set it back to true is quite unguessable.为什么你不能将它设置回 true 是非常难以猜测的。

What you said makes no sense to me at all for a few reasons.你说的话对我来说毫无意义,有几个原因。

1) 1)

The imports for the winform: winform 的导入:

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

As you can tell, windows.h is in there.如您所知,windows.h 就在其中。

2) the ShowWindor error is not in the DLL, there I can call it fine, it's in the WinForm code. 2) ShowWindor 错误不在 DLL 中,我可以称之为正常,它在 WinForm 代码中。

3) I never exported ShowWindow, just my own functions. 3)我从来没有导出过ShowWindow,只是我自己的函数。

[/EDIT1] [/EDIT1]

[EDIT2] Uwe Keim said: [EDIT2] Uwe Keim 说:

Why do you need an extra DLL that is merely just a wrapper to another DLL function?为什么你需要一个额外的 DLL,它只是另一个 DLL function 的包装?

I would do it like in eg C# by using PInvoke from your managed C++ application.我会像在 C# 中那样使用托管 C++ 应用程序中的 PInvoke。 The signature for SendMessage would be (in C#): SendMessage 的签名将是(在 C# 中):

The PInvoke stuff just doesn't make any sense, like commenters said.正如评论者所说,PInvoke 的东西没有任何意义。

As for the DLL, it needs to be a DLL because i require a global hook to respond to my hotkeys & WH_CBT.至于 DLL,它必须是 DLL,因为我需要一个全局挂钩来响应我的热键和 WH_CBT。 In this case, I want the program to start hidden & just show a setting screen when pressing a key combo.在这种情况下,我希望程序开始隐藏并在按下组合键时显示设置屏幕。

Everything in the program works as expected, the hotkey works like a charm, the only thin I can't get right, is showing the application, triggered from the DLL.程序中的一切都按预期工作,热键就像一个魅力,唯一我不能正确的瘦,是显示应用程序,从 DLL 触发。 [/EDIT2] [/EDIT2]

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

The linker error message you got on the ShowWindow() attempt is also a strong hint why your current code is not working.您在 ShowWindow() 尝试中收到的 linker 错误消息也是您当前代码无法正常工作的强烈提示。 You forgot to add error checking code, GetProcAddress() can fail and will return a NULL pointer.您忘记添加错误检查代码,GetProcAddress() 可能会失败并返回 NULL 指针。 It will, the function isn't exported by the "hideme" name.它会,function 不会由“隐藏”名称导出。 In a 32-bit build, it will be exported as "_hideme", note the underscore.在 32 位版本中,它将导出为“_hideme”,请注意下划线。 Which was added to indicate that the function uses the __cdecl calling convention.添加它以表明 function 使用 __cdecl 调用约定。 The linker error on ShowWindow demonstrates C++ name decoration, you forgot to #include windows.h and made up your own, incorrect, declaration for ShowWindow. ShowWindow 上的 linker 错误演示了 C++ 名称装饰,您忘记了 #include windows.h 并为 ShowWindow 编写了自己的不正确声明。

This is not the right way to do it, you should just set the Visible property to false.这不是正确的方法,您应该将 Visible 属性设置为 false。 Like you tried.就像你试过的那样。 Why you cannot set it back to true is quite unguessable.为什么你不能将它设置回 true 是非常难以猜测的。

Why do you need an extra DLL that is merely just a wrapper to another DLL function?为什么你需要一个额外的 DLL,它只是另一个 DLL function 的包装?

I would do it like in eg C# by using PInvoke from your managed C++ application .我会像在 C# 中那样使用托管 C++ 应用程序中的 PInvoke The signature for SendMessage would be (in C#): SendMessage的签名将是(在 C# 中):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM