• R/O
  • HTTP
  • SSH
  • HTTPS

SeraphyScriptTools: Commit

SeraphyScriptTools v1.1以降のソースコード管理


Commit MetaInfo

Revisionf0185382cb749542135c2d49145b95c97ff769d3 (tree)
Time2015-08-19 06:30:04
Authorseraphy <seraphy@sera...>
Commiterseraphy

Log Message

ObjectMap, ObjectVectorの値をByRef外しするようにした。他、ソースコード整形

Change Summary

Incremental Difference

--- a/ObjectMap.cpp
+++ b/ObjectMap.cpp
@@ -2,6 +2,7 @@
22 #include "stdafx.h"
33 #include "SeraphyScriptTools.h"
44 #include "ObjectMap.h"
5+#include "generic.h"
56 #include "profilesection.h"
67 #include "CComEnumDynaVARIANT.h"
78
@@ -85,14 +86,20 @@ STDMETHODIMP CObjectMap::put_Value(VARIANT key, VARIANT newVal)
8586 return hr;
8687 }
8788
89+ // ByRefをByValに変換コピーする
90+ CComVariant tmp;
91+ if (FAILED(hr = VariantCopyByVal(&tmp, &newVal))) {
92+ return hr;
93+ }
94+
8895 VariantMap::iterator p = m_mapVariant.find(varName.bstrVal);
8996 if (p != m_mapVariant.end()) {
9097 // 既存
91- p->second = newVal;
98+ p->second = tmp;
9299 }
93100 else {
94101 // 新規
95- m_mapVariant.insert(std::make_pair(varName.bstrVal, newVal));
102+ m_mapVariant.insert(std::make_pair(varName.bstrVal, tmp));
96103 }
97104 return S_OK;
98105 }
@@ -366,7 +373,7 @@ STDMETHODIMP CObjectMap::LoadProfile(IUnknown *punkVal)
366373 long idx = 0;
367374 while (idx <= mx) {
368375 CComVariant varKey, varVal;
369- if (SafeArrayGetElement(varArray.parray, &idx, &varKey) == S_OK) {
376+ if (SUCCEEDED(SafeArrayGetElement(varArray.parray, &idx, &varKey))) {
370377 if (SUCCEEDED(pSection->get_Value(varKey, &varVal))) {
371378 put_Value(varKey, varVal);
372379 }
--- a/ObjectVector.cpp
+++ b/ObjectVector.cpp
@@ -21,7 +21,11 @@ STDMETHODIMP CObjectVector::CreateVector(IUnknown **punkVal)
2121 return hr;
2222 }
2323
24- return pVct->QueryInterface(punkVal);
24+ if (FAILED(hr = pVct->QueryInterface(punkVal))) {
25+ delete pVct;
26+ return hr;
27+ }
28+ return S_OK;
2529 }
2630
2731 STDMETHODIMP CObjectVector::Duplicate(VARIANT idx, VARIANT count, IUnknown **punkVal)
@@ -37,6 +41,7 @@ STDMETHODIMP CObjectVector::Duplicate(VARIANT idx, VARIANT count, IUnknown **pun
3741 return hr;
3842 }
3943 if (FAILED(hr = pVct->QueryInterface(punkVal))) {
44+ delete pVct;
4045 return hr;
4146 }
4247
@@ -111,8 +116,15 @@ STDMETHODIMP CObjectVector::Erase(VARIANT idx, VARIANT count)
111116
112117 STDMETHODIMP CObjectVector::Push(VARIANT newVal)
113118 {
119+ HRESULT hr;
120+
121+ CComVariant tmp;
122+ if (FAILED(hr = VariantCopyByVal(&tmp, &newVal))) {
123+ return hr;
124+ }
125+
114126 // 末尾に追加
115- m_vctVariant.push_back(newVal);
127+ m_vctVariant.push_back(tmp);
116128 return S_OK;
117129 }
118130
@@ -143,7 +155,14 @@ STDMETHODIMP CObjectVector::Insert(VARIANT idx, VARIANT newVal)
143155 return DISP_E_BADINDEX;
144156 }
145157
146- m_vctVariant.insert(m_vctVariant.begin() + nIdx, newVal);
158+ HRESULT hr;
159+
160+ CComVariant tmp;
161+ if (FAILED(hr = VariantCopyByVal(&tmp, &newVal))) {
162+ return hr;
163+ }
164+
165+ m_vctVariant.insert(m_vctVariant.begin() + nIdx, tmp);
147166 return S_OK;
148167 }
149168
@@ -164,9 +183,9 @@ STDMETHODIMP CObjectVector::get_Value(VARIANT idx, VARIANT *pVal)
164183 long mx = m_vctVariant.size();
165184 if (nIdx < mx) {
166185 // ベクターの範囲内なら値を取得する
167- ::VariantCopy(pVal, &m_vctVariant[nIdx]);
186+ return ::VariantCopy(pVal, &m_vctVariant[nIdx]);
168187 }
169- return S_OK;
188+ return S_FALSE;
170189 }
171190
172191 STDMETHODIMP CObjectVector::put_Value(VARIANT idx, VARIANT newVal)
@@ -190,10 +209,20 @@ STDMETHODIMP CObjectVector::put_Value(VARIANT idx, VARIANT newVal)
190209 mx++;
191210 }
192211 }
212+
213+ HRESULT hr;
214+
215+ CComVariant tmp;
216+ if (FAILED(hr = VariantCopyByVal(&tmp, &newVal))) {
217+ return hr;
218+ }
219+
193220 // ベクターの範囲内なら値を再設定する
194- ::VariantClear(&m_vctVariant.at(nIdx));
195- ::VariantCopy(&m_vctVariant.at(nIdx), &newVal);
196- return S_OK;
221+ if (FAILED(hr = ::VariantClear(&m_vctVariant.at(nIdx)))) {
222+ return hr;
223+ }
224+
225+ return ::VariantCopy(&m_vctVariant.at(nIdx), &tmp);
197226 }
198227
199228 STDMETHODIMP CObjectVector::get_Count(long *pVal)
@@ -216,17 +245,20 @@ STDMETHODIMP CObjectVector::get__NewEnum(IUnknown **pVal)
216245
217246 STDMETHODIMP CObjectVector::Merge(VARIANT unkVal)
218247 {
219- HRESULT ret = DISP_E_TYPEMISMATCH;
248+ HRESULT hr;
249+
220250 CComVariant varUnk;
221251 if (SUCCEEDED(varUnk.ChangeType(VT_UNKNOWN, &unkVal))) {
222252 // インターフェイスの場合
223- IObjectVector* pVect = NULL;
224- if (SUCCEEDED(varUnk.punkVal->QueryInterface(IID_IObjectVector, (void**)&pVect))) {
253+ CComPtr<IObjectVector> pVect;
254+ if (FAILED(hr = varUnk.punkVal->QueryInterface(&pVect))) {
225255 // 指定外のインターフェイスである
226- return DISP_E_TYPEMISMATCH;
256+ return hr;
227257 }
258+
228259 long mx;
229260 pVect->get_Count(&mx);
261+
230262 long i;
231263 for (i = 0; i < mx; i++) {
232264 CComVariant idx((long)i);
@@ -235,51 +267,60 @@ STDMETHODIMP CObjectVector::Merge(VARIANT unkVal)
235267 pVect->get_Value(idx, &ret);
236268 m_vctVariant.push_back(ret);
237269 }
238- pVect->Release();
239- ret = S_OK;
240- }
241- else {
242- VARTYPE vt = VT_EMPTY;
243- SAFEARRAY* pArray = GetArrayFromVariant(unkVal, &vt);
244- if (pArray && vt == VT_VARIANT) {
245- long lb = 0;
246- long ub = 0;
247- int dm = SafeArrayGetDim(pArray);
248- SafeArrayGetLBound(pArray, 1, &lb); // 左側の添え字
249- SafeArrayGetUBound(pArray, 1, &ub);
250- if (dm == 1 && lb == 0 && vt == VT_VARIANT) {
251- // 1次元配列で、0ベースのバリアント配列である
252- int cnt;
253- long dim[1];
254- for (cnt = 0; cnt <= ub; cnt++) {
255- // VARIANTの配列である
256- VARIANT tmp;
257- ::VariantInit(&tmp);
258- dim[0] = cnt;
259- SafeArrayGetElement(pArray, dim, &tmp);
260- m_vctVariant.push_back(tmp);
261- }//next(配列のループ)
262- ret = S_OK;
263- }
264- }
270+ pVect.Release();
271+ return S_OK;
265272 }
266- return ret;
267-}
268273
274+ VARTYPE vt = VT_EMPTY;
275+ SAFEARRAY* pArray = GetArrayFromVariant(unkVal, &vt);
276+ if (!pArray || vt != VT_VARIANT) {
277+ return S_FALSE;
278+ }
279+
280+ long lb = 0;
281+ long ub = 0;
282+ int dm = SafeArrayGetDim(pArray);
283+ SafeArrayGetLBound(pArray, 1, &lb); // 左側の添え字
284+ SafeArrayGetUBound(pArray, 1, &ub);
285+ if (dm == 1 && lb == 0 && vt == VT_VARIANT) {
286+ // 1次元配列で、0ベースのバリアント配列である
287+ int cnt;
288+ long dim[1];
289+ for (cnt = 0; cnt <= ub; cnt++) {
290+ // VARIANTの配列である
291+ VARIANT tmp;
292+ ::VariantInit(&tmp);
293+ dim[0] = cnt;
294+ SafeArrayGetElement(pArray, dim, &tmp);
295+ m_vctVariant.push_back(tmp);
296+ }//next(配列のループ)
297+ }
298+ return S_OK;
299+}
269300
270301 STDMETHODIMP CObjectVector::MakeArray(VARIANT *pVal)
271302 {
272303 long mx = m_vctVariant.size();
273304 SAFEARRAY* pArray = SafeArrayCreateVector(VT_VARIANT, 0, mx);
305+ if (!pArray) {
306+ return E_OUTOFMEMORY;
307+ }
308+
309+ HRESULT hr;
310+
274311 VARIANT* pvars;
275- if (SUCCEEDED(SafeArrayAccessData(pArray, (void**)&pvars))) {
276- long cnt = 0;
277- for (cnt = 0; cnt < mx; cnt++) {
278- VariantInit(&pvars[cnt]);
279- VariantCopy(&pvars[cnt], &m_vctVariant.at(cnt));
280- }
281- SafeArrayUnaccessData(pArray);
312+ if (FAILED(hr = SafeArrayAccessData(pArray, (void**)&pvars))) {
313+ SafeArrayDestroy(pArray);
314+ return hr;
282315 }
316+
317+ long cnt = 0;
318+ for (cnt = 0; cnt < mx; cnt++) {
319+ VariantInit(&pvars[cnt]);
320+ VariantCopy(&pvars[cnt], &m_vctVariant.at(cnt));
321+ }
322+ SafeArrayUnaccessData(pArray);
323+
283324 pArray->fFeatures |= FADF_HAVEVARTYPE;
284325 pVal->vt = VT_ARRAY | VT_VARIANT;
285326 pVal->parray = pArray;
--- a/ObjectVector.h
+++ b/ObjectVector.h
@@ -18,7 +18,7 @@ class ATL_NO_VTABLE CObjectVector :
1818 public:
1919 CObjectVector()
2020 {
21- m_vctVariant.reserve(100); // 初期状態で100のバッファを確保する
21+ m_vctVariant.reserve(256); // 初期状態で256のバッファを確保する
2222 }
2323 void FinalRelease()
2424 {
--- a/OverlappedWindow.cpp
+++ b/OverlappedWindow.cpp
@@ -66,7 +66,7 @@ HRESULT COverlappedWindow::FinalConstruct()
6666 }
6767 m_pForm->AddRef();
6868 m_pForm->SetWindowSize(windowParam.width, windowParam.height,
69- windowParam.GetStyle(), windowParam.exstyle);
69+ windowParam.ComputeStyle(), windowParam.exstyle);
7070
7171 // 描画オブジェクトの生成
7272 m_pCanvas = NULL;
@@ -98,8 +98,7 @@ void COverlappedWindow::FinalRelease()
9898
9999 // クラスオブジェクトの放棄
100100 if (m_pClassDisp) {
101- m_pClassDisp->Release();
102- m_pClassDisp = NULL;
101+ m_pClassDisp.Release();
103102 }
104103
105104 // アイコンの破棄
@@ -225,7 +224,7 @@ HWND COverlappedWindow::SafeCreateWnd()
225224 windowParam.wndstyle = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
226225 }
227226
228- WNDCLASSEX wcex = {0};
227+ WNDCLASSEX wcex = { 0 };
229228 wcex.cbSize = sizeof(WNDCLASSEX);
230229 wcex.lpfnWndProc = (WNDPROC)WindowProc;
231230 wcex.cbClsExtra = 0;
@@ -244,7 +243,7 @@ HWND COverlappedWindow::SafeCreateWnd()
244243 WS_EX_CONTROLPARENT,
245244 windowParam.szClassName,
246245 _TEXT(""), // ダミー
247- windowParam.GetStyle(),
246+ windowParam.ComputeStyle(),
248247 CW_USEDEFAULT,
249248 CW_USEDEFAULT,
250249 windowParam.width,
@@ -254,13 +253,13 @@ HWND COverlappedWindow::SafeCreateWnd()
254253 ::SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) this); // クラスと関連付ける
255254 m_hPopupWnd = hWnd;
256255 // ウィンドウスタイルの再設定
257- ::SetWindowLong(m_hPopupWnd, GWL_STYLE, windowParam.GetStyle());
256+ ::SetWindowLong(m_hPopupWnd, GWL_STYLE, windowParam.ComputeStyle());
258257 Refresh();
259258
260259 // システムメニューにフレーム移動メニューをつける
261260 HMENU hMenu = ::GetSystemMenu(m_hPopupWnd, false);
262261 int cnt = ::GetMenuItemCount(hMenu);
263- MENUITEMINFO minfo = {0};
262+ MENUITEMINFO minfo = { 0 };
264263 minfo.cbSize = sizeof(MENUITEMINFO);
265264 minfo.fMask = MIIM_TYPE | MIIM_ID;
266265 minfo.fType = MFT_STRING;
@@ -293,327 +292,325 @@ LRESULT CALLBACK COverlappedWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wPar
293292 }
294293
295294 switch (uMsg) {
296- case WM_MOVENEXT_OVERLAPPED:
297- {
298- me->MoveNextOverlapped();
299- return 0;
295+ case WM_MOVENEXT_OVERLAPPED:
296+ {
297+ me->MoveNextOverlapped();
298+ return 0;
299+ }
300+ case WM_CREATE:
301+ {
302+ // ディフォルトの動作を行う
303+ break;
304+ }
305+ case WM_PAINT:
306+ {
307+ PAINTSTRUCT ps;
308+ RECT rt;
309+ ::GetClientRect(hWnd, &rt);
310+ HDC hdc = ::BeginPaint(hWnd, &ps);
311+ HDC hdc2 = hdc;
312+ HBITMAP bmp;
313+ BOOL bDblBuf = me->windowParam.doublebuffer;
314+ if (bDblBuf) {
315+ // ちらつきを無くするためにバブルバッファ風にするか?
316+ hdc2 = ::CreateCompatibleDC(NULL);
317+ bmp = ::CreateCompatibleBitmap(hdc, rt.right, rt.bottom);
318+ ::SelectObject(hdc2, bmp);
300319 }
301- case WM_CREATE:
302- {
303- // ディフォルトの動作を行う
304- break;
320+ // 背景を塗りつぶす
321+ ::SetBkColor(hdc2, COLORREF(me->m_dwBackColor));
322+ ::SetBkMode(hdc2, TRANSPARENT);
323+ ::SetPolyFillMode(hdc2, ALTERNATE);
324+ FillRect(hdc2, &rt, me->m_hBkBrush);
325+
326+ // ドローイングデーターの描画
327+ if (me->m_pCanvas) {
328+ me->m_pCanvas->Draw(hdc2, rt);
305329 }
306- case WM_PAINT:
307- {
308- PAINTSTRUCT ps;
309- RECT rt;
310- ::GetClientRect(hWnd, &rt);
311- HDC hdc = ::BeginPaint(hWnd, &ps);
312- HDC hdc2 = hdc;
313- HBITMAP bmp;
314- BOOL bDblBuf = me->windowParam.doublebuffer;
315- if (bDblBuf) {
316- // ちらつきを無くするためにバブルバッファ風にするか?
317- hdc2 = ::CreateCompatibleDC(NULL);
318- bmp = ::CreateCompatibleBitmap(hdc, rt.right, rt.bottom);
319- ::SelectObject(hdc2, bmp);
320- }
321- // 背景を塗りつぶす
322- ::SetBkColor(hdc2, COLORREF(me->m_dwBackColor));
323- ::SetBkMode(hdc2, TRANSPARENT);
324- ::SetPolyFillMode(hdc2, ALTERNATE);
325- FillRect(hdc2, &rt, me->m_hBkBrush);
326-
327- // ドローイングデーターの描画
328- if (me->m_pCanvas) {
329- me->m_pCanvas->Draw(hdc2, rt);
330- }
331330
332- if (bDblBuf) {
333- // ダブルバッファの転送
334- ::BitBlt(hdc, 0, 0, rt.right, rt.bottom, hdc2, 0, 0, SRCCOPY);
335- DeleteDC(hdc2);
336- DeleteObject(bmp);
337- }
338- ::EndPaint(hWnd, &ps);
339- break;
331+ if (bDblBuf) {
332+ // ダブルバッファの転送
333+ ::BitBlt(hdc, 0, 0, rt.right, rt.bottom, hdc2, 0, 0, SRCCOPY);
334+ DeleteDC(hdc2);
335+ DeleteObject(bmp);
340336 }
341- case WM_SYSCOMMAND:
342- {
343- if (wParam == SC_CLOSE) {
344- if (me->windowParam.autoclose) {
345- me->Close();
346- }
347- me->m_bQuit = true;
348- me->m_dModalExitCode = IDABORT;
349- me->AddEventSingle(WM_COMMAND, IDABORT, 0);
350- return false;
337+ ::EndPaint(hWnd, &ps);
338+ break;
339+ }
340+ case WM_SYSCOMMAND:
341+ {
342+ if (wParam == SC_CLOSE) {
343+ if (me->windowParam.autoclose) {
344+ me->Close();
351345 }
352- else if (wParam == WM_MOVENEXT_OVERLAPPED) {
353- SendMessage(hWnd, WM_MOVENEXT_OVERLAPPED, 0, 0);
354- return 0;
355- }
356- break;
346+ me->m_bQuit = true;
347+ me->m_dModalExitCode = IDABORT;
348+ me->AddEventSingle(WM_COMMAND, IDABORT, 0);
349+ return false;
357350 }
358- case WM_MOUSEMOVE:
359- {
360- me->AddEventSingle(WM_MOUSEMOVE, 0, 0);
361- break;
351+ else if (wParam == WM_MOVENEXT_OVERLAPPED) {
352+ SendMessage(hWnd, WM_MOVENEXT_OVERLAPPED, 0, 0);
353+ return 0;
362354 }
363- case WM_LBUTTONDBLCLK:
364- {
365- me->AddEvent(WM_LBUTTONDBLCLK, 0, 0);
366- break;
355+ break;
356+ }
357+ case WM_MOUSEMOVE:
358+ {
359+ me->AddEventSingle(WM_MOUSEMOVE, 0, 0);
360+ break;
361+ }
362+ case WM_LBUTTONDBLCLK:
363+ {
364+ me->AddEvent(WM_LBUTTONDBLCLK, 0, 0);
365+ break;
366+ }
367+ case WM_RBUTTONDBLCLK:
368+ {
369+ me->AddEvent(WM_RBUTTONDBLCLK, 0, 0);
370+ break;
371+ }
372+ case WM_LBUTTONDOWN:
373+ {
374+ if (me->m_dCaptureMode == 0) {
375+ me->AddEvent(WM_LBUTTONDOWN, 0, 0);
376+ ::SetCapture(hWnd);
377+ me->m_dCaptureMode |= 0x01;
367378 }
368- case WM_RBUTTONDBLCLK:
369- {
370- me->AddEvent(WM_RBUTTONDBLCLK, 0, 0);
371- break;
379+ else {
380+ ReleaseCapture();
372381 }
373- case WM_LBUTTONDOWN:
374- {
375- if (me->m_dCaptureMode == 0) {
376- me->AddEvent(WM_LBUTTONDOWN, 0, 0);
377- ::SetCapture(hWnd);
378- me->m_dCaptureMode |= 0x01;
379- }
380- else {
381- ReleaseCapture();
382- }
383- break;
382+ break;
383+ }
384+ case WM_LBUTTONUP:
385+ {
386+ if (me->m_dCaptureMode & 0x01) {
387+ me->AddEvent(WM_LBUTTONUP, 0, 0);
388+ me->m_dCaptureMode &= ~0x01;
389+ ReleaseCapture();
384390 }
385- case WM_LBUTTONUP:
386- {
387- if (me->m_dCaptureMode & 0x01) {
388- me->AddEvent(WM_LBUTTONUP, 0, 0);
389- me->m_dCaptureMode &= ~0x01;
390- ReleaseCapture();
391- }
392- break;
391+ break;
392+ }
393+ case WM_RBUTTONDOWN:
394+ {
395+ if (me->m_dCaptureMode == 0) {
396+ me->AddEvent(WM_RBUTTONDOWN, 0, 0);
397+ ::SetCapture(hWnd);
398+ me->m_dCaptureMode |= 0x02;
393399 }
394- case WM_RBUTTONDOWN:
395- {
396- if (me->m_dCaptureMode == 0) {
397- me->AddEvent(WM_RBUTTONDOWN, 0, 0);
398- ::SetCapture(hWnd);
399- me->m_dCaptureMode |= 0x02;
400- }
401- else {
402- ReleaseCapture();
403- }
404- break;
400+ else {
401+ ReleaseCapture();
405402 }
406- case WM_RBUTTONUP:
407- {
408- if (me->m_dCaptureMode & 0x02) {
409- me->AddEvent(WM_RBUTTONUP, 0, 0);
410- me->m_dCaptureMode &= ~0x02;
411- ReleaseCapture();
412- }
413- break;
403+ break;
404+ }
405+ case WM_RBUTTONUP:
406+ {
407+ if (me->m_dCaptureMode & 0x02) {
408+ me->AddEvent(WM_RBUTTONUP, 0, 0);
409+ me->m_dCaptureMode &= ~0x02;
410+ ReleaseCapture();
414411 }
415- case WM_CAPTURECHANGED:
416- {
417- if (me->m_dCaptureMode & 0x01) {
418- me->AddEvent(WM_CAPTURECHANGED, 1, 0);
419- }
420- if (me->m_dCaptureMode & 0x02) {
421- me->AddEvent(WM_CAPTURECHANGED, 2, 0);
422- }
423- me->m_dCaptureMode = 0;
424- break;
412+ break;
413+ }
414+ case WM_CAPTURECHANGED:
415+ {
416+ if (me->m_dCaptureMode & 0x01) {
417+ me->AddEvent(WM_CAPTURECHANGED, 1, 0);
425418 }
426- case WM_SIZE:
427- {
428- me->AddEventSingle(WM_SIZE, 0, 0);
429- break;
419+ if (me->m_dCaptureMode & 0x02) {
420+ me->AddEvent(WM_CAPTURECHANGED, 2, 0);
430421 }
431- case WM_TIMER:
432- {
433- if (wParam == 1) {
434- me->AddEventSingle(WM_TIMER, 0, 0);
422+ me->m_dCaptureMode = 0;
423+ break;
424+ }
425+ case WM_SIZE:
426+ {
427+ me->AddEventSingle(WM_SIZE, 0, 0);
428+ break;
429+ }
430+ case WM_TIMER:
431+ {
432+ if (wParam == 1) {
433+ me->AddEventSingle(WM_TIMER, 0, 0);
434+ }
435+ break;
436+ }
437+ case WM_DROPFILES:
438+ {
439+ HDROP hDrop = (HDROP)wParam;
440+ me->m_dropfiles.SetDropFiles(hDrop);
441+ me->AddEvent(WM_DROPFILES, 0, 0);
442+ break;
443+ }
444+ case WM_KEYDOWN:
445+ {
446+ DWORD st = 0;
447+ if (GetKeyState(VK_SHIFT) & 0x8000) st |= 0x01;
448+ if (GetKeyState(VK_CONTROL) & 0x8000) st |= 0x02;
449+ if (GetKeyState(VK_MENU) & 0x8000) st |= 0x04;
450+ me->AddEventSingle(WM_KEYDOWN, wParam, st);
451+ return 0;
452+ }
453+ case WM_KEYDOWN_EX:
454+ {
455+ DWORD st = 0;
456+ if (GetKeyState(VK_SHIFT) & 0x8000) st |= 0x01;
457+ if (GetKeyState(VK_CONTROL) & 0x8000) st |= 0x02;
458+ if (GetKeyState(VK_MENU) & 0x8000) st |= 0x04;
459+ me->AddEventSingle(WM_KEYDOWN_EX, wParam, st);
460+ return 0;
461+ }
462+ case WM_COMMAND:
463+ {
464+#ifdef _DEBUG
465+ ATLTRACE(_TEXT("command=%d:%d\n"), HIWORD(wParam), LOWORD(wParam));
466+#endif
467+ HWND hControl = (HWND)lParam;
468+ int nID = LOWORD(wParam);
469+ int notify = HIWORD(wParam);
470+ if (!notify) {
471+ if (nID == IDABORT) {
472+ // IDABORTと同一ならquitを立てる
473+ me->m_bQuit = true;
474+ }
475+ me->AddEventSingle(WM_COMMAND, nID, 0);
476+ }
477+ else {
478+ // コントロール通知
479+ switch (notify) {
480+ case CBN_SETFOCUS:
481+ case LBN_SETFOCUS:
482+ case EN_SETFOCUS:
483+ case BN_SETFOCUS:
484+ // TreeView - ListView以外のコントロールがフォーカスを受け取ったことを通知する
485+ me->m_hLastFocusControl = hControl;
486+ break;
487+ case LBN_DBLCLK:
488+ // LISTBOXがダブルクリックされた
489+ me->AddEvent(WM_COMMAND, nID, 0);
490+ default:
491+ break;
435492 }
436- break;
437493 }
438- case WM_DROPFILES:
494+ break;
495+ }
496+ case WM_NOTIFY:
497+ {
498+ NMHDR* notify = (NMHDR*)lParam;
499+ switch (notify->code) {
500+ case NM_SETFOCUS:
439501 {
440- HDROP hDrop = (HDROP)wParam;
441- me->m_dropfiles.DropFiles(hDrop);
442- me->AddEvent(WM_DROPFILES, 0, 0);
443- break;
502+ // TreeView - ListViewがフォーカスを受け取ったことを通知する
503+ me->m_hLastFocusControl = notify->hwndFrom;
504+ return 0;
444505 }
445- case WM_KEYDOWN:
506+ case TVN_SELCHANGED:
446507 {
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, wParam, st);
508+ // TreeViewの選択が変更されたことを通知される
509+ LPNMTREEVIEW pnmTv = (LPNMTREEVIEW)lParam;
510+ me->AddEvent(WM_COMMAND, pnmTv->hdr.idFrom, 0);
452511 return 0;
453512 }
454- case WM_KEYDOWN_EX:
513+ case NM_DBLCLK:
455514 {
456- DWORD st = 0;
457- if (GetKeyState(VK_SHIFT) & 0x8000) st |= 0x01;
458- if (GetKeyState(VK_CONTROL) & 0x8000) st |= 0x02;
459- if (GetKeyState(VK_MENU) & 0x8000) st |= 0x04;
460- me->AddEventSingle(WM_KEYDOWN_EX, wParam, st);
515+ // ListView - TreeViewでダブルクリックされたことを通知された
516+ LPNMITEMACTIVATE pnmLv = (LPNMITEMACTIVATE)lParam;
517+ me->AddEvent(WM_COMMAND, pnmLv->hdr.idFrom, 0);
461518 return 0;
462519 }
463- case WM_COMMAND:
520+ case LVN_COLUMNCLICK:
464521 {
465-#ifdef _DEBUG
466- TCHAR mes[MAX_PATH];
467- wsprintf(mes, _TEXT("command=%d:%d\n"), HIWORD(wParam), LOWORD(wParam));
468- OutputDebugString(mes);
469-#endif
470- HWND hControl = (HWND)lParam;
471- int nID = LOWORD(wParam);
472- int notify = HIWORD(wParam);
473- if (!notify) {
474- if (nID == IDABORT) {
475- // IDABORTと同一ならquitを立てる
476- me->m_bQuit = true;
477- }
478- me->AddEventSingle(WM_COMMAND, nID, 0);
479- }
480- else {
481- // コントロール通知
482- switch (notify) {
483- case CBN_SETFOCUS:
484- case LBN_SETFOCUS:
485- case EN_SETFOCUS:
486- case BN_SETFOCUS:
487- // TreeView - ListView以外のコントロールがフォーカスを受け取ったことを通知する
488- me->m_hLastFocusControl = hControl;
489- break;
490- case LBN_DBLCLK:
491- // LISTBOXがダブルクリックされた
492- me->AddEvent(WM_COMMAND, nID, 0);
493- default:
494- break;
495- }
522+ // ListViewでカラムがクリックされたことを通知する
523+ LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam;
524+ LONG_PTR addr = ::GetWindowLongPtr(pnmv->hdr.hwndFrom, GWLP_USERDATA);
525+ if (addr) {
526+ // カラムクリックによるソーティングを行う
527+ CComObject<CControl>* pCtrl = (CComObject<CControl>*)addr;
528+ pCtrl->ListSort(pnmv->iSubItem);
496529 }
497- break;
530+ return 0;
498531 }
499- case WM_NOTIFY:
532+ case LVN_ENDLABELEDIT:
500533 {
501- NMHDR* notify = (NMHDR*)lParam;
502- switch (notify->code) {
503- case NM_SETFOCUS:
504- {
505- // TreeView - ListViewがフォーカスを受け取ったことを通知する
506- me->m_hLastFocusControl = notify->hwndFrom;
507- return 0;
508- }
509- case TVN_SELCHANGED:
510- {
511- // TreeViewの選択が変更されたことを通知される
512- LPNMTREEVIEW pnmTv = (LPNMTREEVIEW)lParam;
513- me->AddEvent(WM_COMMAND, pnmTv->hdr.idFrom, 0);
514- return 0;
515- }
516- case NM_DBLCLK:
517- {
518- // ListView - TreeViewでダブルクリックされたことを通知された
519- LPNMITEMACTIVATE pnmLv = (LPNMITEMACTIVATE)lParam;
520- me->AddEvent(WM_COMMAND, pnmLv->hdr.idFrom, 0);
521- return 0;
522- }
523- case LVN_COLUMNCLICK:
524- {
525- // ListViewでカラムがクリックされたことを通知する
526- LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam;
527- LONG_PTR addr = ::GetWindowLongPtr(pnmv->hdr.hwndFrom, GWLP_USERDATA);
528- if (addr) {
529- // カラムクリックによるソーティングを行う
530- CComObject<CControl>* pCtrl = (CComObject<CControl>*)addr;
531- pCtrl->ListSort(pnmv->iSubItem);
532- }
533- return 0;
534- }
535- case LVN_ENDLABELEDIT:
536- {
537- // ListViewで項目が編集されたことを通知する
538- NMLVDISPINFO* pdi = (NMLVDISPINFO*)lParam;
539- if (pdi->item.mask & LVIF_TEXT) {
540- ListView_SetItemText(pdi->hdr.hwndFrom, pdi->item.iItem, 0, pdi->item.pszText);
541- }
542- return 0;
543- }
544- case LVN_KEYDOWN:
545- {
546- // ListViewでキーボードが押されたことを通知する
547- LPNMLVKEYDOWN pnkd = (LPNMLVKEYDOWN)lParam;
548- if (pnkd->wVKey == VK_SPACE) {
549- // スペースキーでダブルクリックと同じ効果を持たせる
550- me->AddEvent(WM_COMMAND, pnkd->hdr.idFrom, 0);
551- }
552- else if (pnkd->wVKey == VK_DELETE) {
553- // デリート
554- me->AddEvent(WM_NOTIFY, pnkd->hdr.idFrom, VK_DELETE);
555- }
556- else if (pnkd->wVKey == VK_F2) {
557- // ラベル編集開始
558- int idx = ListView_GetNextItem(pnkd->hdr.hwndFrom, -1, LVNI_FOCUSED);
559- ListView_EditLabel(pnkd->hdr.hwndFrom, idx);
560- }
561- return 0;
562- }
563- case TVN_KEYDOWN:
564- {
565- LPNMTVKEYDOWN ptvkd = (LPNMTVKEYDOWN)lParam;
566- if (ptvkd->wVKey == VK_DELETE) {
567- // デリート
568- me->AddEvent(WM_NOTIFY, ptvkd->hdr.idFrom, VK_DELETE);
569- }
570- return 0;
571- }
572- case NM_RCLICK:
573- {
574- // ListView - TreeView で右クリックされたことを通知する
575- LPNMHDR lpnmh = (LPNMHDR)lParam;
576- LONG_PTR addr = ::GetWindowLongPtr(lpnmh->hwndFrom, GWLP_USERDATA);
577- if (addr) {
578- CComObject<CControl>* pCtrl = (CComObject<CControl>*)addr;
579- pCtrl->OnRClick(); // コントロールに右クリックを通知し前処理を行わせる
580- }
581- me->AddEvent(WM_NOTIFY, lpnmh->idFrom, VK_RBUTTON);
582- return 0;
583- }
584- default:
585- break;
534+ // ListViewで項目が編集されたことを通知する
535+ NMLVDISPINFO* pdi = (NMLVDISPINFO*)lParam;
536+ if (pdi->item.mask & LVIF_TEXT) {
537+ ListView_SetItemText(pdi->hdr.hwndFrom, pdi->item.iItem, 0, pdi->item.pszText);
586538 }
587- break;
539+ return 0;
588540 }
589- case WM_CTLCOLORSTATIC:
541+ case LVN_KEYDOWN:
590542 {
591- HDC hdc = (HDC)wParam;
592- ::SetBkColor(hdc, me->m_dwBackColor);
593- ::SetTextColor(hdc, ::GetSysColor(COLOR_WINDOWTEXT));
594- return (LPARAM)me->m_hBkBrush;
543+ // ListViewでキーボードが押されたことを通知する
544+ LPNMLVKEYDOWN pnkd = (LPNMLVKEYDOWN)lParam;
545+ if (pnkd->wVKey == VK_SPACE) {
546+ // スペースキーでダブルクリックと同じ効果を持たせる
547+ me->AddEvent(WM_COMMAND, pnkd->hdr.idFrom, 0);
548+ }
549+ else if (pnkd->wVKey == VK_DELETE) {
550+ // デリート
551+ me->AddEvent(WM_NOTIFY, pnkd->hdr.idFrom, VK_DELETE);
552+ }
553+ else if (pnkd->wVKey == VK_F2) {
554+ // ラベル編集開始
555+ int idx = ListView_GetNextItem(pnkd->hdr.hwndFrom, -1, LVNI_FOCUSED);
556+ ListView_EditLabel(pnkd->hdr.hwndFrom, idx);
557+ }
558+ return 0;
595559 }
596- case WM_CTLCOLOREDIT:
597- case WM_CTLCOLORLISTBOX:
598- case WM_CTLCOLORMSGBOX:
560+ case TVN_KEYDOWN:
599561 {
600- if (me->m_pForm) {
601- // フォームで指定されたコントロール背景ブラシを取得する
602- HDC hdc = (HDC)wParam;
603- ::SetBkColor(hdc, me->m_pForm->GetControlColor());
604- ::SetTextColor(hdc, ::GetSysColor(COLOR_WINDOWTEXT));
605- return (LPARAM)me->m_pForm->GetControlColorBrush();
562+ LPNMTVKEYDOWN ptvkd = (LPNMTVKEYDOWN)lParam;
563+ if (ptvkd->wVKey == VK_DELETE) {
564+ // デリート
565+ me->AddEvent(WM_NOTIFY, ptvkd->hdr.idFrom, VK_DELETE);
606566 }
607- break;
567+ return 0;
608568 }
609- case WM_SETCURSOR:
569+ case NM_RCLICK:
610570 {
611- if (me->m_dWaitCursor > 0) {
612- ::SetCursor(::LoadCursor(NULL, IDC_WAIT));
613- return true;
571+ // ListView - TreeView で右クリックされたことを通知する
572+ LPNMHDR lpnmh = (LPNMHDR)lParam;
573+ LONG_PTR addr = ::GetWindowLongPtr(lpnmh->hwndFrom, GWLP_USERDATA);
574+ if (addr) {
575+ CComObject<CControl>* pCtrl = (CComObject<CControl>*)addr;
576+ pCtrl->OnRClick(); // コントロールに右クリックを通知し前処理を行わせる
614577 }
578+ me->AddEvent(WM_NOTIFY, lpnmh->idFrom, VK_RBUTTON);
579+ return 0;
580+ }
581+ default:
615582 break;
616583 }
584+ break;
585+ }
586+ case WM_CTLCOLORSTATIC:
587+ {
588+ HDC hdc = (HDC)wParam;
589+ ::SetBkColor(hdc, me->m_dwBackColor);
590+ ::SetTextColor(hdc, ::GetSysColor(COLOR_WINDOWTEXT));
591+ return (LPARAM)me->m_hBkBrush;
592+ }
593+ case WM_CTLCOLOREDIT:
594+ case WM_CTLCOLORLISTBOX:
595+ case WM_CTLCOLORMSGBOX:
596+ {
597+ if (me->m_pForm) {
598+ // フォームで指定されたコントロール背景ブラシを取得する
599+ HDC hdc = (HDC)wParam;
600+ ::SetBkColor(hdc, me->m_pForm->GetControlColor());
601+ ::SetTextColor(hdc, ::GetSysColor(COLOR_WINDOWTEXT));
602+ return (LPARAM)me->m_pForm->GetControlColorBrush();
603+ }
604+ break;
605+ }
606+ case WM_SETCURSOR:
607+ {
608+ if (me->m_dWaitCursor > 0) {
609+ ::SetCursor(::LoadCursor(NULL, IDC_WAIT));
610+ return true;
611+ }
612+ break;
613+ }
617614 }
618615 return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
619616 }
@@ -667,173 +664,173 @@ STDMETHODIMP COverlappedWindow::DoEvent(VARIANT *varResult)
667664 // このオブジェクトを引数として渡すためにインターフェイスを生成する
668665 CComPtr<IUnknown> pUnk;
669666 HRESULT hr;
670- if (FAILED(hr = QueryInterface(IID_IUnknown, (void**) &pUnk))) {
667+ if (FAILED(hr = QueryInterface(IID_IUnknown, (void**)&pUnk))) {
671668 return hr;
672669 }
673670
674671 // イベントに対するライズ
675672 switch (pEv->GetMessage()) {
676- case WM_KEYDOWN:
677- {
678- Fire_OnKeydown();
679- Fire_OnKeydownEx(pUnk);
680- ClassObjectInvoke(L"OnKeydown");
681- break;
682- }
683- case WM_KEYDOWN_EX:
684- {
685- Fire_OnKeydown2();
686- Fire_OnKeydown2Ex(pUnk);
687- ClassObjectInvoke(L"OnKeydown2");
688- break;
689- }
690- case WM_MOUSEMOVE:
691- {
692- Fire_OnMouseMove();
693- Fire_OnMouseMoveEx(pUnk);
694- ClassObjectInvoke(L"OnMouseMove");
695- break;
696- }
697- case WM_LBUTTONDBLCLK:
698- {
699- Fire_OnDblClick();
700- Fire_OnDblClickEx(pUnk);
701- ClassObjectInvoke(L"OnDblClick");
702- break;
703- }
704- case WM_LBUTTONDOWN:
705- {
706- Fire_OnClick();
707- Fire_OnClickEx(pUnk);
708- ClassObjectInvoke(L"OnClick");
709- break;
710- }
711- case WM_RBUTTONDBLCLK:
712- {
713- Fire_OnRDblClick();
714- Fire_OnRDblClickEx(pUnk);
715- ClassObjectInvoke(L"OnRDblClick");
716- break;
717- }
718- case WM_RBUTTONDOWN:
719- {
720- Fire_OnRClick();
721- Fire_OnRClickEx(pUnk);
722- ClassObjectInvoke(L"OnRClick");
723- break;
724- }
725- case WM_LBUTTONUP:
726- {
727- Fire_OnClickOut();
728- Fire_OnClickOutEx(pUnk);
729- ClassObjectInvoke(L"OnClickOut");
730- break;
673+ case WM_KEYDOWN:
674+ {
675+ Fire_OnKeydown();
676+ Fire_OnKeydownEx(pUnk);
677+ ClassObjectInvoke(L"OnKeydown");
678+ break;
679+ }
680+ case WM_KEYDOWN_EX:
681+ {
682+ Fire_OnKeydown2();
683+ Fire_OnKeydown2Ex(pUnk);
684+ ClassObjectInvoke(L"OnKeydown2");
685+ break;
686+ }
687+ case WM_MOUSEMOVE:
688+ {
689+ Fire_OnMouseMove();
690+ Fire_OnMouseMoveEx(pUnk);
691+ ClassObjectInvoke(L"OnMouseMove");
692+ break;
693+ }
694+ case WM_LBUTTONDBLCLK:
695+ {
696+ Fire_OnDblClick();
697+ Fire_OnDblClickEx(pUnk);
698+ ClassObjectInvoke(L"OnDblClick");
699+ break;
700+ }
701+ case WM_LBUTTONDOWN:
702+ {
703+ Fire_OnClick();
704+ Fire_OnClickEx(pUnk);
705+ ClassObjectInvoke(L"OnClick");
706+ break;
707+ }
708+ case WM_RBUTTONDBLCLK:
709+ {
710+ Fire_OnRDblClick();
711+ Fire_OnRDblClickEx(pUnk);
712+ ClassObjectInvoke(L"OnRDblClick");
713+ break;
714+ }
715+ case WM_RBUTTONDOWN:
716+ {
717+ Fire_OnRClick();
718+ Fire_OnRClickEx(pUnk);
719+ ClassObjectInvoke(L"OnRClick");
720+ break;
721+ }
722+ case WM_LBUTTONUP:
723+ {
724+ Fire_OnClickOut();
725+ Fire_OnClickOutEx(pUnk);
726+ ClassObjectInvoke(L"OnClickOut");
727+ break;
728+ }
729+ case WM_RBUTTONUP:
730+ {
731+ Fire_OnRClickOut();
732+ Fire_OnRClickOutEx(pUnk);
733+ ClassObjectInvoke(L"OnRClickOut");
734+ break;
735+ }
736+ case WM_CAPTURECHANGED:
737+ {
738+ if (pEv->GetParam() == 1) {
739+ Fire_OnClickCancel();
740+ Fire_OnClickCancelEx(pUnk);
741+ ClassObjectInvoke(L"OnClickCancel");
731742 }
732- case WM_RBUTTONUP:
733- {
734- Fire_OnRClickOut();
735- Fire_OnRClickOutEx(pUnk);
736- ClassObjectInvoke(L"OnRClickOut");
737- break;
743+ else {
744+ Fire_OnRClickCancel();
745+ Fire_OnRClickCancelEx(pUnk);
746+ ClassObjectInvoke(L"OnRClickCancel");
738747 }
739- case WM_CAPTURECHANGED:
740- {
741- if (pEv->GetParam() == 1) {
742- Fire_OnClickCancel();
743- Fire_OnClickCancelEx(pUnk);
744- ClassObjectInvoke(L"OnClickCancel");
748+ break;
749+ }
750+ case WM_SIZE:
751+ {
752+ Fire_OnSize();
753+ Fire_OnSizeEx(pUnk);
754+ ClassObjectInvoke(L"OnSize");
755+ break;
756+ }
757+ case WM_COMMAND:
758+ {
759+ int nID = pEv->GetParam();
760+ switch (nID) {
761+ case IDOK:
762+ if (m_bDefaultAction) {
763+ m_bQuit = true;
745764 }
746- else {
747- Fire_OnRClickCancel();
748- Fire_OnRClickCancelEx(pUnk);
749- ClassObjectInvoke(L"OnRClickCancel");
765+ m_dModalExitCode = IDOK;
766+ Fire_OnOK();
767+ Fire_OnOKEx(pUnk);
768+ ClassObjectInvoke(L"OnOK");
769+ break;
770+ case IDCANCEL:
771+ if (m_bDefaultAction) {
772+ m_bQuit = true;
750773 }
774+ m_dModalExitCode = IDCANCEL;
775+ Fire_OnCancel();
776+ Fire_OnCancelEx(pUnk);
777+ ClassObjectInvoke(L"OnCancel");
751778 break;
752- }
753- case WM_SIZE:
754- {
755- Fire_OnSize();
756- Fire_OnSizeEx(pUnk);
757- ClassObjectInvoke(L"OnSize");
779+ case IDABORT:
780+ m_bQuit = true;
781+ m_dModalExitCode = IDABORT;
782+ Fire_OnExit();
783+ Fire_OnExitEx(pUnk);
784+ ClassObjectInvoke(L"OnExit");
758785 break;
786+ default:
787+ Fire_OnCommand();
788+ Fire_OnCommandEx(pUnk);
789+ ClassObjectInvoke(L"OnCommand");
759790 }
760- case WM_COMMAND:
761- {
762- int nID = pEv->GetParam();
763- switch (nID) {
764- case IDOK:
765- if (m_bDefaultAction) {
766- m_bQuit = true;
767- }
768- m_dModalExitCode = IDOK;
769- Fire_OnOK();
770- Fire_OnOKEx(pUnk);
771- ClassObjectInvoke(L"OnOK");
772- break;
773- case IDCANCEL:
774- if (m_bDefaultAction) {
775- m_bQuit = true;
776- }
777- m_dModalExitCode = IDCANCEL;
778- Fire_OnCancel();
779- Fire_OnCancelEx(pUnk);
780- ClassObjectInvoke(L"OnCancel");
781- break;
782- case IDABORT:
783- m_bQuit = true;
784- m_dModalExitCode = IDABORT;
785- Fire_OnExit();
786- Fire_OnExitEx(pUnk);
787- ClassObjectInvoke(L"OnExit");
788- break;
789- default:
790- Fire_OnCommand();
791- Fire_OnCommandEx(pUnk);
792- ClassObjectInvoke(L"OnCommand");
793- }
794- // 関連づけられたコントロールがあるのか?
795- if (m_pForm) {
796- BSTR eventname = NULL;
797- if (m_pForm->FindControlEventName(nID, &eventname)) {
798- if (SysStringLen(eventname) > 0) {
799- ClassObjectInvoke(eventname);
800- }
801- SysFreeString(eventname);
791+ // 関連づけられたコントロールがあるのか?
792+ if (m_pForm) {
793+ BSTR eventname = NULL;
794+ if (m_pForm->FindControlEventName(nID, &eventname)) {
795+ if (SysStringLen(eventname) > 0) {
796+ ClassObjectInvoke(eventname);
802797 }
798+ SysFreeString(eventname);
803799 }
804- // メニューの検索
805- if (m_hMenu && nID >= 100) {
806- std::map<int, CComBSTR>::iterator p = m_cMenuMap.find(nID);
807- if (p != m_cMenuMap.end()) {
808- // 発見された
809- ClassObjectInvoke(p->second);
810- }
800+ }
801+ // メニューの検索
802+ if (m_hMenu && nID >= 100) {
803+ std::map<int, CComBSTR>::iterator p = m_cMenuMap.find(nID);
804+ if (p != m_cMenuMap.end()) {
805+ // 発見された
806+ ClassObjectInvoke(p->second);
811807 }
812- break;
813808 }
814- case WM_DROPFILES:
815- {
816- Fire_OnDropFiles();
817- Fire_OnDropFilesEx(pUnk);
818- ClassObjectInvoke(L"OnDropFiles");
809+ break;
810+ }
811+ case WM_DROPFILES:
812+ {
813+ Fire_OnDropFiles();
814+ Fire_OnDropFilesEx(pUnk);
815+ ClassObjectInvoke(L"OnDropFiles");
816+ break;
817+ }
818+ case WM_NOTIFY:
819+ {
820+ switch (pEv->GetLParam()) {
821+ case VK_DELETE:
822+ Fire_OnContextDelete();
823+ Fire_OnContextDeleteEx(pUnk);
824+ ClassObjectInvoke(L"OnContextDelete");
819825 break;
820- }
821- case WM_NOTIFY:
822- {
823- switch (pEv->GetLParam()) {
824- case VK_DELETE:
825- Fire_OnContextDelete();
826- Fire_OnContextDeleteEx(pUnk);
827- ClassObjectInvoke(L"OnContextDelete");
828- break;
829- case VK_RBUTTON:
830- Fire_OnContextMenu();
831- Fire_OnContextMenuEx(pUnk);
832- ClassObjectInvoke(L"OnContextMenu");
833- break;
834- }
826+ case VK_RBUTTON:
827+ Fire_OnContextMenu();
828+ Fire_OnContextMenuEx(pUnk);
829+ ClassObjectInvoke(L"OnContextMenu");
835830 break;
836831 }
832+ break;
833+ }
837834 }
838835 // この引数として渡したインターフェイスを解放する
839836 if (pUnk) {
@@ -972,8 +969,7 @@ STDMETHODIMP COverlappedWindow::Close()
972969
973970 // クラスオブジェクトの放棄
974971 if (m_pClassDisp && m_bAutoReleaseClassObject) {
975- m_pClassDisp->Release();
976- m_pClassDisp = NULL;
972+ m_pClassDisp.Release();
977973 }
978974
979975 // フォーカスを移動する
@@ -989,7 +985,12 @@ STDMETHODIMP COverlappedWindow::Close()
989985
990986 STDMETHODIMP COverlappedWindow::get_DoubleBuffer(BOOL *pVal)
991987 {
988+ if (!pVal) {
989+ return E_POINTER;
990+ }
991+
992992 *pVal = windowParam.doublebuffer ? VB_TRUE : VB_FALSE;
993+
993994 return S_OK;
994995 }
995996
@@ -1002,9 +1003,15 @@ STDMETHODIMP COverlappedWindow::put_DoubleBuffer(BOOL newVal)
10021003
10031004 STDMETHODIMP COverlappedWindow::get_TopMost(BOOL *pVal)
10041005 {
1006+ if (!pVal) {
1007+ return E_POINTER;
1008+ }
1009+
10051010 SafeCreateWnd();
1011+
10061012 DWORD exstyle = ::GetWindowLong(m_hPopupWnd, GWL_EXSTYLE);
10071013 *pVal = (exstyle & WS_EX_TOPMOST) ? VB_TRUE : VB_FALSE;
1014+
10081015 return S_OK;
10091016 }
10101017
@@ -1017,13 +1024,19 @@ STDMETHODIMP COverlappedWindow::put_TopMost(BOOL newVal)
10171024
10181025 STDMETHODIMP COverlappedWindow::get_PosX(short *pVal)
10191026 {
1027+ if (!pVal) {
1028+ return E_POINTER;
1029+ }
1030+
10201031 if (m_hPopupWnd) {
1021- WINDOWPLACEMENT pls = {0};
1032+ WINDOWPLACEMENT pls = { 0 };
10221033 pls.length = sizeof(WINDOWPLACEMENT);
10231034 ::GetWindowPlacement(m_hPopupWnd, &pls);
10241035 windowParam.posX = (int)pls.rcNormalPosition.left;
10251036 }
1037+
10261038 *pVal = windowParam.posX;
1039+
10271040 return S_OK;
10281041 }
10291042
@@ -1031,7 +1044,7 @@ STDMETHODIMP COverlappedWindow::put_PosX(short newVal)
10311044 {
10321045 windowParam.posX = newVal;
10331046 if (m_hPopupWnd) {
1034- WINDOWPLACEMENT pls = {0};
1047+ WINDOWPLACEMENT pls = { 0 };
10351048 pls.length = sizeof(WINDOWPLACEMENT);
10361049 ::GetWindowPlacement(m_hPopupWnd, &pls);
10371050 ::SetWindowPos(m_hPopupWnd, NULL,
@@ -1044,13 +1057,19 @@ STDMETHODIMP COverlappedWindow::put_PosX(short newVal)
10441057
10451058 STDMETHODIMP COverlappedWindow::get_PosY(short *pVal)
10461059 {
1060+ if (!pVal) {
1061+ return E_POINTER;
1062+ }
1063+
10471064 if (m_hPopupWnd) {
1048- WINDOWPLACEMENT pls = {0};
1065+ WINDOWPLACEMENT pls = { 0 };
10491066 pls.length = sizeof(WINDOWPLACEMENT);
10501067 ::GetWindowPlacement(m_hPopupWnd, &pls);
10511068 windowParam.posY = (int)pls.rcNormalPosition.top;
10521069 }
1070+
10531071 *pVal = windowParam.posY;
1072+
10541073 return S_OK;
10551074 }
10561075
@@ -1058,7 +1077,7 @@ STDMETHODIMP COverlappedWindow::put_PosY(short newVal)
10581077 {
10591078 windowParam.posY = newVal;
10601079 if (m_hPopupWnd) {
1061- WINDOWPLACEMENT pls = {0};
1080+ WINDOWPLACEMENT pls = { 0 };
10621081 pls.length = sizeof(WINDOWPLACEMENT);
10631082 ::GetWindowPlacement(m_hPopupWnd, &pls);
10641083 ::SetWindowPos(m_hPopupWnd, NULL,
@@ -1071,21 +1090,28 @@ STDMETHODIMP COverlappedWindow::put_PosY(short newVal)
10711090
10721091 STDMETHODIMP COverlappedWindow::get_Width(short *pVal)
10731092 {
1093+ if (!pVal) {
1094+ return E_POINTER;
1095+ }
1096+
10741097 if (m_hPopupWnd) {
1075- WINDOWPLACEMENT pls = {0};
1098+ WINDOWPLACEMENT pls = { 0 };
10761099 pls.length = sizeof(WINDOWPLACEMENT);
10771100 ::GetWindowPlacement(m_hPopupWnd, &pls);
10781101 windowParam.width = (int)(pls.rcNormalPosition.right - pls.rcNormalPosition.left);
10791102 }
1103+
10801104 *pVal = windowParam.width;
1105+
10811106 return S_OK;
10821107 }
10831108
10841109 STDMETHODIMP COverlappedWindow::put_Width(short newVal)
10851110 {
10861111 windowParam.width = newVal;
1112+
10871113 if (m_hPopupWnd) {
1088- WINDOWPLACEMENT pls = {0};
1114+ WINDOWPLACEMENT pls = { 0 };
10891115 pls.length = sizeof(WINDOWPLACEMENT);
10901116 ::GetWindowPlacement(m_hPopupWnd, &pls);
10911117 ::SetWindowPos(m_hPopupWnd, NULL,
@@ -1093,31 +1119,39 @@ STDMETHODIMP COverlappedWindow::put_Width(short newVal)
10931119 windowParam.width,
10941120 pls.rcNormalPosition.bottom - pls.rcNormalPosition.top, SWP_NOZORDER | SWP_NOMOVE);
10951121 }
1122+
10961123 if (m_pForm) {
10971124 // フォームのサイズを変更する
10981125 m_pForm->SetWindowSize(windowParam.width, windowParam.height,
1099- windowParam.GetStyle(), windowParam.exstyle);
1126+ windowParam.ComputeStyle(), windowParam.exstyle);
11001127 }
11011128 return S_OK;
11021129 }
11031130
11041131 STDMETHODIMP COverlappedWindow::get_Height(short *pVal)
11051132 {
1133+ if (!pVal) {
1134+ return E_POINTER;
1135+ }
1136+
11061137 if (m_hPopupWnd) {
1107- WINDOWPLACEMENT pls = {0};
1138+ WINDOWPLACEMENT pls = { 0 };
11081139 pls.length = sizeof(WINDOWPLACEMENT);
11091140 ::GetWindowPlacement(m_hPopupWnd, &pls);
11101141 windowParam.height = (short)(pls.rcNormalPosition.right - pls.rcNormalPosition.left);
11111142 }
1143+
11121144 *pVal = windowParam.height;
1145+
11131146 return S_OK;
11141147 }
11151148
11161149 STDMETHODIMP COverlappedWindow::put_Height(short newVal)
11171150 {
11181151 windowParam.height = newVal;
1152+
11191153 if (m_hPopupWnd) {
1120- WINDOWPLACEMENT pls = {0};
1154+ WINDOWPLACEMENT pls = { 0 };
11211155 pls.length = sizeof(WINDOWPLACEMENT);
11221156 ::GetWindowPlacement(m_hPopupWnd, &pls);
11231157 ::SetWindowPos(m_hPopupWnd, NULL, 0, 0,
@@ -1125,19 +1159,26 @@ STDMETHODIMP COverlappedWindow::put_Height(short newVal)
11251159 windowParam.height,
11261160 SWP_NOZORDER | SWP_NOMOVE);
11271161 }
1162+
11281163 if (m_pForm) {
11291164 // フォームのサイズを変更する
11301165 m_pForm->SetWindowSize(windowParam.width, windowParam.height,
1131- windowParam.GetStyle(), windowParam.exstyle);
1166+ windowParam.ComputeStyle(), windowParam.exstyle);
11321167 }
11331168 return S_OK;
11341169 }
11351170
11361171 STDMETHODIMP COverlappedWindow::get_AcceptFiles(BOOL *pVal)
11371172 {
1173+ if (!pVal) {
1174+ return E_POINTER;
1175+ }
1176+
11381177 SafeCreateWnd();
1178+
11391179 DWORD exstyle = ::GetWindowLong(m_hPopupWnd, GWL_EXSTYLE);
11401180 *pVal = (exstyle & WS_EX_ACCEPTFILES) ? VB_TRUE : VB_FALSE;
1181+
11411182 return S_OK;
11421183 }
11431184
@@ -1167,15 +1208,22 @@ STDMETHODIMP COverlappedWindow::SetFocus()
11671208
11681209 STDMETHODIMP COverlappedWindow::get_Enable(BOOL *pVal)
11691210 {
1211+ if (!pVal) {
1212+ return E_POINTER;
1213+ }
11701214 SafeCreateWnd();
1215+
11711216 *pVal = ::IsWindowEnabled(m_hPopupWnd) ? VB_TRUE : VB_FALSE;
1217+
11721218 return S_OK;
11731219 }
11741220
11751221 STDMETHODIMP COverlappedWindow::put_Enable(BOOL newVal)
11761222 {
11771223 SafeCreateWnd();
1224+
11781225 ::EnableWindow(m_hPopupWnd, newVal);
1226+
11791227 if (m_pForm) {
11801228 m_pForm->EnableAllControl(newVal);
11811229 ::SetActiveWindow(m_hPopupWnd);
@@ -1186,8 +1234,14 @@ STDMETHODIMP COverlappedWindow::put_Enable(BOOL newVal)
11861234
11871235 STDMETHODIMP COverlappedWindow::get_Iconic(BOOL *pVal)
11881236 {
1237+ if (!pVal) {
1238+ return E_POINTER;
1239+ }
1240+
11891241 SafeCreateWnd();
1242+
11901243 *pVal = ::IsIconic(m_hPopupWnd) ? VB_TRUE : VB_FALSE;
1244+
11911245 return S_OK;
11921246 }
11931247
@@ -1201,8 +1255,14 @@ STDMETHODIMP COverlappedWindow::put_Iconic(BOOL newVal)
12011255
12021256 STDMETHODIMP COverlappedWindow::get_Zoomed(BOOL *pVal)
12031257 {
1258+ if (!pVal) {
1259+ return E_POINTER;
1260+ }
1261+
12041262 SafeCreateWnd();
1263+
12051264 *pVal = ::IsZoomed(m_hPopupWnd) ? VB_TRUE : VB_FALSE;
1265+
12061266 return S_OK;
12071267 }
12081268
@@ -1215,12 +1275,18 @@ STDMETHODIMP COverlappedWindow::put_Zoomed(BOOL newVal)
12151275
12161276 STDMETHODIMP COverlappedWindow::get_Visible(BOOL *pVal)
12171277 {
1278+ if (!pVal) {
1279+ return E_POINTER;
1280+ }
1281+
12181282 *pVal = VB_FALSE;
1283+
12191284 if (::IsWindow(m_hPopupWnd)) {
12201285 // ウィンドウが作成済みであれば調査する
12211286 DWORD style = ::GetWindowLong(m_hPopupWnd, GWL_STYLE);
12221287 *pVal = (style & WS_VISIBLE) ? VB_TRUE : VB_FALSE;
12231288 }
1289+
12241290 return S_OK;
12251291 }
12261292
@@ -1230,16 +1296,23 @@ STDMETHODIMP COverlappedWindow::put_Visible(BOOL newVal)
12301296 // FALSEなら、あえて作成は試みない
12311297 return S_OK;
12321298 }
1299+
12331300 SafeCreateWnd();
1301+
12341302 ::ShowWindow(m_hPopupWnd, newVal ? SW_SHOWNORMAL : SW_HIDE);
12351303 ::SetActiveWindow(m_hPopupWnd);
1304+
12361305 return S_OK;
12371306 }
12381307
12391308 STDMETHODIMP COverlappedWindow::WaitEvent(VARIANT varTim, BOOL* pRet)
12401309 {
1310+ if (!pRet) {
1311+ return E_POINTER;
1312+ }
1313+
12411314 SafeCreateWnd();
1242- *pRet = false;
1315+ *pRet = VB_FALSE;
12431316
12441317 // 待機時間の取得
12451318 DWORD sleeptim = 1000;
@@ -1251,8 +1324,8 @@ STDMETHODIMP COverlappedWindow::WaitEvent(VARIANT varTim, BOOL* pRet)
12511324 sleeptim = INFINITE;
12521325 }
12531326
1254- HANDLE hEvent[MAXIMUM_WAIT_OBJECTS] = {NULL};
1255- HWND hWnd[MAXIMUM_WAIT_OBJECTS] = {NULL};
1327+ HANDLE hEvent[MAXIMUM_WAIT_OBJECTS] = { NULL };
1328+ HWND hWnd[MAXIMUM_WAIT_OBJECTS] = { NULL };
12561329 int cnt = 0;
12571330 SetWaitParam(&cnt, hWnd, hEvent);
12581331 *pRet = MessageLoop(sleeptim, cnt, hWnd, hEvent) ? VB_TRUE : VB_FALSE;
@@ -1263,137 +1336,147 @@ STDMETHODIMP COverlappedWindow::WaitEvent(VARIANT varTim, BOOL* pRet)
12631336 STDMETHODIMP COverlappedWindow::SetMenu(VARIANT fmt)
12641337 {
12651338 SafeCreateWnd();
1266- HRESULT hRet = S_OK;
1339+
1340+ HRESULT hr;
1341+
12671342 CComVariant tmp;
1268- if (tmp.ChangeType(VT_BSTR, &fmt) == S_OK) {
1269- ATL::CString buf(tmp.bstrVal);
1270-
1271- // 古いメニューを破棄する
1272- if (m_hMenu) {
1273- m_cMenuMap.clear();
1274- ::SetMenu(m_hPopupWnd, NULL);
1275- DestroyMenu(m_hMenu);
1276- m_hMenu = NULL;
1277- }
1343+ if (FAILED(hr = tmp.ChangeType(VT_BSTR, &fmt))) {
1344+ return hr;
1345+ }
12781346
1279- if (buf.GetLength() > 0) {
1280- // 項目があればメニュー名をパースする
1281- m_hMenu = CreateMenu();
1282- TCHAR menuname[MAX_PATH];
1283- TCHAR szSubmenu[MAX_PATH];
1284- HMENU hPopupMenu = NULL;
1285- int lv1 = 0;
1286- int lv2 = 0;
1287- int cmd = 0;
1288-
1289- LPTSTR p = buf.GetBuffer();
1290- while (*p) {
1291- while (*p == ' ' || *p == '\t') p++; // ブランクスキップ
1292- if (*p == '/') {
1293- p++;
1294- // ポップアップメニューの作成
1295- if (hPopupMenu) {
1296- // 既存のポップアップを埋め込む
1297- MENUITEMINFO inf = {0};
1298- inf.cbSize = sizeof(MENUITEMINFO);
1299- inf.fMask = MIIM_SUBMENU | MIIM_TYPE;
1300- inf.fType = MFT_STRING;
1301- inf.dwTypeData = szSubmenu;
1302- inf.hSubMenu = hPopupMenu;
1303- InsertMenuItem(m_hMenu, lv1, true, &inf);
1304- }
1305- lv1++;
1306- lv2 = 0;
1307- cmd = 0;
1347+ ATL::CString buf(tmp.bstrVal);
13081348
1309- hPopupMenu = CreatePopupMenu();
1349+ // 古いメニューを破棄する
1350+ if (m_hMenu) {
1351+ m_cMenuMap.clear();
1352+ ::SetMenu(m_hPopupWnd, NULL);
1353+ DestroyMenu(m_hMenu);
1354+ m_hMenu = NULL;
1355+ }
1356+
1357+ if (buf.GetLength() > 0) {
1358+ // 項目があればメニュー名をパースする
1359+ m_hMenu = CreateMenu();
1360+ TCHAR menuname[MAX_PATH];
1361+ TCHAR szSubmenu[MAX_PATH];
1362+ HMENU hPopupMenu = NULL;
1363+ int lv1 = 0;
1364+ int lv2 = 0;
1365+ int cmd = 0;
1366+
1367+ LPTSTR p = buf.GetBuffer();
1368+ while (*p) {
1369+ while (*p == ' ' || *p == '\t') p++; // ブランクスキップ
1370+ if (*p == '/') {
1371+ p++;
1372+ // ポップアップメニューの作成
1373+ if (hPopupMenu) {
1374+ // 既存のポップアップを埋め込む
1375+ MENUITEMINFO inf = { 0 };
1376+ inf.cbSize = sizeof(MENUITEMINFO);
1377+ inf.fMask = MIIM_SUBMENU | MIIM_TYPE;
1378+ inf.fType = MFT_STRING;
1379+ inf.dwTypeData = szSubmenu;
1380+ inf.hSubMenu = hPopupMenu;
1381+ InsertMenuItem(m_hMenu, lv1, true, &inf);
1382+ }
1383+ lv1++;
1384+ lv2 = 0;
1385+ cmd = 0;
1386+
1387+ hPopupMenu = CreatePopupMenu();
1388+ LPTSTR st = p;
1389+ while (*p && *p != ',' && *p != '/' && *p != ':') {
1390+ p = CharNext(p);
1391+ }
1392+ ZeroMemory(szSubmenu, MAX_PATH);
1393+ int submenuLen = p - st;
1394+ if (submenuLen > 0) {
1395+ _tcsncpy_s(szSubmenu, MAX_PATH, st, submenuLen);
1396+ }
1397+ if (*p == ',' || *p == ':') {
1398+ p++;
1399+ }
1400+ }
1401+ else {
1402+ // メニューの作成
1403+ if (hPopupMenu) {
13101404 LPTSTR st = p;
13111405 while (*p && *p != ',' && *p != '/' && *p != ':') {
13121406 p = CharNext(p);
13131407 }
1314- ZeroMemory(szSubmenu, MAX_PATH);
1315- int submenuLen = p - st;
1316- if (submenuLen > 0) {
1317- _tcsncpy_s(szSubmenu, MAX_PATH, st, submenuLen);
1318- }
1319- if (*p == ',' || *p == ':') {
1320- p++;
1408+
1409+ ZeroMemory(menuname, MAX_PATH);
1410+ int menunameLen = p - st;
1411+ if (menunameLen > 0) {
1412+ _tcsncpy_s(menuname, MAX_PATH, st, menunameLen);
13211413 }
1322- }
1323- else {
1324- // メニューの作成
1325- if (hPopupMenu) {
1326- LPTSTR st = p;
1327- while (*p && *p != ',' && *p != '/' && *p != ':') {
1328- p = CharNext(p);
1329- }
13301414
1331- ZeroMemory(menuname, MAX_PATH);
1332- int menunameLen = p - st;
1333- if (menunameLen > 0) {
1334- _tcsncpy_s(menuname, MAX_PATH, st, menunameLen);
1335- }
1415+ // コマンドセパレーターを検査する
1416+ CComBSTR eventname;
1417+ LPTSTR findcmd = _tcschr(menuname, _TEXT('@'));
1418+ if (findcmd) {
1419+ *findcmd = 0;
1420+ eventname = findcmd + 1;
13361421
1337- // コマンドセパレーターを検査する
1338- CComBSTR eventname;
1339- LPTSTR findcmd = _tcschr(menuname, _TEXT('@'));
1340- if (findcmd) {
1341- *findcmd = 0;
1342- eventname = findcmd + 1;
1343-
1344- } else {
1345- TCHAR tmp[64];
1346- wsprintf(tmp, _TEXT("OnMenu%d"), lv1 * 100 + cmd);
1347- eventname = tmp;
1348- }
1349- m_cMenuMap.insert(std::make_pair(lv1 * 100 + cmd, eventname));
1422+ }
1423+ else {
1424+ TCHAR tmp[64];
1425+ wsprintf(tmp, _TEXT("OnMenu%d"), lv1 * 100 + cmd);
1426+ eventname = tmp;
1427+ }
1428+ m_cMenuMap.insert(std::make_pair(lv1 * 100 + cmd, eventname));
13501429
1351- // メニューの作成
1352- MENUITEMINFO inf = {0};
1430+ // メニューの作成
1431+ MENUITEMINFO inf = { 0 };
1432+ inf.cbSize = sizeof(MENUITEMINFO);
1433+ inf.fMask = MIIM_TYPE | MIIM_ID;
1434+ inf.fType = MFT_STRING;
1435+ inf.wID = lv1 * 100 + cmd;
1436+ inf.dwTypeData = menuname;
1437+ InsertMenuItem(hPopupMenu, lv2, true, &inf);
1438+ lv2++;
1439+ cmd++;
1440+
1441+ // セパレーターの指定か?
1442+ if (*p == ',') {
1443+ p++;
1444+
1445+ }
1446+ else if (*p == ':') {
1447+ MENUITEMINFO inf = { 0 };
13531448 inf.cbSize = sizeof(MENUITEMINFO);
1354- inf.fMask = MIIM_TYPE | MIIM_ID;
1355- inf.fType = MFT_STRING;
1356- inf.wID = lv1 * 100 + cmd;
1357- inf.dwTypeData = menuname;
1449+ inf.fMask = MIIM_TYPE;
1450+ inf.fType = MFT_SEPARATOR;
13581451 InsertMenuItem(hPopupMenu, lv2, true, &inf);
1452+ p++;
13591453 lv2++;
1360- cmd++;
1361-
1362- // セパレーターの指定か?
1363- if (*p == ',') {
1364- p++;
1365-
1366- } else if (*p == ':') {
1367- MENUITEMINFO inf = {0};
1368- inf.cbSize = sizeof(MENUITEMINFO);
1369- inf.fMask = MIIM_TYPE;
1370- inf.fType = MFT_SEPARATOR;
1371- InsertMenuItem(hPopupMenu, lv2, true, &inf);
1372- p++;
1373- lv2++;
1374- }
13751454 }
13761455 }
13771456 }
1378- // 未挿入のポップアップメニューの挿入
1379- if (hPopupMenu) {
1380- // 既存のポップアップを埋め込む
1381- MENUITEMINFO inf = {0};
1382- inf.cbSize = sizeof(MENUITEMINFO);
1383- inf.fMask = MIIM_SUBMENU | MIIM_TYPE;
1384- inf.fType = MFT_STRING;
1385- inf.dwTypeData = szSubmenu;
1386- inf.hSubMenu = hPopupMenu;
1387- InsertMenuItem(m_hMenu, lv1, true, &inf);
1388- }
1389- ::SetMenu(m_hPopupWnd, m_hMenu);
13901457 }
1458+ // 未挿入のポップアップメニューの挿入
1459+ if (hPopupMenu) {
1460+ // 既存のポップアップを埋め込む
1461+ MENUITEMINFO inf = { 0 };
1462+ inf.cbSize = sizeof(MENUITEMINFO);
1463+ inf.fMask = MIIM_SUBMENU | MIIM_TYPE;
1464+ inf.fType = MFT_STRING;
1465+ inf.dwTypeData = szSubmenu;
1466+ inf.hSubMenu = hPopupMenu;
1467+ InsertMenuItem(m_hMenu, lv1, true, &inf);
1468+ }
1469+ ::SetMenu(m_hPopupWnd, m_hMenu);
13911470 }
1392- return hRet;
1471+ return S_OK;
13931472 }
13941473
1395-STDMETHODIMP COverlappedWindow::TrackPopupMenu(VARIANT text, VARIANT cmd, VARIANT* pRet)
1474+STDMETHODIMP COverlappedWindow::TrackPopupMenu(VARIANT text, VARIANT pcmd, VARIANT* pRet)
13961475 {
1476+ if (!pRet) {
1477+ return E_POINTER;
1478+ }
1479+
13971480 SafeCreateWnd();
13981481
13991482 CComVariant varRet;
@@ -1401,80 +1484,86 @@ STDMETHODIMP COverlappedWindow::TrackPopupMenu(VARIANT text, VARIANT cmd, VARIAN
14011484
14021485 int nCommand = 0;
14031486 CComVariant varCmd;
1404- if (varCmd.ChangeType(VT_I2, &cmd) == S_OK) {
1487+ if (SUCCEEDED(varCmd.ChangeType(VT_I2, &pcmd))) {
14051488 nCommand = varCmd.iVal;
14061489 }
14071490
1491+ HRESULT hr;
1492+
14081493 CComVariant varText;
1409- if (varText.ChangeType(VT_BSTR, &text) == S_OK) {
1410- TCHAR menuname[MAX_PATH];
1494+ if (FAILED(hr = varText.ChangeType(VT_BSTR, &text))) {
1495+ return hr;
1496+ }
14111497
1412- ATL::CString buf(varText.bstrVal);
1413- UINT len = buf.GetLength() + 1;
1414- LPTSTR p = buf.GetBuffer();
1498+ TCHAR menuname[MAX_PATH];
14151499
1416- int lv = 0;
1417- int cmd = 0;
1418- HMENU hPopupMenu = CreatePopupMenu();
1419- while (*p) {
1420- LPTSTR st = p;
1421- while (*p == ' ' || *p == '\t') {
1422- p++;
1423- }
1424- while (*p && *p != ',' && *p != '/' && *p != ':') {
1425- p = CharNext(p);
1426- }
1427- ZeroMemory(menuname, MAX_PATH);
1428- int menunameLen = p - st;
1429- if (menunameLen > 0) {
1430- _tcsncpy_s(menuname, MAX_PATH, st, menunameLen);
1431- }
1432- MENUITEMINFO inf = {0};
1433- inf.cbSize = sizeof(MENUITEMINFO);
1434- inf.fMask = MIIM_TYPE | MIIM_ID;
1435- inf.fType = MFT_STRING;
1500+ ATL::CString buf(varText.bstrVal);
1501+ UINT len = buf.GetLength() + 1;
1502+ LPTSTR p = buf.GetBuffer();
1503+
1504+ int lv = 0;
1505+ int cmd = 0;
1506+ HMENU hPopupMenu = CreatePopupMenu();
1507+ while (*p) {
1508+ LPTSTR st = p;
1509+ while (*p == ' ' || *p == '\t') {
1510+ p++;
1511+ }
1512+ while (*p && *p != ',' && *p != '/' && *p != ':') {
1513+ p = CharNext(p);
1514+ }
1515+ ZeroMemory(menuname, MAX_PATH);
1516+ int menunameLen = p - st;
1517+ if (menunameLen > 0) {
1518+ _tcsncpy_s(menuname, MAX_PATH, st, menunameLen);
1519+ }
1520+ MENUITEMINFO inf = { 0 };
1521+ inf.cbSize = sizeof(MENUITEMINFO);
1522+ inf.fMask = MIIM_TYPE | MIIM_ID;
1523+ inf.fType = MFT_STRING;
14361524
1437- if (nCommand != 0) {
1438- inf.wID = nCommand + cmd;
1525+ if (nCommand != 0) {
1526+ inf.wID = nCommand + cmd;
14391527
1440- } else {
1441- // コマンドベースが0ならばコマンドイベントは発生させない。
1442- // TrackPopupMenuはコマンドを選択しなかった場合は0を返すため、0よりも大きな値にする必要がある。
1443- inf.wID = nCommand + cmd + 1;
1444- }
1528+ }
1529+ else {
1530+ // コマンドベースが0ならばコマンドイベントは発生させない。
1531+ // TrackPopupMenuはコマンドを選択しなかった場合は0を返すため、0よりも大きな値にする必要がある。
1532+ inf.wID = nCommand + cmd + 1;
1533+ }
14451534
1446- inf.dwTypeData = menuname;
1447- InsertMenuItem(hPopupMenu, lv, true, &inf);
1448- lv++;
1449- cmd++;
1535+ inf.dwTypeData = menuname;
1536+ InsertMenuItem(hPopupMenu, lv, true, &inf);
1537+ lv++;
1538+ cmd++;
14501539
1451- if (*p == ',' || *p == '/') {
1452- p++;
1540+ if (*p == ',' || *p == '/') {
1541+ p++;
14531542
1454- } else if (*p == ':') {
1455- inf.fMask = MIIM_TYPE;
1456- inf.fType = MFT_SEPARATOR;
1457- InsertMenuItem(hPopupMenu, lv, true, &inf);
1458- p++;
1459- lv++;
1460- }
14611543 }
1544+ else if (*p == ':') {
1545+ inf.fMask = MIIM_TYPE;
1546+ inf.fType = MFT_SEPARATOR;
1547+ InsertMenuItem(hPopupMenu, lv, true, &inf);
1548+ p++;
1549+ lv++;
1550+ }
1551+ }
14621552
1463- // TrackPopupMene
1464- DWORD pos = GetMessagePos();
1465- ::SetFocus(m_hPopupWnd);
1466- varRet = (SHORT) ::TrackPopupMenuEx(hPopupMenu,
1467- TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON |
1468- (nCommand == 0 ? (TPM_NONOTIFY | TPM_RETURNCMD) : 0), // コマンドベースが0であれば、コマンドイベントを通知させない。
1469- LOWORD(pos),
1470- HIWORD(pos),
1471- m_hPopupWnd,
1472- NULL);
1553+ // TrackPopupMene
1554+ DWORD pos = GetMessagePos();
1555+ ::SetFocus(m_hPopupWnd);
1556+ varRet = (SHORT) ::TrackPopupMenuEx(hPopupMenu,
1557+ TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON |
1558+ (nCommand == 0 ? (TPM_NONOTIFY | TPM_RETURNCMD) : 0), // コマンドベースが0であれば、コマンドイベントを通知させない。
1559+ LOWORD(pos),
1560+ HIWORD(pos),
1561+ m_hPopupWnd,
1562+ NULL);
14731563
1474- DestroyMenu(hPopupMenu);
1475- }
1476- varRet.Detach(pRet);
1477- return S_OK;
1564+ DestroyMenu(hPopupMenu);
1565+
1566+ return varRet.Detach(pRet);
14781567 }
14791568
14801569 STDMETHODIMP COverlappedWindow::get_HWND(long *pVal)
@@ -1521,7 +1610,8 @@ STDMETHODIMP COverlappedWindow::SetTimer(VARIANT tim, BOOL* pVal)
15211610 if (timer) {
15221611 *pVal = ::SetTimer(m_hPopupWnd, 1, timer, NULL) ? VB_TRUE : VB_FALSE;
15231612
1524- } else {
1613+ }
1614+ else {
15251615 *pVal = ::KillTimer(m_hPopupWnd, 1) ? VB_TRUE : VB_FALSE;
15261616 }
15271617 return S_OK;
@@ -1549,7 +1639,7 @@ STDMETHODIMP COverlappedWindow::CheckMenu(VARIANT cmd, VARIANT mode)
15491639
15501640 if (nCmd >= 100) {
15511641 // メニューコマンドは100以上であるので。
1552- MENUITEMINFO inf = {0};
1642+ MENUITEMINFO inf = { 0 };
15531643 inf.cbSize = sizeof(MENUITEMINFO);
15541644 inf.fMask = MIIM_STATE;
15551645 inf.fState = nMode ? MFS_CHECKED : MFS_UNCHECKED;
@@ -1580,7 +1670,7 @@ STDMETHODIMP COverlappedWindow::EnableMenu(VARIANT cmd, VARIANT mode)
15801670
15811671 if (nCmd >= 100) {
15821672 // メニューコマンドは100以上であるので。
1583- MENUITEMINFO inf = {0};
1673+ MENUITEMINFO inf = { 0 };
15841674 inf.cbSize = sizeof(MENUITEMINFO);
15851675 inf.fMask = MIIM_STATE;
15861676 inf.fState = nMode ? MFS_ENABLED : MFS_GRAYED;
@@ -1661,9 +1751,7 @@ STDMETHODIMP COverlappedWindow::get_DropFiles(VARIANT *pVal)
16611751 return E_POINTER;
16621752 }
16631753
1664- m_dropfiles.GetPathArray(pVal);
1665-
1666- return S_OK;
1754+ return m_dropfiles.GetPathArray(pVal);
16671755 }
16681756
16691757 STDMETHODIMP COverlappedWindow::get_Quit(BOOL *pVal)
@@ -1714,20 +1802,24 @@ STDMETHODIMP COverlappedWindow::get_Style(long *pVal)
17141802 return E_POINTER;
17151803 }
17161804
1805+ DWORD style;
17171806 if (m_hPopupWnd) {
1718- windowParam.style = ::GetWindowLong(m_hPopupWnd, GWL_STYLE);
1807+ style = ::GetWindowLong(m_hPopupWnd, GWL_STYLE);
1808+
1809+ }
1810+ else {
1811+ style = windowParam.ComputeStyle();
17191812 }
17201813
1721- *pVal = (long)windowParam.style;
1814+ *pVal = (long)style;
17221815
17231816 return S_OK;
17241817 }
17251818
17261819 STDMETHODIMP COverlappedWindow::put_Style(long newVal)
17271820 {
1728- windowParam.style = (DWORD)newVal;
17291821 if (m_hPopupWnd) {
1730- ::SetWindowLong(m_hPopupWnd, GWL_STYLE, windowParam.style);
1822+ ::SetWindowLong(m_hPopupWnd, GWL_STYLE, (DWORD)newVal);
17311823 }
17321824 return S_OK;
17331825 }
@@ -1810,7 +1902,7 @@ STDMETHODIMP COverlappedWindow::SetPlacement(VARIANT x, VARIANT y, VARIANT w, VA
18101902 if (m_pForm) {
18111903 // フォームのサイズを変更する
18121904 m_pForm->SetWindowSize(windowParam.width, windowParam.height,
1813- windowParam.GetStyle(), windowParam.exstyle);
1905+ windowParam.ComputeStyle(), windowParam.exstyle);
18141906 }
18151907 CreateThisInterface(pvarUnk);
18161908 return S_OK;
@@ -1849,7 +1941,7 @@ STDMETHODIMP COverlappedWindow::SetWindowStyle(VARIANT frametype, VARIANT captio
18491941 windowParam.maxbox = (varMaxMin.iVal & 0x02);
18501942 }
18511943 if (m_hPopupWnd) {
1852- ::SetWindowLong(m_hPopupWnd, GWL_STYLE, windowParam.GetStyle());
1944+ ::SetWindowLong(m_hPopupWnd, GWL_STYLE, windowParam.ComputeStyle());
18531945 Refresh();
18541946 }
18551947 CreateThisInterface(pvarUnk);
@@ -1863,7 +1955,7 @@ void COverlappedWindow::PurgeUnusedWindows()
18631955 while (p != m_lstChild.end()) {
18641956 DWORD refCount = (*p)->m_dwRef;
18651957 if ((*p)->m_dwRef == 1) {
1866- // 参照カウントが1しかない = このクラスしか使っていない = 不要
1958+ // 参照カウントが1しかない = このクラスしか使っていない = 不要候補
18671959 BOOL bVisible = false;
18681960 (*p)->get_Visible(&bVisible);
18691961 if (!bVisible) {
@@ -2190,7 +2282,8 @@ STDMETHODIMP COverlappedWindow::CenterWindow()
21902282 // 親ウィンドウがあれば、その中央に位置あわせする
21912283 ::GetWindowRect(m_hParentWnd, &rct);
21922284
2193- } else {
2285+ }
2286+ else {
21942287 HWND hwnd = ::GetDesktopWindow();
21952288 if (!hwnd) {
21962289 return S_OK;
@@ -2200,7 +2293,7 @@ STDMETHODIMP COverlappedWindow::CenterWindow()
22002293
22012294 int x = rct.left + (rct.right - rct.left) / 2 - windowParam.width / 2;
22022295 int y = rct.top + (rct.bottom - rct.top) / 2 - windowParam.height / 2;
2203- WINDOWPLACEMENT pls = {0};
2296+ WINDOWPLACEMENT pls = { 0 };
22042297 pls.length = sizeof(WINDOWPLACEMENT);
22052298 pls.rcNormalPosition.top = y;
22062299 pls.rcNormalPosition.left = x;
@@ -2228,17 +2321,22 @@ STDMETHODIMP COverlappedWindow::get_ClassObject(VARIANT* pVal)
22282321 STDMETHODIMP COverlappedWindow::put_ClassObject(VARIANT newVal)
22292322 {
22302323 if (m_pClassDisp) {
2231- m_pClassDisp->Release();
2232- m_pClassDisp = NULL;
2324+ // 現在の参照を解除する.
2325+ m_pClassDisp.Release();
22332326 }
22342327
2235- if (newVal.vt == VT_DISPATCH) {
2236- m_pClassDisp = newVal.pdispVal;
2237- m_pClassDisp->AddRef();
2328+ if (newVal.vt == VT_EMPTY || newVal.vt == VT_ERROR || newVal.vt == VT_NULL) {
2329+ // 省略時またはNULL, EMPTYの場合は参照解除のみ
2330+ return S_FALSE;
22382331 }
2239- else if (!(newVal.vt == VT_EMPTY || newVal.vt == VT_ERROR || newVal.vt == VT_NULL)) {
2332+
2333+ if (newVal.vt != VT_DISPATCH) {
2334+ // DISPATCHインターフェイス以外が指定された場合
22402335 return DISP_E_TYPEMISMATCH;
22412336 }
2337+
2338+ m_pClassDisp = newVal.pdispVal;
2339+
22422340 return S_OK;
22432341 }
22442342
@@ -2247,46 +2345,75 @@ HRESULT COverlappedWindow::ClassObjectInvoke(LPCWSTR handler)
22472345 if (!m_pClassDisp) {
22482346 return S_FALSE;
22492347 }
2250- DISPID dispid;
2348+
22512349 HRESULT hr;
2252- if (FAILED(hr = m_pClassDisp->GetIDsOfNames(IID_NULL, (LPWSTR*)&handler, 1, LOCALE_SYSTEM_DEFAULT, &dispid))) {
2350+
2351+ DISPID dispid;
2352+ if (FAILED(hr = m_pClassDisp->GetIDsOfNames(IID_NULL,
2353+ (LPWSTR*)&handler, 1, LOCALE_SYSTEM_DEFAULT, &dispid))) {
22532354 return hr;
22542355 }
2255- DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
2256- return m_pClassDisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispparamsNoArgs, NULL, NULL, NULL);
2356+
2357+ DISPPARAMS dispparamsNoArgs = { NULL, NULL, 0, 0 };
2358+
2359+ return m_pClassDisp->Invoke(dispid,
2360+ IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD,
2361+ &dispparamsNoArgs, NULL, NULL, NULL);
22572362 }
22582363
22592364 STDMETHODIMP COverlappedWindow::get_ClientWidth(long *pVal)
22602365 {
2366+ if (!pVal) {
2367+ return E_POINTER;
2368+ }
22612369 SafeCreateWnd();
2370+
22622371 RECT rct;
22632372 ::GetClientRect(m_hPopupWnd, &rct);
2373+
22642374 *pVal = rct.right;
2375+
22652376 return S_OK;
22662377 }
22672378
22682379 STDMETHODIMP COverlappedWindow::get_ClientHeight(long *pVal)
22692380 {
2381+ if (!pVal) {
2382+ return E_POINTER;
2383+ }
22702384 SafeCreateWnd();
2385+
22712386 RECT rct;
22722387 ::GetClientRect(m_hPopupWnd, &rct);
2388+
22732389 *pVal = rct.bottom;
2390+
22742391 return S_OK;
22752392 }
22762393
22772394 STDMETHODIMP COverlappedWindow::get_innerWidth(double *pVal)
22782395 {
2396+ if (!pVal) {
2397+ return E_POINTER;
2398+ }
2399+
22792400 SafeCreateWnd();
2401+
22802402 RECT rct;
22812403 ::GetClientRect(m_hPopupWnd, &rct);
2282- POINT pt = {rct.right, 0 - rct.bottom};
2404+
2405+ POINT pt = { rct.right, 0 - rct.bottom };
2406+
22832407 HDC hdc = ::GetWindowDC(m_hPopupWnd);
2408+
22842409 int md = ::GetMapMode(hdc);
2285- ::SetMapMode(hdc, MM_LOMETRIC);
2410+ ::SetMapMode(hdc, MM_LOMETRIC); // 論理単位を0.1mmへ変換する
22862411 ::DPtoLP(hdc, &pt, 1);
22872412 ::SetMapMode(hdc, md);
22882413 ::ReleaseDC(m_hPopupWnd, hdc);
2289- *pVal = pt.x / 10.;
2414+
2415+ *pVal = pt.x / 10.; // ミリ単位へ
2416+
22902417 return S_OK;
22912418 }
22922419
@@ -2297,17 +2424,21 @@ STDMETHODIMP COverlappedWindow::get_innerHeight(double *pVal)
22972424 }
22982425
22992426 SafeCreateWnd();
2427+
23002428 RECT rct;
23012429 ::GetClientRect(m_hPopupWnd, &rct);
2302- POINT pt = {rct.right, 0 - rct.bottom};
2430+
2431+ POINT pt = { rct.right, 0 - rct.bottom };
2432+
23032433 HDC hdc = ::GetWindowDC(m_hPopupWnd);
2434+
23042435 int md = ::GetMapMode(hdc);
2305- ::SetMapMode(hdc, MM_LOMETRIC);
2436+ ::SetMapMode(hdc, MM_LOMETRIC);// 論理単位を0.1mmへ変換する
23062437 ::DPtoLP(hdc, &pt, 1);
23072438 ::SetMapMode(hdc, md);
23082439 ::ReleaseDC(m_hPopupWnd, hdc);
23092440
2310- *pVal = pt.y / 10.;
2441+ *pVal = pt.y / 10.; // ミリ単位へ
23112442
23122443 return S_OK;
23132444 }
@@ -2382,7 +2513,8 @@ STDMETHODIMP COverlappedWindow::GetClipboardText(VARIANT *pVarText)
23822513 }
23832514 }
23842515
2385- } else if (IsClipboardFormatAvailable(CF_TEXT)) {
2516+ }
2517+ else if (IsClipboardFormatAvailable(CF_TEXT)) {
23862518 // UNICODE文字列がない場合
23872519 HGLOBAL hGlobal = ::GetClipboardData(CF_TEXT);
23882520 if (hGlobal) {
--- a/OverlappedWindow.h
+++ b/OverlappedWindow.h
@@ -23,15 +23,17 @@
2323
2424 ///////////////////////////////////////////////////////////////////////
2525 // ドロップされたファイルの保持
26-class dropfiledata
26+class CDropFileData
2727 {
2828 public:
29- dropfiledata()
29+ CDropFileData()
3030 {
3131 }
32- ~dropfiledata(){
32+
33+ ~CDropFileData(){
3334 Clear();
3435 }
36+
3537 void Clear()
3638 {
3739 std::list<LPTSTR>::iterator p = m_lstPath.begin();
@@ -40,7 +42,8 @@ public:
4042 p = m_lstPath.erase(p);
4143 }
4244 }
43- void DropFiles(HDROP hDrop)
45+
46+ void SetDropFiles(HDROP hDrop)
4447 {
4548 Clear();
4649 int count = ::DragQueryFile(hDrop, -1, NULL, 0);
@@ -51,29 +54,51 @@ public:
5154 m_lstPath.push_back(pBuf);
5255 }
5356 }
54- void GetPathArray(VARIANT *pvarPathName)
57+
58+ HRESULT GetPathArray(VARIANT *pvarPathName)
5559 {
60+ if (!pvarPathName) {
61+ return E_POINTER;
62+ }
63+
64+ VariantInit(pvarPathName);
5665 if (m_lstPath.empty()) {
5766 // 空である
5867 pvarPathName->vt = VT_EMPTY;
59- return;
68+ return S_FALSE;
6069 }
70+
6171 SAFEARRAY* pArray = SafeArrayCreateVector(VT_VARIANT, 0, m_lstPath.size());
72+ if (!pArray) {
73+ return E_OUTOFMEMORY;
74+ }
75+
6276 VARIANT* pvars;
63- if (SafeArrayAccessData(pArray, (void**)&pvars) == S_OK) {
64- int i = 0;
65- std::list<LPTSTR>::iterator p = m_lstPath.begin();
66- while (p != m_lstPath.end()) {
67- CComVariant wbuf(*p);
68- wbuf.Detach(&pvars[i]);
69- p++;
70- i++;
77+ HRESULT hr;
78+ if (FAILED(hr = SafeArrayAccessData(pArray, (void**)&pvars))) {
79+ return hr;
80+ }
81+ int i = 0;
82+ std::list<LPTSTR>::iterator p = m_lstPath.begin();
83+ while (p != m_lstPath.end()) {
84+ CComVariant wbuf(*p);
85+ hr = wbuf.Detach(&pvars[i]);
86+ if (FAILED(hr)) {
87+ break;
7188 }
72- SafeArrayUnaccessData(pArray);
89+ p++;
90+ i++;
7391 }
74- VariantInit(pvarPathName);
92+ SafeArrayUnaccessData(pArray);
93+
94+ if (FAILED(hr)) {
95+ SafeArrayDestroy(pArray);
96+ return hr;
97+ }
98+
7599 pvarPathName->vt = VT_ARRAY | VT_VARIANT;
76100 pvarPathName->parray = pArray;
101+ return S_OK;
77102 }
78103
79104 protected:
@@ -82,26 +107,25 @@ protected:
82107
83108 /////////////////////////////////////////////////////////////////////////////
84109 // COverlappedWindow
85-class CreateOverlappedWindow
110+struct OverlappedWindowParam
86111 {
87-public:
88- CreateOverlappedWindow()
112+ OverlappedWindowParam()
113+ : exstyle(0)
114+ , showMode(0)
115+ , noclose(false)
116+ , frametype(true)
117+ , captionbar(true)
118+ , systemmenu(true)
119+ , minbox(true)
120+ , maxbox(true)
121+ , autoclose(true)
122+ , automessageloop(true)
89123 {
90- style = 0;
91- exstyle = 0;
92- showMode = 0;
93- noclose = false;
94- frametype = true;
95- captionbar = true;
96- systemmenu = true;
97- minbox = true;
98- maxbox = true;
99- autoclose = true;
100- automessageloop = true;
101124 ZeroMemory(szClassName, MAX_PATH);
102125 posX = posY = width = height = 0;
103126 }
104- DWORD GetStyle()
127+
128+ DWORD ComputeStyle()
105129 {
106130 DWORD style = WS_CLIPCHILDREN | WS_OVERLAPPED;
107131 if (captionbar) { style |= WS_CAPTION; }
@@ -111,6 +135,7 @@ public:
111135 if (maxbox) { style |= WS_MAXIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME; }
112136 return style;
113137 }
138+
114139 inline void SetWindowPlacement(int x, int y, int w, int h)
115140 {
116141 posX = x;
@@ -118,13 +143,14 @@ public:
118143 width = w;
119144 height = h;
120145 }
146+
121147 inline void SetWindowClassName(LPCTSTR name)
122148 {
123149 StringCchCopy(szClassName, MAX_PATH, name);
124150 }
151+
125152 TCHAR szClassName[MAX_PATH];
126153 DWORD wndstyle;
127- DWORD style;
128154 DWORD exstyle;
129155 int posX;
130156 int posY;
@@ -232,19 +258,27 @@ protected:
232258 HRESULT ClassObjectInvoke(LPCWSTR handler);
233259
234260 public:
261+
262+#pragma region TRACEREF
263+#ifdef _DEBUG
264+ ///////////////////////////////
265+ // 参照カウントの追跡デバッグ用
266+
235267 ULONG InternalAddRef()
236268 {
237269 ULONG ref = CComObjectRootEx<CComSingleThreadModel>::InternalAddRef();
238- ATLTRACE(_TEXT("*addref=%d\n"), ref);
270+ ATLTRACE(_TEXT("* overlappedwindow: addref refcount=%d\n"), ref);
239271 return ref;
240272 }
241273
242274 ULONG InternalRelease()
243275 {
244276 ULONG ref = CComObjectRootEx<CComSingleThreadModel>::InternalRelease();
245- ATLTRACE(_TEXT("*release=%d\n"), ref);
277+ ATLTRACE(_TEXT("* overlappedwindow:release refcount=%d\n"), ref);
246278 return ref;
247279 }
280+#endif
281+#pragma endregion
248282
249283 // IOverlappedWindow
250284 public:
@@ -267,17 +301,11 @@ public:
267301 STDMETHOD(get_ExitCode)(/*[out, retval]*/ short *pVal);
268302 STDMETHOD(put_ExitCode)(/*[in]*/ short newVal);
269303 STDMETHOD(get_Object)(/*[in,optional]*/VARIANT idx, /*[out, retval]*/ VARIANT *pVal);
270- void MoveNextOverlapped();
271- void CreateWindowList(std::list<HWND>& lstWnd, BOOL bSearchRoot);
272304 STDMETHOD(get_AutoClose)(/*[out, retval]*/ BOOL *pVal);
273305 STDMETHOD(put_AutoClose)(/*[in]*/ BOOL newVal);
274306 STDMETHOD(DoModal)(/*[out,retval]*/VARIANT* retcode);
275307 STDMETHOD(get_AutoMessageLoop)(/*[out, retval]*/ BOOL *pVal);
276308 STDMETHOD(put_AutoMessageLoop)(/*[in]*/ BOOL newVal);
277- static DWORD MessageLoop(DWORD sleeptim, int count, HWND* hWnd, HANDLE* hEvent);
278- void SetWaitParam(int* count, HWND* phWnd, HANDLE* phWaitHandle);
279- HANDLE GetEventHandle();
280- void SetParent(HWND hParent);
281309 STDMETHOD(CreateChild)(/*[out,retval]*/VARIANT* pvarUnk);
282310 STDMETHOD(SetWindowStyle)(/*[in]*/VARIANT frametype,/*[in,optional]*/VARIANT caption_system,/*[in,optional]*/VARIANT maxmin,/*[out,retval]*/VARIANT* pvarUnk);
283311 STDMETHOD(SetPlacement)(/*[in]*/VARIANT x,/*[in]*/VARIANT y,/*[in,optional]*/VARIANT w,/*[in,optional]*/VARIANT h,/*[out,retval]*/VARIANT* pvarUnk);
@@ -293,23 +321,6 @@ public:
293321 STDMETHOD(DoEvent)(/*[out,retval]*/VARIANT* varResult);
294322 STDMETHOD(get_IsEventEmpty)(/*[out, retval]*/ BOOL *pVal);
295323 STDMETHOD(SetTimer)(/*[in]*/VARIANT tim,/*[out,retval]*/BOOL* pVal);
296-
297- HRESULT OnDraw(ATL_DRAWINFO& di)
298- {
299- RECT& rc = *(RECT*)di.prcBounds;
300- Rectangle(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom);
301-
302- SetTextAlign(di.hdcDraw, TA_CENTER | TA_BASELINE);
303- LPCTSTR pszText = _T("SeraphyScriptTools.OverlappedWindow");
304- TextOut(di.hdcDraw,
305- (rc.left + rc.right) / 2,
306- (rc.top + rc.bottom) / 2,
307- pszText,
308- lstrlen(pszText));
309-
310- return S_OK;
311- }
312-
313324 STDMETHOD(get_Caption)(/*[out, retval]*/ BSTR *pVal);
314325 STDMETHOD(put_Caption)(/*[in]*/ BSTR newVal);
315326 STDMETHOD(get_backColor)(/*[out, retval]*/ long *pVal);
@@ -353,23 +364,61 @@ public:
353364 STDMETHOD(put_TopMost)(/*[in]*/ BOOL newVal);
354365 STDMETHOD(get_DoubleBuffer)(/*[out, retval]*/ BOOL *pVal);
355366 STDMETHOD(put_DoubleBuffer)(/*[in]*/ BOOL newVal);
367+
368+public:
369+ void MoveNextOverlapped();
370+ void CreateWindowList(std::list<HWND>& lstWnd, BOOL bSearchRoot);
371+ static DWORD MessageLoop(DWORD sleeptim, int count, HWND* hWnd, HANDLE* hEvent);
372+ void SetWaitParam(int* count, HWND* phWnd, HANDLE* phWaitHandle);
373+ HANDLE GetEventHandle();
374+ void SetParent(HWND hParent);
375+
376+ HRESULT OnDraw(ATL_DRAWINFO& di)
377+ {
378+ RECT& rc = *(RECT*)di.prcBounds;
379+ Rectangle(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom);
380+
381+ SetTextAlign(di.hdcDraw, TA_CENTER | TA_BASELINE);
382+ LPCTSTR pszText = _T("SeraphyScriptTools.OverlappedWindow");
383+ TextOut(di.hdcDraw,
384+ (rc.left + rc.right) / 2,
385+ (rc.top + rc.bottom) / 2,
386+ pszText,
387+ lstrlen(pszText));
388+
389+ return S_OK;
390+ }
391+
392+public:
356393 CComBSTR m_bstrCaption;
394+
357395 protected:
358- HWND SafeCreateWnd();
359- CreateOverlappedWindow windowParam;
396+ OverlappedWindowParam windowParam;
397+
360398 CComObject<CCanvas>* m_pCanvas;
399+
361400 CComObject<CForm>* m_pForm;
401+
362402 CComObject<CEvent>* m_pEvent;
403+
363404 CComObject<CObjectMap>* m_pObject;
405+
364406 std::list<CComObject<CEvent>*> m_lstEvent;
407+
365408 std::list<CComObject<COverlappedWindow>*> m_lstChild;
366- std::vector<CComVariant> m_vectorObject;
367- dropfiledata m_dropfiles;
409+
410+ CDropFileData m_dropfiles;
411+
368412 CRITICAL_SECTION m_objEventDataProtection;
413+
369414 BOOL m_bAutoReleaseClassObject;
415+
370416 BOOL m_bDefaultAction;
371417
418+ CComPtr<IDispatch> m_pClassDisp;
419+
372420 protected:
421+ HWND SafeCreateWnd();
373422 static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
374423 void AddEvent(int message, WPARAM wParam, LPARAM lParam);
375424 void AddEventSingle(int message, WPARAM wParam, LPARAM lParam);
@@ -378,7 +427,6 @@ protected:
378427 void PurgeUnusedWindows();
379428
380429 protected:
381- IDispatch* m_pClassDisp;
382430 int m_dWaitCursor;
383431 BOOL m_bQuit;
384432 int m_dModalExitCode;
--- a/SeraphyScriptTools.h
+++ b/SeraphyScriptTools.h
@@ -4,7 +4,7 @@
44
55
66 /* File created by MIDL compiler version 8.00.0603 */
7-/* at Tue Aug 18 01:30:13 2015
7+/* at Wed Aug 19 06:02:15 2015
88 */
99 /* Compiler settings for SeraphyScriptTools.idl:
1010 Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.00.0603
--- a/StdAfx.h
+++ b/StdAfx.h
@@ -58,11 +58,3 @@ extern ATL::CComModule _Module;
5858
5959 #define VB_TRUE -1
6060 #define VB_FALSE 0
61-
62-/*
63-#if defined(_DEBUG)
64-#define ATLTRACE(mes) OutputDebugString(mes)
65-#else
66-#define ATLTRACE(mes)
67-#endif
68-*/
--- /dev/null
+++ b/TestScript/dropfiles.vbs
@@ -0,0 +1,40 @@
1+option explicit
2+
3+dim obj, edt, retcode
4+set obj = CreateObject("SeraphyScriptTools.Instance")
5+
6+wscript.ConnectObject obj.mainframe, "event_"
7+with obj.MainFrame
8+ .AcceptFiles = True
9+ .SetPlacement ,,350,260
10+ with .form
11+ .label "ここにファイルをドロップします"
12+ set edt = .edit(,20,10)
13+ .controlbreak
14+ .button("終了", 5).SetID(1)
15+ end with
16+ .Open "DropFiles"
17+ retcode = .DoModal
18+end with
19+wscript.disconnectobject obj.mainframe
20+obj.dialog.messagebox "リターンコード = " & retcode
21+
22+sub event_OnSizeEx(wnd)
23+ dim w
24+ with wnd
25+ w = .clientWidth - .form.RightMargin - .form.LeftMargin
26+ end with
27+ if not isempty(edt) then
28+ edt.SetPlacement ,,w
29+ end if
30+end sub
31+
32+sub event_OnDropFilesEx(wnd)
33+ dim buf, file
34+ buf = ""
35+ for each file in wnd.DropFiles
36+ buf = buf & file & vbcrlf
37+ next
38+ 'obj.dialog.messagebox buf
39+ edt.Text = buf
40+end sub
--- /dev/null
+++ b/TestScript/objectvector.vbs
@@ -0,0 +1,34 @@
1+option explicit
2+
3+dim instance, fso, lst
4+set instance = createobject("SeraphyScriptTools.Instance")
5+set lst = createobject("SeraphyScriptTools.ObjectVector")
6+set fso = CreateObject("Scripting.FileSystemObject")
7+
8+dim dirname, msg, x
9+do
10+ dirname = instance.dialog.browseforfolder(,dirname)
11+ if len(dirname) > 0 then
12+ dim folder
13+ set folder = fso.GetFolder(dirname)
14+ lst.Clear
15+ EnumFolder folder, lst
16+ msgbox lst.Count
17+ msg = ""
18+ for each x in lst '.MakeArray
19+ msg = msg & "," & x
20+ next
21+ msgbox msg
22+ else
23+ exit do
24+ end if
25+loop
26+
27+sub EnumFolder(folder, lst)
28+ dim dirname,subfolder
29+ dirname = folder.name
30+ lst.Push dirname
31+ for each subfolder in folder.subfolders
32+ EnumFolder subfolder, lst
33+ next
34+end sub
--- a/TestScript/pro3err.vbs
+++ b/TestScript/pro3err.vbs
@@ -2,4 +2,5 @@ dim pro1
22 set pro1 = createobject("SeraphyScriptTools.privateprofile")
33
44 dim sec1
5+' ↓ ここでエラーを発生させる.
56 set sec1 = pro1.OpenSection("")
--- a/TestScript/tree1.vbs
+++ b/TestScript/tree1.vbs
@@ -13,6 +13,7 @@ set obj = new mainframe
1313 class mainframe
1414 public instance
1515 public tree
16+ public dirname
1617 public sub class_initialize
1718 set instance = createobject("seraphyscripttools.instance")
1819 with instance.mainframe
@@ -41,8 +42,8 @@ class mainframe
4142 end sub
4243
4344 public sub OnStart
44- dim dirname,item,folder
45- dirname = instance.dialog.browseforfolder
45+ dim item,folder
46+ dirname = instance.dialog.browseforfolder(,dirname)
4647 if(len(dirname) > 0) then
4748 item = null
4849 set folder = fso.GetFolder(dirname)
--- a/generic.cpp
+++ b/generic.cpp
@@ -34,4 +34,34 @@ SAFEARRAY* GetArrayFromVariant(VARIANT& var, VARTYPE* pVt)
3434 return pArray;
3535 }
3636
37+/**
38+ * VARIANT型が変数(ByRef型)をさしている場合は、
39+ * それ自身が値となるようにByVal型に強制変換してコピーする.
40+ * (ByValであれば単純にコピーする.)
41+ */
42+HRESULT VariantCopyByVal(VARIANT *pDestVal, const VARIANT *pSrcVal)
43+{
44+ if (!pDestVal || !pSrcVal) {
45+ return E_POINTER;
46+ }
47+ ATLASSERT(pDestVal != pSrcVal);
48+
49+ VariantInit(pDestVal);
50+
51+ if (pSrcVal->vt & VT_BYREF) {
52+ // ByRefの場合はByValに変換する.
53+ VARTYPE vt = pSrcVal->vt & ~VT_BYREF;
3754
55+ if (vt == VT_VARIANT) {
56+ // Variantのポインタの場合は、そのポインタをコピーするのみ
57+ return VariantCopy(pDestVal, pSrcVal->pvarVal);
58+ }
59+ else {
60+ // 型変換を使ってByRefを外す
61+ return VariantChangeType(pDestVal, pSrcVal, 0, vt);
62+ }
63+ }
64+
65+ // ByValの場合はコピーするのみ
66+ return VariantCopy(pDestVal, pSrcVal);
67+}
--- a/generic.h
+++ b/generic.h
@@ -3,3 +3,6 @@
33 #pragma once
44
55 SAFEARRAY* GetArrayFromVariant(VARIANT& var, VARTYPE* pVt);
6+
7+HRESULT VariantCopyByVal(VARIANT *pDestVal, const VARIANT *pSrcVal);
8+
Show on old repository browser