1. 버튼 자식윈도우 만들기 ( 가칭 : MyButton )
more..
// 자식( 버튼) 이 부모에게 보낼 때 사용할 통지 코드(메세지를 보내는 이유)를 설계
#define BTN_LCLICK 1
#define BTN_RCLICK 2
#define BTN_DISABLED 3
#define BTN_BTN_ENABLED 4
// 부모가 자식(버튼)을 만들어 놓고 보낼 때 사용할 메세지를 설계한다.
// 일반적으로 컨트롤당 수개~수십개가 설계된다.
#define BM_SETTHICK WM_USER+10
#define BM_SETSTYLE WM_USER+11
void Draw3dRect(HDC hdc, int x, int y, int xx, int yy, BOOL down, int width );
LRESULT CALLBACK BtnProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static BOOL bDown = FALSE;
static int width, height;
static int thick = 2;
switch( msg )
{
// 부모가 보낸 메세지 처리
case BM_SETTHICK:
thick = (int)wParam; // 두께를 변경한다.
InvalidateRect( hwnd, 0, FALSE ); // 다시 그린다.
return 0;
case WM_SIZE:
width = LOWORD(lParam);
height = HIWORD(lParam);
InvalidateRect( hwnd, 0, TRUE );
return 0;
case WM_LBUTTONDOWN:
bDown = TRUE;
InvalidateRect( hwnd, 0, FALSE );
SetCapture( hwnd );
return 0;
case WM_LBUTTONUP:
if( GetCapture() == hwnd )
{
ReleaseCapture();
bDown = FALSE;
InvalidateRect( hwnd, 0, FALSE );
// 자신이 눌려 졌다는 사실을 부모에게 알려준다.
HWND hParent = GetParent( hwnd ); // 부모의 핸들 구하기
UINT id = GetDlgCtrlID( hwnd ); // 자신의 ID 구하기
SendMessage( hParent, WM_COMMAND, MAKELONG( id, BTN_LCLICK ), //하위16:id 상위16:통지
(LPARAM)hwnd ); // 자신의 핸들
}
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint( hwnd, &ps );
// 이제 자식은 그림을 그리기 전에 DC를 부모에게 전달해서
// 부모가 색상을 바꿀 수 있는 기회를 제공한다.
HWND hParent = GetParent( hwnd );
SendMessage( hParent, WM_CTLCOLORBTN, (WPARAM)hdc, (LPARAM)hwnd );
// ------------------------------------------------------------
// 이제 부모가 변경한 DC를 가지고 그림을 그린다.
Draw3dRect( hdc, 0, 0, width, height, bDown, thick );
char title[256];
GetWindowText( hwnd, title, 256 ); // 부모가 지정한 캡션문자열을 얻는다.
RECT rc = { 0, 0, width, height };
if ( bDown == TRUE ) // 버튼이 눌린 경우
OffsetRect( &rc, thick, thick );
SetBkMode( hdc, TRANSPARENT );
DrawText( hdc, title, -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER );
EndPaint( hwnd, &ps );
}
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HWND hBtn;
switch( msg )
{
// 자식이 자신의 색상을 변경하라고 부모에게 보내주는 메세지
case WM_CTLCOLORBTN:
{
HDC hdc = (HDC)wParam;
HWND h = (HWND)lParam;
if( h == hBtn ) // 버튼이 여러 개일 경우.. 원하는 버튼인지 조사
{
SetTextColor( hdc, RGB( 255, 0, 0 ) );
return 0;
}
}
return 0; //DefWindowProc( hwnd, msg, wParam, lParam );
case WM_LBUTTONDOWN:
{
static int n = 1;
++n;
// 자식(버튼)의 두께를 변경한다.
SendMessage( hBtn, BM_SETTHICK, n, 0 );
}
return 0;
// 자식(버튼)이 보내는 메세지 처리
case WM_COMMAND:
switch( LOWORD( wParam ) )
{
case 1:
if( HIWORD(wParam) == BTN_LCLICK ) //통지 코드 조사
{
MessageBox( 0, "Click", "", MB_OK );
}
break;
}
return 0;
// 자식( 버튼)이 보내는 메세지 처리
case WM_CREATE:
hBtn = CreateWindowEx( 0, "MyButton", "확인", WS_CHILD | WS_VISIBLE | WS_BORDER,
10, 10, 100, 100, hwnd, (HMENU)1,
GetModuleHandle(0), 0);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
void Draw3dRect(HDC hdc, int x, int y, int xx, int yy, BOOL down, int width )
{
COLORREF clrMain = RGB(192,192,192),
clrLight = RGB(255,255,255),
clrDark = RGB(128,128,128);
HPEN hPen1, hPen2, hOldPen;
HBRUSH hBrush, hOldBrush;
if(down)
{
hPen2 = CreatePen(PS_SOLID,1,clrLight);
hPen1 = CreatePen(PS_SOLID,1,clrDark);
}
else
{
hPen1 = CreatePen(PS_SOLID,1,clrLight);
hPen2 = CreatePen(PS_SOLID,1,clrDark);
}
hBrush = CreateSolidBrush( clrMain );
hOldPen = (HPEN)SelectObject(hdc, hPen1);
hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
Rectangle(hdc, x , y, xx+1, yy+1);
for(int i=0; i < width; i++)
{
SelectObject(hdc, hPen1);
MoveToEx(hdc, xx - 1, y, 0 );
LineTo(hdc, x, y);
LineTo(hdc, x, yy - 1 );
SelectObject(hdc, hPen2);
MoveToEx(hdc, x, yy,0);
LineTo(hdc, xx, yy);
LineTo(hdc, xx, y);
x++; y++; xx--; yy--;
}
SelectObject(hdc, hOldPen);
SelectObject(hdc, hOldBrush);
DeleteObject(hPen1);
DeleteObject(hPen2);
DeleteObject(hBrush);
}
2. 메시지 박스에 static text 쓰기 ( 10초 지나면 자동으로 닫기 )
more..
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static char sz[256] = "10 Seconds";
switch( msg )
{
case WM_CREATE:
return 0;
case WM_LBUTTONDOWN:
SetTimer( hwnd, 1, 1000, 0 );
MessageBox( hwnd, sz, "Test", MB_OKCANCEL ); //blocking....
KillTimer( hwnd, 1 );
return 0;
case WM_TIMER:
{
HWND hBox = FindWindow( "#32770", "Test" );
static int c = 10;
--c;
wsprintf( sz, "%d Seconds", c );
// 메세지 박스의 Static Control의 내용을 변경한다.
SetDlgItemText( hBox, 0x0000FFFF, sz );
if( c == 0 )
{
// MessageBox를 닫는다. - 어떻게..??
// 결국 MessageBox()는 모달 다이얼로그 이다.
EndDialog( hBox, IDCANCEL );
}
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
}
3. Button Control Dll 로 만들어 보기 cpp
more..
// button.cpp
#undef UNICODE
#undef _UNICODE
#define DLL_SOURCE
#include <windows.h>
#include <tchar.h>
#include "button.h"
//////////////////
void Draw3dRect(HDC hdc, int x, int y, int xx, int yy,
BOOL down, int width )
{
COLORREF clrMain = RGB(192,192,192),
clrLight = RGB(255,255,255),
clrDark = RGB(128,128,128);
HPEN hPen1, hPen2, hOldPen;
HBRUSH hBrush, hOldBrush;
if(down)
{
hPen2 = CreatePen(PS_SOLID,1,clrLight);
hPen1 = CreatePen(PS_SOLID,1,clrDark);
}
else
{
hPen1 = CreatePen(PS_SOLID,1,clrLight);
hPen2 = CreatePen(PS_SOLID,1,clrDark);
}
hBrush = CreateSolidBrush( clrMain );
hOldPen = (HPEN)SelectObject(hdc, hPen1);
hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
Rectangle(hdc, x , y, xx+1, yy+1);
for(int i=0; i < width; i++)
{
SelectObject(hdc, hPen1);
MoveToEx(hdc, xx - 1, y, 0 );
LineTo(hdc, x, y);
LineTo(hdc, x, yy - 1 );
SelectObject(hdc, hPen2);
MoveToEx(hdc, x, yy,0);
LineTo(hdc, xx, yy);
LineTo(hdc, xx, y);
x++; y++; xx--; yy--;
}
SelectObject(hdc, hOldPen);
SelectObject(hdc, hOldBrush);
DeleteObject(hPen1);
DeleteObject(hPen2);
DeleteObject(hBrush);
}
//////////////////////////
LRESULT CALLBACK BtnProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static BOOL bDown = FALSE;
static int width, height;
static int thick = 2;
switch( msg )
{
// 부모가 보낸 메세지 처리
case BM_SETTHICK:
thick = (int)wParam; // 두께를 변경한다.
InvalidateRect( hwnd, 0, FALSE ); // 다시 그린다.
return 0;
case WM_SIZE:
width = LOWORD(lParam);
height = HIWORD(lParam);
InvalidateRect( hwnd, 0, TRUE );
return 0;
case WM_LBUTTONDOWN:
bDown = TRUE;
InvalidateRect( hwnd, 0, FALSE );
SetCapture( hwnd );
return 0;
case WM_LBUTTONUP:
if( GetCapture() == hwnd )
{
ReleaseCapture();
bDown = FALSE;
InvalidateRect( hwnd, 0, FALSE );
// 자신이 눌려 졌다는 사실을 부모에게 알려준다.
HWND hParent = GetParent( hwnd ); // 부모의 핸들 구하기
UINT id = GetDlgCtrlID( hwnd ); // 자신의 ID 구하기
SendMessage( hParent, WM_COMMAND, MAKELONG( id, BTN_LCLICK ), //하위16:id 상위16:통지
(LPARAM)hwnd ); // 자신의 핸들
}
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint( hwnd, &ps );
// 이제 자식은 그림을 그리기 전에 DC를 부모에게 전달해서
// 부모가 색상을 바꿀 수 있는 기회를 제공한다.
HWND hParent = GetParent( hwnd );
SendMessage( hParent, WM_CTLCOLORBTN, (WPARAM)hdc, (LPARAM)hwnd );
// ------------------------------------------------------------
// 이제 부모가 변경한 DC를 가지고 그림을 그린다.
Draw3dRect( hdc, 0, 0, width, height, bDown, thick );
char title[256];
GetWindowText( hwnd, title, 256 ); // 부모가 지정한 캡션문자열을 얻는다.
RECT rc = { 0, 0, width, height };
if ( bDown == TRUE ) // 버튼이 눌린 경우
OffsetRect( &rc, thick, thick );
SetBkMode( hdc, TRANSPARENT );
DrawText( hdc, title, -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER );
EndPaint( hwnd, &ps );
}
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
void InitButtonControl()
{
ATOM atom;
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground= 0;
wc.hCursor = LoadCursor( 0, IDC_ARROW );
wc.hIcon = 0;//LoadIcon( 0, IDI_APPLICATION);
wc.hInstance = GetModuleHandle(0);
wc.lpfnWndProc = BtnProc;
wc.lpszClassName= _T("mybutton");
wc.lpszMenuName = 0;
wc.style = CS_GLOBALCLASS; // dll 에서 윈도우 클래스를 등록할때 사용!!!
atom = RegisterClass( &wc);
}
// 모든 DLL은 메모리에 Load될때 아래 함수가 호출된다.
BOOL WINAPI DllMain( HMODULE hDll, DWORD r, LPVOID how )
{
if( r == DLL_PROCESS_ATTACH )
{
InitButtonControl();
}
return TRUE;
}
4. Button Control Dll 로 만들어 보기 .h
more..
#ifdef DLL_SOURCE
#define DLLAPI __declspec(dllexport)
#else
#define DLLAPI __declspec(dllimport)
#endif
// 자식( 버튼) 이 부모에게 보낼 때 사용할 통지 코드(메세지를 보내는 이유)를 설계
#define BTN_LCLICK 1
#define BTN_RCLICK 2
#define BTN_DISABLED 3
#define BTN_BTN_ENABLED 4
// 부모가 자식(버튼)을 만들어 놓고 보낼 때 사용할 메세지를 설계한다.
// 일반적으로 컨트롤당 수개~수십개가 설계된다.
#define BM_SETTHICK WM_USER+10
#define BM_SETSTYLE WM_USER+11
#ifdef __cplusplus
extern "C" {
#endif
DLLAPI void InitButtonControl();
#ifdef __cplusplus
}
#endif
5. Button Dll 사용하기
more..
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HWND hBtn;
switch( msg )
{
case WM_COMMAND:
switch( LOWORD( wParam ) )
{
case 1:
if( HIWORD( wParam) == BTN_LCLICK )
MessageBox( 0, "Click", "", MB_OK );
break;
}
return 0;
case WM_CREATE:
InitButtonControl();
hBtn = CreateWindowEx(
0, "mybutton", "OK",
WS_CHILD | WS_VISIBLE | WS_BORDER,
10, 10, 100, 100, hwnd, (HMENU)1,
GetModuleHandle(0), 0 );
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}