c++ - 在 API 中控制 WndProc 函数的问题

标签 c++ api

现在我正在实现一个简单的 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/

相关文章:

node.js - package.json 中的代理不影响获取请求

c++ - GCC 的 STL 排序问题

c++ - 为什么我的 linux 信号处理程序只运行一次

python - Python 3.3 中的 Py_FlushLine 发生了什么?

javascript - Soundcloud HTML5 API 不适用于 Facebook JS

javascript - 设置要运行的 NodeJS 脚本的计划作业

sql - jOOQ——为领域创造值(value)

c++ - 帮助简化多个可执行文件的 Makefile

c++ - 是否有解决方法可以在 C++ 中为 Shorts 定义用户定义的文字?

c++ - Windows 上 OpenCL 库的 0xc000007b 加载时错误