在开始阅读问题之前,请注意我已经阅读了Petzold的书(Windows编程第5版)!
在form.hi中声明了名为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
******
formbutton.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;
}
形式
#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();
};
表格
#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()
{
}
helper.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);
}
source.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
构造函数。