OSDN Git Service

CLSIDの変更
[seraphyscrtools/SeraphyScriptTools.git] / OverlappedWindow.cpp
1 // OverlappedWindow.cpp : COverlappedWindow \82Ì\83C\83\93\83v\83\8a\83\81\83\93\83e\81[\83V\83\87\83\93
2
3
4 // /D "_ATL_MIN_CRT" \82ð\8aO\82·
5
6 #include "stdafx.h"
7 #include "SeraphyScriptTools.h"
8 #include "OverlappedWindow.h"
9 #include "generic.h"
10 #include <list>
11 #include <stack>
12
13 /////////////////////////////////////////////////////////////////////////////
14 // COverlappedWindow
15
16
17 HRESULT COverlappedWindow::FinalConstruct()
18 {
19         m_pUnkMarshaler = NULL;
20
21         // \83A\83C\83R\83\93\82Ì\8f\89\8aú\89»
22         m_hIcon = NULL;
23
24         // \83C\83x\83\93\83g\91Ò\8b@\97p\83C\83x\83\93\83g\83n\83\93\83h\83\8b\81A\83C\83x\83\93\83g\8f\88\97\9d\92\86\83Z\83}\83t\83H
25         m_hWaitEvent = CreateEvent(NULL, false, false, NULL); // \8e©\93®\83C\83x\83\93\83g : \8f\89\8aúFALSE
26         // \83N\83\8a\83e\83B\83J\83\8b\83Z\83N\83V\83\87\83\93
27         InitializeCriticalSection(&m_objEventDataProtection);
28
29         // \83C\83x\83\93\83g\83C\83\93\83^\81[\83t\83F\83C\83X\82Ì\8f\89\8aú\89»
30         m_pEvent = NULL;
31         // \83N\83\89\83X\83I\83u\83W\83F\83N\83g\82Ì\8f\89\8aú\89»
32         m_pClassDisp = NULL;
33         m_bAutoReleaseClassObject = true;
34
35         // \83E\83B\83\93\83h\83E\83T\83C\83Y
36         // \81¦ Windows2000\8e\9e\91ã\82Í300x300\82¾\82Á\82½\82ª\81ALuna\88È\8d~\82Å\98g\95\9d\82ª\95Ï\8dX\82³\82ê\82½\82±\82Æ\82É\82æ\82è
37         // \89¡\95\9d308\82É\8fC\90³\82µ\82½\81B(2015/08)
38         windowParam.SetWindowPlacement(CW_USEDEFAULT, CW_USEDEFAULT, 308, 300);
39         windowParam.noclose = false;
40         windowParam.doublebuffer = true;
41         windowParam.automessageloop = true;
42         // \83o\83b\83N\83O\83\89\83E\83\93\83h\83u\83\89\83V
43         m_dwBackColor = ::GetSysColor(COLOR_WINDOW);
44         m_hBkBrush = CreateSolidBrush(COLORREF(m_dwBackColor));
45         // \83E\83B\83\93\83h\83E\82Ì\8dì\90¬
46         m_hParentWnd = NULL;
47         m_hPopupWnd = NULL;
48         m_hMenu = NULL;
49
50         // \83\86\81[\83U\81[\83\82\81[\83h\82Ì\8f\89\8aú\89»
51         m_bQuit = false; // \95Â\82\82ç\82ê\82Ä\82¢\82È\82¢\82±\82Æ\82ð\8e¦\82·
52         m_dModalExitCode = 0;   // \83\82\81[\83_\83\8b\95Ô\93\9a\83R\81[\83h
53         m_dCaptureMode = 0;
54         m_bDefaultAction = true; // \83f\83B\83t\83H\83\8b\83g\82ÌOK/CANCEL\83A\83N\83V\83\87\83\93\82Å\95Â\82\82é
55
56         // \83t\83H\81[\83\80\83C\83\93\83^\81[\83t\83F\83C\83X\82Ì\8dì\90¬
57         m_hLastFocusControl = NULL;
58
59
60         HRESULT hr;
61
62         // \83t\83H\81[\83\80\83I\83u\83W\83F\83N\83g\82Ì\90\90¬
63         m_pForm = NULL;
64         if (FAILED(hr = CComObject<CForm>::CreateInstance(&m_pForm))) {
65                 return hr;
66         }
67         m_pForm->AddRef();
68         m_pForm->SetWindowSize(windowParam.width, windowParam.height,
69                 windowParam.ComputeStyle(), windowParam.exstyle);
70
71         // \95`\89æ\83I\83u\83W\83F\83N\83g\82Ì\90\90¬
72         m_pCanvas = NULL;
73         if (FAILED(hr = CComObject<CCanvas>::CreateInstance(&m_pCanvas))) {
74                 return hr;
75         }
76         m_pCanvas->AddRef();
77
78         // \83\86\81[\83U\81[\92è\8b`\98A\91z\94z\97ñ\83I\83u\83W\83F\83N\83g\82Ì\90\90¬
79         m_pObject = NULL;
80         if (FAILED(hr = CComObject<CObjectMap>::CreateInstance(&m_pObject))) {
81                 return hr;
82         }
83         m_pObject->AddRef();
84
85         // \83E\83F\83C\83g\83J\81[\83\\83\8b\82Ì\8f\89\8aú\89»
86         m_dWaitCursor = 0;
87
88         // \8fW\96ñ\82Ì\82½\82ß\82Ì\83t\83\8a\81[\83X\83\8c\83b\83h\83}\81[\83V\83\83\83\89\82Ì\90Ý\92è
89         return CoCreateFreeThreadedMarshaler(
90                 GetControllingUnknown(), &m_pUnkMarshaler.p);
91 }
92
93 void COverlappedWindow::FinalRelease()
94 {
95         // \83E\83B\83\93\83h\83E\82ª\94j\8aü\82³\82ê\82é\82±\82Æ\82ð\92Ê\92m\82·\82é\83C\83x\83\93\83g
96         Fire_ExitWindow();
97         ClassObjectInvoke(L"ExitWindow");
98
99         // \83N\83\89\83X\83I\83u\83W\83F\83N\83g\82Ì\95ú\8aü
100         if (m_pClassDisp) {
101                 m_pClassDisp.Release();
102         }
103
104         // \83A\83C\83R\83\93\82Ì\94j\8aü
105         if (m_hIcon) {
106                 ::DestroyIcon(m_hIcon);
107         }
108         // \83`\83\83\83C\83\8b\83h\83|\83b\83v\83A\83b\83v\82Ì\94j\8aü
109         std::list<CComObject<COverlappedWindow>*>::iterator pWnd = m_lstChild.begin();
110         while (pWnd != m_lstChild.end()) {
111                 (*pWnd)->Close();
112                 (*pWnd)->Release();
113                 pWnd = m_lstChild.erase(pWnd);
114         }
115         // \83C\83x\83\93\83g\83I\83u\83W\83F\83N\83g\82Ì\94j\8aü
116         if (m_pEvent) {
117                 m_pEvent->Release();
118                 m_pEvent = NULL;
119         }
120
121         // \83h\83\8d\81[\83C\83\93\83O\83I\83u\83W\83F\83N\83g\82Ì\83f\83^\83b\83`\82Æ\83C\83\93\83^\81[\83t\83F\83C\83X\82Ì\95ú\8aü
122         if (m_pCanvas) {
123                 m_pCanvas->DetachOwner();
124                 m_pCanvas->Release();
125                 m_pCanvas = NULL;
126         }
127         // \83t\83H\81[\83\80\82Ì\94j\8aü
128         if (m_pForm) {
129                 m_pForm->DetachOwner();
130                 m_pForm->Release();
131                 m_pForm = NULL;
132         }
133         // \83\86\81[\83U\81[\92è\8b`\98A\91z\94z\97ñ\83I\83u\83W\83F\83N\83g\82Ì\94j\8aü
134         if (m_pObject) {
135                 m_pObject->Release();
136                 m_pObject = NULL;
137         }
138
139         // \94w\8ci\83u\83\89\83V\82Ì\89ð\95ú
140         if (m_hBkBrush) {
141                 DeleteObject(m_hBkBrush);
142         }
143
144         EnterCriticalSection(&m_objEventDataProtection);
145         // \83C\83x\83\93\83g\83f\81[\83^\82Ì\89ð\95ú
146         std::list<CComObject<CEvent>*>::iterator pEv = m_lstEvent.begin();
147         while (pEv != m_lstEvent.end()) {
148                 (*pEv)->Release();
149                 pEv = m_lstEvent.erase(pEv);
150         }
151         LeaveCriticalSection(&m_objEventDataProtection);
152
153         // \83C\83x\83\93\83g\83n\83\93\83h\83\8b\82Ì\89ð\95ú
154         if (m_hWaitEvent) {
155                 CloseHandle(m_hWaitEvent);
156                 m_hWaitEvent = NULL;
157         }
158         // \83\81\83j\83\85\81[\82Ì\94j\8aü
159         if (m_hMenu) {
160                 DestroyMenu(m_hMenu);
161                 m_hMenu = NULL;
162         }
163         // \83\81\83C\83\93\83E\83B\83\93\83h\83E\82Ì\94j\8aü
164         if (m_hPopupWnd) {
165                 ::DestroyWindow(m_hPopupWnd);
166                 m_hPopupWnd = NULL;
167         }
168         // \83N\83\8a\83e\83B\83J\83\8b\83Z\83b\83V\83\87\83\93\82Ì\94j\8aü
169         DeleteCriticalSection(&m_objEventDataProtection);
170
171         m_pUnkMarshaler.Release();
172         ATLTRACE("COverlappedWindow::FinalRelease\r\n");
173 }
174
175 STDMETHODIMP COverlappedWindow::get_Caption(BSTR* pVal)
176 {
177         *pVal = SysAllocString(m_bstrCaption);
178         return S_OK;
179 }
180
181 STDMETHODIMP COverlappedWindow::put_Caption(BSTR newVal)
182 {
183         SysReAllocString(&m_bstrCaption, newVal);
184         SetTitle();
185         return S_OK;
186 }
187
188 STDMETHODIMP COverlappedWindow::get_backColor(long *pVal)
189 {
190         *pVal = m_dwBackColor;
191         return S_OK;
192 }
193
194 STDMETHODIMP COverlappedWindow::put_backColor(long newVal)
195 {
196         m_dwBackColor = newVal;
197         if (m_hBkBrush) {
198                 DeleteObject(m_hBkBrush);
199         }
200         m_hBkBrush = CreateSolidBrush(COLORREF(newVal));
201         if (m_hPopupWnd) {
202                 ::InvalidateRect(m_hPopupWnd, NULL, true);
203                 ::UpdateWindow(m_hPopupWnd);
204         }
205         return S_OK;
206 }
207
208 HWND COverlappedWindow::SafeCreateWnd()
209 {
210         // \90\90¬\8dÏ\82Ý\82Å\82 \82ê\82Î\89½\82à\82µ\82È\82¢\81B
211         if (m_hPopupWnd) {
212                 return m_hPopupWnd;
213         }
214         // \83E\83B\83\93\83h\83E\90\90¬\82É\95K\97v\82È\91S\83p\83\89\83\81\81[\83^\81[\82Í\83R\83\93\83X\83g\83\89\83N\83^\82Å\8dì\90¬\8dÏ\82Ý
215         // \82 \82Æ\82Í\83E\83B\83\93\83h\83E\82ª\95K\97v\82É\82È\82Á\82½\83^\83C\83~\83\93\83O\82Å\90\90¬\82ð\8ds\82¤
216
217         if (windowParam.noclose) {
218                 // \95Â\82\82é\83{\83^\83\93\82È\82µ\83^\83C\83v
219                 windowParam.SetWindowClassName(_TEXT("SeraphyScriptToolsOverlappedWindowNC"));
220                 windowParam.wndstyle = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_NOCLOSE;
221         }
222         else {
223                 windowParam.SetWindowClassName(_TEXT("SeraphyScriptToolsOverlappedWindow"));
224                 windowParam.wndstyle = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
225         }
226
227         WNDCLASSEX wcex = { 0 };
228         wcex.cbSize = sizeof(WNDCLASSEX);
229         wcex.lpfnWndProc = (WNDPROC)WindowProc;
230         wcex.cbClsExtra = 0;
231         wcex.cbWndExtra = 0;
232         wcex.hInstance = _Module.m_hInst;
233         wcex.hIcon = NULL;//(HICON)LoadImage(NULL,"SETUPICON.ICO",IMAGE_ICON,16,16,LR_LOADFROMFILE);//LoadIcon(hInstance, (LPCTSTR)IDI_INSTPAC);
234         wcex.hIconSm = m_hIcon;//LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
235         wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
236         wcex.hbrBackground = NULL;
237         wcex.lpszMenuName = NULL;
238         wcex.lpszClassName = windowParam.szClassName;
239         wcex.style = windowParam.wndstyle;
240         ATOM atm = RegisterClassEx(&wcex);
241
242         HWND hWnd = CreateWindowEx(
243                 WS_EX_CONTROLPARENT,
244                 windowParam.szClassName,
245                 _TEXT(""), // \83_\83~\81[
246                 windowParam.ComputeStyle(),
247                 CW_USEDEFAULT,
248                 CW_USEDEFAULT,
249                 windowParam.width,
250                 windowParam.height,
251                 m_hParentWnd,
252                 NULL, _Module.m_hInst, this);
253         ::SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) this); // \83N\83\89\83X\82Æ\8aÖ\98A\95t\82¯\82é
254         m_hPopupWnd = hWnd;
255         // \83E\83B\83\93\83h\83E\83X\83^\83C\83\8b\82Ì\8dÄ\90Ý\92è
256         ::SetWindowLong(m_hPopupWnd, GWL_STYLE, windowParam.ComputeStyle());
257         Refresh();
258
259         // \83V\83X\83e\83\80\83\81\83j\83\85\81[\82É\83t\83\8c\81[\83\80\88Ú\93®\83\81\83j\83\85\81[\82ð\82Â\82¯\82é
260         HMENU hMenu = ::GetSystemMenu(m_hPopupWnd, false);
261         int cnt = ::GetMenuItemCount(hMenu);
262         MENUITEMINFO minfo = { 0 };
263         minfo.cbSize = sizeof(MENUITEMINFO);
264         minfo.fMask = MIIM_TYPE | MIIM_ID;
265         minfo.fType = MFT_STRING;
266         minfo.wID = WM_MOVENEXT_OVERLAPPED;
267         minfo.dwTypeData = _TEXT("\8e\9f\82Ì\83E\83B\83\93\83h\83E\82É\88Ú\93®\tF6"); //FIXME: \83\8a\83\\81[\83X\82É\88Ú\93®\82·\82é
268         ::InsertMenuItem(hMenu, cnt, true, &minfo);
269
270         // \83t\83H\81[\83\80\82Ì\83\81\83C\83\93\83E\83B\83\93\83h\83E\97p\82Æ\82µ\82Ä\83A\83^\83b\83`\82·\82é
271         if (m_pForm) {
272                 // \83R\83\93\83g\83\8d\81[\83\8b\82Ì\8e\96\91O\8dì\90¬\95ª\82à\8e©\93®\90\90¬\82³\82ê\82é
273                 m_pForm->AttachOwner(m_hPopupWnd);
274         }
275
276         // \83E\83B\83\93\83h\83E\82ª\90\90¬\82³\82ê\82½\83C\83x\83\93\83g\82ð\94­\8ds\82·\82é
277         Fire_InitWindow();
278         ClassObjectInvoke(L"InitWindow");
279
280         return hWnd;
281 }
282
283 LRESULT CALLBACK COverlappedWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
284 {
285         COverlappedWindow* me = (COverlappedWindow*)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
286
287         // \8bÙ\8b}\92â\8e~\82Ì\94»\92è
288         if (GetAsyncKeyState(VK_PAUSE) & 0x8000) {
289                 ::EnableWindow(hWnd, true);
290                 me->m_bQuit = 1;
291                 me->m_dModalExitCode = 3;
292         }
293
294         switch (uMsg) {
295         case WM_MOVENEXT_OVERLAPPED:
296         {
297                 me->MoveNextOverlapped();
298                 return 0;
299         }
300         case WM_CREATE:
301         {
302                 // \83f\83B\83t\83H\83\8b\83g\82Ì\93®\8dì\82ð\8ds\82¤
303                 break;
304         }
305         case WM_PAINT:
306         {
307                 PAINTSTRUCT ps;
308                 RECT rt;
309                 ::GetClientRect(hWnd, &rt);
310                 HDC hdc = ::BeginPaint(hWnd, &ps);
311                 HDC hdc2 = hdc;
312                 HBITMAP bmp;
313                 BOOL bDblBuf = me->windowParam.doublebuffer;
314                 if (bDblBuf) {
315                         // \82¿\82ç\82Â\82«\82ð\96³\82­\82·\82é\82½\82ß\82É\83o\83u\83\8b\83o\83b\83t\83@\95\97\82É\82·\82é\82©\81H
316                         hdc2 = ::CreateCompatibleDC(NULL);
317                         bmp = ::CreateCompatibleBitmap(hdc, rt.right, rt.bottom);
318                         ::SelectObject(hdc2, bmp);
319                 }
320                 // \94w\8ci\82ð\93h\82è\82Â\82Ô\82·
321                 ::SetBkColor(hdc2, COLORREF(me->m_dwBackColor));
322                 ::SetBkMode(hdc2, TRANSPARENT);
323                 ::SetPolyFillMode(hdc2, ALTERNATE);
324                 FillRect(hdc2, &rt, me->m_hBkBrush);
325
326                 // \83h\83\8d\81[\83C\83\93\83O\83f\81[\83^\81[\82Ì\95`\89æ
327                 if (me->m_pCanvas) {
328                         me->m_pCanvas->Draw(hdc2, rt);
329                 }
330
331                 if (bDblBuf) {
332                         // \83_\83u\83\8b\83o\83b\83t\83@\82Ì\93]\91\97
333                         ::BitBlt(hdc, 0, 0, rt.right, rt.bottom, hdc2, 0, 0, SRCCOPY);
334                         DeleteDC(hdc2);
335                         DeleteObject(bmp);
336                 }
337                 ::EndPaint(hWnd, &ps);
338                 break;
339         }
340         case WM_SYSCOMMAND:
341         {
342                 if (wParam == SC_CLOSE) {
343                         if (me->windowParam.autoclose) {
344                                 me->Close();
345                         }
346                         me->m_bQuit = true;
347                         me->m_dModalExitCode = IDABORT;
348                         me->AddEventSingle(WM_COMMAND, IDABORT, 0);
349                         return false;
350                 }
351                 else if (wParam == WM_MOVENEXT_OVERLAPPED) {
352                         SendMessage(hWnd, WM_MOVENEXT_OVERLAPPED, 0, 0);
353                         return 0;
354                 }
355                 break;
356         }
357         case WM_MOUSEMOVE:
358         {
359                 me->AddEventSingle(WM_MOUSEMOVE, 0, 0);
360                 break;
361         }
362         case WM_LBUTTONDBLCLK:
363         {
364                 me->AddEvent(WM_LBUTTONDBLCLK, 0, 0);
365                 break;
366         }
367         case WM_RBUTTONDBLCLK:
368         {
369                 me->AddEvent(WM_RBUTTONDBLCLK, 0, 0);
370                 break;
371         }
372         case WM_LBUTTONDOWN:
373         {
374                 if (me->m_dCaptureMode == 0) {
375                         me->AddEvent(WM_LBUTTONDOWN, 0, 0);
376                         ::SetCapture(hWnd);
377                         me->m_dCaptureMode |= 0x01;
378                 }
379                 else {
380                         ReleaseCapture();
381                 }
382                 break;
383         }
384         case WM_LBUTTONUP:
385         {
386                 if (me->m_dCaptureMode & 0x01) {
387                         me->AddEvent(WM_LBUTTONUP, 0, 0);
388                         me->m_dCaptureMode &= ~0x01;
389                         ReleaseCapture();
390                 }
391                 break;
392         }
393         case WM_RBUTTONDOWN:
394         {
395                 if (me->m_dCaptureMode == 0) {
396                         me->AddEvent(WM_RBUTTONDOWN, 0, 0);
397                         ::SetCapture(hWnd);
398                         me->m_dCaptureMode |= 0x02;
399                 }
400                 else {
401                         ReleaseCapture();
402                 }
403                 break;
404         }
405         case WM_RBUTTONUP:
406         {
407                 if (me->m_dCaptureMode & 0x02) {
408                         me->AddEvent(WM_RBUTTONUP, 0, 0);
409                         me->m_dCaptureMode &= ~0x02;
410                         ReleaseCapture();
411                 }
412                 break;
413         }
414         case WM_CAPTURECHANGED:
415         {
416                 if (me->m_dCaptureMode & 0x01) {
417                         me->AddEvent(WM_CAPTURECHANGED, 1, 0);
418                 }
419                 if (me->m_dCaptureMode & 0x02) {
420                         me->AddEvent(WM_CAPTURECHANGED, 2, 0);
421                 }
422                 me->m_dCaptureMode = 0;
423                 break;
424         }
425         case WM_SIZE:
426         {
427                 me->AddEventSingle(WM_SIZE, 0, 0);
428                 break;
429         }
430         case WM_TIMER:
431         {
432                 if (wParam == 1) {
433                         me->AddEventSingle(WM_TIMER, 0, 0);
434                 }
435                 break;
436         }
437         case WM_DROPFILES:
438         {
439                 HDROP hDrop = (HDROP)wParam;
440                 me->m_dropfiles.SetDropFiles(hDrop);
441                 me->AddEvent(WM_DROPFILES, 0, 0);
442                 break;
443         }
444         case WM_KEYDOWN:
445         {
446                 DWORD st = 0;
447                 if (GetKeyState(VK_SHIFT) & 0x8000) st |= 0x01;
448                 if (GetKeyState(VK_CONTROL) & 0x8000) st |= 0x02;
449                 if (GetKeyState(VK_MENU) & 0x8000) st |= 0x04;
450                 me->AddEventSingle(WM_KEYDOWN, wParam, st);
451                 return 0;
452         }
453         case WM_KEYDOWN_EX:
454         {
455                 DWORD st = 0;
456                 if (GetKeyState(VK_SHIFT) & 0x8000) st |= 0x01;
457                 if (GetKeyState(VK_CONTROL) & 0x8000) st |= 0x02;
458                 if (GetKeyState(VK_MENU) & 0x8000) st |= 0x04;
459                 me->AddEventSingle(WM_KEYDOWN_EX, wParam, st);
460                 return 0;
461         }
462         case WM_COMMAND:
463         {
464 #ifdef _DEBUG
465                 ATLTRACE(_TEXT("command=%d:%d\n"), HIWORD(wParam), LOWORD(wParam));
466 #endif
467                 HWND hControl = (HWND)lParam;
468                 int nID = LOWORD(wParam);
469                 int notify = HIWORD(wParam);
470                 if (!notify) {
471                         if (nID == IDABORT) {
472                                 // IDABORT\82Æ\93¯\88ê\82È\82çquit\82ð\97§\82Ä\82é
473                                 me->m_bQuit = true;
474                         }
475                         me->AddEventSingle(WM_COMMAND, nID, 0);
476                 }
477                 else {
478                         // \83R\83\93\83g\83\8d\81[\83\8b\92Ê\92m
479                         switch (notify) {
480                         case CBN_SETFOCUS:
481                         case LBN_SETFOCUS:
482                         case EN_SETFOCUS:
483                         case BN_SETFOCUS:
484                                 // TreeView - ListView\88È\8aO\82Ì\83R\83\93\83g\83\8d\81[\83\8b\82ª\83t\83H\81[\83J\83X\82ð\8eó\82¯\8eæ\82Á\82½\82±\82Æ\82ð\92Ê\92m\82·\82é
485                                 me->m_hLastFocusControl = hControl;
486                                 break;
487                         case LBN_DBLCLK:
488                                 // LISTBOX\82ª\83_\83u\83\8b\83N\83\8a\83b\83N\82³\82ê\82½
489                                 me->AddEvent(WM_COMMAND, nID, 0);
490                         default:
491                                 break;
492                         }
493                 }
494                 break;
495         }
496         case WM_NOTIFY:
497         {
498                 NMHDR* notify = (NMHDR*)lParam;
499                 switch (notify->code) {
500                 case NM_SETFOCUS:
501                 {
502                         // TreeView - ListView\82ª\83t\83H\81[\83J\83X\82ð\8eó\82¯\8eæ\82Á\82½\82±\82Æ\82ð\92Ê\92m\82·\82é
503                         me->m_hLastFocusControl = notify->hwndFrom;
504                         return 0;
505                 }
506                 case TVN_SELCHANGED:
507                 {
508                         // TreeView\82Ì\91I\91ð\82ª\95Ï\8dX\82³\82ê\82½\82±\82Æ\82ð\92Ê\92m\82³\82ê\82é
509                         LPNMTREEVIEW pnmTv = (LPNMTREEVIEW)lParam;
510                         me->AddEvent(WM_COMMAND, pnmTv->hdr.idFrom, 0);
511                         return 0;
512                 }
513                 case NM_DBLCLK:
514                 {
515                         // ListView - TreeView\82Å\83_\83u\83\8b\83N\83\8a\83b\83N\82³\82ê\82½\82±\82Æ\82ð\92Ê\92m\82³\82ê\82½
516                         LPNMITEMACTIVATE pnmLv = (LPNMITEMACTIVATE)lParam;
517                         me->AddEvent(WM_COMMAND, pnmLv->hdr.idFrom, 0);
518                         return 0;
519                 }
520                 case LVN_COLUMNCLICK:
521                 {
522                         // ListView\82Å\83J\83\89\83\80\82ª\83N\83\8a\83b\83N\82³\82ê\82½\82±\82Æ\82ð\92Ê\92m\82·\82é
523                         LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam;
524                         LONG_PTR addr = ::GetWindowLongPtr(pnmv->hdr.hwndFrom, GWLP_USERDATA);
525                         if (addr) {
526                                 // \83J\83\89\83\80\83N\83\8a\83b\83N\82É\82æ\82é\83\\81[\83e\83B\83\93\83O\82ð\8ds\82¤
527                                 CComObject<CControl>* pCtrl = (CComObject<CControl>*)addr;
528                                 pCtrl->ListSort(pnmv->iSubItem);
529                         }
530                         return 0;
531                 }
532                 case LVN_ENDLABELEDIT:
533                 {
534                         // ListView\82Å\8d\80\96Ú\82ª\95Ò\8fW\82³\82ê\82½\82±\82Æ\82ð\92Ê\92m\82·\82é
535                         NMLVDISPINFO* pdi = (NMLVDISPINFO*)lParam;
536                         if (pdi->item.mask & LVIF_TEXT) {
537                                 ListView_SetItemText(pdi->hdr.hwndFrom, pdi->item.iItem, 0, pdi->item.pszText);
538                         }
539                         return 0;
540                 }
541                 case LVN_KEYDOWN:
542                 {
543                         // ListView\82Å\83L\81[\83{\81[\83h\82ª\89\9f\82³\82ê\82½\82±\82Æ\82ð\92Ê\92m\82·\82é
544                         LPNMLVKEYDOWN pnkd = (LPNMLVKEYDOWN)lParam;
545                         if (pnkd->wVKey == VK_SPACE) {
546                                 // \83X\83y\81[\83X\83L\81[\82Å\83_\83u\83\8b\83N\83\8a\83b\83N\82Æ\93¯\82\8cø\89Ê\82ð\8e\9d\82½\82¹\82é
547                                 me->AddEvent(WM_COMMAND, pnkd->hdr.idFrom, 0);
548                         }
549                         else if (pnkd->wVKey == VK_DELETE) {
550                                 // \83f\83\8a\81[\83g
551                                 me->AddEvent(WM_NOTIFY, pnkd->hdr.idFrom, VK_DELETE);
552                         }
553                         else if (pnkd->wVKey == VK_F2) {
554                                 // \83\89\83x\83\8b\95Ò\8fW\8aJ\8en
555                                 int idx = ListView_GetNextItem(pnkd->hdr.hwndFrom, -1, LVNI_FOCUSED);
556                                 ListView_EditLabel(pnkd->hdr.hwndFrom, idx);
557                         }
558                         return 0;
559                 }
560                 case TVN_KEYDOWN:
561                 {
562                         LPNMTVKEYDOWN ptvkd = (LPNMTVKEYDOWN)lParam;
563                         if (ptvkd->wVKey == VK_DELETE) {
564                                 // \83f\83\8a\81[\83g
565                                 me->AddEvent(WM_NOTIFY, ptvkd->hdr.idFrom, VK_DELETE);
566                         }
567                         return 0;
568                 }
569                 case NM_RCLICK:
570                 {
571                         // ListView - TreeView \82Å\89E\83N\83\8a\83b\83N\82³\82ê\82½\82±\82Æ\82ð\92Ê\92m\82·\82é
572                         LPNMHDR lpnmh = (LPNMHDR)lParam;
573                         LONG_PTR addr = ::GetWindowLongPtr(lpnmh->hwndFrom, GWLP_USERDATA);
574                         if (addr) {
575                                 CComObject<CControl>* pCtrl = (CComObject<CControl>*)addr;
576                                 pCtrl->OnRClick(); // \83R\83\93\83g\83\8d\81[\83\8b\82É\89E\83N\83\8a\83b\83N\82ð\92Ê\92m\82µ\91O\8f\88\97\9d\82ð\8ds\82í\82¹\82é
577                         }
578                         me->AddEvent(WM_NOTIFY, lpnmh->idFrom, VK_RBUTTON);
579                         return 0;
580                 }
581                 default:
582                         break;
583                 }
584                 break;
585         }
586         case WM_CTLCOLORSTATIC:
587         {
588                 HDC hdc = (HDC)wParam;
589                 ::SetBkColor(hdc, me->m_dwBackColor);
590                 ::SetTextColor(hdc, ::GetSysColor(COLOR_WINDOWTEXT));
591                 return (LPARAM)me->m_hBkBrush;
592         }
593         case WM_CTLCOLOREDIT:
594         case WM_CTLCOLORLISTBOX:
595         case WM_CTLCOLORMSGBOX:
596         {
597                 if (me->m_pForm) {
598                         // \83t\83H\81[\83\80\82Å\8ew\92è\82³\82ê\82½\83R\83\93\83g\83\8d\81[\83\8b\94w\8ci\83u\83\89\83V\82ð\8eæ\93¾\82·\82é
599                         HDC hdc = (HDC)wParam;
600                         ::SetBkColor(hdc, me->m_pForm->GetControlColor());
601                         ::SetTextColor(hdc, ::GetSysColor(COLOR_WINDOWTEXT));
602                         return (LPARAM)me->m_pForm->GetControlColorBrush();
603                 }
604                 break;
605         }
606         case WM_SETCURSOR:
607         {
608                 if (me->m_dWaitCursor > 0) {
609                         ::SetCursor(::LoadCursor(NULL, IDC_WAIT));
610                         return true;
611                 }
612                 break;
613         }
614         }
615         return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
616 }
617
618 STDMETHODIMP COverlappedWindow::DoEvent(VARIANT *varResult)
619 {
620         SafeCreateWnd();
621
622         CComVariant ret;
623         ret = 0;
624
625         // \83C\83x\83\93\83L\83\85\81[\82Ì\8eæ\93¾
626         EnterCriticalSection(&m_objEventDataProtection);
627         CComObject<CEvent>* pEv = NULL;
628         if (!m_lstEvent.empty()) {
629                 // \83C\83x\83\93\83g\83\8a\83X\83g\82É\83f\81[\83^\81[\82ª\93ü\82Á\82Ä\82¢\82é
630                 pEv = m_lstEvent.front();
631                 m_lstEvent.pop_front();
632         }
633         if (m_lstEvent.empty()) {
634                 // \82±\82ê\88È\8fã\83\81\83b\83Z\81[\83W\82ª\82È\82¢\82Ì\82È\82ç\82Î\81A\83C\83x\83\93\83g\83t\83\89\83O\82ð\83\8a\83Z\83b\83g\82·\82é
635                 ResetEvent(m_hWaitEvent);
636         }
637         else {
638                 // \82Ü\82¾\83\81\83b\83Z\81[\83W\82ª\82 \82é\82Ì\82Å\83C\83x\83\93\83g\82ð\82½\82Ä\82é
639                 SetEvent(m_hWaitEvent);
640         }
641         LeaveCriticalSection(&m_objEventDataProtection);
642
643         // \8eæ\82è\8fo\82µ\82½\83C\83x\83\93\83g\82Ì\8f\88\97\9d
644         if (pEv) {
645                 // \95Ô\93\9a\83C\83x\83\93\83g\83R\81[\83h
646                 ret = pEv->GetMessage();
647                 //
648                 if (pEv->GetMessage() == WM_TIMER) {
649                         // \83^\83C\83}\81[\83C\83x\83\93\83g\82ÍUI\82É\8aÖ\8cW\82È\82­\8a\84\82è\8d\9e\82Ü\82ê\82é\82½\82ß
650                         // \83C\83x\83\93\83g\83v\83\8d\83p\83e\83B\81[\82É\82Í\83Z\83b\83g\82¹\82¸\81A\83\89\83C\83Y\82·\82é\82¾\82¯\81B
651                         Fire_OnTimer();
652                         ClassObjectInvoke(L"OnTimer");
653                 }
654                 else {
655                         // \82»\82Ì\82Ù\82©\82Ì\83C\83x\83\93\83g\82Í \8c»\8dÝ\82Ì\83C\83x\83\93\83g\83I\83u\83W\83F\83N\83g\82ð\83v\83\8d\83p\83e\83B\81[\82É\83Z\83b\83g\82·\82é
656                         if (m_pEvent) {
657                                 // \8cÃ\82¢\83I\83u\83W\83F\83N\83g\82Ì\94j\8aü
658                                 m_pEvent->Release();
659                                 m_pEvent = NULL;
660                         }
661                         m_pEvent = pEv;
662                         m_pEvent->AddRef();
663
664                         // \82±\82Ì\83I\83u\83W\83F\83N\83g\82ð\88ø\90\94\82Æ\82µ\82Ä\93n\82·\82½\82ß\82É\83C\83\93\83^\81[\83t\83F\83C\83X\82ð\90\90¬\82·\82é
665                         CComPtr<IUnknown> pUnk;
666                         HRESULT hr;
667                         if (FAILED(hr = QueryInterface(IID_IUnknown, (void**)&pUnk))) {
668                                 return hr;
669                         }
670
671                         // \83C\83x\83\93\83g\82É\91Î\82·\82é\83\89\83C\83Y
672                         switch (pEv->GetMessage()) {
673                         case WM_KEYDOWN:
674                         {
675                                 Fire_OnKeydown();
676                                 Fire_OnKeydownEx(pUnk);
677                                 ClassObjectInvoke(L"OnKeydown");
678                                 break;
679                         }
680                         case WM_KEYDOWN_EX:
681                         {
682                                 Fire_OnKeydown2();
683                                 Fire_OnKeydown2Ex(pUnk);
684                                 ClassObjectInvoke(L"OnKeydown2");
685                                 break;
686                         }
687                         case WM_MOUSEMOVE:
688                         {
689                                 Fire_OnMouseMove();
690                                 Fire_OnMouseMoveEx(pUnk);
691                                 ClassObjectInvoke(L"OnMouseMove");
692                                 break;
693                         }
694                         case WM_LBUTTONDBLCLK:
695                         {
696                                 Fire_OnDblClick();
697                                 Fire_OnDblClickEx(pUnk);
698                                 ClassObjectInvoke(L"OnDblClick");
699                                 break;
700                         }
701                         case WM_LBUTTONDOWN:
702                         {
703                                 Fire_OnClick();
704                                 Fire_OnClickEx(pUnk);
705                                 ClassObjectInvoke(L"OnClick");
706                                 break;
707                         }
708                         case WM_RBUTTONDBLCLK:
709                         {
710                                 Fire_OnRDblClick();
711                                 Fire_OnRDblClickEx(pUnk);
712                                 ClassObjectInvoke(L"OnRDblClick");
713                                 break;
714                         }
715                         case WM_RBUTTONDOWN:
716                         {
717                                 Fire_OnRClick();
718                                 Fire_OnRClickEx(pUnk);
719                                 ClassObjectInvoke(L"OnRClick");
720                                 break;
721                         }
722                         case WM_LBUTTONUP:
723                         {
724                                 Fire_OnClickOut();
725                                 Fire_OnClickOutEx(pUnk);
726                                 ClassObjectInvoke(L"OnClickOut");
727                                 break;
728                         }
729                         case WM_RBUTTONUP:
730                         {
731                                 Fire_OnRClickOut();
732                                 Fire_OnRClickOutEx(pUnk);
733                                 ClassObjectInvoke(L"OnRClickOut");
734                                 break;
735                         }
736                         case WM_CAPTURECHANGED:
737                         {
738                                 if (pEv->GetParam() == 1) {
739                                         Fire_OnClickCancel();
740                                         Fire_OnClickCancelEx(pUnk);
741                                         ClassObjectInvoke(L"OnClickCancel");
742                                 }
743                                 else {
744                                         Fire_OnRClickCancel();
745                                         Fire_OnRClickCancelEx(pUnk);
746                                         ClassObjectInvoke(L"OnRClickCancel");
747                                 }
748                                 break;
749                         }
750                         case WM_SIZE:
751                         {
752                                 Fire_OnSize();
753                                 Fire_OnSizeEx(pUnk);
754                                 ClassObjectInvoke(L"OnSize");
755                                 break;
756                         }
757                         case WM_COMMAND:
758                         {
759                                 int nID = pEv->GetParam();
760                                 switch (nID) {
761                                 case IDOK:
762                                         if (m_bDefaultAction) {
763                                                 m_bQuit = true;
764                                         }
765                                         m_dModalExitCode = IDOK;
766                                         Fire_OnOK();
767                                         Fire_OnOKEx(pUnk);
768                                         ClassObjectInvoke(L"OnOK");
769                                         break;
770                                 case IDCANCEL:
771                                         if (m_bDefaultAction) {
772                                                 m_bQuit = true;
773                                         }
774                                         m_dModalExitCode = IDCANCEL;
775                                         Fire_OnCancel();
776                                         Fire_OnCancelEx(pUnk);
777                                         ClassObjectInvoke(L"OnCancel");
778                                         break;
779                                 case IDABORT:
780                                         m_bQuit = true;
781                                         m_dModalExitCode = IDABORT;
782                                         Fire_OnExit();
783                                         Fire_OnExitEx(pUnk);
784                                         ClassObjectInvoke(L"OnExit");
785                                         break;
786                                 default:
787                                         Fire_OnCommand();
788                                         Fire_OnCommandEx(pUnk);
789                                         ClassObjectInvoke(L"OnCommand");
790                                 }
791                                 // \8aÖ\98A\82Ã\82¯\82ç\82ê\82½\83R\83\93\83g\83\8d\81[\83\8b\82ª\82 \82é\82Ì\82©\81H
792                                 if (m_pForm) {
793                                         BSTR eventname = NULL;
794                                         if (m_pForm->FindControlEventName(nID, &eventname)) {
795                                                 if (SysStringLen(eventname) > 0) {
796                                                         ClassObjectInvoke(eventname);
797                                                 }
798                                                 SysFreeString(eventname);
799                                         }
800                                 }
801                                 // \83\81\83j\83\85\81[\82Ì\8c\9f\8dõ
802                                 if (m_hMenu && nID >= 100) {
803                                         std::map<int, CComBSTR>::iterator p = m_cMenuMap.find(nID);
804                                         if (p != m_cMenuMap.end()) {
805                                                 // \94­\8c©\82³\82ê\82½
806                                                 ClassObjectInvoke(p->second);
807                                         }
808                                 }
809                                 break;
810                         }
811                         case WM_DROPFILES:
812                         {
813                                 Fire_OnDropFiles();
814                                 Fire_OnDropFilesEx(pUnk);
815                                 ClassObjectInvoke(L"OnDropFiles");
816                                 break;
817                         }
818                         case WM_NOTIFY:
819                         {
820                                 switch (pEv->GetLParam()) {
821                                 case VK_DELETE:
822                                         Fire_OnContextDelete();
823                                         Fire_OnContextDeleteEx(pUnk);
824                                         ClassObjectInvoke(L"OnContextDelete");
825                                         break;
826                                 case VK_RBUTTON:
827                                         Fire_OnContextMenu();
828                                         Fire_OnContextMenuEx(pUnk);
829                                         ClassObjectInvoke(L"OnContextMenu");
830                                         break;
831                                 }
832                                 break;
833                         }
834                         }
835                         // \82±\82Ì\88ø\90\94\82Æ\82µ\82Ä\93n\82µ\82½\83C\83\93\83^\81[\83t\83F\83C\83X\82ð\89ð\95ú\82·\82é
836                         if (pUnk) {
837                                 pUnk.Release();
838                         }
839                 }
840                 // \8f\88\97\9d\82³\82ê\82½\83C\83x\83\93\83g\82Í\89ð\95ú\82·\82é
841                 pEv->Release();
842         }
843         else {
844                 // \83C\83x\83\93\83g\82ª\82È\82¢\8fê\8d\87\82Í\83C\83x\83\93\83g\82Ì\83N\83\8a\83A
845                 if (m_pEvent) {
846                         // \8cÃ\82¢\83I\83u\83W\83F\83N\83g\82Ì\94j\8aü
847                         m_pEvent->Release();
848                         m_pEvent = NULL;
849                 }
850         }
851         // \83C\83x\83\93\83g\83R\81[\83h\82ð\96ß\82·\81B
852         ret.Detach(varResult);
853         return S_OK;
854 }
855
856 void COverlappedWindow::AddEventSingle(int message, WPARAM wParam, LPARAM lParam)
857 {
858         // \83C\83x\83\93\83g\83o\83b\83t\83@\82É\96¢\8f\88\97\9d\82Ì\83C\83x\83\93\83g\82ª\82 \82ê\82Î\83C\83x\83\93\83g\82ð\94­\8ds\82µ\82È\82¢\81B
859         BOOL bFind = false;
860         EnterCriticalSection(&m_objEventDataProtection);
861         std::list<CComObject<CEvent>*>::iterator p = m_lstEvent.begin();
862         while (p != m_lstEvent.end()) {
863                 if ((*p)->GetMessage() == message && (*p)->GetParam() == wParam) {
864                         bFind = true;
865                         break;
866                 }
867                 p++;
868         }
869         LeaveCriticalSection(&m_objEventDataProtection);
870         if (!bFind) {
871                 // \93¯\88ê\83C\83x\83\93\83g\82ª\82È\82¯\82ê\82Î\83C\83x\83\93\83g\82Ì\94­\8ds\82ð\8ds\82¤
872                 AddEvent(message, wParam, lParam);
873         }
874 }
875
876 void COverlappedWindow::AddEvent(int message, WPARAM wParam, LPARAM lParam)
877 {
878         // \83C\83x\83\93\83g\94­\90\8e\9e\82Ì\83}\83E\83X\88Ê\92u\82ð\83N\83\89\83C\83G\83\93\83g\8dÀ\95W\82É\95Ï\8a·\82·\82é
879         POINT pt, lp;
880         DWORD pos = GetMessagePos();
881         pt.x = LOWORD(pos);
882         pt.y = HIWORD(pos);
883         lp.x = lp.y = 0;
884         if (m_hPopupWnd) {
885                 ::ScreenToClient(m_hPopupWnd, &pt);
886                 // \8dÀ\95W\8cn\82Ì\95Ï\8a·
887                 lp = pt;
888                 HDC hdc = ::GetDC(m_hPopupWnd);
889                 POINT org;
890                 RECT rct;
891                 ::GetClientRect(m_hPopupWnd, &rct);
892                 ::SetViewportOrgEx(hdc, 0, rct.bottom, &org);
893                 int md = ::GetMapMode(hdc);
894                 ::SetMapMode(hdc, MM_LOMETRIC);
895                 ::DPtoLP(hdc, &lp, 1);
896                 ::SetMapMode(hdc, md);
897                 ::SetViewportOrgEx(hdc, org.x, org.y, NULL);
898                 ::ReleaseDC(m_hPopupWnd, hdc);
899         }
900
901         // \83C\83x\83\93\83g\82Ì\90Ï\82Ý\8fã\82°
902         EnterCriticalSection(&m_objEventDataProtection);
903         CComObject<CEvent>* pEvent = NULL;
904         HRESULT hr;
905         if (SUCCEEDED(hr = CComObject<CEvent>::CreateInstance(&pEvent))) {
906                 pEvent->AddRef();
907                 pEvent->SetData(message, wParam, lParam, pt, lp);
908                 m_lstEvent.push_back(pEvent);
909         }
910         ATLASSERT(SUCCEEDED(hr));
911
912         LeaveCriticalSection(&m_objEventDataProtection);
913
914         // \83C\83x\83\93\83g\83n\83\93\83h\83\8b\82ð\83V\83O\83i\83\8b\82É\82·\82é
915         SetEvent(m_hWaitEvent);
916
917         if (windowParam.automessageloop) {
918                 // \82½\82¾\82¿\82É\83C\83x\83\93\83g\8f\88\97\9d\82ð\8ds\82¤
919                 CComVariant tmp;
920                 DoEvent(&tmp);
921         }
922 }
923
924
925 STDMETHODIMP COverlappedWindow::Draw()
926 {
927         // \95`\89æ\82·\82é
928         if (m_hPopupWnd) {
929                 ::InvalidateRect(m_hPopupWnd, NULL, true);
930                 ::UpdateWindow(m_hPopupWnd);
931         }
932         return S_OK;
933 }
934
935
936 STDMETHODIMP COverlappedWindow::get_IsEventEmpty(BOOL *pVal)
937 {
938         // \83C\83x\83\93\83g\82ª\8bó\82È\82çtrue
939         *pVal = m_lstEvent.empty() ? VB_TRUE : VB_FALSE;
940         return S_OK;
941 }
942
943 STDMETHODIMP COverlappedWindow::Open(VARIANT caption, VARIANT* pvarUnk)
944 {
945         SafeCreateWnd();
946         CComVariant tmp;
947         if ((caption.vt != VT_ERROR && caption.vt != VT_NULL) && tmp.ChangeType(VT_BSTR, &caption) == S_OK) {
948                 put_Caption(tmp.bstrVal);
949         }
950         put_Enable(true);
951         put_Visible(true);
952         m_bQuit = false;
953         m_dModalExitCode = 0;     // \83\82\81[\83_\83\8b\95Ô\93\9a\83R\81[\83h
954         CreateThisInterface(pvarUnk);
955         return S_OK;
956 }
957
958 STDMETHODIMP COverlappedWindow::Close()
959 {
960         // \83`\83\83\83C\83\8b\83h\82ð\8e\9d\82Á\82Ä\82¢\82é\8fê\8d\87\82Í\81A\83`\83\83\83C\83\8b\83h\82à\83N\83\8d\81[\83Y\82·\82é
961         std::list<CComObject<COverlappedWindow>*>::iterator pWnd = m_lstChild.begin();
962         while (pWnd != m_lstChild.end()) {
963                 (*pWnd)->Close();
964                 pWnd++;
965         }
966         // \82±\82Ì\83E\83B\83\93\83h\83E\82ð\94ñ\95\\8e¦\82É\82·\82é
967         put_Visible(false);
968         m_bQuit = true;
969
970         // \83N\83\89\83X\83I\83u\83W\83F\83N\83g\82Ì\95ú\8aü
971         if (m_pClassDisp && m_bAutoReleaseClassObject) {
972                 m_pClassDisp.Release();
973         }
974
975         // \83t\83H\81[\83J\83X\82ð\88Ú\93®\82·\82é
976         if (m_hParentWnd) {
977                 ::SetActiveWindow(m_hParentWnd);
978                 ::SetFocus(m_hParentWnd);
979         }
980         else {
981                 MoveNextOverlapped();
982         }
983         return S_OK;
984 }
985
986 STDMETHODIMP COverlappedWindow::get_DoubleBuffer(BOOL *pVal)
987 {
988         if (!pVal) {
989                 return E_POINTER;
990         }
991
992         *pVal = windowParam.doublebuffer ? VB_TRUE : VB_FALSE;
993
994         return S_OK;
995 }
996
997 STDMETHODIMP COverlappedWindow::put_DoubleBuffer(BOOL newVal)
998 {
999         windowParam.doublebuffer = newVal;
1000         return S_OK;
1001 }
1002
1003
1004 STDMETHODIMP COverlappedWindow::get_TopMost(BOOL *pVal)
1005 {
1006         if (!pVal) {
1007                 return E_POINTER;
1008         }
1009
1010         SafeCreateWnd();
1011
1012         DWORD exstyle = ::GetWindowLong(m_hPopupWnd, GWL_EXSTYLE);
1013         *pVal = (exstyle & WS_EX_TOPMOST) ? VB_TRUE : VB_FALSE;
1014
1015         return S_OK;
1016 }
1017
1018 STDMETHODIMP COverlappedWindow::put_TopMost(BOOL newVal)
1019 {
1020         SafeCreateWnd();
1021         ::SetWindowPos(m_hPopupWnd, newVal ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
1022         return S_OK;
1023 }
1024
1025 STDMETHODIMP COverlappedWindow::get_PosX(short *pVal)
1026 {
1027         if (!pVal) {
1028                 return E_POINTER;
1029         }
1030
1031         if (m_hPopupWnd) {
1032                 WINDOWPLACEMENT pls = { 0 };
1033                 pls.length = sizeof(WINDOWPLACEMENT);
1034                 ::GetWindowPlacement(m_hPopupWnd, &pls);
1035                 windowParam.posX = (int)pls.rcNormalPosition.left;
1036         }
1037
1038         *pVal = windowParam.posX;
1039
1040         return S_OK;
1041 }
1042
1043 STDMETHODIMP COverlappedWindow::put_PosX(short newVal)
1044 {
1045         windowParam.posX = newVal;
1046         if (m_hPopupWnd) {
1047                 WINDOWPLACEMENT pls = { 0 };
1048                 pls.length = sizeof(WINDOWPLACEMENT);
1049                 ::GetWindowPlacement(m_hPopupWnd, &pls);
1050                 ::SetWindowPos(m_hPopupWnd, NULL,
1051                         windowParam.posX,
1052                         pls.rcNormalPosition.top,
1053                         0, 0, SWP_NOZORDER | SWP_NOSIZE);
1054         }
1055         return S_OK;
1056 }
1057
1058 STDMETHODIMP COverlappedWindow::get_PosY(short *pVal)
1059 {
1060         if (!pVal) {
1061                 return E_POINTER;
1062         }
1063
1064         if (m_hPopupWnd) {
1065                 WINDOWPLACEMENT pls = { 0 };
1066                 pls.length = sizeof(WINDOWPLACEMENT);
1067                 ::GetWindowPlacement(m_hPopupWnd, &pls);
1068                 windowParam.posY = (int)pls.rcNormalPosition.top;
1069         }
1070
1071         *pVal = windowParam.posY;
1072
1073         return S_OK;
1074 }
1075
1076 STDMETHODIMP COverlappedWindow::put_PosY(short newVal)
1077 {
1078         windowParam.posY = newVal;
1079         if (m_hPopupWnd) {
1080                 WINDOWPLACEMENT pls = { 0 };
1081                 pls.length = sizeof(WINDOWPLACEMENT);
1082                 ::GetWindowPlacement(m_hPopupWnd, &pls);
1083                 ::SetWindowPos(m_hPopupWnd, NULL,
1084                         pls.rcNormalPosition.left,
1085                         windowParam.posY,
1086                         0, 0, SWP_NOZORDER | SWP_NOSIZE);
1087         }
1088         return S_OK;
1089 }
1090
1091 STDMETHODIMP COverlappedWindow::get_Width(short *pVal)
1092 {
1093         if (!pVal) {
1094                 return E_POINTER;
1095         }
1096
1097         if (m_hPopupWnd) {
1098                 WINDOWPLACEMENT pls = { 0 };
1099                 pls.length = sizeof(WINDOWPLACEMENT);
1100                 ::GetWindowPlacement(m_hPopupWnd, &pls);
1101                 windowParam.width = (int)(pls.rcNormalPosition.right - pls.rcNormalPosition.left);
1102         }
1103
1104         *pVal = windowParam.width;
1105
1106         return S_OK;
1107 }
1108
1109 STDMETHODIMP COverlappedWindow::put_Width(short newVal)
1110 {
1111         windowParam.width = newVal;
1112
1113         if (m_hPopupWnd) {
1114                 WINDOWPLACEMENT pls = { 0 };
1115                 pls.length = sizeof(WINDOWPLACEMENT);
1116                 ::GetWindowPlacement(m_hPopupWnd, &pls);
1117                 ::SetWindowPos(m_hPopupWnd, NULL,
1118                         0, 0,
1119                         windowParam.width,
1120                         pls.rcNormalPosition.bottom - pls.rcNormalPosition.top, SWP_NOZORDER | SWP_NOMOVE);
1121         }
1122
1123         if (m_pForm) {
1124                 // \83t\83H\81[\83\80\82Ì\83T\83C\83Y\82ð\95Ï\8dX\82·\82é
1125                 m_pForm->SetWindowSize(windowParam.width, windowParam.height,
1126                         windowParam.ComputeStyle(), windowParam.exstyle);
1127         }
1128         return S_OK;
1129 }
1130
1131 STDMETHODIMP COverlappedWindow::get_Height(short *pVal)
1132 {
1133         if (!pVal) {
1134                 return E_POINTER;
1135         }
1136
1137         if (m_hPopupWnd) {
1138                 WINDOWPLACEMENT pls = { 0 };
1139                 pls.length = sizeof(WINDOWPLACEMENT);
1140                 ::GetWindowPlacement(m_hPopupWnd, &pls);
1141                 windowParam.height = (short)(pls.rcNormalPosition.right - pls.rcNormalPosition.left);
1142         }
1143
1144         *pVal = windowParam.height;
1145
1146         return S_OK;
1147 }
1148
1149 STDMETHODIMP COverlappedWindow::put_Height(short newVal)
1150 {
1151         windowParam.height = newVal;
1152
1153         if (m_hPopupWnd) {
1154                 WINDOWPLACEMENT pls = { 0 };
1155                 pls.length = sizeof(WINDOWPLACEMENT);
1156                 ::GetWindowPlacement(m_hPopupWnd, &pls);
1157                 ::SetWindowPos(m_hPopupWnd, NULL, 0, 0,
1158                         pls.rcNormalPosition.right - pls.rcNormalPosition.left,
1159                         windowParam.height,
1160                         SWP_NOZORDER | SWP_NOMOVE);
1161         }
1162
1163         if (m_pForm) {
1164                 // \83t\83H\81[\83\80\82Ì\83T\83C\83Y\82ð\95Ï\8dX\82·\82é
1165                 m_pForm->SetWindowSize(windowParam.width, windowParam.height,
1166                         windowParam.ComputeStyle(), windowParam.exstyle);
1167         }
1168         return S_OK;
1169 }
1170
1171 STDMETHODIMP COverlappedWindow::get_AcceptFiles(BOOL *pVal)
1172 {
1173         if (!pVal) {
1174                 return E_POINTER;
1175         }
1176
1177         SafeCreateWnd();
1178
1179         DWORD exstyle = ::GetWindowLong(m_hPopupWnd, GWL_EXSTYLE);
1180         *pVal = (exstyle & WS_EX_ACCEPTFILES) ? VB_TRUE : VB_FALSE;
1181
1182         return S_OK;
1183 }
1184
1185 STDMETHODIMP COverlappedWindow::put_AcceptFiles(BOOL newVal)
1186 {
1187         SafeCreateWnd();
1188         DWORD exstyle = ::GetWindowLong(m_hPopupWnd, GWL_EXSTYLE);
1189         exstyle &= ~WS_EX_ACCEPTFILES;
1190         exstyle |= newVal ? WS_EX_ACCEPTFILES : 0;
1191         ::SetWindowLong(m_hPopupWnd, GWL_EXSTYLE, exstyle);
1192         return S_OK;
1193 }
1194
1195 STDMETHODIMP COverlappedWindow::SetForegroundWindow()
1196 {
1197         SafeCreateWnd();
1198         ::SetForegroundWindow(m_hPopupWnd);
1199         return S_OK;
1200 }
1201
1202 STDMETHODIMP COverlappedWindow::SetFocus()
1203 {
1204         SafeCreateWnd();
1205         ::SetFocus(m_hPopupWnd);
1206         return S_OK;
1207 }
1208
1209 STDMETHODIMP COverlappedWindow::get_Enable(BOOL *pVal)
1210 {
1211         if (!pVal) {
1212                 return E_POINTER;
1213         }
1214         SafeCreateWnd();
1215
1216         *pVal = ::IsWindowEnabled(m_hPopupWnd) ? VB_TRUE : VB_FALSE;
1217
1218         return S_OK;
1219 }
1220
1221 STDMETHODIMP COverlappedWindow::put_Enable(BOOL newVal)
1222 {
1223         SafeCreateWnd();
1224
1225         ::EnableWindow(m_hPopupWnd, newVal);
1226
1227         if (m_pForm) {
1228                 m_pForm->EnableAllControl(newVal);
1229                 ::SetActiveWindow(m_hPopupWnd);
1230         }
1231         return S_OK;
1232 }
1233
1234
1235 STDMETHODIMP COverlappedWindow::get_Iconic(BOOL *pVal)
1236 {
1237         if (!pVal) {
1238                 return E_POINTER;
1239         }
1240
1241         SafeCreateWnd();
1242
1243         *pVal = ::IsIconic(m_hPopupWnd) ? VB_TRUE : VB_FALSE;
1244
1245         return S_OK;
1246 }
1247
1248 STDMETHODIMP COverlappedWindow::put_Iconic(BOOL newVal)
1249 {
1250         SafeCreateWnd();
1251         ::ShowWindow(m_hPopupWnd, newVal ? SW_MINIMIZE : SW_SHOWNORMAL);
1252         return S_OK;
1253 }
1254
1255
1256 STDMETHODIMP COverlappedWindow::get_Zoomed(BOOL *pVal)
1257 {
1258         if (!pVal) {
1259                 return E_POINTER;
1260         }
1261
1262         SafeCreateWnd();
1263
1264         *pVal = ::IsZoomed(m_hPopupWnd) ? VB_TRUE : VB_FALSE;
1265
1266         return S_OK;
1267 }
1268
1269 STDMETHODIMP COverlappedWindow::put_Zoomed(BOOL newVal)
1270 {
1271         SafeCreateWnd();
1272         ::ShowWindow(m_hPopupWnd, newVal ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL);
1273         return S_OK;
1274 }
1275
1276 STDMETHODIMP COverlappedWindow::get_Visible(BOOL *pVal)
1277 {
1278         if (!pVal) {
1279                 return E_POINTER;
1280         }
1281
1282         *pVal = VB_FALSE;
1283
1284         if (::IsWindow(m_hPopupWnd)) {
1285                 // \83E\83B\83\93\83h\83E\82ª\8dì\90¬\8dÏ\82Ý\82Å\82 \82ê\82Î\92²\8d¸\82·\82é
1286                 DWORD style = ::GetWindowLong(m_hPopupWnd, GWL_STYLE);
1287                 *pVal = (style & WS_VISIBLE) ? VB_TRUE : VB_FALSE;
1288         }
1289
1290         return S_OK;
1291 }
1292
1293 STDMETHODIMP COverlappedWindow::put_Visible(BOOL newVal)
1294 {
1295         if (!newVal && !::IsWindow(m_hPopupWnd)) {
1296                 // FALSE\82È\82ç\81A\82 \82¦\82Ä\8dì\90¬\82Í\8e\8e\82Ý\82È\82¢
1297                 return S_OK;
1298         }
1299
1300         SafeCreateWnd();
1301
1302         ::ShowWindow(m_hPopupWnd, newVal ? SW_SHOWNORMAL : SW_HIDE);
1303         ::SetActiveWindow(m_hPopupWnd);
1304
1305         return S_OK;
1306 }
1307
1308 STDMETHODIMP COverlappedWindow::WaitEvent(VARIANT varTim, BOOL* pRet)
1309 {
1310         if (!pRet) {
1311                 return E_POINTER;
1312         }
1313
1314         SafeCreateWnd();
1315         *pRet = VB_FALSE;
1316
1317         // \91Ò\8b@\8e\9e\8aÔ\82Ì\8eæ\93¾
1318         DWORD sleeptim = 1000;
1319         CComVariant tim;
1320         if (tim.ChangeType(VT_I4, &varTim) == S_OK) {
1321                 sleeptim = (DWORD)tim.lVal;
1322         }
1323         if (sleeptim == 0) {
1324                 sleeptim = INFINITE;
1325         }
1326
1327         HANDLE hEvent[MAXIMUM_WAIT_OBJECTS] = { NULL };
1328         HWND   hWnd[MAXIMUM_WAIT_OBJECTS] = { NULL };
1329         int cnt = 0;
1330         SetWaitParam(&cnt, hWnd, hEvent);
1331         *pRet = MessageLoop(sleeptim, cnt, hWnd, hEvent) ? VB_TRUE : VB_FALSE;
1332
1333         return S_OK;
1334 }
1335
1336 STDMETHODIMP COverlappedWindow::SetMenu(VARIANT fmt)
1337 {
1338         SafeCreateWnd();
1339
1340         HRESULT hr;
1341
1342         CComVariant tmp;
1343         if (FAILED(hr = tmp.ChangeType(VT_BSTR, &fmt))) {
1344                 return hr;
1345         }
1346
1347         ATL::CString buf(tmp.bstrVal);
1348
1349         // \8cÃ\82¢\83\81\83j\83\85\81[\82ð\94j\8aü\82·\82é
1350         if (m_hMenu) {
1351                 m_cMenuMap.clear();
1352                 ::SetMenu(m_hPopupWnd, NULL);
1353                 DestroyMenu(m_hMenu);
1354                 m_hMenu = NULL;
1355         }
1356
1357         if (buf.GetLength() > 0) {
1358                 // \8d\80\96Ú\82ª\82 \82ê\82Î\83\81\83j\83\85\81[\96¼\82ð\83p\81[\83X\82·\82é
1359                 m_hMenu = CreateMenu();
1360                 TCHAR menuname[MAX_PATH];
1361                 TCHAR szSubmenu[MAX_PATH];
1362                 HMENU hPopupMenu = NULL;
1363                 int lv1 = 0;
1364                 int lv2 = 0;
1365                 int cmd = 0;
1366
1367                 LPTSTR p = buf.GetBuffer();
1368                 while (*p) {
1369                         while (*p == ' ' || *p == '\t') p++; // \83u\83\89\83\93\83N\83X\83L\83b\83v
1370                         if (*p == '/') {
1371                                 p++;
1372                                 // \83|\83b\83v\83A\83b\83v\83\81\83j\83\85\81[\82Ì\8dì\90¬
1373                                 if (hPopupMenu) {
1374                                         // \8aù\91\82Ì\83|\83b\83v\83A\83b\83v\82ð\96\84\82ß\8d\9e\82Þ
1375                                         MENUITEMINFO inf = { 0 };
1376                                         inf.cbSize = sizeof(MENUITEMINFO);
1377                                         inf.fMask = MIIM_SUBMENU | MIIM_TYPE;
1378                                         inf.fType = MFT_STRING;
1379                                         inf.dwTypeData = szSubmenu;
1380                                         inf.hSubMenu = hPopupMenu;
1381                                         InsertMenuItem(m_hMenu, lv1, true, &inf);
1382                                 }
1383                                 lv1++;
1384                                 lv2 = 0;
1385                                 cmd = 0;
1386
1387                                 hPopupMenu = CreatePopupMenu();
1388                                 LPTSTR st = p;
1389                                 while (*p && *p != ',' && *p != '/' && *p != ':') {
1390                                         p = CharNext(p);
1391                                 }
1392                                 ZeroMemory(szSubmenu, MAX_PATH);
1393                                 int submenuLen = p - st;
1394                                 if (submenuLen > 0) {
1395                                         _tcsncpy_s(szSubmenu, MAX_PATH, st, submenuLen);
1396                                 }
1397                                 if (*p == ',' || *p == ':') {
1398                                         p++;
1399                                 }
1400                         }
1401                         else {
1402                                 // \83\81\83j\83\85\81[\82Ì\8dì\90¬
1403                                 if (hPopupMenu) {
1404                                         LPTSTR st = p;
1405                                         while (*p && *p != ',' && *p != '/' && *p != ':') {
1406                                                 p = CharNext(p);
1407                                         }
1408
1409                                         ZeroMemory(menuname, MAX_PATH);
1410                                         int menunameLen = p - st;
1411                                         if (menunameLen > 0) {
1412                                                 _tcsncpy_s(menuname, MAX_PATH, st, menunameLen);
1413                                         }
1414
1415                                         // \83R\83}\83\93\83h\83Z\83p\83\8c\81[\83^\81[\82ð\8c\9f\8d¸\82·\82é
1416                                         CComBSTR eventname;
1417                                         LPTSTR findcmd = _tcschr(menuname, _TEXT('@'));
1418                                         if (findcmd) {
1419                                                 *findcmd = 0;
1420                                                 eventname = findcmd + 1;
1421
1422                                         }
1423                                         else {
1424                                                 TCHAR tmp[64];
1425                                                 wsprintf(tmp, _TEXT("OnMenu%d"), lv1 * 100 + cmd);
1426                                                 eventname = tmp;
1427                                         }
1428                                         m_cMenuMap.insert(std::make_pair(lv1 * 100 + cmd, eventname));
1429
1430                                         // \83\81\83j\83\85\81[\82Ì\8dì\90¬
1431                                         MENUITEMINFO inf = { 0 };
1432                                         inf.cbSize = sizeof(MENUITEMINFO);
1433                                         inf.fMask = MIIM_TYPE | MIIM_ID;
1434                                         inf.fType = MFT_STRING;
1435                                         inf.wID = lv1 * 100 + cmd;
1436                                         inf.dwTypeData = menuname;
1437                                         InsertMenuItem(hPopupMenu, lv2, true, &inf);
1438                                         lv2++;
1439                                         cmd++;
1440
1441                                         // \83Z\83p\83\8c\81[\83^\81[\82Ì\8ew\92è\82©?
1442                                         if (*p == ',') {
1443                                                 p++;
1444
1445                                         }
1446                                         else if (*p == ':') {
1447                                                 MENUITEMINFO inf = { 0 };
1448                                                 inf.cbSize = sizeof(MENUITEMINFO);
1449                                                 inf.fMask = MIIM_TYPE;
1450                                                 inf.fType = MFT_SEPARATOR;
1451                                                 InsertMenuItem(hPopupMenu, lv2, true, &inf);
1452                                                 p++;
1453                                                 lv2++;
1454                                         }
1455                                 }
1456                         }
1457                 }
1458                 // \96¢\91}\93ü\82Ì\83|\83b\83v\83A\83b\83v\83\81\83j\83\85\81[\82Ì\91}\93ü
1459                 if (hPopupMenu) {
1460                         // \8aù\91\82Ì\83|\83b\83v\83A\83b\83v\82ð\96\84\82ß\8d\9e\82Þ
1461                         MENUITEMINFO inf = { 0 };
1462                         inf.cbSize = sizeof(MENUITEMINFO);
1463                         inf.fMask = MIIM_SUBMENU | MIIM_TYPE;
1464                         inf.fType = MFT_STRING;
1465                         inf.dwTypeData = szSubmenu;
1466                         inf.hSubMenu = hPopupMenu;
1467                         InsertMenuItem(m_hMenu, lv1, true, &inf);
1468                 }
1469                 ::SetMenu(m_hPopupWnd, m_hMenu);
1470         }
1471         return S_OK;
1472 }
1473
1474 STDMETHODIMP COverlappedWindow::TrackPopupMenu(VARIANT text, VARIANT pcmd, VARIANT* pRet)
1475 {
1476         if (!pRet) {
1477                 return E_POINTER;
1478         }
1479
1480         SafeCreateWnd();
1481
1482         CComVariant varRet;
1483         varRet = 0;
1484
1485         int nCommand = 0;
1486         CComVariant varCmd;
1487         if (SUCCEEDED(varCmd.ChangeType(VT_I2, &pcmd))) {
1488                 nCommand = varCmd.iVal;
1489         }
1490
1491         HRESULT hr;
1492
1493         CComVariant varText;
1494         if (FAILED(hr = varText.ChangeType(VT_BSTR, &text))) {
1495                 return hr;
1496         }
1497
1498         TCHAR menuname[MAX_PATH];
1499
1500         ATL::CString buf(varText.bstrVal);
1501         UINT len = buf.GetLength() + 1;
1502         LPTSTR p = buf.GetBuffer();
1503
1504         int lv = 0;
1505         int cmd = 0;
1506         HMENU hPopupMenu = CreatePopupMenu();
1507         while (*p) {
1508                 LPTSTR st = p;
1509                 while (*p == ' ' || *p == '\t') {
1510                         p++;
1511                 }
1512                 while (*p && *p != ',' && *p != '/' && *p != ':') {
1513                         p = CharNext(p);
1514                 }
1515                 ZeroMemory(menuname, MAX_PATH);
1516                 int menunameLen = p - st;
1517                 if (menunameLen > 0) {
1518                         _tcsncpy_s(menuname, MAX_PATH, st, menunameLen);
1519                 }
1520                 MENUITEMINFO inf = { 0 };
1521                 inf.cbSize = sizeof(MENUITEMINFO);
1522                 inf.fMask = MIIM_TYPE | MIIM_ID;
1523                 inf.fType = MFT_STRING;
1524
1525                 if (nCommand != 0) {
1526                         inf.wID = nCommand + cmd;
1527
1528                 }
1529                 else {
1530                         // \83R\83}\83\93\83h\83x\81[\83X\82ª0\82È\82ç\82Î\83R\83}\83\93\83h\83C\83x\83\93\83g\82Í\94­\90\82³\82¹\82È\82¢\81B
1531                         // TrackPopupMenu\82Í\83R\83}\83\93\83h\82ð\91I\91ð\82µ\82È\82©\82Á\82½\8fê\8d\87\82Í0\82ð\95Ô\82·\82½\82ß\81A0\82æ\82è\82à\91å\82«\82È\92l\82É\82·\82é\95K\97v\82ª\82 \82é\81B
1532                         inf.wID = nCommand + cmd + 1;
1533                 }
1534
1535                 inf.dwTypeData = menuname;
1536                 InsertMenuItem(hPopupMenu, lv, true, &inf);
1537                 lv++;
1538                 cmd++;
1539
1540                 if (*p == ',' || *p == '/') {
1541                         p++;
1542
1543                 }
1544                 else if (*p == ':') {
1545                         inf.fMask = MIIM_TYPE;
1546                         inf.fType = MFT_SEPARATOR;
1547                         InsertMenuItem(hPopupMenu, lv, true, &inf);
1548                         p++;
1549                         lv++;
1550                 }
1551         }
1552
1553         // TrackPopupMene
1554         DWORD pos = GetMessagePos();
1555         ::SetFocus(m_hPopupWnd);
1556         varRet = (SHORT) ::TrackPopupMenuEx(hPopupMenu,
1557                 TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON |
1558                 (nCommand == 0 ? (TPM_NONOTIFY | TPM_RETURNCMD) : 0), // \83R\83}\83\93\83h\83x\81[\83X\82ª0\82Å\82 \82ê\82Î\81A\83R\83}\83\93\83h\83C\83x\83\93\83g\82ð\92Ê\92m\82³\82¹\82È\82¢\81B
1559                 LOWORD(pos),
1560                 HIWORD(pos),
1561                 m_hPopupWnd,
1562                 NULL);
1563
1564         DestroyMenu(hPopupMenu);
1565
1566         return varRet.Detach(pRet);
1567 }
1568
1569 STDMETHODIMP COverlappedWindow::get_HWND(long *pVal)
1570 {
1571         *pVal = (LONG)m_hPopupWnd;
1572         return S_OK;
1573 }
1574
1575 STDMETHODIMP COverlappedWindow::GetSysColor(VARIANT typ, VARIANT *col)
1576 {
1577         if (!col) {
1578                 return E_POINTER;
1579         }
1580         VariantInit(col);
1581
1582         // \83V\83X\83e\83\80\83J\83\89\81[\82Ì\8eæ\93¾
1583         HRESULT hr;
1584
1585         CComVariant varType;
1586         if (FAILED(hr = varType.ChangeType(VT_I2, &typ))) {
1587                 return hr;
1588         }
1589
1590         CComVariant varRet;
1591         varRet = (long)::GetSysColor(varType.iVal);
1592         return varRet.Detach(col);
1593 }
1594
1595 STDMETHODIMP COverlappedWindow::SetTimer(VARIANT tim, BOOL* pVal)
1596 {
1597         if (!pVal) {
1598                 return E_POINTER;
1599         }
1600
1601         SafeCreateWnd();
1602
1603         long timer = 0;
1604
1605         CComVariant varTim;
1606         if (SUCCEEDED(varTim.ChangeType(VT_I4, &tim))) {
1607                 timer = varTim.lVal;
1608         }
1609
1610         if (timer) {
1611                 *pVal = ::SetTimer(m_hPopupWnd, 1, timer, NULL) ? VB_TRUE : VB_FALSE;
1612
1613         }
1614         else {
1615                 *pVal = ::KillTimer(m_hPopupWnd, 1) ? VB_TRUE : VB_FALSE;
1616         }
1617         return S_OK;
1618 }
1619
1620
1621 STDMETHODIMP COverlappedWindow::CheckMenu(VARIANT cmd, VARIANT mode)
1622 {
1623         SafeCreateWnd();
1624         if (!m_hMenu) {
1625                 return Error(IDS_ERR_NOCREATEMENU);
1626         }
1627
1628         int nCmd = 0;
1629         CComVariant varCmd;
1630         if (SUCCEEDED(varCmd.ChangeType(VT_I2, &cmd))) {
1631                 nCmd = varCmd.iVal;
1632         }
1633
1634         int nMode = 0;
1635         CComVariant varMode;
1636         if (SUCCEEDED(varMode.ChangeType(VT_I2, &mode))) {
1637                 nMode = varMode.iVal;
1638         }
1639
1640         if (nCmd >= 100) {
1641                 // \83\81\83j\83\85\81[\83R\83}\83\93\83h\82Í100\88È\8fã\82Å\82 \82é\82Ì\82Å\81B
1642                 MENUITEMINFO inf = { 0 };
1643                 inf.cbSize = sizeof(MENUITEMINFO);
1644                 inf.fMask = MIIM_STATE;
1645                 inf.fState = nMode ? MFS_CHECKED : MFS_UNCHECKED;
1646                 ::SetMenuItemInfo(m_hMenu, nCmd, false, &inf);
1647         }
1648
1649         return S_OK;
1650 }
1651
1652 STDMETHODIMP COverlappedWindow::EnableMenu(VARIANT cmd, VARIANT mode)
1653 {
1654         SafeCreateWnd();
1655         if (!m_hMenu) {
1656                 return Error(IDS_ERR_NOCREATEMENU);
1657         }
1658
1659         int nCmd = 0;
1660         CComVariant varCmd;
1661         if (SUCCEEDED(varCmd.ChangeType(VT_I2, &cmd))) {
1662                 nCmd = varCmd.iVal;
1663         }
1664
1665         int nMode = 0;
1666         CComVariant varMode;
1667         if (SUCCEEDED(varMode.ChangeType(VT_I2, &mode))) {
1668                 nMode = varMode.iVal;
1669         }
1670
1671         if (nCmd >= 100) {
1672                 // \83\81\83j\83\85\81[\83R\83}\83\93\83h\82Í100\88È\8fã\82Å\82 \82é\82Ì\82Å\81B
1673                 MENUITEMINFO inf = { 0 };
1674                 inf.cbSize = sizeof(MENUITEMINFO);
1675                 inf.fMask = MIIM_STATE;
1676                 inf.fState = nMode ? MFS_ENABLED : MFS_GRAYED;
1677                 ::SetMenuItemInfo(m_hMenu, nCmd, false, &inf);
1678         }
1679         return S_OK;
1680 }
1681
1682 STDMETHODIMP COverlappedWindow::get_CreateNoCloseWindow(BOOL *pVal)
1683 {
1684         if (!pVal) {
1685                 return E_POINTER;
1686         }
1687
1688         // \83N\83\8d\81[\83Y\8bÖ\8e~\83E\83B\83\93\83h\83E?
1689         *pVal = windowParam.noclose ? VB_TRUE : VB_FALSE;
1690
1691         return S_OK;
1692 }
1693
1694 STDMETHODIMP COverlappedWindow::put_CreateNoCloseWindow(BOOL newVal)
1695 {
1696         if (m_hPopupWnd) {
1697                 // \83E\83B\83\93\83h\83E\8dì\90¬\8cã\82É\82Í\8ew\92è\82Å\82«\82È\82¢
1698                 return Error(IDS_ERR_CREATEDWND);
1699         }
1700         windowParam.noclose = newVal;
1701         return S_OK;
1702 }
1703
1704 STDMETHODIMP COverlappedWindow::get_Canvas(VARIANT *pVal)
1705 {
1706         if (!pVal) {
1707                 return E_POINTER;
1708         }
1709
1710         // \83h\83\8d\81[\83C\83\93\83O\83C\83\93\83^\81[\83t\83F\83C\83X\82ð\93n\82·
1711         ::VariantInit(pVal);
1712
1713         if (m_pCanvas) {
1714                 HRESULT hr;
1715                 CComPtr<IUnknown> pUnk;
1716                 if (FAILED(hr = m_pCanvas->QueryInterface(&pUnk))) {
1717                         return hr;
1718                 }
1719                 pVal->vt = VT_UNKNOWN;
1720                 pVal->punkVal = pUnk.Detach();
1721         }
1722
1723         return S_OK;
1724 }
1725
1726 STDMETHODIMP COverlappedWindow::get_Event(VARIANT *pVal)
1727 {
1728         if (!pVal) {
1729                 return E_POINTER;
1730         }
1731
1732         ::VariantInit(pVal);
1733
1734         if (m_pEvent) {
1735                 // \83C\83x\83\93\83g\83C\83\93\83^\81[\83t\83F\83C\83X\82Ì\8eæ\93¾
1736                 HRESULT hr;
1737                 CComPtr<IUnknown> pUnk;
1738                 if (FAILED(hr = m_pEvent->QueryInterface(&pUnk))) {
1739                         return hr;
1740                 }
1741                 pVal->vt = VT_UNKNOWN;
1742                 pVal->punkVal = pUnk.Detach();
1743         }
1744
1745         return S_OK;
1746 }
1747
1748 STDMETHODIMP COverlappedWindow::get_DropFiles(VARIANT *pVal)
1749 {
1750         if (!pVal) {
1751                 return E_POINTER;
1752         }
1753
1754         return m_dropfiles.GetPathArray(pVal);
1755 }
1756
1757 STDMETHODIMP COverlappedWindow::get_Quit(BOOL *pVal)
1758 {
1759         if (!pVal) {
1760                 return E_POINTER;
1761         }
1762
1763         *pVal = m_bQuit ? VB_TRUE : VB_FALSE;
1764
1765         return S_OK;
1766 }
1767
1768 STDMETHODIMP COverlappedWindow::put_Quit(BOOL newVal)
1769 {
1770         m_bQuit = newVal;
1771         if (m_hPopupWnd) {
1772                 // \83C\83x\83\93\83g\82ð\94­\90\82³\82¹\91Ò\8b@\8fó\91Ô\82ð\89ð\82­
1773                 SetEvent(m_hWaitEvent);
1774         }
1775         return S_OK;
1776 }
1777
1778 STDMETHODIMP COverlappedWindow::get_Form(VARIANT *pVal)
1779 {
1780         if (!pVal) {
1781                 return E_POINTER;
1782         }
1783
1784         // \83t\83H\81[\83\80\82Ì\8cö\8aJ
1785         ::VariantInit(pVal);
1786
1787         if (m_pForm) {
1788                 HRESULT hr;
1789                 CComPtr<IUnknown> pUnk;
1790                 if (FAILED(hr = m_pForm->QueryInterface(&pUnk))) {
1791                         return hr;
1792                 }
1793                 pVal->vt = VT_UNKNOWN;
1794                 pVal->punkVal = pUnk.Detach();
1795         }
1796         return S_OK;
1797 }
1798
1799 STDMETHODIMP COverlappedWindow::get_Style(long *pVal)
1800 {
1801         if (!pVal) {
1802                 return E_POINTER;
1803         }
1804
1805         DWORD style;
1806         if (m_hPopupWnd) {
1807                 style = ::GetWindowLong(m_hPopupWnd, GWL_STYLE);
1808
1809         }
1810         else {
1811                 style = windowParam.ComputeStyle();
1812         }
1813
1814         *pVal = (long)style;
1815
1816         return S_OK;
1817 }
1818
1819 STDMETHODIMP COverlappedWindow::put_Style(long newVal)
1820 {
1821         if (m_hPopupWnd) {
1822                 ::SetWindowLong(m_hPopupWnd, GWL_STYLE, (DWORD)newVal);
1823         }
1824         return S_OK;
1825 }
1826
1827 STDMETHODIMP COverlappedWindow::get_Exstyle(long *pVal)
1828 {
1829         if (m_hPopupWnd) {
1830                 windowParam.exstyle = ::GetWindowLong(m_hPopupWnd, GWL_EXSTYLE);
1831         }
1832         *pVal = (long)windowParam.exstyle;
1833         return S_OK;
1834 }
1835
1836 STDMETHODIMP COverlappedWindow::put_Exstyle(long newVal)
1837 {
1838         windowParam.exstyle = (DWORD)newVal;
1839         if (m_hPopupWnd) {
1840                 ::SetWindowLong(m_hPopupWnd, GWL_STYLE, windowParam.exstyle);
1841         }
1842         return S_OK;
1843 }
1844
1845 STDMETHODIMP COverlappedWindow::get_WindowClassName(BSTR *pVal)
1846 {
1847         if (!pVal) {
1848                 return E_POINTER;
1849         }
1850
1851         CComBSTR tmp(windowParam.szClassName);
1852         *pVal = tmp.Detach();
1853         return S_OK;
1854 }
1855
1856 STDMETHODIMP COverlappedWindow::Refresh()
1857 {
1858         if (m_hPopupWnd) {
1859                 ::SetWindowPos(
1860                         m_hPopupWnd,
1861                         NULL,
1862                         0, 0, 0, 0,
1863                         SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOCOPYBITS);
1864         }
1865         return S_OK;
1866 }
1867
1868 void COverlappedWindow::SetTitle()
1869 {
1870         if (!m_hPopupWnd) {
1871                 return;
1872         }
1873         ATL::CString tmp(m_bstrCaption);
1874         ::SetWindowText(m_hPopupWnd, tmp);
1875 }
1876
1877 STDMETHODIMP COverlappedWindow::SetPlacement(VARIANT x, VARIANT y, VARIANT w, VARIANT h, VARIANT *pvarUnk)
1878 {
1879         // \83T\83C\83Y\95Ï\8dX
1880         CComVariant varX, varY, varW, varH;
1881         UINT flag = SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE;
1882         if ((x.vt != VT_EMPTY && x.vt != VT_NULL && x.vt != VT_ERROR) && varX.ChangeType(VT_I2, &x) == S_OK) {
1883                 windowParam.posX = varX.iVal;
1884                 flag &= ~SWP_NOMOVE;
1885         }
1886         if ((y.vt != VT_EMPTY && y.vt != VT_NULL && y.vt != VT_ERROR) && varY.ChangeType(VT_I2, &y) == S_OK) {
1887                 windowParam.posY = varY.iVal;
1888                 flag &= ~SWP_NOMOVE;
1889         }
1890         if ((w.vt != VT_EMPTY && w.vt != VT_NULL && w.vt != VT_ERROR) && varW.ChangeType(VT_I2, &w) == S_OK) {
1891                 windowParam.width = varW.iVal;
1892                 flag &= ~SWP_NOSIZE;
1893         }
1894         if ((h.vt != VT_EMPTY && h.vt != VT_NULL && h.vt != VT_ERROR) && varH.ChangeType(VT_I2, &h) == S_OK) {
1895                 windowParam.height = varH.iVal;
1896                 flag &= ~SWP_NOSIZE;
1897         }
1898         // \83E\83B\83\93\83h\83E\82ª\95\\8e¦\82³\82ê\82Ä\82¢\82ê\82Î\82½\82¾\82¿\82É\94½\89f
1899         if (m_hPopupWnd) {
1900                 ::SetWindowPos(m_hPopupWnd, NULL, windowParam.posX, windowParam.posY, windowParam.width, windowParam.height, flag);
1901         }
1902         if (m_pForm) {
1903                 // \83t\83H\81[\83\80\82Ì\83T\83C\83Y\82ð\95Ï\8dX\82·\82é
1904                 m_pForm->SetWindowSize(windowParam.width, windowParam.height,
1905                         windowParam.ComputeStyle(), windowParam.exstyle);
1906         }
1907         CreateThisInterface(pvarUnk);
1908         return S_OK;
1909 }
1910
1911 void COverlappedWindow::CreateThisInterface(VARIANT* pvarUnk)
1912 {
1913         ATLASSERT(pvarUnk != NULL);
1914
1915         // \82±\82Ì\83C\83\93\83^\81[\83t\83F\83C\83X\82ð\95Ô\82·
1916         ::VariantInit(pvarUnk);
1917
1918         CComPtr<IUnknown> pUnk;
1919         HRESULT hr = QueryInterface(IID_IUnknown, (void**)&pUnk);
1920         ATLASSERT(SUCCEEDED(hr));
1921
1922         pvarUnk->vt = VT_UNKNOWN;
1923         pvarUnk->punkVal = pUnk.Detach();
1924 }
1925
1926 STDMETHODIMP COverlappedWindow::SetWindowStyle(VARIANT frametype, VARIANT caption_system, VARIANT maxmin, VARIANT *pvarUnk)
1927 {
1928         CComVariant varFrametype, varCaptionSystem, varMaxMin;
1929         if (frametype.vt != VT_EMPTY && frametype.vt != VT_ERROR && frametype.vt != VT_NULL
1930                 && varFrametype.ChangeType(VT_I2, &frametype) == S_OK) {
1931                 windowParam.frametype = varFrametype.iVal;
1932         }
1933         if (caption_system.vt != VT_EMPTY && caption_system.vt != VT_ERROR && caption_system.vt != VT_NULL
1934                 && varCaptionSystem.ChangeType(VT_I2, &caption_system) == S_OK) {
1935                 windowParam.captionbar = (varCaptionSystem.iVal > 0);
1936                 windowParam.systemmenu = (varCaptionSystem.iVal > 1);
1937         }
1938         if (maxmin.vt != VT_EMPTY && maxmin.vt != VT_ERROR && maxmin.vt != VT_NULL
1939                 && varMaxMin.ChangeType(VT_I2, &maxmin) == S_OK) {
1940                 windowParam.minbox = (varMaxMin.iVal & 0x01);
1941                 windowParam.maxbox = (varMaxMin.iVal & 0x02);
1942         }
1943         if (m_hPopupWnd) {
1944                 ::SetWindowLong(m_hPopupWnd, GWL_STYLE, windowParam.ComputeStyle());
1945                 Refresh();
1946         }
1947         CreateThisInterface(pvarUnk);
1948         return S_OK;
1949 }
1950
1951 void COverlappedWindow::PurgeUnusedWindows()
1952 {
1953         // \8eQ\8fÆ\83J\83E\83\93\83g\82ª1\82Â\82µ\82©\82È\82¢\83E\83B\83\93\83h\83E\82Ì\94j\8aü\82ð\8ds\82¤
1954         std::list<CComObject<COverlappedWindow>*>::iterator p = m_lstChild.begin();
1955         while (p != m_lstChild.end()) {
1956                 DWORD refCount = (*p)->m_dwRef;
1957                 if ((*p)->m_dwRef == 1) {
1958                         // \8eQ\8fÆ\83J\83E\83\93\83g\82ª1\82µ\82©\82È\82¢ = \82±\82Ì\83N\83\89\83X\82µ\82©\8eg\82Á\82Ä\82¢\82È\82¢ = \95s\97v\8có\95â
1959                         BOOL bVisible = false;
1960                         (*p)->get_Visible(&bVisible);
1961                         if (!bVisible) {
1962                                 // \95\\8e¦\82³\82ê\82Ä\82¢\82È\82¯\82ê\82Î\8fÁ\82µ\82Ä\82æ\82µ\81B
1963                                 (*p)->Release();
1964                                 p = m_lstChild.erase(p);
1965                                 continue;
1966                         }
1967                 }
1968                 p++;
1969         }
1970 }
1971
1972
1973 STDMETHODIMP COverlappedWindow::CreateChild(VARIANT *pvarUnk)
1974 {
1975         if (!pvarUnk) {
1976                 return E_POINTER;
1977         }
1978
1979         SafeCreateWnd();
1980         ::VariantInit(pvarUnk);
1981
1982         // \96¢\8eg\97p\82Ì\83E\83B\83\93\83h\83E\82ð\8dí\8f\9c\82·\82é
1983         PurgeUnusedWindows();
1984
1985         // \83I\83u\83W\83F\83N\83g\82Ì\8dì\90¬
1986         CComObject<COverlappedWindow>* pChild = NULL;
1987         HRESULT hr;
1988         if (FAILED(hr = CComObject<COverlappedWindow>::CreateInstance(&pChild))) {
1989                 return hr;
1990         }
1991
1992         // \95Ô\8bp\97p\83C\83\93\83^\81[\83t\83F\83C\83X\82Ì\8eæ\93¾
1993         CComPtr<IUnknown> pUnk;
1994         if (FAILED(hr = pChild->QueryInterface(&pUnk))) {
1995                 delete pChild;
1996                 return hr;
1997         }
1998
1999         pChild->SetParent(m_hPopupWnd);
2000         pChild->put_WaitCursor(m_dWaitCursor);
2001
2002         // \83\8a\83X\83g\82É\95Û\91\82·\82é\82½\82ß\8eQ\8fÆ\83J\83E\83\93\83g+1\82·\82é.
2003         pChild->AddRef();
2004         m_lstChild.push_back(pChild);
2005
2006         // \83C\83\93\83^\81[\83t\83F\83C\83X\82ð\95Ô\82·
2007         pvarUnk->vt = VT_UNKNOWN;
2008         pvarUnk->punkVal = pUnk.Detach();
2009         return S_OK;
2010 }
2011
2012 void COverlappedWindow::SetParent(HWND hParent)
2013 {
2014         m_hParentWnd = hParent;
2015 }
2016
2017 HANDLE COverlappedWindow::GetEventHandle()
2018 {
2019         return m_hWaitEvent;
2020 }
2021
2022 void COverlappedWindow::SetWaitParam(int *count, HWND *hWnd, HANDLE *hEvent)
2023 {
2024         // \82·\82×\82Ä\82Ì\8eq\83I\81[\83o\81[\83\89\83b\83v\83E\83B\83\93\83h\83E\82Ì\83C\83x\83\93\83g\83n\83\93\83h\83\8b\82ð\8eæ\93¾
2025         if (*count < MAXIMUM_WAIT_OBJECTS) {
2026                 // \8e©\95ª\8e©\90g\82ð\93o\98^
2027                 hEvent[*count] = m_hWaitEvent;
2028                 hWnd[*count] = m_hPopupWnd;
2029                 (*count)++;
2030                 // \83`\83\83\83C\83\8b\83h\82ð\93o\98^
2031                 std::list<CComObject<COverlappedWindow>*>::iterator p = m_lstChild.begin();
2032                 while ((p != m_lstChild.end()) && (*count < MAXIMUM_WAIT_OBJECTS)) {
2033                         // \83`\83\83\83C\83\8b\83h\82ª\8f\8a\97L\82·\82é\83`\83\83\83C\83\8b\83h\82ð\8dÄ\8bN\93I\82É\8cÄ\82Ñ\8fo\82·
2034                         (*p)->SetWaitParam(count, hWnd, hEvent);
2035                         p++;
2036                 }
2037         }
2038 }
2039
2040 DWORD COverlappedWindow::MessageLoop(DWORD sleeptim, int cnt, HWND *hWnd, HANDLE* hEvent)
2041 {
2042         // \83\81\83b\83Z\81[\83W\83\8b\81[\83v\82ð\8f\88\97\9d\82·\82é
2043         DWORD ret = 0;
2044         DWORD retWait = MsgWaitForMultipleObjects(cnt, hEvent, false, sleeptim, QS_ALLEVENTS | QS_ALLINPUT);
2045
2046         if (retWait != WAIT_TIMEOUT) {
2047                 ret = 0;
2048                 if (retWait >= WAIT_OBJECT_0 && retWait < WAIT_OBJECT_0 + cnt) {
2049                         // \83C\83x\83\93\83g\82Ì\94­\90\82µ\82½\83n\83\93\83h\83\8b\82ð\8e¯\95Ê\82·\82é
2050                         ret = retWait - WAIT_OBJECT_0 + 1;
2051                 }
2052                 //
2053                 MSG msg;
2054                 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
2055                         BOOL bTranslated = false;
2056                         HWND hOwner = NULL;
2057                         if (msg.hwnd) {
2058                                 // \83\81\83b\83Z\81[\83W\82ª\91®\82·\82é\83I\81[\83i\81[\83E\83B\83\93\83h\83E\82ð\92T\82µ\8fo\82·
2059                                 HWND hParent = msg.hwnd;
2060                                 while (!hOwner && hParent) {
2061                                         int i;
2062                                         for (i = 0; i < cnt && hWnd[i]; i++) {
2063                                                 if (hParent == hWnd[i]) {
2064                                                         hOwner = hWnd[i];
2065                                                         break;
2066                                                 }
2067                                         }
2068                                         hParent = ::GetParent(hParent);
2069                                 }
2070                         }
2071                         if (hOwner) {
2072                                 BOOL bTranslatedDlg = false;
2073                                 if (msg.message == WM_KEYDOWN) {
2074                                         // \82Æ\82 \82¦\82¸\81A\8c»\8dÝ\82Ì\83L\81[\83R\81[\83h\82ð\83E\83B\83\93\83h\83E\83v\83\8d\83V\83W\83\83\82É\8f\88\97\9d\82³\82¹\82é
2075                                         ::SendMessage(hOwner, WM_KEYDOWN_EX, msg.wParam, msg.lParam);
2076                                         bTranslated = true;
2077                                         // \83_\83C\83A\83\8d\83O\82à\82Ç\82«\8f\88\97\9d\82ð\8ds\82¤
2078                                         BOOL bShift = GetKeyState(VK_SHIFT) & 0x8000;
2079                                         BOOL bCtrl = GetKeyState(VK_CONTROL) & 0x8000;
2080                                         if (msg.wParam == VK_TAB) {
2081                                                 // TAB = MOVE FOCUS 
2082                                                 if (!bCtrl) {
2083                                                         HWND hNextFocus = ::GetNextDlgTabItem(hOwner, GetFocus(), bShift);
2084                                                         if (hNextFocus) {
2085                                                                 ::SetFocus(hNextFocus);
2086                                                         }
2087                                                 }
2088                                                 bTranslatedDlg = true;
2089                                         }
2090                                         else if (msg.wParam == VK_F6) {
2091                                                 // ESCAPE = CANCEL
2092                                                 SendMessage(hOwner, WM_MOVENEXT_OVERLAPPED, 0, 0);
2093                                                 bTranslatedDlg = true;
2094                                         }
2095                                 }
2096                                 if (!bTranslatedDlg) {
2097                                         bTranslated |= ::IsDialogMessage(hOwner, &msg);
2098                                 }
2099                         }
2100                         if (!bTranslated) {
2101                                 ::TranslateMessage(&msg);
2102                                 ::DispatchMessage(&msg);
2103                         }
2104                 }
2105         }
2106         return ret;
2107 }
2108
2109 STDMETHODIMP COverlappedWindow::get_AutoMessageLoop(BOOL *pVal)
2110 {
2111         *pVal = windowParam.automessageloop ? VB_TRUE : VB_FALSE;
2112         return S_OK;
2113 }
2114
2115 STDMETHODIMP COverlappedWindow::put_AutoMessageLoop(BOOL newVal)
2116 {
2117         windowParam.automessageloop = newVal;
2118         return S_OK;
2119 }
2120
2121 STDMETHODIMP COverlappedWindow::DoModal(VARIANT* pRetCode)
2122 {
2123         CComVariant dmy, retdmy;
2124         dmy.vt = VT_ERROR;
2125         dmy.scode = DISP_E_PARAMNOTFOUND;
2126         Open(dmy, &retdmy);
2127
2128         CComVariant tim = (short)1000;
2129         BOOL ret;
2130         while (!m_bQuit && ::IsWindow(m_hPopupWnd)) {
2131                 WaitEvent(tim, &ret);
2132                 if (ret) {
2133                         DoEvent(&dmy);
2134                 }
2135         }
2136         Close();
2137
2138         ::VariantInit(pRetCode);
2139         pRetCode->vt = VT_I2;
2140         pRetCode->iVal = m_dModalExitCode;
2141         return S_OK;
2142 }
2143
2144 STDMETHODIMP COverlappedWindow::get_AutoClose(BOOL *pVal)
2145 {
2146         *pVal = windowParam.autoclose ? VB_TRUE : VB_FALSE;
2147         return S_OK;
2148 }
2149
2150 STDMETHODIMP COverlappedWindow::put_AutoClose(BOOL newVal)
2151 {
2152         windowParam.autoclose = newVal;
2153         return S_OK;
2154 }
2155
2156 void COverlappedWindow::CreateWindowList(std::list<HWND>& lstWnd, BOOL bSearchRoot)
2157 {
2158         HWND* hWnds = NULL;
2159         if (m_hParentWnd && bSearchRoot) {
2160                 // \8dª\8c³\82Å\82È\82¯\82ê\82Î\81A\82³\82ç\82É\96â\82¢\8d\87\82í\82¹\82é
2161                 COverlappedWindow* pParent = (COverlappedWindow*)::GetWindowLongPtr(m_hParentWnd, GWLP_USERDATA);
2162                 if (pParent) {
2163                         pParent->CreateWindowList(lstWnd, true);
2164                 }
2165         }
2166         else {
2167                 // \82±\82±\82ª\8dª\8c³\82Å\82 \82é
2168                 std::list<CComObject<COverlappedWindow>*>::iterator p = m_lstChild.begin();
2169                 DWORD stl = ::GetWindowLong(m_hPopupWnd, GWL_STYLE);
2170                 if (stl & WS_VISIBLE) {
2171                         // \95\\8e¦\82³\82ê\82Ä\82¢\82é\83E\83B\83\93\83h\83E\82Ì\82Ý\82ð\93o\98^\82·\82é
2172                         lstWnd.push_back(m_hPopupWnd);
2173                 }
2174                 while (p != m_lstChild.end()) {
2175                         // \82·\82×\82Ä\82Ì\8eq\83I\81[\83o\81[\83\89\83b\83v\82ð\97ñ\8b\93\82·\82é
2176                         HWND hWnd = NULL;
2177                         (*p)->get_HWND((long*)&hWnd);
2178                         if (hWnd && ::IsWindow(hWnd)) {
2179                                 (*p)->CreateWindowList(lstWnd, false);
2180                         }
2181                         p++;
2182                 }
2183         }
2184 }
2185
2186 void COverlappedWindow::MoveNextOverlapped()
2187 {
2188         // \8f\87\8f\98\83\8a\83X\83g\82Ì\90\90¬\82ð\88Ë\97\8a\82·\82é
2189         std::list<HWND>lstWnd;
2190         CreateWindowList(lstWnd, true);
2191         // \8c»\8dÝ\88Ê\92u\82ð\94c\88¬\82·\82é
2192         HWND hActiveWnd = ::GetActiveWindow();
2193         std::list<HWND>::iterator p = lstWnd.begin();
2194         while (p != lstWnd.end()) {
2195                 // \97ñ\8b\93
2196                 if (hActiveWnd == *p) {
2197                         // \83A\83N\83e\83B\83u\83E\83B\83\93\83h\83E\82ð\94­\8c©\82µ\82½
2198                         p++;
2199                         HWND hNext = lstWnd.front();
2200                         if (p != lstWnd.end()) {
2201                                 hNext = *p;
2202                         }
2203                         //                      ::SetActiveWindow(hNext);
2204                         ::SetFocus(hNext);
2205                         break;
2206                 }
2207                 p++;
2208         }
2209 }
2210
2211 STDMETHODIMP COverlappedWindow::get_Object(VARIANT idx, VARIANT *pVal)
2212 {
2213         // \83I\81[\83o\81[\83\89\83b\83v\83I\83u\83W\83F\83N\83g\82É\83o\83C\83\93\83h\82·\82é\82±\82Æ\82Ì\82Å\82«\82é\98A\91z\94z\97ñ
2214         ::VariantInit(pVal);
2215         pVal->vt = VT_UNKNOWN;
2216         m_pObject->QueryInterface(IID_IUnknown, (void**)&(pVal->punkVal));
2217         return S_OK;
2218 }
2219
2220
2221 STDMETHODIMP COverlappedWindow::get_ExitCode(short *pVal)
2222 {
2223         *pVal = (short)m_dModalExitCode;
2224         return S_OK;
2225 }
2226
2227 STDMETHODIMP COverlappedWindow::put_ExitCode(short newVal)
2228 {
2229         m_dModalExitCode = newVal;
2230         return S_OK;
2231 }
2232
2233 STDMETHODIMP COverlappedWindow::get_WaitCursor(short *pVal)
2234 {
2235         *pVal = (short)m_dWaitCursor;
2236         return S_OK;
2237 }
2238
2239 STDMETHODIMP COverlappedWindow::put_WaitCursor(short newVal)
2240 {
2241         m_dWaitCursor = newVal;
2242         if (m_hPopupWnd) {
2243                 ::SendMessage(m_hPopupWnd, WM_SETCURSOR, (WPARAM)m_hPopupWnd, 0);
2244         }
2245         // \83`\83\83\83C\83\8b\83h\82ð\8e\9d\82Á\82Ä\82¢\82é\8fê\8d\87\82Í\81A\83`\83\83\83C\83\8b\83h\82É\82à\83E\83F\83C\83g\83J\81[\83\\83\8b\82ð\93K\97p\82·\82é
2246         std::list<CComObject<COverlappedWindow>*>::iterator pWnd = m_lstChild.begin();
2247         while (pWnd != m_lstChild.end()) {
2248                 (*pWnd)->put_WaitCursor(newVal);
2249                 pWnd++;
2250         }
2251         return S_OK;
2252 }
2253
2254 STDMETHODIMP COverlappedWindow::LoadIcon(VARIANT text)
2255 {
2256         CComVariant varText;
2257         if (varText.ChangeType(VT_BSTR, &text) != S_OK) {
2258                 return DISP_E_TYPEMISMATCH;
2259         }
2260         ATL::CString szPath(varText.bstrVal);
2261
2262         if (m_hIcon) {
2263                 DestroyIcon(m_hIcon);
2264                 m_hIcon = NULL;
2265         }
2266         m_hIcon = (HICON)LoadImage(NULL, szPath, IMAGE_ICON,
2267                 GetSystemMetrics(SM_CXSMICON),
2268                 GetSystemMetrics(SM_CYSMICON),
2269                 LR_LOADFROMFILE);
2270
2271         if (m_hIcon && m_hPopupWnd) {
2272                 ::SendMessage(m_hPopupWnd, WM_SETICON, false, (LPARAM)m_hIcon);
2273         }
2274         return S_OK;
2275 }
2276
2277 STDMETHODIMP COverlappedWindow::CenterWindow()
2278 {
2279         SafeCreateWnd();
2280         RECT rct;
2281         if (m_hParentWnd) {
2282                 // \90e\83E\83B\83\93\83h\83E\82ª\82 \82ê\82Î\81A\82»\82Ì\92\86\89\9b\82É\88Ê\92u\82 \82í\82¹\82·\82é
2283                 ::GetWindowRect(m_hParentWnd, &rct);
2284
2285         }
2286         else {
2287                 HWND hwnd = ::GetDesktopWindow();
2288                 if (!hwnd) {
2289                         return S_OK;
2290                 }
2291                 ::GetWindowRect(hwnd, &rct);
2292         }
2293
2294         int x = rct.left + (rct.right - rct.left) / 2 - windowParam.width / 2;
2295         int y = rct.top + (rct.bottom - rct.top) / 2 - windowParam.height / 2;
2296         WINDOWPLACEMENT pls = { 0 };
2297         pls.length = sizeof(WINDOWPLACEMENT);
2298         pls.rcNormalPosition.top = y;
2299         pls.rcNormalPosition.left = x;
2300         pls.rcNormalPosition.bottom = y + windowParam.height;
2301         pls.rcNormalPosition.right = x + windowParam.width;
2302         ::SetWindowPlacement(m_hPopupWnd, &pls);
2303
2304         return S_OK;
2305 }
2306
2307 STDMETHODIMP COverlappedWindow::get_ClassObject(VARIANT* pVal)
2308 {
2309         if (!pVal) {
2310                 return E_POINTER;
2311         }
2312
2313         ::VariantInit(pVal);
2314         if (m_pClassDisp) {
2315                 CComVariant tmp(m_pClassDisp);
2316                 return tmp.Detach(pVal);
2317         }
2318         return S_OK;
2319 }
2320
2321 STDMETHODIMP COverlappedWindow::put_ClassObject(VARIANT newVal)
2322 {
2323         if (m_pClassDisp) {
2324                 // \8c»\8dÝ\82Ì\8eQ\8fÆ\82ð\89ð\8f\9c\82·\82é.
2325                 m_pClassDisp.Release();
2326         }
2327
2328         if (newVal.vt == VT_EMPTY || newVal.vt == VT_ERROR || newVal.vt == VT_NULL) {
2329                 // \8fÈ\97ª\8e\9e\82Ü\82½\82ÍNULL, EMPTY\82Ì\8fê\8d\87\82Í\8eQ\8fÆ\89ð\8f\9c\82Ì\82Ý
2330                 return S_FALSE;
2331         }
2332
2333         if (newVal.vt != VT_DISPATCH) {
2334                 // DISPATCH\83C\83\93\83^\81[\83t\83F\83C\83X\88È\8aO\82ª\8ew\92è\82³\82ê\82½\8fê\8d\87
2335                 return DISP_E_TYPEMISMATCH;
2336         }
2337
2338         m_pClassDisp = newVal.pdispVal;
2339
2340         return S_OK;
2341 }
2342
2343 HRESULT COverlappedWindow::ClassObjectInvoke(LPCWSTR handler)
2344 {
2345         if (!m_pClassDisp) {
2346                 return S_FALSE;
2347         }
2348
2349         HRESULT hr;
2350
2351         DISPID dispid;
2352         if (FAILED(hr = m_pClassDisp->GetIDsOfNames(IID_NULL,
2353                         (LPWSTR*)&handler, 1, LOCALE_SYSTEM_DEFAULT, &dispid))) {
2354                 return hr;
2355         }
2356
2357         DISPPARAMS dispparamsNoArgs = { NULL, NULL, 0, 0 };
2358
2359         return m_pClassDisp->Invoke(dispid,
2360                 IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD,
2361                 &dispparamsNoArgs, NULL, NULL, NULL);
2362 }
2363
2364 STDMETHODIMP COverlappedWindow::get_ClientWidth(long *pVal)
2365 {
2366         if (!pVal) {
2367                 return E_POINTER;
2368         }
2369         SafeCreateWnd();
2370
2371         RECT rct;
2372         ::GetClientRect(m_hPopupWnd, &rct);
2373
2374         *pVal = rct.right;
2375
2376         return S_OK;
2377 }
2378
2379 STDMETHODIMP COverlappedWindow::get_ClientHeight(long *pVal)
2380 {
2381         if (!pVal) {
2382                 return E_POINTER;
2383         }
2384         SafeCreateWnd();
2385
2386         RECT rct;
2387         ::GetClientRect(m_hPopupWnd, &rct);
2388
2389         *pVal = rct.bottom;
2390
2391         return S_OK;
2392 }
2393
2394 STDMETHODIMP COverlappedWindow::get_innerWidth(double *pVal)
2395 {
2396         if (!pVal) {
2397                 return E_POINTER;
2398         }
2399
2400         SafeCreateWnd();
2401
2402         RECT rct;
2403         ::GetClientRect(m_hPopupWnd, &rct);
2404
2405         POINT pt = { rct.right, 0 - rct.bottom };
2406
2407         HDC hdc = ::GetWindowDC(m_hPopupWnd);
2408
2409         int md = ::GetMapMode(hdc);
2410         ::SetMapMode(hdc, MM_LOMETRIC); // \98_\97\9d\92P\88Ê\82ð0.1mm\82Ö\95Ï\8a·\82·\82é
2411         ::DPtoLP(hdc, &pt, 1);
2412         ::SetMapMode(hdc, md);
2413         ::ReleaseDC(m_hPopupWnd, hdc);
2414
2415         *pVal = pt.x / 10.; // \83~\83\8a\92P\88Ê\82Ö
2416
2417         return S_OK;
2418 }
2419
2420 STDMETHODIMP COverlappedWindow::get_innerHeight(double *pVal)
2421 {
2422         if (!pVal) {
2423                 return E_POINTER;
2424         }
2425
2426         SafeCreateWnd();
2427
2428         RECT rct;
2429         ::GetClientRect(m_hPopupWnd, &rct);
2430
2431         POINT pt = { rct.right, 0 - rct.bottom };
2432
2433         HDC hdc = ::GetWindowDC(m_hPopupWnd);
2434
2435         int md = ::GetMapMode(hdc);
2436         ::SetMapMode(hdc, MM_LOMETRIC);// \98_\97\9d\92P\88Ê\82ð0.1mm\82Ö\95Ï\8a·\82·\82é
2437         ::DPtoLP(hdc, &pt, 1);
2438         ::SetMapMode(hdc, md);
2439         ::ReleaseDC(m_hPopupWnd, hdc);
2440
2441         *pVal = pt.y / 10.; // \83~\83\8a\92P\88Ê\82Ö
2442
2443         return S_OK;
2444 }
2445
2446 STDMETHODIMP COverlappedWindow::get_AutoReleaseClassObject(BOOL *pVal)
2447 {
2448         if (!pVal) {
2449                 return E_POINTER;
2450         }
2451
2452         *pVal = m_bAutoReleaseClassObject ? VB_TRUE : VB_FALSE;
2453
2454         return S_OK;
2455 }
2456
2457 STDMETHODIMP COverlappedWindow::put_AutoReleaseClassObject(BOOL newVal)
2458 {
2459         m_bAutoReleaseClassObject = newVal;
2460         return S_OK;
2461 }
2462
2463 STDMETHODIMP COverlappedWindow::get_DefaultAction(BOOL *pVal)
2464 {
2465         if (!pVal) {
2466                 return E_POINTER;
2467         }
2468
2469         *pVal = m_bDefaultAction ? VB_TRUE : VB_FALSE;
2470
2471         return S_OK;
2472 }
2473
2474 STDMETHODIMP COverlappedWindow::put_DefaultAction(BOOL newVal)
2475 {
2476         m_bDefaultAction = newVal;
2477         return S_OK;
2478 }
2479
2480 STDMETHODIMP COverlappedWindow::SetClipboardText(BSTR text)
2481 {
2482         SafeCreateWnd();
2483         if (::OpenClipboard(m_hPopupWnd)) {
2484                 ::EmptyClipboard();
2485                 if (text) {
2486                         int len = SysStringByteLen(text);
2487                         HGLOBAL hGlobal = GlobalAlloc(GMEM_DDESHARE, (len + 1) * sizeof(WCHAR));
2488                         LPWSTR p = (LPWSTR)GlobalLock(hGlobal);
2489                         StringCchCopyW(p, len + 1, text);
2490                         GlobalUnlock(hGlobal);
2491                         ::SetClipboardData(CF_UNICODETEXT, hGlobal);
2492                 }
2493                 ::CloseClipboard();
2494         }
2495         return S_OK;
2496 }
2497
2498 STDMETHODIMP COverlappedWindow::GetClipboardText(VARIANT *pVarText)
2499 {
2500         SafeCreateWnd();
2501         ::VariantInit(pVarText);
2502         if (::OpenClipboard(m_hPopupWnd)) {
2503                 if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
2504                         // UNICODE\95\8e\9a\97ñ\82ª\82 \82ê\82Î\81A\82»\82¿\82ç\82ð\97D\90æ\82µ\82Ä\8eæ\93¾\82·\82é
2505                         HGLOBAL hGlobal = ::GetClipboardData(CF_UNICODETEXT);
2506                         if (hGlobal) {
2507                                 LPCWSTR p = (LPCWSTR)GlobalLock(hGlobal);
2508                                 if (p) {
2509                                         CComBSTR wstr(p);
2510                                         GlobalUnlock(hGlobal);
2511                                         pVarText->bstrVal = wstr.Detach();
2512                                         pVarText->vt = VT_BSTR;
2513                                 }
2514                         }
2515
2516                 }
2517                 else if (IsClipboardFormatAvailable(CF_TEXT)) {
2518                         // UNICODE\95\8e\9a\97ñ\82ª\82È\82¢\8fê\8d\87
2519                         HGLOBAL hGlobal = ::GetClipboardData(CF_TEXT);
2520                         if (hGlobal) {
2521                                 LPCSTR p = (LPCSTR)GlobalLock(hGlobal);
2522                                 if (p) {
2523                                         CComBSTR wstr(p);
2524                                         GlobalUnlock(hGlobal);
2525                                         pVarText->bstrVal = wstr.Detach();
2526                                         pVarText->vt = VT_BSTR;
2527                                 }
2528                         }
2529                 }
2530                 ::CloseClipboard();
2531         }
2532         return S_OK;
2533 }