当我改变他的背景时,我失去了按钮的功能
问题描述:
我试着用实现子类来替换按钮的背景。当我改变他的背景时,我失去了按钮的功能
当我改变背景时,我有一个方形的形状,不可能点击它。 有人可以分享一个很好的教程或代码示例?
反正 这是我的代码:
LRESULT CALLBACK DrawPushButton(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdcMem;
HBITMAP hbmMem;
HANDLE hnd;
PAINTSTRUCT ps;
HDC hdc;
int win_width=100;
int win_height=50;
switch(uMsg)
{
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
hdcMem = CreateCompatibleDC(hdc);
hbmMem = CreateCompatibleBitmap(hdc, win_width, win_height);
hnd = SelectObject(hdcMem, hbmMem);
BitBlt(hdc, 0, 0, win_width, win_height, hdcMem, 0, 0, SRCCOPY);
EndPaint(hwnd, &ps);
return 0;
break;
}
return CallWindowProc (OldWndProc, hwnd, uMsg, wParam, lParam);
}
编辑: 我加入了BS_OWNERDRAW windows风格的按钮:
HWND hWndButton=CreateWindowEx(NULL,L"BUTTON",L"OK",WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON|BS_OWNERDRAW,50,220,100,24,hWnd,(HMENU)IDC_MAIN_BUTTON,GetModuleHandle(NULL),NULL);
,我改变了回调,但WM_DRAWITEM没有电话:
LRESULT CALLBACK DrawPushButton(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_DRAWITEM:
HDC hdc = GetDC(hwnd);
TextOut(hdc,0,0,L"itay",4);
break;
}
return 0;
}
答
这不是一个'好'的代码,虽然它是功能性的 - 您应该像上面提到的那样使用BS_OWNERDRAW样式,并在包含按钮的对话框/窗口的wndproc中处理图形。我已经选择粘贴一个我已经用过的方式来处理它的旧例子。你必须自己做全部。但是,您确实有机会对WM_TIMER消息做出响应,即获得按钮使其跳动或脉动。 (不确定是否有机会这样做,如果你只是从对话框/窗口的WindowProc中进行绘图)
为了简单起见,我还选择使用被取代的子分类方法。由于公共控件版本6,您应该使用SetWindowSubclass(http://msdn.microsoft.com/en-us/library/windows/desktop/bb762102(v=vs.85).aspx)
的main.cpp
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include "resource.h"
HINSTANCE hInst;
LRESULT CALLBACK btnProc(HWND btnWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
long oldWndProc;
int i;
oldWndProc = GetWindowLong(btnWnd, GWL_USERDATA);
switch (uMsg)
{
case WM_PAINT:
{
HDC hdc;
PAINTSTRUCT ps;
RECT mRect;
HBRUSH mBrush;
hdc = BeginPaint(btnWnd, &ps);
mBrush = CreateSolidBrush(RGB(100, 147, 111));
GetClientRect(btnWnd, &mRect);
FillRect(hdc, &mRect, mBrush);
DeleteObject(mBrush);
EndPaint(btnWnd, &ps);
}
return 0;
}
return CallWindowProc((WNDPROC)oldWndProc, btnWnd, uMsg, wParam, lParam);
}
void onCommand(HWND hwndDlg, WPARAM wParam, LPARAM lParam)
{
switch (LOWORD(wParam))
{
case IDC_BUTTON1:
MessageBeep(MB_ICONEXCLAMATION);
break;
}
}
LRESULT CALLBACK DlgMain(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
{
HWND btnWnd;
long oldBtnProc;
btnWnd = GetDlgItem(hwndDlg, IDC_BUTTON1);
oldBtnProc = GetWindowLong(btnWnd, GWL_WNDPROC);
SetWindowLong(btnWnd, GWL_USERDATA, oldBtnProc);
SetWindowLong(btnWnd, GWL_WNDPROC, (long)btnProc);
}
return TRUE;
case WM_CLOSE:
{
EndDialog(hwndDlg, 0);
}
return TRUE;
case WM_COMMAND:
onCommand(hwndDlg, wParam, lParam);
return TRUE;
}
return FALSE;
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
hInst=hInstance;
InitCommonControls();
return DialogBox(hInst, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DlgMain);
}
RESOURCE.H
#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif
#define DLG_MAIN 100
#define IDC_BUTTON1 1000
RESOURCE.RC
// Generated by ResEdit 1.5.11
// Copyright (C) 2006-2012
// http://www.resedit.net
#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"
//
// Dialog resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
DLG_MAIN DIALOG 0, 0, 186, 95
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "Ms Shell Dlg"
{
PUSHBUTTON "Button1", IDC_BUTTON1, 7, 7, 50, 14
}
//
// Manifest resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
1 RT_MANIFEST ".\\manifest.xml"
的manifest.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
要自定义绘制一个按钮,你需要给它的'BS_OWNERDRAW'窗口样式,然后处理'WM_DRAWITEM'消息。 –
你不认为你应该删除你正在创建的DC和位图*每次按钮绘制*时? –
@RemyLebeau我添加了BS_OWNERDRAW,但是当我调试程序时,WM_DRAWITEM没有调用。看到我上面的评论。 –