OSDN Git Service

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