// 따로 예제를 작성했습니다.
// 참고하시기 바랍니다.
#include “windows.h”
LRESULT CALLBACK
WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
LPSTR lpszClass=”Button Subclass 1″;
HWND g_hWndMain;
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE
hPrevInstance
,LPSTR lpszCmdParam,int
nCmdShow)
{
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
g_hInst=hInstance;
WndClass.cbClsExtra=0;
WndClass.cbWndExtra=0;
WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
WndClass.hInstance=hInstance;
WndClass.lpfnWndProc=(WNDPROC)WndProc;
WndClass.lpszClassName=lpszClass;
WndClass.lpszMenuName=NULL;
WndClass.style=CS_HREDRAW |
CS_VREDRAW;
RegisterClass(&WndClass);
hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
NULL,(HMENU)NULL,hInstance,NULL);
g_hWndMain=hWnd;
ShowWindow(hWnd,nCmdShow);
while(GetMessage(&Message,0,0,0))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return Message.wParam;
}
#define ID_BUTTONS_BEGIN 300
typedef struct
{
int nNum;
int nClick;
}Button_Data;
Button_Data *pBtnData=NULL;
int nButton_num=100;
int iButtonWidth=25;
int iButtonHeight=25;
HWND *pButtons=NULL;
WNDPROC OldEditProc;
HWND hButton_Main=NULL;
char
*pButtonPropName=”Button_Prop_Name”;
LRESULT CALLBACK ButtonSubProc(HWND hWnd,UINT
iMessage,WPARAM wParam,LPARAM lParam)
{
char str[256];
Button_Data *pBDataTmp=NULL;
switch (iMessage)
{
case WM_RBUTTONDOWN:
pBDataTmp=(Button_Data
*)GetProp(hWnd,pButtonPropName);
wsprintf(str,”%lu”,(DWORD)pBDataTmp->nNum);
switch(pBDataTmp->nClick)
{
case 0:
SetWindowText(hWnd,”★”);
pBDataTmp->nClick=1;
break;
case 1:
SetWindowText(hWnd,”♣”);
pBDataTmp->nClick=2;
break;
default:
SetWindowText(hWnd,”♠”);
pBDataTmp->nClick=0;
}
// 아래에서 return문을 쓰면 메시지가 버튼에 전달되지
않습니다.
// 메시지를 막을 이유가 없으면 break문을 써서
CallWindowProc함수를 통해
// 버튼윈도우에 메시지가 전달되도록 해줘야 합니다.
break;
}
return
CallWindowProc(OldEditProc,hWnd,iMessage,wParam,lParam);
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT
iMessage,WPARAM wParam,LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
int i;
int x, y;
char Mes[]=”버튼의 마우스 오른쪽 버튼 클릭을
검출합니다”;
switch(iMessage)
{
case WM_CREATE:
pButtons=(HWND
*)malloc(sizeof(HWND)*nButton_num);
if (pButtons==NULL)
{
MessageBox(hWnd,”Error!”,”Error!”,MB_OK);
DestroyWindow(hWnd);
}
pBtnData=(Button_Data
*)malloc(sizeof(Button_Data)*nButton_num);
if (pBtnData==NULL)
{
free(pButtons);
MessageBox(hWnd,”Error!”,”Error!”,MB_OK);
DestroyWindow(hWnd);
}
// 전역 서브클래싱을 위한 버튼을 하나 만듭니다.
// 이 버튼은 하는 일이 없이 단지 서브클래싱을 하기위해 생성한
것이므로
// 크기를 0으로 만든다음 윈도우의 바깥으로 보내서
감춥니다.
hButton_Main=CreateWindow(“button”,NULL,WS_CHILD |
WS_VISIBLE | BS_PUSHBUTTON,
-1,-1,0,0,hWnd,(HMENU)0,g_hInst,NULL);
// 버튼 윈도우를 전역서브클래싱을 합니다.
OldEditProc=(WNDPROC)SetClassLong(hButton_Main,GCL_WNDPROC,(LONG)ButtonSubProc);
// 서브클래싱된 버튼윈도우들을 만듭니다.
for(i=0; i < nButton_num; i++)
{
x=(i%10)*iButtonWidth;
y=(i/10)*iButtonHeight;
pBtnData[i].nClick=0;
pBtnData[i].nNum=i;
pButtons[i]=CreateWindow(“button”,”♠”,WS_CHILD |
WS_VISIBLE | BS_PUSHBUTTON,
x+10,y+40,iButtonWidth,iButtonHeight,hWnd,
(HMENU)ID_BUTTONS_BEGIN+i,g_hInst,NULL);
// 버튼의 윈도우프로퍼티에 버튼에 대한 정보를 담은
구조체의
// 주소값을 저장합니다.
SetProp(pButtons[i],pButtonPropName,(HANDLE)(pBtnData+i));
}
SetFocus(pButtons[0]);
return 0;
case WM_PAINT:
hdc=BeginPaint(hWnd, &ps);
TextOut(hdc,10,10,Mes,strlen(Mes));
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
if (pButtons)
{
for(i=0; i < nButton_num;
i++)RemoveProp(pButtons[i],pButtonPropName);
free(pButtons);
}
if (pBtnData) free(pBtnData);
SetClassLong(hButton_Main,GCL_WNDPROC,(LONG)OldEditProc);
PostQuitMessage(0);
return 0;
}
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}