南石龟好养吗:VC自绘按钮的实现(NO MFC)

来源:百度文库 编辑:偶看新闻 时间:2024/04/28 07:50:59
VC自绘按钮的实现(NO MFC) 发布于:软件开发网 来源:互联网 作者:佚名 时间:2009-02-26 00:02


使用MFC的CBitmaPButton或者CButtonST等类很容易在按钮上画出位图 文字的Button。但是如果不使用MFC该怎么画呢?下面就是纯粹的SDK做的位图 文字的Button:

//OwnerDrawBtn.cpp:Definestheentrypointfortheapplication.
//

#include"stdafx.h"
#include"resource.h"

#defineICON_HEIGHT32
#defineICON_WIDTH32

staticHINSTANCEhInst;//currentinstance
staticHICONhIcon=NULL;

staticvoidInitializeDialog(HWNDhwnd);
staticvoidDrawTheIcon(HWNDhButtonWnd,HDC*dc,BOOLbHasTitle,RECT*rpItem,RECT*rpTitle,BOOLbIsPressed,BOOLbIsDisabled);
staticvoidPrepareImageRect(HWNDhButtonWnd,BOOLbHasTitle,RECT*rpItem,RECT*rpTitle,BOOLbIsPressed,DWORDdwWidth,DWORDdwHeight,RECT*rpImage);

LRESULTCALLBACKDialogFunc(HWNDhWnd,UINTmessage,WPARAMwParam,LPARAMlParam);

intAPIENTRYWinMain(HINSTANCEhInstance,
HINSTANCEhPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
staticcharszAppName[]="OWNERDRAWBUTTON";
HWNDhwnd;
MSGmsg;
WNDCLASSEXwndclass;

wndclass.cbSize =sizeof(WNDCLASSEX);
wndclass.style =CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc =DialogFunc;
wndclass.cbClsExtra =0;
wndclass.cbWndExtra =DLGWINDOWEXTRA;
wndclass.hInstance =hInstance;
wndclass.hIcon =LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));
wndclass.hCursor =LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground =(HBRUSH)(COLOR_WINDOW 1);
wndclass.lpszMenuName =(LPCSTR)szAppName;
wndclass.lpszClassName =szAppName;
wndclass.hIconSm =LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));

ReGISterClassEx(&wndclass);

hInst=hInstance;//getcurrentinstance.

hwnd=CreateDialog(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),GetDesktopWindow(),(DLGPROC)DialogFunc);

ShowWindow(hwnd,nCmdShow);

