Windows API "CreateWindowEx" 可以在 Python (3.6.8) 64 位使用的 DLL 中工作吗?
Will Windows API "CreateWindowEx" work in a DLL used by Python (3.6.8) 64-bit?
我有一个 C++ DLL,它使用 extern "C"
公开了 API 函数,我在 Python 中使用函数 ctypes
包装函数来利用这些函数。本质上,我只是想制作一个包装器来访问我的 DLL 的 API。
但是,我注意到虽然我的大部分功能都可以正常工作,但有关注册回调过程和仅消息的功能 window 利用 Windows API 函数 RegisterClassEx
和 CreateWindowEx
不起作用。
我使用的是 Python (3.6.8) 64 位,所以我想知道是否存在不匹配。我的 DLL 是 64 位的,它可以在其他环境中运行。 Windows API 不起作用有什么原因吗?
调试结果:
我的代码在回调过程中到达了 WM_CREATE
事件,但没有到达 WM_DEVICECHANGE
事件。同样,此代码在其他环境中出现,因此我试图找出使用 Python.
的不同之处
Message-Only Windows 不 接收广播消息:
A message-only window enables you to send and receive messages. It is
not visible, has no z-order, cannot be enumerated, and does not
receive broadcast messages. The window simply dispatches messages.
相反,您应该创建 top-level window 并且不要调用 showWindow
.
此外,您不需要通过DLL调用CreateWindow
/CreateWindowEx
,尝试通过导入模块win32api、win32con、win32gui来使用WinAPI。这是一个 sample.
更新:
无法使用 Message-only window.
接收 WM_DEVICECHANGE
的 C++ 示例
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
MessageBox(NULL, "WM_CREATE", "Message", 0);
break;
case WM_DEVICECHANGE:
MessageBox(NULL, "WM_DEVICECHANGE", "Message", 0);
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
int main()
{
static const char* class_name = "NAME_CLASS";
WNDCLASSEX wx = {};
HWND hwnd;
HINSTANCE hInstance = GetModuleHandleA(NULL);
wx.cbSize = sizeof(WNDCLASSEX);
wx.lpfnWndProc = WndProc; // function which will handle messages
wx.hInstance = hInstance;
wx.lpszClassName = class_name;
if (RegisterClassEx(&wx)) {
hwnd = CreateWindowEx(0, class_name, "Title", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
// hwnd = CreateWindowEx(0, class_name, "Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
// Create a normal top-level window which can receive the broadcast messages.
}
HACCEL hAccelTable = LoadAccelerators(hInstance, class_name);
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
编辑:
创建后需要泵消息 window。
我有一个 C++ DLL,它使用 extern "C"
公开了 API 函数,我在 Python 中使用函数 ctypes
包装函数来利用这些函数。本质上,我只是想制作一个包装器来访问我的 DLL 的 API。
但是,我注意到虽然我的大部分功能都可以正常工作,但有关注册回调过程和仅消息的功能 window 利用 Windows API 函数 RegisterClassEx
和 CreateWindowEx
不起作用。
我使用的是 Python (3.6.8) 64 位,所以我想知道是否存在不匹配。我的 DLL 是 64 位的,它可以在其他环境中运行。 Windows API 不起作用有什么原因吗?
调试结果:
我的代码在回调过程中到达了 WM_CREATE
事件,但没有到达 WM_DEVICECHANGE
事件。同样,此代码在其他环境中出现,因此我试图找出使用 Python.
Message-Only Windows 不 接收广播消息:
A message-only window enables you to send and receive messages. It is not visible, has no z-order, cannot be enumerated, and does not receive broadcast messages. The window simply dispatches messages.
相反,您应该创建 top-level window 并且不要调用 showWindow
.
此外,您不需要通过DLL调用CreateWindow
/CreateWindowEx
,尝试通过导入模块win32api、win32con、win32gui来使用WinAPI。这是一个 sample.
更新:
无法使用 Message-only window.
接收WM_DEVICECHANGE
的 C++ 示例
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
MessageBox(NULL, "WM_CREATE", "Message", 0);
break;
case WM_DEVICECHANGE:
MessageBox(NULL, "WM_DEVICECHANGE", "Message", 0);
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
int main()
{
static const char* class_name = "NAME_CLASS";
WNDCLASSEX wx = {};
HWND hwnd;
HINSTANCE hInstance = GetModuleHandleA(NULL);
wx.cbSize = sizeof(WNDCLASSEX);
wx.lpfnWndProc = WndProc; // function which will handle messages
wx.hInstance = hInstance;
wx.lpszClassName = class_name;
if (RegisterClassEx(&wx)) {
hwnd = CreateWindowEx(0, class_name, "Title", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
// hwnd = CreateWindowEx(0, class_name, "Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
// Create a normal top-level window which can receive the broadcast messages.
}
HACCEL hAccelTable = LoadAccelerators(hInstance, class_name);
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
编辑:
创建后需要泵消息 window。