所以基本上我有一个由GUI应用程序加载的插件DLL。在这个DLL中,我需要检测Windows何时进入休眠状态。我无法修改GUI-App。 GetMessage只在调用线程与UI线程相同时才起作用,而不是。有任何想法吗?如何在不运行Win32 GUI应用程序时获取Windows Power State Message(WM_POWERBROADCAST)?
回答
您可以在DLL代码的单独线程中创建一个隐藏窗口。并处理消息如下所示。
你可以使用这个Window类。
#pragma once
#include <windows.h>
#include <process.h>
#include <iostream>
using namespace std;
static const char *g_AppName = "Test";
class CMyWindow
{
HWND _hWnd;
int _width;
int _height;
public:
CMyWindow(const int width,const int height):_hWnd(NULL),_width(width),_height(height)
{
_beginthread(&CMyWindow::thread_entry, 0, this);
}
~CMyWindow(void)
{
SendMessage(_hWnd, WM_CLOSE, NULL, NULL);
}
private:
static void thread_entry(void * p_userdata)
{
CMyWindow * p_win = static_cast<CMyWindow*> (p_userdata);
p_win->create_window();
p_win->message_loop();
}
void create_window()
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = &CMyWindow::WindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = GetModuleHandle(NULL);
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = g_AppName;
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wcex);
_hWnd = CreateWindow(g_AppName, g_AppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, GetModuleHandle(NULL), NULL);
ShowWindow(_hWnd, SW_SHOWDEFAULT);
UpdateWindow(_hWnd);
}
void message_loop()
{
MSG msg = {0};
while (GetMessage(&msg, NULL, 0, 0))
{
if(msg.message == WM_QUIT)
{
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
static LRESULT WINAPI WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_POWERBROADCAST:
{
//power management code here
}
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
};
此外请确保包含退出条件。
您可以让您的DLL的用户通过他们的HWND。一旦你有这个句柄,你可以GetWindowLongPtr窗口过程(GWL_WNDPROC),然后SetWindowLongPtr你自己的窗口过程,将处理WM_POWERBROADCAST并将所有消息传递到您从初始GetWindowLongPtr存储的旧窗口过程。
当DLL退出时,您可以将SetWindowLongPtr设置为其自己的窗口过程,即使您的DLL已卸载,thinigs仍会继续良好地播放。
这可以工作,但我没有直接的方式来获得HWND句柄。我不得不使用类似FindWindow()的东西来获取句柄。 – 2009-07-22 15:28:50
我遇到了Windows控制台应用程序的类似问题。我写了一篇关于问题是什么的博客文章,隐藏窗口是如何成为唯一的解决方案,以及如何去做。该帖子可用here,源代码可用here。我使用的基本原则与Indeera的答案几乎完全相同。
我不确定您是否必须修改我的解决方案才能在DLL中运行。我相信所有具有消息队列的线程(以及线程在创建窗口时都会执行这些操作)会收到WM_POWERBROADCAST消息,因此即使您由Windows应用程序加载,也可以使用自己的后台消息。
值得注意的是,在系统进入Hibernate之前(例如从关键电池状态)或任何其他睡眠状态,您不能保证收到通知。但是,如果在发生此类事件后系统重新联机,您将收到PBT_APMRESUMEAUTOMATIC事件(或在Vista之前的系统上为PBT_APMRESUMECRITICAL)。
- 1. 如何在windows vm上运行gui应用程序?
- 2. 如何运行Windows GUI应用程序作为服务?
- 3. 如何使用Win32 API在Windows中获取应用程序的进程HANDLE
- 4. pyqt4 gui应用程序不运行
- 5. 如何获取运行时Web应用程序路径?
- 6. 如何在运行时获取应用程序ID
- 7. 在Windows XP 64位下运行Win32 IIS应用程序
- 8. Glade C++应用程序,在运行时GUI设计不一样
- 9. Win32 GUI演示应用程序到Java(小程序)GUI
- 10. 在同步模式下运行Windows GUI应用程序?
- 11. 是否可以在Windows容器中运行GUI应用程序?
- 12. 在Windows服务模式下运行GUI应用程序
- 13. 如何在不支持GUI的无头Linux上运行Java GUI应用程序?
- 14. 学习Win32开发GUI应用程序
- 15. 如何在Windows Phone应用程序中使用F#Power Pack
- 16. 如何获取我的应用程序运行时间?
- 17. 如何开发在Windows启动之前运行的GUI程序?
- 18. 如何在Docker for Mac上运行GUI应用程序?
- 19. 如何在Win32 C++程序在后台运行时检测KeyPress
- 20. 无法将Visual Web Gui应用程序运行到Windows Azure
- 21. 如何在Windows 7上运行Windows 8使vb应用程序?
- 22. 如何在node.js运行的应用程序中获取日期?
- 23. 定时器不在Windows服务应用程序中运行
- 24. 应用程序在Windows XP中运行良好,但在Windows 7中运行时应用程序崩溃?
- 25. 在mini2440主板上运行GUI应用程序时出错
- 26. 如何获得Windows的运行的应用程序不是所有的过程
- 27. Windows服务如何执行GUI应用程序?
- 28. 在运行时获取iPhone应用程序的产品名称?
- 29. 在运行GWT应用程序时获取Unitcahche异常
- 30. 在运行时获取应用程序的路径+ cocoa
谢谢,这完美的作品! – 2009-07-22 15:26:51
真的很好的例子..我可以知道如何在应用程序中使用这个DLL吗? – RDX 2016-11-15 06:10:25