while(GetMessage(&msg,NULL,0,0))
{
if(!IsWindow(hwnd)||!IsDialogMessage(hwnd,&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

returnmsg.wParam;
}

LRESULTCALLBACKDialogFunc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam)
{
switch(message)
{
caseWM_INITDIALOG:
InitializeDialog(hwnd);
break;

caseWM_CREATE:
break;

caseWM_COMMAND:
switch(LOWORD(wParam))
{
caseIDOK:
::EndDialog(hwnd,LOWORD(wParam));
::PostQuitMessage(0);
break;
default:
break;
}
break;

caseWM_DRAWITEM:
{
//drawtheownerdrawbutton
LPDRAWITEMSTRUCTlpDIS=(LPDRAWITEMSTRUCT)lParam;

if(lpDIS->CtlID!=IDC_BMPBTN)
{
return(0);
}

HDCdc=lpDIS->hDC;

//buttonstate
BOOLbIsPressed= (lpDIS->itemState&ODS_SELECTED);
BOOLbIsFocused =(lpDIS->itemState&ODS_FOCUS);
BOOLbIsDisabled=(lpDIS->itemState&ODS_DISABLED);

RECTitemRect=lpDIS->rcItem;

::SetBkMode(dc,TRANSPARENT);

if(bIsFocused)
{
HBRUSHbr=CreateSolidBrush(RGB(0,0,0)); 
::FrameRect(dc,&itemRect,br);
::InflateRect(&itemRect,-1,-1);
::DeleteObject(br);
}

COLORREFcrColor=GetSysColor(COLOR_BTNFACE);

HBRUSH brBackground=CreateSolidBrush(crColor);

::FillRect(dc,&itemRect,brBackground);

::DeleteObject(brBackground);

//Drawpressedbutton
if(bIsPressed)
{
HBRUSHbrBtnShadow=CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
::FrameRect(dc,&itemRect,brBtnShadow);
::DeleteObject(brBtnShadow);
}
else//...elsedrawnonpressedbutton
{
UINTuState=DFCS_BUTTONPUSH|((bIsPressed)?DFCS_PUSHED:0);

::DrawFrameControl(dc,&itemRect,DFC_BUTTON,uState);
}

//Readthebutton'stitle
charsTitle[100];
::GetWindowText(::GetDlgItem(hwnd,IDC_BMPBTN),sTitle,100);

RECTcaptionRect=lpDIS->rcItem;

BOOLbHasTitle=(sTitle[0]!='\0');
DrawTheIcon(::GetDlgItem(hwnd,IDC_BMPBTN),&dc,bHasTitle,&lpDIS->rcItem,&captionRect,bIsPressed,bIsDisabled);

if(bHasTitle)
{//Drawthebutton'stitle
//Centertext
RECTcenterRect=captionRect;
::DrawText(dc,sTitle,-1,&captionRect,DT_WORDBREAK|DT_CENTER|DT_CALCRECT);
LONGcaptionRectWidth=captionRect.right-captionRect.left;
LONGcaptionRectHeight=captionRect.bottom-captionRect.top;
LONGcenterRectWidth=centerRect.right-centerRect.left;
LONGcenterRectHeight=centerRect.bottom-centerRect.top;
::OffsetRect(&captionRect,(centerRectWidth-captionRectWidth)/2,(centerRectHeight-captionRectHeight)/2);

::SetBkMode(dc,TRANSPARENT);

if(bIsDisabled)
{
::OffsetRect(&captionRect,1,1);
::SetTextColor(dc,::GetSysColor(COLOR_3DHILIGHT));
::DrawText(dc,sTitle,-1,&captionRect,DT_WORDBREAK|DT_CENTER);
::OffsetRect(&captionRect,-1,-1);
::SetTextColor(dc,::GetSysColor(COLOR_3DSHADOW));
::DrawText(dc,sTitle,-1,&captionRect,DT_WORDBREAK|DT_CENTER);
}
else
{
::SetTextColor(dc,::GetSysColor(COLOR_BTNTEXT));
::SetBkColor(dc,::GetSysColor(COLOR_BTNFACE));
::DrawText(dc,sTitle,-1,&captionRect,DT_WORDBREAK|DT_CENTER);
}

//Drawthefocusrect
if(bIsFocused)
{
RECTfocusRect=itemRect;
::InflateRect(&focusRect,-3,-3);
::DrawFocusRect(dc,&focusRect);
}

return(TRUE);
}//Endif

break;
}

caseWM_DESTROY:
::PostQuitMessage(0);
returnFALSE;
}

returnFALSE;
}

voidInitializeDialog(HWNDhwnd)
{
hIcon=::LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON1));

::SetFocus(::GetDlgItem(hwnd,IDC_BMPBTN));
}

staticvoidDrawTheIcon(HWNDhButtonWnd,HDC*dc,BOOLbHasTitle,RECT*rpItem,RECT*rpTitle,BOOLbIsPressed,BOOLbIsDisabled)
{
RECT rImage;
PrepareImageRect(hButtonWnd,bHasTitle,rpItem,rpTitle,bIsPressed,ICON_WIDTH,ICON_HEIGHT,&rImage);

//Ole'!
::DrawState(*dc,
NULL,
NULL,
(LPARAM)hIcon,
0,
rImage.left,
rImage.top,
(rImage.right-rImage.left),
(rImage.bottom-rImage.top),
(bIsDisabled?DSS_DISABLED:DSS_NORMAL)|DST_ICON);
}

staticvoidPrepareImageRect(HWNDhButtonWnd,BOOLbHasTitle,RECT*rpItem,RECT*rpTitle,BOOLbIsPressed,DWORDdwWidth,DWORDdwHeight,RECT*rpImage)
{
RECTrBtn;

::CopyRect(rpImage,rpItem);

::GetClientRect(hButtonWnd,&rBtn);
if(bHasTitle==FALSE)
{
//Centerimagehorizontally
LONGrpImageWidth=rpImage->right-rpImage->left;
rpImage->left =((rpImageWidth-(long)dwWidth)/2);
}
else
{
//Imagemustbeplacedjustinsidethefocusrect
LONGrpTitleWidth=rpTitle->right-rpTitle->left;
rpTitle->right=rpTitleWidth-dwWidth-30;
rpTitle->left=30;
rpImage->left=rBtn.right-dwWidth-30;
//Centerimagevertically
LONGrpImageHeight=rpImage->bottom-rpImage->top;
rpImage->top =((rpImageHeight-(long)dwHeight)/2);
}
}

关键点:必须在BUTTON的属性中设置:Ownerdraw,这样才会产生WM_DRAWITEM消息