karamazovbros
karamazovbros

Reputation: 979

Will Windows API "CreateWindowEx" work in a DLL used by Python (3.6.8) 64-bit?

I have a C++ DLL with exposed API function using extern "C" and I utilize these functions in Python using function ctypes wrapper functions. Essentially, I just want to make a wrapper to access the API of my DLL.

However, I noticed that while most of my functions work correctly, the functionality regarding a registered callback process and a message-only window utilizing the Windows API functions RegisterClassEx and CreateWindowEx don't work.

I'm using Python (3.6.8) 64-bit, so I was wondering if there might be a mismatch. My DLL is 64-bit and it works in other environments. Is there any reason just the Windows API doesn't work?

Debugging Results:

My code reaches the WM_CREATE event within the callback process, but doesn't reach WM_DEVICECHANGE event. Again, this code is reached in other environments, so I'm trying to figure out what's different using Python.

Upvotes: 0

Views: 947

Answers (1)

Drake Wu
Drake Wu

Reputation: 7170

Message-Only Windows DOES NOT receive broadcast messages:

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.

Instead, you should create a top-level window and do not call showWindow.

In addition, you don't need to call CreateWindow/CreateWindowEx through DLL, try to use WinAPI by importing the module win32api, win32con, win32gui. Here is an sample.

UPDATE:

C++ sample that cannot receive WM_DEVICECHANGE with Message-only window.

#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);
        }
    }
}

EDIT:

Pump messages is needed after create window.

Upvotes: 1

Related Questions