1. Control 사용해보기
#define IDC_BUTTON 1
#define IDC_EDIT 2
#define IDC_LISTBOX 3
int CALLBACK foo(
ENUMLOGFONTEX *lpelfe, // logical-font data
NEWTEXTMETRICEX *lpntme, // physical-font data
DWORD FontType, // type of font
LPARAM lParam // application-defined data
)
{
HWND hList = (HWND)lParam;
SendMessage( hList, LB_ADDSTRING, 0, (LPARAM)lpelfe->elfLogFont.lfFaceName );
return 1;
}
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HWND hBtn, hEdit, hList;
static HBRUSH brush = CreateSolidBrush( RGB(0,255,255) );
//(HBRUSH)GetStockObject( NULL_BRUSH ); // 투명한 배경을 원할때..
switch( msg )
{
case WM_COMMAND:
switch( LOWORD(wParam) )
{
case IDC_BUTTON:
if( HIWORD(wParam) == BN_CLICKED )
{
MessageBox( 0, "click", "", MB_OK );
}
break;
}
return 0;
// EditBox가 그려지기 전에 보내는 메세지
case WM_CTLCOLOREDIT:
{
HDC hdc = (HDC)wParam;
HWND h = (HWND)lParam;
if( h == hEdit )
{
SetTextColor( hdc, RGB(255, 0, 0) );
SetBkColor( hdc, RGB(0,255,0) );
return (LRESULT)brush; // 리턴된 브러쉬로 배경을 채워준다.
}
}
// 처리하지 않은 경우.. 반드시 디폴트로...
// 디폴트가 기본색상을 채워준다..
return DefWindowProc( hwnd, msg, wParam, lParam );
case WM_CREATE:
hBtn = CreateWindow (
"button", "Ok", WS_CHILD | WS_VISIBLE | WS_BORDER | BS_AUTOCHECKBOX, 10, 10, 100, 100, hwnd, (HMENU)IDC_BUTTON, GetModuleHandle(0), 0 );
hEdit = CreateWindow (
"edit", "", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | WS_VSCROLL | WS_HSCROLL, 210, 10, 100, 100, hwnd, (HMENU)IDC_EDIT, GetModuleHandle(0), 0 );
// EditBox의 Margin 을 지정한다.
SendMessage( hEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN,
MAKELONG( 20, 30 ) );
hList = CreateWindow( "listbox", "", WS_CHILD | WS_VISIBLE | WS_BORDER,
410, 10, 100, 100, hwnd, (HMENU)IDC_LISTBOX, GetModuleHandle(0), 0 );
// 역시 listbox에 항목 추가 메세지를 전달한다.
SendMessage( hList, LB_ADDSTRING, 0, (LPARAM)"AAA" );
SendMessage( hList, LB_ADDSTRING, 0, (LPARAM)"BBB" );
{
LOGFONT f;
f.lfCharSet = DEFAULT_CHARSET;
f.lfFaceName[0] = '\0';
HDC hdc = GetDC(hwnd);
EnumFontFamiliesEx( hdc, &f, (FONTENUMPROC)foo, (LPARAM)hList, 0 );
ReleaseDC( hwnd, hdc );
}
// 리턴값, 클래스 이름, 캡션 내용, x좌표, ID 값을 변경하면 됩니다.
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
2. 사용자가 x키보드를 누를때 프로그램 종료( Messag loop 에서 하도록 함)
3. 서브클래싱 구현( edit control 의 "ABCDEF" 를 쓰지 못하게 중간에서 가로챔 )
more..
#define IDC_BUTTON 1
#define IDC_EDIT 2
#define IDC_LISTBOX 3
int CALLBACK foo(
ENUMLOGFONTEX *lpelfe, // logical-font data
NEWTEXTMETRICEX *lpntme, // physical-font data
DWORD FontType, // type of font
LPARAM lParam // application-defined data
)
{
HWND hList = (HWND)lParam;
SendMessage( hList, LB_ADDSTRING, 0, (LPARAM)lpelfe->elfLogFont.lfFaceName );
return 1;
}
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HWND hBtn, hEdit, hList;
static HBRUSH brush = CreateSolidBrush( RGB(0,255,255) );
//(HBRUSH)GetStockObject( NULL_BRUSH ); // 투명한 배경을 원할때..
switch( msg )
{
case WM_COMMAND:
switch( LOWORD(wParam) )
{
case IDC_BUTTON:
if( HIWORD(wParam) == BN_CLICKED )
{
MessageBox( 0, "click", "", MB_OK );
}
break;
}
return 0;
// EditBox가 그려지기 전에 보내는 메세지
case WM_CTLCOLOREDIT:
{
HDC hdc = (HDC)wParam;
HWND h = (HWND)lParam;
if( h == hEdit )
{
SetTextColor( hdc, RGB(255, 0, 0) );
SetBkColor( hdc, RGB(0,255,0) );
return (LRESULT)brush; // 리턴된 브러쉬로 배경을 채워준다.
}
}
// 처리하지 않은 경우.. 반드시 디폴트로...
// 디폴트가 기본색상을 채워준다..
return DefWindowProc( hwnd, msg, wParam, lParam );
case WM_CREATE:
hBtn = CreateWindow (
"button", "Ok", WS_CHILD | WS_VISIBLE | WS_BORDER | BS_AUTOCHECKBOX, 10, 10, 100, 100, hwnd, (HMENU)IDC_BUTTON, GetModuleHandle(0), 0 );
hEdit = CreateWindow (
"edit", "", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | WS_VSCROLL | WS_HSCROLL, 210, 10, 100, 100, hwnd, (HMENU)IDC_EDIT, GetModuleHandle(0), 0 );
// EditBox의 Margin 을 지정한다.
SendMessage( hEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN,
MAKELONG( 20, 30 ) );
hList = CreateWindow( "listbox", "", WS_CHILD | WS_VISIBLE | WS_BORDER,
410, 10, 100, 100, hwnd, (HMENU)IDC_LISTBOX, GetModuleHandle(0), 0 );
// 역시 listbox에 항목 추가 메세지를 전달한다.
SendMessage( hList, LB_ADDSTRING, 0, (LPARAM)"AAA" );
SendMessage( hList, LB_ADDSTRING, 0, (LPARAM)"BBB" );
{
LOGFONT f;
f.lfCharSet = DEFAULT_CHARSET;
f.lfFaceName[0] = '\0';
HDC hdc = GetDC(hwnd);
EnumFontFamiliesEx( hdc, &f, (FONTENUMPROC)foo, (LPARAM)hList, 0 );
ReleaseDC( hwnd, hdc );
}
// 리턴값, 클래스 이름, 캡션 내용, x좌표, ID 값을 변경하면 됩니다.
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
2. 사용자가 x키보드를 누를때 프로그램 종료( Messag loop 에서 하도록 함)
more..
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL PreTranslateMessage( HWND hwnd, MSG *pMsg )
{
if( pMsg->message == WM_KEYDOWN && pMsg->wParam == 'X' )
{
SendMessage( hwnd, WM_CLOSE, 0, 0 );
return TRUE; // 메세지를 분배 하지 않는다.
}
return FALSE; // 계속 메세지를 분배한다.
}
int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nShowCmd )
{
TCHAR szApp[] = _T("First");
ATOM atom;
WNDCLASS wc;
HWND hwnd;
MSG msg;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground= (HBRUSH)GetStockObject( WHITE_BRUSH );
wc.hCursor = LoadCursor( 0, IDC_ARROW );
wc.hIcon = LoadIcon( 0, IDI_APPLICATION);
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName= szApp;
wc.lpszMenuName = 0;
wc.style = 0;
atom = RegisterClass( &wc);
if ( atom == 0 )
{
MessageBox( 0, _T("Fail To RegisterClass"), _T("Error"), MB_OK);
return 0;
}
hwnd = CreateWindowEx( 0, szApp, szApp, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT,0, 0, 0,
hInstance, 0);
ShowWindow( hwnd, nShowCmd);
UpdateWindow( hwnd );
while ( GetMessage( &msg, 0, 0, 0) )
{
//if ( msg.message == WM_KEYDOWN && msg.wParam == 'X' )
//{
// SendMessage( hwnd, WM_CLOSE, 0, 0 );
//}
//else
if( !PreTranslateMessage( hwnd, &msg ) )
{
TranslateMessage(&msg);
DispatchMessage( &msg);
}
}
return 0;
}
//-------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HWND hEdit;
switch( msg )
{
// 사용자가 'X' 키보드를 누를때 프로그램을 종료 하는 코드를 만들어 보세요.
// 종료하는 방법은 "SendMessage( hwnd, WM_CLOSE, 0, 0 )" 으로 하면됩니다.
//case WM_KEYDOWN:
// if( wParam == 'X' ) SendMessage( hwnd, WM_CLOSE, 0, 0 );
// return 0;
case WM_CREATE:
hEdit = CreateWindow( "edit", "", WS_CHILD | WS_VISIBLE | WS_BORDER,
10, 10, 300, 300, hwnd, (HMENU)1, GetModuleHandle(0), 0 );
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
BOOL PreTranslateMessage( HWND hwnd, MSG *pMsg )
{
if( pMsg->message == WM_KEYDOWN && pMsg->wParam == 'X' )
{
SendMessage( hwnd, WM_CLOSE, 0, 0 );
return TRUE; // 메세지를 분배 하지 않는다.
}
return FALSE; // 계속 메세지를 분배한다.
}
int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nShowCmd )
{
TCHAR szApp[] = _T("First");
ATOM atom;
WNDCLASS wc;
HWND hwnd;
MSG msg;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground= (HBRUSH)GetStockObject( WHITE_BRUSH );
wc.hCursor = LoadCursor( 0, IDC_ARROW );
wc.hIcon = LoadIcon( 0, IDI_APPLICATION);
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName= szApp;
wc.lpszMenuName = 0;
wc.style = 0;
atom = RegisterClass( &wc);
if ( atom == 0 )
{
MessageBox( 0, _T("Fail To RegisterClass"), _T("Error"), MB_OK);
return 0;
}
hwnd = CreateWindowEx( 0, szApp, szApp, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT,0, 0, 0,
hInstance, 0);
ShowWindow( hwnd, nShowCmd);
UpdateWindow( hwnd );
while ( GetMessage( &msg, 0, 0, 0) )
{
//if ( msg.message == WM_KEYDOWN && msg.wParam == 'X' )
//{
// SendMessage( hwnd, WM_CLOSE, 0, 0 );
//}
//else
if( !PreTranslateMessage( hwnd, &msg ) )
{
TranslateMessage(&msg);
DispatchMessage( &msg);
}
}
return 0;
}
//-------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HWND hEdit;
switch( msg )
{
// 사용자가 'X' 키보드를 누를때 프로그램을 종료 하는 코드를 만들어 보세요.
// 종료하는 방법은 "SendMessage( hwnd, WM_CLOSE, 0, 0 )" 으로 하면됩니다.
//case WM_KEYDOWN:
// if( wParam == 'X' ) SendMessage( hwnd, WM_CLOSE, 0, 0 );
// return 0;
case WM_CREATE:
hEdit = CreateWindow( "edit", "", WS_CHILD | WS_VISIBLE | WS_BORDER,
10, 10, 300, 300, hwnd, (HMENU)1, GetModuleHandle(0), 0 );
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
3. 서브클래싱 구현( edit control 의 "ABCDEF" 를 쓰지 못하게 중간에서 가로챔 )
more..
#define EM_SETMASK_STRING WM_USER+999
WNDPROC EditProc; // 원래의 메세지 처리 함수 주소를 보관할 변수
LRESULT CALLBACK foo( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
static BOOL mask[256] = { TRUE };
switch( msg )
{
case EM_SETMASK_STRING:
{
BOOL b = (BOOL)wParam;
char* p = (char*)lParam;
for( int i = 0; i < 255; ++i )
{
mask[i] = !b;
}
for( int i = 0; i < strlen(p); ++i )
{
mask[ p[i] ] = b;
}
}
return 0;
case WM_CHAR:
if( mask[wParam] ) // 숫자 입력
break;
return 0;
}
// WM_CHAR를 제외한 모든 메세지와 숫자인 경우는 원래의 함수로 보낸다.
return CallWindowProc( EditProc, hwnd, msg, wParam, lParam );
//return EditProc( hwnd, msg, wParam, lParam ); // msdn에서 UNICODE상에서 문제로 금지함..-_-.
}
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HWND hEdit;
switch( msg )
{
case WM_CREATE:
hEdit = CreateWindow( "edit", "", WS_CHILD | WS_VISIBLE | WS_BORDER,
10, 10, 200, 200,
hwnd, (HMENU)1,
GetModuleHandle(0), 0 );
EditProc = (WNDPROC)SetWindowLong( hEdit, GWL_WNDPROC, (LONG)foo );
SendMessage( hEdit, EM_SETMASK_STRING, (WPARAM)FALSE, (LPARAM)"ABCDEF");
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
WNDPROC EditProc; // 원래의 메세지 처리 함수 주소를 보관할 변수
LRESULT CALLBACK foo( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
static BOOL mask[256] = { TRUE };
switch( msg )
{
case EM_SETMASK_STRING:
{
BOOL b = (BOOL)wParam;
char* p = (char*)lParam;
for( int i = 0; i < 255; ++i )
{
mask[i] = !b;
}
for( int i = 0; i < strlen(p); ++i )
{
mask[ p[i] ] = b;
}
}
return 0;
case WM_CHAR:
if( mask[wParam] ) // 숫자 입력
break;
return 0;
}
// WM_CHAR를 제외한 모든 메세지와 숫자인 경우는 원래의 함수로 보낸다.
return CallWindowProc( EditProc, hwnd, msg, wParam, lParam );
//return EditProc( hwnd, msg, wParam, lParam ); // msdn에서 UNICODE상에서 문제로 금지함..-_-.
}
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HWND hEdit;
switch( msg )
{
case WM_CREATE:
hEdit = CreateWindow( "edit", "", WS_CHILD | WS_VISIBLE | WS_BORDER,
10, 10, 200, 200,
hwnd, (HMENU)1,
GetModuleHandle(0), 0 );
EditProc = (WNDPROC)SetWindowLong( hEdit, GWL_WNDPROC, (LONG)foo );
SendMessage( hEdit, EM_SETMASK_STRING, (WPARAM)FALSE, (LPARAM)"ABCDEF");
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}