win32 c ++句柄按下按钮,PeekMessage不工作?

时间:2016-05-20 09:10:17

标签: c++ windows winapi button callback

我想在原生窗口中处理c ++ win32 API按钮,我目前正在尝试这样做 -

#include <stdint.h>
#include <Windows.h>
#include <process.h>
#include <iostream>
#include <sstream>
#include <tchar.h>
#include <strsafe.h>
#include <crtdefs.h>

#include <stdafx.h>
#include <stdio.h>

#include "stdafx.h"
#include "name.h"
#include "libobs/obs.h"
#include "libobs/obs-module.h"

#define uploadName "Upload Window"
#define uploadWNDWidth 500
#define uploadWNDHeight 500
#define IDC_SELECT_VIDEO (100)

HWND  hBtnParent = HWND("UploadVideo");
HWND SelectVideoBTN, UploadBTN, hWnd, hBtn;

WPARAM wmId, wmEvent;

HINSTANCE hUpload;

WNDCLASSEX wcexUpload;

int nCmdShowUpload = 1;

using namespace std;

LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
//load obs modules
class load{
public:
    void static loading(){
        obs_module_load;
        obs_module_load_locale;
    }
};

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case BM_CLICK:
        if (wParam == IDC_SELECT_VIDEO) {
            MessageBox(hWnd, L"if", L"if", 0);
        }
        else{
            MessageBox(hWnd, L"else", L"else", 0);
        }
        break;
    default:
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
}

bool obs_module_load(void)
{
    //init handler
    //HANDLE messageLoopThreadHandler;

    //set the handler to the thread
    //messageLoopThreadHandler = (HANDLE)_beginthreadex(0, 0, &messageLoopThread, 0, 0, 0);

    //wait for object to be in specified state
    //WaitForSingleObject(messageLoopThreadHandler, INFINITE);

    //startMessageThreadLoop ThreadLoopInstance;

    //ThreadLoopInstance.startMyThread();

    MessageBox(hWnd, L"ThreadStart", L"ThreadStart", 0);
    //create message loop for buttons

    //cleanup thread created by _beginThreadEx
    //CloseHandle(messageLoopThreadHandler);

    WNDCLASSEX vidUploader;

    vidUploader.cbSize = sizeof(WNDCLASSEX);

    vidUploader.style = CS_HREDRAW | CS_VREDRAW;
    vidUploader.lpfnWndProc = WndProc;
    vidUploader.cbClsExtra = 0;
    vidUploader.cbWndExtra = 0;
    vidUploader.hInstance = hUpload;
    vidUploader.hIcon = LoadIcon(hUpload, MAKEINTRESOURCE(IDI_P2GOVIDEOUPLOADER20));
    vidUploader.hCursor = LoadCursor(NULL, IDC_ARROW);
    vidUploader.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    vidUploader.lpszMenuName = MAKEINTRESOURCE(IDC_P2GOVIDEOUPLOADER20);
    vidUploader.lpszClassName = (LPCWSTR)(L"UploadVideo");
    vidUploader.hIconSm = LoadIcon(wcexUpload.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    RegisterClassEx(&vidUploader);

    hInst = hUpload; // Store instance handle in our global variable

    // The parameters to CreateWindow explained:
    // szWindowClass: the name of the application
    // szTitle: the text that appears in the title bar
    // WS_OVERLAPPEDWINDOW: the type of window to create
    // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
    // 500, 100: initial size (width, length)
    // NULL: the parent of this window
    // NULL: this application dows not have a menu bar
    // hInstance: the first parameter from WinMain
    // NULL: not used in this application
    hWnd = CreateWindow((LPCWSTR)(L"UploadVideo"), (LPCWSTR)(L"Upload Video's"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 100, NULL, NULL, hUpload, NULL);

    SelectVideoBTN = CreateWindow(
        L"BUTTON",  // Predefined class; Unicode assumed 
        L"Select Video's",      // Button text 
        WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,  // Styles 
        10,         // x position 
        460,        // y position 
        100,        // Button width
        25,         // Button height
        hWnd,       // Parent window
        (HMENU)IDC_SELECT_VIDEO, // Assign appropriate control ID
        (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
        NULL);      // Pointer not needed.

    UploadBTN = CreateWindow(
        L"BUTTON",  // Predefined class; Unicode assumed 
        L"Upload",      // Button text 
        WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,  // Styles 
        390,         // x position 
        460,         // y position 
        100,        // Button width
        25,        // Button height
        hWnd,     // Parent window
        NULL,       // No menu.
        (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
        NULL);      // Pointer not needed.

    RECT rect = { 0, 0, uploadWNDWidth, uploadWNDHeight };
    AdjustWindowRect(&rect, GetWindowLong(hWnd, GWL_STYLE), FALSE);
    SetWindowPos(hWnd, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE);

    if (!hWnd)
    {
        MessageBox(NULL, _T("Call to CreateWindow failed!"), _T("Win32 Guided Tour"), NULL);

        return 1;
    }

    MSG msge = { 0 };
    while (PeekMessage(&msge, NULL, 0, 0, PM_REMOVE) > 0)
    {
        //translate and send messages
        TranslateMessage(&msge);
        DispatchMessage(&msge);
    }

    MSG msg;

    // The parameters to ShowWindow explained:
    // hWnd: the value returned from CreateWindow
    //nCmdShow: the fourth parameter from WinMain
    ShowWindow(hWnd, nCmdShowUpload);

    UpdateWindow(hWnd);
    load::loading();

    return true;
}

当我当前加载OBS时,在包含dll之后会发生什么 -

OBS开始了 窗口弹出你 我点击窗口 什么都没发生 在第4步,在点击按钮后,一个MessageBox应该弹出说 - MessageBox(hWnd,L&#34;否则&#34;,L&#34;否则&#34;,0);如果它进入else,如果if语句为真,那么MessageBox(hWnd,L&#34;如果&#34;,L&#34;如果&#34;,0);

但是我的代码甚至无法进入回调函数。

编辑 -

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_COMMAND:
        wmId = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        load::loading();
        // Parse the menu selections:
        switch (wmId)
        {
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: Add any drawing code here...
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

这是WndProc引用引用的地方。

2 个答案:

答案 0 :(得分:2)

您正在处理button click的错误接收。您应该处理WM_COMMAND消息并检查WPARAM的高位字以获取通知代码。

答案 1 :(得分:0)

你应该使用GetMessage,它不会挂起程序。

如果您想要不断更新,可以使用PeekMessage。例如,在需要不断绘制窗口的游戏中。它必须是这样的:

//create window...
//show window...

MSG msg = { 0 };
while (msg.message != WM_QUIT)
{
    //default message processing
    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    else 
    { 
        //constantly paint the window when there is no other message
        render_window(hwnd);
    }
}

//do cleanup here

return 0;

请注意,当上述while循环结束时,程序将终止。在此之后,您无法添加ShowWindow / UpdateWindow

其次,您的主窗口似乎是vidUploader。并且它的窗口过程设置为vidUploader.lpfnWndProc = WndProc;但您尚未定义WndProc。相反,你有一些名为WindowProcedure

的东西

检查按钮通知:

case WM_COMMAND:
    if (LOWORD(wParam) == IDC_SELECT_VIDEO) 
        MessageBox...;
    break;