Windows API“ CreateWindowEx”是否可以在Python(3.6.8)64位使用的DLL中使用?

时间:2019-07-17 00:40:16

标签: python c++ windows winapi ctypes

我有一个带有extern "C"公开API函数的C ++ DLL,并且我在Python中使用函数ctypes包装函数来利用这些函数。本质上,我只想包装一个即可访问我的DLL的API。

但是,我注意到虽然我的大多数功能都能正常工作,但是有关注册的回调过程和使用Windows API函数RegisterClassExCreateWindowEx的仅消息窗口的功能无法正常工作。

我正在使用64位Python(3.6.8),所以我想知道是否可能存在不匹配。我的DLL是64位的,并且可以在其他环境中使用。 Windows API不能正常工作吗?

调试结果:

我的代码在回调过程中到达了WM_CREATE事件,但没有达到WM_DEVICECHANGE事件。同样,在其他环境中也可以访问此代码,因此我试图找出使用Python的不同之处。

1 个答案:

答案 0 :(得分:1)

Message-Only Windows 接收广播消息:

  

仅消息窗口使您可以发送和接收消息。它是   不可见,没有z顺序,无法枚举并且不   接收广播消息。窗口只是调度消息。

相反,您应该创建一个顶层窗口,并且不要调用showWindow

此外,您不需要通过DLL调用CreateWindow / CreateWindowEx,而是通过导入模块win32api,win32con,win32gui尝试使用WinAPI。这是sample

更新:

在纯消息窗口中无法接收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);
        }
    }
}

编辑:

在创建窗口后需要泵送消息。