发送消息无法将自定义消息发送到主窗口



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

form.h中,我已经声明了名为CMessage的自定义消息(它代表"自定义消息",后来调用创建按钮的方法),在formbutton中.cpp我将消息从其构造函数发送到在form.cpp中创建的主窗口。我从我的帮助程序类中的getLastError方法中发现发送消息由于无效的窗口句柄而失败,这很奇怪,因为如果我在发送消息之前使用isWindow(forms.mainWindowHandle),我得到的消息框显示"操作成功完成"。在将整个代码拆分为多个标头和 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构造函数。

最新更新