我正在尝试做一些Windows编程。我创建了一个组合框和一个按钮。我的目标是,当用户选择组合框中的项目时,该按钮被激活并需要单击以继续。到目前为止,我做过类似的事情:
这是我创建组合框的方式:
Func.h
#ifndef FUNCS_H
#define FUNCS_H
// Winapi headers....
#include <windows.h>
#include <windowsx.h>
#include <shlobj.h>
//created lib
#include "Resource.h"
// Standard C/C++ headers...
#include <iostream>
#include <string>
#include <dirent.h> // directory manipulation....
#include <cstring>
#include <fstream>
using std::cout;
using std::endl;
using std::string;
using std::ofstream;
HWND hselectOK;
HWND hComboBox1;
void createControls(HWND hwnd) // Create our combo box
{
HWND hselectFeature;
HINSTANCE hInstance = GetModuleHandle(NULL);
// Create our List box
hComboBox1 = CreateWindow(WC_COMBOBOX,"", CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD |WS_OVERLAPPED |WS_VISIBLE , 7, 20, 300, 100, hwnd, NULL, hInstance, NULL);
SendMessage(hComboBox1, CB_ADDSTRING, 0,(LPARAM)"Histogram of Oriented Gradients (HOG)");
SendMessage(hComboBox1, CB_ADDSTRING, 0,(LPARAM)"Scale Invariant Feature Transform (SIFT)");
SendMessage(hComboBox1, CB_ADDSTRING, 0,(LPARAM)"Speeded Up Robust Features (SURF)");
// SendMessage(hComboBox1, CB_SETCURSEL, (WPARAM)2,(LPARAM)0); //CB_SETCURSEL
// Create our push bottons
hselectFeature = CreateWindow("STATIC", "Select Feature", SS_LEFT | WS_CHILD, 320,20, 100, 21,hwnd, (HMENU)1, hInstance, NULL);
ShowWindow(hselectFeature,1);
hselectOK = CreateWindow("BUTTON", "Ok", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON | WS_DISABLED, 320,45, 100, 21,hwnd, NULL, hInstance, NULL);
}
#endif // FUNCS_H
WinProc.h
#ifndef WINPROC_H
#define WINPROC_H
// Winapi Headers
#include <CommDlg.h>
#include <winuser.h>
// OpenCV headers
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
// Standard C/C++ headers
#include <iostream>
#include <string>
// Created headers;
#include "Funcs.h"
#include "Resource.h"
using std::cout;
using std::endl;
using std::string;
using namespace cv;
int classNumber;
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
string dirPath;
int comboIndex;
switch (message) /* handle the messages */
{
case WM_CREATE:
createControls(hwnd);
break;
case WM_COMMAND:
{
switch(HIWORD(wParam))
{
case CBN_SELCHANGE: // When user select item in combo box, enable the button.
{
EnableWindow(hselectOK, TRUE); // enable the button
}
break;
case BN_CLICKED: // When user has chosen a list, the button is used to proceed with further task associated to the selected item.
{
char listName[200];
comboIndex = SendMessage(hComboBox1, (UINT) CB_GETCURSEL, 0, 0);
SendMessage(hComboBox1, (UINT)CB_GETLBTEXT, (WPARAM)comboIndex, (LPARAM)listName);
if(comboIndex == 0)
{
MessageBox(hwnd,listName, "You chose", MB_OK);
// Want to Do some function here.
}
else if(comboIndex == 1)
{
MessageBox(hwnd,listName, "You chose", MB_OK);
// Want to Do some function here.
}
else if(comboIndex == 2)
{
MessageBox(hwnd,listName, "You chose", MB_OK);
// Want to Do some function here.
}
}
break;
}
switch LOWORD(wParam)
{
case IDM_IMG_PATH:
{
dirPath = browseFolder(hwnd);
DialogBox(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_CLASS),hwnd, ClassDlgProcedure);
createClassLabelFile(hwnd, dirPath, classNumber);
return 0;
}
case IDM_EXIT:
{
PostMessage(hwnd, WM_CLOSE,0 , 0);
}
break;
}
}
break;
case WM_DESTROY:
PostQuitMessage(0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
#endif // WINPROC_H
这些部分只是代码的一些相关部分。
问题是,当我使用案例IDM_EXIT退出程序时,总是会出现案例BN_CLICKED下的消息框,然后程序关闭。我希望当我们关闭程序时,不会出现这样的消息框,但事实并非如此。我所说的是,消息框出现两次,一次选择单击按钮时以及何时关闭程序。为什么会这样。任何想法或建议?
答案 0 :(得分:1)
问题在于您假设WM_COMMAND是您的ComboBox唯一的消息,而不是。
看看这个旧的但是金blog post。
引自作者,
wParam参数的高位字&#34;指定 通知代码,如果消息来自控件&#34;。是什么 &#34;控制&#34;这意味着什么请记住,你必须把事情放在上下文中。 WM_COMMAND消息正在Win32的上下文中呈现 一般而言,特别是在窗口管理器的上下文中。 通常是诸如编辑框,按钮和列表框之类的窗口 调用&#34;控制&#34;,以及&#34;常见的所有窗口类 控制图书馆&#34;。在窗口管理器的世界中,一个&#34;控制&#34;是 一个窗口,其目的是提供一定程度的交互性 (在静态控制的情况下,可能没有交互性 在其父窗口的服务中。这个事实 WM_COMMAND主要用于对话框的上下文中 强调术语&#34;控制&#34;这只是一个同义词 for&#34; child window&#34;。
总而言之,应用程序窗口内的任何按钮单击都将转换为带有BN_CLICKED wParam的WM_COMMAND。这包括窗口的关闭按钮。
要处理组合框中的特定点击,您有两种选择。简单的方法是过滤发送消息的控件的hWnd,你应该已经知道你的组合框的窗口句柄,并且它不应该是一个与它进行比较的问题。
另一个选项是定义自己的消息并检查WndProc处理程序中的消息。 Web上有很多关于如何定义自己的应用程序/控件特定消息的示例。
答案 1 :(得分:0)
当您单击“退出”菜单时,窗口还会向“WindowProcedure”功能发送“BN_CLICKED”消息,这就是出现消息框的原因。您应该使用按钮的ID,而不是像这样使用'hmenu'参数'NULL':
hselectOK = CreateWindow("BUTTON", "Ok", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON | WS_DISABLED, 320,45, 100, 21,hwnd,
(HMENU)305, // Here is the ID of your button ( You may use your own ID )
hInstance, NULL);
您必须在“案例BN_CLICKED”中添加一些ID检查代码,如下所示:
case BN_CLICKED: // When user has chosen a list, the button is used to proceed with further task associated to the selected item.
{
// You must do this check otherwise the message box will appear again when you click the 'Exit' menu
if ( LOWORD(wParam) == 305 ) // '305' is the ID which I have used as the button ID in above code
{
// Now add your click event code here
}
}
break;