现在我正在实现一个简单的 API 程序,如下所示。
目的是我想用我的用户定义消息来控制 WndProc 函数。
但我不知道该怎么做? MessageBox() 函数不起作用。
#include <Windows.h>
#include <tchar.h>
#define WIDTHBYTES(w, bitcount) ((((w)*(bitcount)+31)& ~31) >> 3)
int RAW2DIB(HWND);
unsigned char *_Orgin_Pixel_;
unsigned char *_Copy_Pixel_;
unsigned int W_Image = 750;
unsigned int H_Image = 800;
unsigned int widthbytes = WIDTHBYTES(W_Image, 8);
unsigned int S_Image = widthbytes * H_Image;
BITMAPINFO *BmInfo;
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
static HANDLE hTimer;
switch (iMessage)
{
case WM_CREATE:
return 0;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case 0:
hTimer = (HANDLE)SetTimer(hWnd, 1, 10, NULL); //10ms
SendMessage(hWnd, WM_TIMER, 1, 0);
break;
case 1:
VirtualFree(_Orgin_Pixel_, sizeof(BYTE)*(S_Image), MEM_DECOMMIT); //Memory free
VirtualFree(_Copy_Pixel_, sizeof(BYTE)*(S_Image), MEM_DECOMMIT); //Memory free
free(BmInfo); //Memory free
KillTimer(hWnd, 1);
break;
case 2:
PostQuitMessage(0);
break;
}
return 0;
case WM_TIMER:
switch (wParam)
{
case 1:
RAW2DIB(hWnd);
break;
}
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
SetDIBitsToDevice(hdc, 0, 0, W_Image, H_Image, 0, 0, 0, H_Image, _Copy_Pixel_, BmInfo, DIB_RGB_COLORS); //복사된 RAW 이미지 데이터 즉, _Copy_Pixel_를 뿌린다.
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
VirtualFree(_Copy_Pixel_, sizeof(BYTE)*(S_Image), MEM_DECOMMIT); //Memery free
VirtualFree(_Orgin_Pixel_, sizeof(BYTE)*(S_Image), MEM_DECOMMIT);//Memery free
free(BmInfo); //Memery free
KillTimer(hWnd, 1);
PostQuitMessage(0);
return 0;
}
return (DefWindowProc(hWnd, iMessage, wParam, lParam));
}
int RAW2DIB(HWND hWnd)
{
unsigned int Picture_x_, Picture_y_, Bitdepth;
//...
InvalidateRect(hWnd, NULL, FALSE);
return 0;
}
INT APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE, TCHAR *pszLine, INT nShow) {
HWND hWnd;
WNDCLASS wc;
MSG msg;
MessageBox(NULL, TEXT("Hello World!"), TEXT("Title"), MB_OK);
//return 0;
}
最佳答案
实现它的方法之一是使用模态对话框。 Windows 中的对话框与其他窗口(具有窗口类)的区别很小。这是示例代码(它来自真实项目,包含一些用于同时显示多个对话框的额外内容):
LRESULT CALLBACK TBasicDialog::ModalDialogBoxProcedure(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
TBasicDialog *inst = (TBasicDialog*)(INT_PTR)::GetWindowLong(hDlg, GWL_USERDATA);
if (inst == NULL && message != WM_INITDIALOG)
return(FALSE);
switch (message)
{
case WM_INITDIALOG:
{
inst = (TBasicDialog*)lParam;
::SetWindowLongPtr(hDlg, GWL_USERDATA, (LONG)(INT_PTR)inst);
inst->m_hDlg = hDlg;
inst->SetDialogIcons(NULL, inst->m_iconIdentBig, inst->m_iconIdentSmall);
return(inst->OnInitDialog((HWND)wParam));
}
break;
case WM_COMMAND:
inst->OnWmCommand((short)LOWORD(wParam), (short)HIWORD(wParam), (HWND)lParam);
break;
case WM_SYSCOMMAND:
inst->OnWmSysCommand((int)wParam);
break;
case WM_NOTIFY:
inst->OnWmNotify((NMHDR*)lParam);
break;
case WM_TIMER:
inst->OnWmTimer((int)wParam);
break;
case WM_CLOSE:
{
// Experiments with debugger show that when the button CANCEL or the Alt-F4 are pressed,
// Windows generates WM_CLOSE event and after that it generates WM_COMMAND with IDCANCEL.
// So, this message can be safely ignored if closing request is handled in the WM_COMMAND handler.
}
break;
case WM_DESTROY:
{
inst->m_bInWmDestroyHandler = TRUE;
if (inst->OnWmDestroy() == FALSE)
{
// Derived class decided not to delete the object. Some of its fields should
// be cleared because it is necessary to allow opening it later.
inst->m_hDlg = NULL;
inst->m_ctrlsPosHelper.ResetHelper();
inst->m_bInWmDestroyHandler = FALSE;
}
}
break;
default:
{
if (message >= WM_USER && message < WM_USER+1000)
inst->OnWmUser(message, wParam, lParam);
}
break;
}
return(FALSE);
}
此处理程序调用类的方法来完成这项工作,但您可以调用静态函数或将代码内联。这并不重要。
这是打开对话框并等待它关闭的方式。
retValue = (int)::DialogBoxParam(m_hInst,
MAKEINTRESOURCE(dialogTemplateId),
hParent, (DLGPROC)ModalDialogBoxProcedure,
(LPARAM)this);
此 Windows API DialogBoxParam
可以从任何地方调用。 WinMain
(或 _tWinMain
)非常适合。
对话框的好处是您不需要注册任何窗口类,Windows 会为您旋转消息循环。从其他角度来看,对话框与窗口相同。
对话框需要对话框模板。但与此同时,这些模板是创建带有一些简单消息和几个按钮的窗口的简便方法。
关于c++ - 在 API 中控制 WndProc 函数的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41009157/