c++ - SendMessage 无法将自定义消息发送到主窗口

标签 c++ winapi

在开始阅读问题之前请注意我阅读了 Petzold 的书(windows 编程第 5 版)!

在 form.h 中,我声明了名为 CMessage 的自定义消息(它代表“自定义消息”,稍后调用创建按钮的方法),在 formbutton.cpp 中,我从其构造函数向主窗口发送消息在 form.cpp 中创建。我从我的助手类中的 getLastError 方法中发现由于窗口句柄无效而发送消息失败,这很奇怪,因为如果我在发送消息之前使用 isWindow(forms.mainWindowHandle) 我得到的消息框显示“操作成功完成”。在将整个代码拆分为多个 header 和 cpps 之前,相同的设计是可行的,但现在已损坏。

******
step by step debugging :

        form myform(hInstance);
        form::form(HINSTANCE hInstanceForm);
         HWND form::Createform(HWND handle, HINSTANCE hInstance, int xPos , int yPos , int xSize , int ySize);
    Formbutton::Formbutton(BOOL create);
    form::form();
    SendMessage(forms.mainWindowHandle, CMessage,0 ,0);//error
    //rest of the code and main window is shown but not the button
******

表单按钮.cpp

#pragma once
#include "FormButton.h"
#include "Form.h"
#include "helper.h"
Formbutton::Formbutton(){}
Formbutton::Formbutton(BOOL create)
{
    helper help;
    form forms;
    if (create)
    {
        SendMessage(forms.mainWindowHandle, CMessage,0 ,0); //same with PostMessage
        help.getLastError();
    }
}

HWND Formbutton::createButton(HWND button, HWND parent)
{
    button = CreateWindow(TEXT("Button"), // window class name
        TEXT("Button"), // window caption
        WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP, // window style
        500, // initial x position
        500, // initial y position
        300, // initial x size
        500, // initial y size
        parent, // parent window handle
        NULL, // window menu handle
        (HINSTANCE)GetWindowLongPtr(parent, -6), // program instance handle
        NULL); // creation parameters
    ShowWindow(button, SW_SHOW);
    return button;
}

表格.h

#pragma once
#include <Windows.h>
#define CMessage (WM_USER+0x0001)
class form 
{
private:
    HWND Createform(HWND handle, HINSTANCE hInstance, int xPos = CW_USEDEFAULT, int yPos = CW_USEDEFAULT, int xSize = GetSystemMetrics(SM_CXFULLSCREEN), int ySize = GetSystemMetrics(SM_CYFULLSCREEN));
    MSG msg;
    WNDCLASS wndclass;
protected:
    static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
public:
     HWND mainWindowHandle; 
    form::form();
    form::form(HINSTANCE hInstanceForm);
    form::~form();

    WPARAM updateForm();
};

表单.cpp

#pragma once
#include "Form.h"
#include "FormButton.h"

 LRESULT CALLBACK form::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    RECT rect;
     Formbutton fb;
    switch (message)
    {
    case WM_CREATE:
        return 0;
    case WM_PAINT:
        InvalidateRect(hwnd, &rect, TRUE);
        hdc = BeginPaint(hwnd, &ps);
        SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
        SetBkMode(hdc, TRANSPARENT);
        EndPaint(hwnd, &ps);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    case CMessage: //this is the custom message
        fb.createButton(fb.buttonHandle, hwnd);

    default:
        return DefWindowProc(hwnd, message, wParam, lParam);
    }

    return 0;
}

 HWND form::Createform(HWND handle, HINSTANCE hInstance, int xPos , int yPos , int xSize , int ySize)
{
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = TEXT("Framework");
    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
            TEXT("Framework"), MB_ICONERROR);
    }
    handle = CreateWindow(TEXT("Framework"), // window class name
        TEXT("The Hello Program"), // window caption
        WS_OVERLAPPEDWINDOW | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SIZEBOX | WS_HSCROLL | WS_VSCROLL, // window style
        xPos, // initial x position
        yPos, // initial y position
        xSize, // initial x size
        ySize, // initial y size
        NULL, // parent window handle
        NULL, // window menu handle
        hInstance, // program instance handle
        NULL); // creation parameters
    //ShowWindow(handle, SW_SHOWMAXIMIZED);
    UpdateWindow(handle);
    return handle;
}
WPARAM form::updateForm()
{
    ShowWindow(mainWindowHandle, 10);
    UpdateWindow(mainWindowHandle);
    while (GetMessage(&msg, NULL, 0, 0))
    {

        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
form::form()
{
}
form::form(HINSTANCE hInstanceForm)
{
    mainWindowHandle = Createform(mainWindowHandle, hInstanceForm);
}

form::~form()
{

}

助手.cpp

#pragma once
#include "helper.h"
#include <strsafe.h>
void helper::getLastError()
{
    wchar_t buf[256];
    FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 256, NULL);
    MessageBox(NULL, buf, TEXT("error"), MB_OK);
}

源代码.cpp

#pragma once
#include <Windows.h>
#include "Form.h"
#include "FormButton.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    PSTR szCmdLine, int iCmdShow)
{
        form myform(hInstance);
        Formbutton btn(true);
        myform.updateForm();
}

最佳答案

您正在创建 form 的两个实例:一个在您的 WinMain() 中,一个在您的 Formbutton 构造函数中。您想将按钮添加到前者,但实际上是将其添加到后者,一旦构造函数返回,后者就不复存在。

我不确定您希望如何构建您的程序,但我的建议是将正确的父表单作为 form * 参数传递给 Formbutton 构造函数。

关于c++ - SendMessage 无法将自定义消息发送到主窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38292981/

相关文章:

c++ - 自动将本地比例应用于非全屏桌面连接(RDP 8.1 版及更高版本)

c++ - 如何调用 shell "file copy dialog"来报告 Win32 中的复制进度?

c++ - 以编程方式在 Windows 中获取事件连接

c++ - 连接到爱沙尼亚身份证时的 WinSCard SCARD_E_PROTO_MISMATCH

c++ - 尝试显示纹理但仅使用 OpenGL 获得纯色

c++ - 使用 std::count 计算一对数组中的相等值

C++ 奇怪的文件输出

c++ - 无法在 C++ 中跟踪 Visual Studio 入口点

C++ - 字符串容量模式

c++ - EnumDisplayDevices vs WMI Win32_DesktopMonitor,如何检测事件监视器?