button无法响应点击事件
我把一个button用setparent()函数把父窗口设置成一个listctrl了。目的是想实现点击listctrl的时候把button 移动到被点击的单元格上(如果不设置成listctrl的子窗体,计算位置太麻烦),这个现在可以实现。但是点击button的时候在对话框的窗口过程里无法响应单击消息。
我用MFC实现上面的功能的时候,把listctrl关联一个类,然后在这个类里做消息映射是可以响应的。但是现在是用win API 开发,所以不知道如何才能做到?求各位大侠帮忙。
[解决办法]
SDK,就需要实现MFC帮你实现的消息循环等
[解决办法]
但是点击button的时候在对话框的窗口过程里无法响应单击消息。
把button 的父窗口设置为listctrl,当然就要在listctrl里响应button 的单击事件
[解决办法]
控件的消息响应函数根据控件种类不同和消息的不同,只会在控件对象本身或你父窗口中有消息响应。
你为了处理在单元格中显示编辑框和按钮的问题,便于计算就把父窗口设为listctrl,所以对话框就与编辑框和按钮没有直接关系了。
你要考虑你的设计意图去构建你的程序逻辑,
如果你的编辑框和按钮就是为了listctrl在单元格用的,那就设按钮父窗口为listctrl,并在listctrl对应类的对象消息处理函数中,把按钮的单击消息再传递给listctrl的父窗口(即对话框);
如果你的编辑框和按钮是对话框上相关功能,只是为了计算显示位置时方便,建议不要改变对话框与按钮的父子窗口关系,而通过参数传递的方式把单元格的CRect传出来,用于显示编辑框和按钮。
[解决办法]
请看代码,我测试过的。你需要修改成符合你自己的。
- C/C++ code
// list.cpp : Defines the entry point for the application.//#include "stdafx.h"#include "resource.h"#define MAX_LOADSTRING 100// Global Variables:HINSTANCE hInst; // current instanceTCHAR szTitle[MAX_LOADSTRING]; // The title bar textTCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text// Foward declarations of functions included in this code module:ATOM MyRegisterClass(HINSTANCE hInstance);BOOL InitInstance(HINSTANCE, int);LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ // TODO: Place code here. MSG msg; HACCEL hAccelTable; // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_LIST, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_LIST); // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return msg.wParam;}//// FUNCTION: MyRegisterClass()//// PURPOSE: Registers the window class.//// COMMENTS://// This function and its usage is only necessary if you want this code// to be compatible with Win32 systems prior to the 'RegisterClassEx'// function that was added to Windows 95. It is important to call this function// so that the application will get 'well formed' small icons associated// with it.//ATOM MyRegisterClass(HINSTANCE hInstance){ WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_LIST); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = (LPCSTR)IDC_LIST; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); return RegisterClassEx(&wcex);}//// FUNCTION: InitInstance(HANDLE, int)//// PURPOSE: Saves instance handle and creates main window//// COMMENTS://// In this function, we save the instance handle in a global variable and// create and display the main program window.//BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){ HWND hWnd; hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE;}//// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)//// PURPOSE: Processes messages for the main window.//// WM_COMMAND - process the application menu// WM_PAINT - Paint the main window// WM_DESTROY - post a quit message and return////LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; TCHAR szHello[MAX_LOADSTRING]; LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING); switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)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... RECT rt; GetClientRect(hWnd, &rt); DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0;}WNDPROC prelistproc = NULL;LRESULT CALLBACK ListProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){ switch (message) { case WM_CREATE: { int i = 0; i = 1; MessageBox( hDlg,"a","b",0 ); } break; case WM_COMMAND: if (LOWORD(wParam) == IDC_BUTTON1 ) { HWND hParent = GetParent( hDlg ); SetWindowText( hParent,"改变了的窗口标题" ); //MessageBox( hDlg,"a","b",0 ); return TRUE; } break; case WM_NCDESTROY: SetWindowLong( GetDlgItem( hDlg,IDC_LIST1 ),GWL_WNDPROC,(long)prelistproc ); break; default: break; } return ::CallWindowProc( prelistproc,hDlg,message,wParam,lParam );}#include "commctrl.h"// Mesage handler for about box.LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){ switch (message) { case WM_INITDIALOG: prelistproc = (WNDPROC)SetWindowLong( GetDlgItem( hDlg,IDC_LIST1 ),GWL_WNDPROC,(long)ListProc ); LVCOLUMN lc; lc.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH | LVCF_FMT; lc.cx = 128; lc.pszText = "姓名"; lc.iSubItem = 0; lc.fmt = LVCFMT_LEFT; ::SendMessage( GetDlgItem( hDlg,IDC_LIST1 ),LVM_INSERTCOLUMN,0,(long)&lc ); SetParent( GetDlgItem(hDlg,IDC_BUTTON1 ) ,GetDlgItem( hDlg,IDC_LIST1 ) ); return TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return TRUE; } break; } return FALSE;}
[解决办法]
我确实用了 SetWindowLog 替换 ListCtrl的窗口过程了,但是这个窗口过程具体怎么写我不清楚啊。
我是这样写的 如果是button点击就执行一个操作 如果是其他消息我就直接 调用对话框的窗口过程。
错!要调用原窗口过程。
1.
- C/C++ code
#define LV_WIDTH 300#define LV_HEIGHT 120//HWND CreateListView(HINSTANCE hInstance, HWND hwndParent){DWORD dwStyle;HWND hwndListView;BOOL bSuccess = TRUE;// custom drawdwStyle = WS_TABSTOP | WS_CHILD | WS_BORDER | WS_VISIBLE | LVS_REPORT | LVS_SINGLESEL;//| LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_GRIDLINES| LVS_EX_INFOTIP | LVS_AUTOARRANGE | LVS_OWNERDATA; hwndListView = CreateWindowEx( WS_EX_WINDOWEDGE,//WS_EX_CLIENTEDGE,// ex style WC_LISTVIEW, // class name defined in commctrl.h NULL, // window text dwStyle, // style 4, // x position 120, // y position LV_WIDTH, // width LV_HEIGHT, // height hwndParent, // parent (HMENU)IDC_LISTVIEW, // ID (HINSTANCE)GetWindowLong(hwndParent, GWL_HINSTANCE), // instance NULL); // no extra data// if(hwndListView) { ListView_SetExtendedListViewStyleEx(hwndListView,LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT); InitLvHead(hwndListView); // LVITEM lvi; ZeroMemory(&lvi, sizeof(lvi)); lvi.mask=LVIF_TEXT;//|LVIF_IMAGE; lvi.cchTextMax=40; lvi.iSubItem=0; lvi.pszText="MainItem"; lvi.iItem=0; int now=ListView_InsertItem(hwndListView,&lvi); // ListView_SetItemText(hwndListView,now,1,"Column 1"); ListView_SetItemText(hwndListView,now,2,"Column 2"); ListView_SetItemText(hwndListView,now,3,"Column 3"); ListView_SetItemText(hwndListView,now,4,"Column 4"); ListView_SetItemText(hwndListView,now,5,"Column 5"); // now=ListView_InsertItem(hwndListView,&lvi); // ListView_SetItemText(hwndListView,now,1,"Column 1"); ListView_SetItemText(hwndListView,now,2,"Column 2"); ListView_SetItemText(hwndListView,now,3,"Column 3"); ListView_SetItemText(hwndListView,now,4,"Column 4"); ListView_SetItemText(hwndListView,now,5,"Column 5"); // now=ListView_InsertItem(hwndListView,&lvi); // ListView_SetItemText(hwndListView,now,1,"Column 1"); ListView_SetItemText(hwndListView,now,2,"Column 2"); ListView_SetItemText(hwndListView,now,3,"Column 3"); ListView_SetItemText(hwndListView,now,4,"Column 4"); ListView_SetItemText(hwndListView,now,5,"Column 5"); // now=ListView_InsertItem(hwndListView,&lvi); // ListView_SetItemText(hwndListView,now,1,"Column 1"); ListView_SetItemText(hwndListView,now,2,"Column 2"); ListView_SetItemText(hwndListView,now,3,"Column 3"); ListView_SetItemText(hwndListView,now,4,"Column 4"); ListView_SetItemText(hwndListView,now,5,"Column 5"); // now=ListView_InsertItem(hwndListView,&lvi); // ListView_SetItemText(hwndListView,now,1,"Column 1"); ListView_SetItemText(hwndListView,now,2,"Column 2"); ListView_SetItemText(hwndListView,now,3,"Column 3"); ListView_SetItemText(hwndListView,now,4,"Column 4"); ListView_SetItemText(hwndListView,now,5,"Column 5"); // now=ListView_InsertItem(hwndListView,&lvi); // ListView_SetItemText(hwndListView,now,1,"Column 1"); ListView_SetItemText(hwndListView,now,2,"Column 2"); ListView_SetItemText(hwndListView,now,3,"Column 3"); ListView_SetItemText(hwndListView,now,4,"Column 4"); ListView_SetItemText(hwndListView,now,5,"Column 5"); // now=ListView_InsertItem(hwndListView,&lvi); // ListView_SetItemText(hwndListView,now,1,"Column 1"); ListView_SetItemText(hwndListView,now,2,"Column 2"); ListView_SetItemText(hwndListView,now,3,"Column 3"); ListView_SetItemText(hwndListView,now,4,"Column 4"); ListView_SetItemText(hwndListView,now,5,"Column 5"); //// HWND hwndHD=ListView_GetHeader(hwndListView); // int all=Header_GetItemCount(hwndHD); // RECT rc;// Header_GetItemRect(hwndHD,all-1,&rc); return hwndListView; } else { return NULL; }}////#define LVCFMT_SPLITBUTTON 0x1000000BOOL InitLvHead(HWND hwndListView){LV_COLUMN lvColumn;int i;TCHAR szString[5][20] = { TEXT("Column 1"), TEXT("Column 2"), TEXT("Column 3"), TEXT("Column 4"), TEXT("Column 5")};//initialize the columns lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT ;//| LVCF_SUBITEM; lvColumn.fmt = LVCFMT_LEFT;// ?? | LVCFMT_SPLITBUTTON; lvColumn.cx = 80; for(i = 0; i < 5; i++) { lvColumn.pszText = szString[i]; SendMessage(hwndListView, LVM_INSERTCOLUMN, (WPARAM)i, (LPARAM)&lvColumn); }// return TRUE;}//