//원형 시계
//ExClock.c #include <windows.h> #include <stdlib.h> #include <time.h> #define CLOCKTIMER 1 #define CLOCKSIZE 100 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); VOID CALLBACK TimeProc(HWND hwnd,UINT iMsg,UINT wParam,DWORD lParam); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static char szAppName[] = "ExClock"; HWND hwnd; MSG msg; WNDCLASSEX wndclass; int cx,x; wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx(&wndclass); //스크린의 가로 크기를 얻는다. cx=GetSystemMetrics(SM_CXFULLSCREEN); x=cx-CLOCKSIZE; hwnd = CreateWindow(szAppName, "원형시계 예제:ExClock", WS_POPUP | WS_VISIBLE, x, 0, CLOCKSIZE, CLOCKSIZE, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; HBRUSH hBrush,oldBrush; HPEN hPen,oldPen; HRGN rgn; switch(iMsg) { case WM_CREATE: SetTimer(hwnd,CLOCKTIMER,100,(TIMERPROC)TimeProc); rgn=CreateRoundRectRgn(0,0,CLOCKSIZE,CLOCKSIZE,CLOCKSIZE,CLOCKSIZE); SetWindowRgn(hwnd,rgn,FALSE); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); hBrush=CreateSolidBrush(RGB(0,0,200)); hPen=CreatePen(PS_SOLID,3,RGB(200,200,91)); oldBrush=SelectObject(hdc,hBrush); oldPen=SelectObject(hdc,hPen); RoundRect(hdc,0,0,CLOCKSIZE,CLOCKSIZE,CLOCKSIZE,CLOCKSIZE); SelectObject(hdc,CreateSolidBrush(RGB(0,0,0))); RoundRect(hdc,15,30,85,60,20,20); SelectObject(hdc,oldBrush); SelectObject(hdc,oldPen); DeleteObject(hBrush); DeleteObject(hPen); EndPaint (hwnd, &ps) ; return 0; case WM_DESTROY: KillTimer(hwnd,CLOCKTIMER); PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, iMsg, wParam, lParam); } VOID CALLBACK TimeProc(HWND hwnd,UINT iMsg,UINT wParam,DWORD lParam) { time_t curtime; struct tm cur; char curdate[80]; HDC hdc; time(&curtime); cur=*localtime(&curtime); wsprintf(curdate,"%02d:%02d:%02d",cur.tm_hour,cur.tm_min,cur.tm_sec); hdc=GetDC(hwnd); SetBkColor(hdc,RGB(0,0,0)); SetTextColor(hdc,RGB(255,255,0)); TextOut(hdc,20,37,curdate,strlen(curdate)); ReleaseDC(hwnd,hdc); }
2010년 3월 10일 수요일
바깥 테두리 투명 처리
2010년 3월 8일 월요일
Dialog를 작업표시줄(task bar)에서 숨기려면
Dialog기반 프로그램을 작업표시줄에서 감추고 싶다면, 간단하게 Window Style을 수정해 주면 된다.
- LRESULT CMainDlg::OnInitDialog(
- UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
- {
- ...
- ModifyStyleEx( WS_EX_APPWINDOW,WS_EX_TOOLWINDOW,0 );
- return TRUE;
- }
문제는!!
이렇게 되면 Alt+Tab으로는 이 window를 선택할 수 없다는 점이다. 어쩌다 포커스를 잃게되면, window를 다시
찾기 상당히 귀찮아진다.
두시간의 삽질-_-을 통해 꽁수를 부려봤다. 좀 더 좋은 방법이 있다면 알려주시길~
WTL기반으로 작업했지만, MFC라도 약간만
응용하면 적용할 수 있다. (오히려 더 쉽게)
한줄요약: 작업표시줄에서는 나타나지 않으면서, Alt + Tab을 통해 활성화 되는 Dialog를 만들어 보자.
1. 바보-_- 윈도를 하나 만들자. (MFC라면 CWnd를 쓰면 되므로 이 과정은 생략)
- class CInvisibleWnd : public CWindowImpl<CInvisibleWnd >
- {
- public:
- DECLARE_WND_CLASS(NULL);
- BEGIN_MSG_MAP(CInvisibleWnd)
- END_MSG_MAP()
- };
2. WTL이라면 Run함수에서 Dialog를 생성할 것이다. (MFC라면
CWinApp::InitInstance)
이때, Dialog의 부모로 바보윈도를 설정해 준다. 눈치
채셨겠지만, 이 꽁수의 핵심은 Dialog의 부모로 설정한 바보윈도는 화면에 표시되면 안된다는 점이다.
- int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT)
- {
- ...
- CInvisibleWnd wndInvisible;
- wndInvisible.Create( NULL, 0, NULL, WS_OVERLAPPEDWINDOW );
- CMainDlg dlgMain;
- if ( dlgMain.Create( wndInvisible ) == NULL )
- {
- ATLTRACE(_T("Main dialog creation failed!\n"));
- return 0;
- }
- dlgMain.ShowWindow(nCmdShow);
- int nRet = theLoop.Run();
- _Module.RemoveMessageLoop();
- if ( wndInvisible.IsWindow() )
- wndInvisible.DestroyWindow();
- return nRet;
- }
그렇다. 바보 윈도는 화면에 표시되지 않고 있으니 작업표시줄에 나타나지 않지만, 인스턴스가 있으므로 Alt + Tab을 치면 나타난다! 그
인스턴스를 활성화 시켜주면 자식윈도로 등록된 Dialog가 활성되는 원리.
중요한점은, 프로그램 종료 시점에서 바보윈도또한
소멸시켜 줘야 한다는 거!
MFC라면 좀 더 쉽다. CDialog를 생성할때, 바보 윈도를 생성자의 parameter로 넘겨주기만 하면된다.
(물론, 소멸은
신경써줘야 한다.)
- BOOL CComaApp::InitInstance()
- {
- ...
- CWnd wndInvisible;
- LPCTSTR pstrOwnerClass = AfxRegisterWndClass(0);
- if (!wndInvisible.CreateEx(0,
- pstrOwnerClass,
- _T(""),
- WS_OVERLAPPEDWINDOW ,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- NULL,
- 0 ))
- {
- TRACE(_T("failed to create invisible window"));
- return FALSE;
- }
- CMainDlg dlg(&wndInvisible);
- m_pMainWnd = &dlg;
- dlg.DoModal();
- if (wndInvisible.m_hWnd != NULL)
- wndInvisible.DestroyWindow();
- }
3. 이제 OnInitDialog에서 ModifyStyleEx( WS_EX_APPWINDOW,0 ); 해주면 된다.
꽁수 끄읏!
2010년 3월 4일 목요일
com 모듈을 웹에서 사용하는 방법
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Ext\PreApproved
이렇게 하면 된다#include <atlctl.h>
class ATL_NO_VTABLE {customclass} :
...
public IObjectSafetyImpl<{customclass},
INTERFACESAFE_FOR_UNTRUSTED_CALLER |
INTERFACESAFE_FOR_UNTRUSTED_DATA>
....
BEGIN_COM_MAP({customclass})
...
COM_INTERFACE_ENTRY(IObjectSafety)
END_COM_MAP()