OSDN Git Service

CLSIDの変更
[seraphyscrtools/SeraphyScriptTools.git] / Control.cpp
1 // Control.cpp : CControl \82Ì\83C\83\93\83v\83\8a\83\81\83\93\83e\81[\83V\83\87\83\93
2 #include "stdafx.h"
3
4 #include "SeraphyScriptTools.h"
5 #include "Control.h"
6 #include "treeitem.h"
7
8 #include "objectmap.h"
9 #include "CComEnumDynaVARIANT.h"
10
11 #include <vector>
12
13 /////////////////////////////////////////////////////////////////////////////
14 // CControl
15
16 STDMETHODIMP CControl::get_Text(BSTR *pVal)
17 {
18         if (!m_hParent || !m_hWnd) {
19                 return Error(IDS_ERR_DESTROYED);
20         }
21
22         DWORD siz = ::GetWindowTextLength(m_hWnd);
23
24         ATL::CString tmp;
25         LPTSTR pMes = tmp.GetBufferSetLength(siz + 1);
26         GetWindowText(m_hWnd, pMes, siz + 1);
27         tmp.ReleaseBuffer();
28
29         CComBSTR ret(tmp);
30         *pVal = ret.Detach();
31         return S_OK;
32 }
33
34 STDMETHODIMP CControl::put_Text(BSTR newVal)
35 {
36         if (!m_hParent || !m_hWnd) {
37                 return Error(IDS_ERR_DESTROYED);
38         }
39
40         ATL::CString tmp(newVal);
41         ::SetWindowText(m_hWnd, tmp);
42         return S_OK;
43 }
44
45 STDMETHODIMP CControl::get_ID(short *pVal)
46 {
47         if (m_hWnd) {
48                 m_nID = (int)GetWindowLong(m_hWnd, GWL_ID);
49         }
50         *pVal = m_nID;
51         return S_OK;
52 }
53
54 STDMETHODIMP CControl::put_ID(short newVal)
55 {
56         m_nID = newVal;
57         if (m_hWnd) {
58                 SetWindowLong(m_hWnd, GWL_ID, newVal);
59                 if ((m_nID == IDOK) && !lstrcmp(m_classname, _TEXT("BUTTON"))) {
60                         // IDOK\82È\82ç\83|\83b\83V\83\85\83{\83^\83\93\8c^\82ð\83f\83B\83t\83H\83\8b\83g\83{\83^\83\93\82É\95Ï\89»\82³\82¹\82é
61                         DWORD m_style = ::GetWindowLong(m_hWnd, GWL_STYLE);
62                         m_style |= BS_DEFPUSHBUTTON;
63                         ::SetWindowLong(m_hWnd, GWL_STYLE, m_style);
64                 }
65         }
66         return S_OK;
67 }
68
69 STDMETHODIMP CControl::get_Visibility(BOOL *pVal)
70 {
71         if (!m_hParent || !m_hWnd) {
72                 *pVal = 0;
73                 return Error(IDS_ERR_DESTROYED);
74         }
75
76         WINDOWPLACEMENT pls = {0};
77         pls.length = sizeof(WINDOWPLACEMENT);
78         ::GetWindowPlacement(m_hWnd, &pls);
79         *pVal = (pls.showCmd != SW_HIDE) ? true : false;
80         return S_OK;
81 }
82
83 STDMETHODIMP CControl::put_Visibility(BOOL newVal)
84 {
85         if (!m_hParent || !m_hWnd) {
86                 return Error(IDS_ERR_DESTROYED);
87         }
88
89         ::ShowWindow(m_hWnd, newVal ? SW_SHOWNORMAL : SW_HIDE);
90         return S_OK;
91 }
92
93 STDMETHODIMP CControl::get_Enable(BOOL *pVal)
94 {
95         if (!m_hParent || !m_hWnd) {
96                 *pVal = 0;
97                 return Error(IDS_ERR_DESTROYED);
98         }
99         *pVal = ::IsWindowEnabled(m_hWnd);
100         return S_OK;
101 }
102
103 STDMETHODIMP CControl::put_Enable(BOOL newVal)
104 {
105         if (!m_hParent || !m_hWnd) {
106                 return Error(IDS_ERR_DESTROYED);
107         }
108         ::EnableWindow(m_hWnd, newVal);
109         return S_OK;
110 }
111
112 STDMETHODIMP CControl::get_CheckState(short *pVal)
113 {
114         if (m_hWnd) {
115                 m_bChecked = (short)::SendMessage(m_hWnd, BM_GETCHECK, 0, 0);
116         }
117         *pVal = m_bChecked;
118         return S_OK;
119 }
120
121 STDMETHODIMP CControl::put_CheckState(short newVal)
122 {
123         m_bChecked = newVal;
124         if (m_hWnd && newVal >= 0 && newVal <= 2) {
125                 // 0:Unchecked 1:Checked 2:interminate
126                 ::SendMessage(m_hWnd, BM_SETCHECK, newVal, 0);
127         }
128         return S_OK;
129 }
130
131 BOOL CControl::Create(HWND hParent)
132 {
133         // << \83f\83t\83H\83\8b\83g\82Ì\83v\83b\83V\83\85\83{\83^\83\93\82É\95Ï\89»\82³\82¹\82é\83N\83\8d\96\82\8fp >>
134         if ((m_nID == IDOK) && !lstrcmp(m_classname, _TEXT("BUTTON"))) {
135                 // IDOK\82È\82ç\95Ï\8dX\82·\82é
136                 m_style |= BS_DEFPUSHBUTTON;
137         }
138
139         //\81@\83R\83\93\83g\83\8d\81[\83\8b\82Ì\90\90¬
140         ATLASSERT(m_hParent == NULL);
141         m_hParent = hParent;
142         m_hWnd = ::CreateWindowEx(m_exstyle, m_classname, m_caption,
143                 m_style | WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
144                 m_x, m_y, m_w, m_h,
145                 hParent,
146                 NULL,
147                 _Module.m_hInst,
148                 NULL);
149         ::SetWindowLongPtr(m_hWnd, GWLP_ID, m_nID);
150         ::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG_PTR) this);
151         ::SetWindowText(m_hWnd, m_caption);
152
153         // \90e\82ª\83f\83B\83Z\81[\83u\83\8b\82È\82ç\8eq\82à\83f\83B\83Z\81[\83u\83\8b\8fó\91Ô\82Å\8dì\90¬\82·\82é
154         if (!::IsWindowEnabled(m_hParent)) {
155                 ::EnableWindow(m_hWnd, false);
156         }
157
158         //////////////////////////
159         // \8e\96\91O\8fó\91Ô\82Ì\90Ý\92è
160         if (!lstrcmp(m_classname, _TEXT("BUTTON"))) {
161                 // \83{\83^\83\93\82È\82ç\83`\83F\83b\83N\8fó\91Ô\82Ì\83Z\83b\83g
162                 if (m_bChecked) {
163                         ::SendMessage(m_hWnd, BM_SETCHECK, 1, 0);
164                 }
165         }
166         else if (!lstrcmp(m_classname, WC_LISTVIEW)) {
167                 // \83\8a\83X\83g\83r\83\85\81[\82È\82ç\83J\83\89\83\80\82Ì\90Ý\92è\82ð\8ds\82¤
168                 LPCTSTR p = m_caption;
169                 m_nColumnCount = 0;
170                 // \83E\83B\83\93\83h\83E\83L\83\83\83v\83V\83\87\83\93\82©\82ç\97ñ\8c©\8fo\82µ\82ð\8dì\90¬\82·\82é
171                 while (*p) {
172                         LPCTSTR st = p;
173                         while (*p && *p != ',' && *p != ':') {
174                                 p = CharNext(p);
175                         }
176
177                         int sz = p - st;
178                         TCHAR szColumn[MAX_PATH] = {0};
179                         _tcsncpy_s(szColumn, MAX_PATH, st, sz);
180
181                         LVCOLUMN col = {0};
182                         col.mask = LVCF_TEXT | LVCF_WIDTH;
183                         col.pszText = szColumn;
184                         col.cx = ListView_GetStringWidth(m_hWnd, szColumn) + 16;
185                         ListView_InsertColumn(m_hWnd, m_nColumnCount, &col);
186
187                         if (*p == ',' || *p == ':') {
188                                 p++;
189                         }
190                         m_nColumnCount++;
191                 }
192                 if (m_afterstyle) {
193                         ListView_SetExtendedListViewStyle(m_hWnd, m_afterstyle);
194                 }
195         }
196         else if (!lstrcmp(m_classname, WC_TREEVIEW)) {
197                 TreeView_SetImageList(m_hWnd, NULL, TVSIL_NORMAL);
198         }
199         return true;
200 }
201
202 void CControl::Destroy()
203 {
204         DeleteAllItems();
205         if (m_hWnd) {
206                 // \83E\83B\83\93\83h\83E\82ð\94j\8aü\82·\82é
207                 // \83E\83B\83\93\83h\83E\82Ì\94j\8aü\82Æ\83C\83\93\83^\81[\83t\83F\83C\83X\82Ì\94j\8aü\82Í\88ê\92v\82µ\82È\82¢\81B
208                 ::DestroyWindow(m_hWnd);
209                 m_hWnd = NULL;
210         }
211 }
212
213 STDMETHODIMP CControl::get_Width(short *pVal)
214 {
215         if (m_hWnd) {
216                 WINDOWPLACEMENT pls = {0};
217                 pls.length = sizeof(WINDOWPLACEMENT);
218                 ::GetWindowPlacement(m_hWnd, &pls);
219                 m_w = (short)(pls.rcNormalPosition.right - pls.rcNormalPosition.left);
220         }
221         *pVal = m_w;
222         return S_OK;
223 }
224
225 STDMETHODIMP CControl::put_Width(short newVal)
226 {
227         m_w = newVal;
228         if (m_hWnd) {
229                 WINDOWPLACEMENT pls = {0};
230                 pls.length = sizeof(WINDOWPLACEMENT);
231                 ::GetWindowPlacement(m_hWnd, &pls);
232                 ::SetWindowPos(
233                         m_hWnd,
234                         NULL,
235                         0, 0,
236                         m_w,
237                         pls.rcNormalPosition.right - pls.rcNormalPosition.left,
238                         SWP_NOZORDER | SWP_NOMOVE
239                         );
240         }
241         return S_OK;
242 }
243
244 STDMETHODIMP CControl::get_Height(short *pVal)
245 {
246         if (m_hWnd) {
247                 WINDOWPLACEMENT pls = {0};
248                 pls.length = sizeof(WINDOWPLACEMENT);
249                 ::GetWindowPlacement(m_hWnd, &pls);
250                 m_h = (short)(pls.rcNormalPosition.bottom - pls.rcNormalPosition.top);
251         }
252         *pVal = m_h;
253         return S_OK;
254 }
255
256 STDMETHODIMP CControl::put_Height(short newVal)
257 {
258         m_h = newVal;
259         if (m_hWnd) {
260                 WINDOWPLACEMENT pls = {0};
261                 pls.length = sizeof(WINDOWPLACEMENT);
262                 ::GetWindowPlacement(m_hWnd, &pls);
263                 ::SetWindowPos(
264                         m_hWnd,
265                         NULL,
266                         0, 0,
267                         m_h,
268                         pls.rcNormalPosition.right - pls.rcNormalPosition.left,
269                         SWP_NOZORDER | SWP_NOMOVE
270                         );
271         }
272         return S_OK;
273 }
274
275 STDMETHODIMP CControl::get_PosX(short *pVal)
276 {
277         if (m_hWnd) {
278                 WINDOWPLACEMENT pls = {0};
279                 pls.length = sizeof(WINDOWPLACEMENT);
280                 ::GetWindowPlacement(m_hWnd, &pls);
281                 m_x = (short)pls.rcNormalPosition.left;
282         }
283         *pVal = m_x;
284         return S_OK;
285 }
286
287 STDMETHODIMP CControl::put_PosX(short newVal)
288 {
289         m_x = newVal;
290         if (m_hWnd) {
291                 WINDOWPLACEMENT pls = {0};
292                 pls.length = sizeof(WINDOWPLACEMENT);
293                 ::GetWindowPlacement(m_hWnd, &pls);
294                 ::SetWindowPos(
295                         m_hWnd,
296                         NULL,
297                         m_x, pls.rcNormalPosition.top,
298                         0, 0,
299                         SWP_NOZORDER | SWP_NOSIZE
300                         );
301         }
302         return S_OK;
303 }
304
305 STDMETHODIMP CControl::get_PosY(short *pVal)
306 {
307         if (m_hWnd) {
308                 WINDOWPLACEMENT pls = {0};
309                 pls.length = sizeof(WINDOWPLACEMENT);
310                 ::GetWindowPlacement(m_hWnd, &pls);
311                 m_y = (short)pls.rcNormalPosition.top;
312         }
313         *pVal = m_y;
314         return S_OK;
315 }
316
317 STDMETHODIMP CControl::put_PosY(short newVal)
318 {
319         m_y = newVal;
320         if (m_hWnd) {
321                 WINDOWPLACEMENT pls = {0};
322                 pls.length = sizeof(WINDOWPLACEMENT);
323                 ::GetWindowPlacement(m_hWnd, &pls);
324                 ::SetWindowPos(
325                         m_hWnd,
326                         NULL,
327                         pls.rcNormalPosition.left,
328                         m_y,
329                         0, 0,
330                         SWP_NOZORDER | SWP_NOSIZE
331                         );
332         }
333         return S_OK;
334 }
335
336 STDMETHODIMP CControl::SetPlacement(VARIANT x, VARIANT y, VARIANT w, VARIANT h, VARIANT *pvarUnk)
337 {
338         // \83T\83C\83Y\95Ï\8dX
339         CComVariant varX, varY, varW, varH;
340         if ((x.vt != VT_EMPTY && x.vt != VT_NULL && x.vt != VT_ERROR) && SUCCEEDED(varX.ChangeType(VT_I2, &x))) {
341                 m_x = varX.iVal;
342         }
343         if ((y.vt != VT_EMPTY && y.vt != VT_NULL && y.vt != VT_ERROR) && SUCCEEDED(varY.ChangeType(VT_I2, &y))) {
344                 m_y = varY.iVal;
345         }
346         if ((h.vt != VT_EMPTY && h.vt != VT_NULL && h.vt != VT_ERROR) && SUCCEEDED(varH.ChangeType(VT_I2, &h))) {
347                 m_h = varH.iVal;
348         }
349         if ((w.vt != VT_EMPTY && w.vt != VT_NULL && w.vt != VT_ERROR) && SUCCEEDED(varW.ChangeType(VT_I2, &w))) {
350                 m_w = varW.iVal;
351         }
352         // \83E\83B\83\93\83h\83E\82ª\95\\8e¦\82³\82ê\82Ä\82¢\82ê\82Î\82½\82¾\82¿\82É\94½\89f
353         if (m_hWnd) {
354                 ::SetWindowPos(m_hWnd, NULL, m_x, m_y, m_w, m_h, SWP_NOZORDER);
355         }
356         GetThisInterface(pvarUnk);
357         return S_OK;
358 }
359
360 STDMETHODIMP CControl::SetCheck(VARIANT *pvarUnk)
361 {
362         // \82½\82¾\82¿\82É\83`\83F\83b\83N\82·\82é
363         put_CheckState(true);
364         GetThisInterface(pvarUnk);
365         return S_OK;
366 }
367
368 STDMETHODIMP CControl::SetID(VARIANT varID, VARIANT *pvarUnk)
369 {
370         // \92¼\82¿\82ÉID\82ð\8a\84\82è\93\96\82Ä\82é
371         CComVariant tmp;
372         if (varID.vt != VT_EMPTY && varID.vt != VT_EMPTY && varID.vt != VT_EMPTY
373                 && SUCCEEDED(tmp.ChangeType(VT_I2, &varID))) {
374                 if (tmp.iVal > 0) {
375                         put_ID(tmp.iVal);
376                 }
377         }
378         GetThisInterface(pvarUnk);
379         return S_OK;
380 }
381
382 void CControl::GetThisInterface(VARIANT *pvarUnk)
383 {
384         // \82±\82Ì\83C\83\93\83^\81[\83t\83F\83C\83X\82ð\95Ô\82·
385         ::VariantInit(pvarUnk);
386         IUnknown* pUnk = NULL;
387         if (SUCCEEDED(QueryInterface(IID_IUnknown, (void**)&pUnk))) {
388                 pvarUnk->vt = VT_UNKNOWN;
389                 pvarUnk->punkVal = pUnk;
390         }
391 }
392
393 int CControl::GetID()
394 {
395         return m_nID;
396 }
397
398 STDMETHODIMP CControl::get_Style(long *pVal)
399 {
400         if (m_hWnd) {
401                 m_style = ::GetWindowLong(m_hWnd, GWL_STYLE);
402         }
403         *pVal = m_style;
404         return S_OK;
405 }
406
407 STDMETHODIMP CControl::put_Style(long newVal)
408 {
409         m_style = newVal;
410         if (m_hWnd) {
411                 ::SetWindowLong(m_hWnd, GWL_STYLE, m_style);
412         }
413         return S_OK;
414 }
415
416 STDMETHODIMP CControl::get_Exstyle(long *pVal)
417 {
418         if (m_hWnd) {
419                 m_exstyle = ::GetWindowLong(m_hWnd, GWL_EXSTYLE);
420         }
421         *pVal = m_exstyle;
422         return S_OK;
423 }
424
425 STDMETHODIMP CControl::put_Exstyle(long newVal)
426 {
427         m_exstyle = newVal;
428         if (m_hWnd) {
429                 ::SetWindowLong(m_hWnd, GWL_EXSTYLE, m_exstyle);
430         }
431         return S_OK;
432 }
433
434 STDMETHODIMP CControl::get_ClassName(BSTR *pVal)
435 {
436         CComBSTR tmp(m_classname);
437         *pVal = tmp.Detach();
438         return S_OK;
439 }
440
441 STDMETHODIMP CControl::Refresh()
442 {
443         if (!m_hParent || !m_hWnd) {
444                 return Error(IDS_ERR_DESTROYED);
445         }
446         ::SetWindowPos(
447                 m_hWnd,
448                 NULL,
449                 0, 0, 0, 0,
450                 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOCOPYBITS);
451         return S_OK;
452 }
453
454 STDMETHODIMP CControl::get_HWND(long *pVal)
455 {
456         *pVal = (long)m_hWnd;
457         return S_OK;
458 }
459
460 HRESULT CControl::ConvertVariantToString(VARIANT text, ATL::CString &retval)
461 {
462         CComVariant varText;
463         HRESULT hr = varText.ChangeType(VT_BSTR, &text);
464         if (FAILED(hr)) {
465                 return hr;
466         }
467
468         retval = varText.bstrVal;
469         return S_OK;
470 }
471
472 STDMETHODIMP CControl::AddString(VARIANT text, VARIANT* pRet)
473 {
474         ::VariantInit(pRet);
475
476         if (!m_hParent || !m_hWnd) {
477                 return Error(IDS_ERR_DESTROYED);
478         }
479
480         ATL::CString buf;
481         HRESULT hr = ConvertVariantToString(text, buf);
482         if (FAILED(hr)) {
483                 return hr;
484         }
485
486         CComVariant ret;
487         if (!lstrcmp(m_classname, _TEXT("COMBOBOX"))) {
488                 // \83R\83\93\83{\83{\83b\83N\83X\82É\95\8e\9a\97ñ\82ð\92Ç\89Á\82·\82é
489                 ret = (short)SendMessage(m_hWnd, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)buf);
490         }
491         else if (!lstrcmp(m_classname, _TEXT("LISTBOX"))) {
492                 // \98A\91z\94z\97ñ\83I\83u\83W\83F\83N\83g\82ð\8dì\90¬\82·\82é
493                 CComObject<CObjectMap>* pMap = NULL;
494                 if (FAILED(hr = CComObject<CObjectMap>::CreateInstance(&pMap))) {
495                         return hr;
496                 }
497                 IUnknown* pMapUnk = NULL;
498                 if (FAILED(hr = pMap->QueryInterface(&pMapUnk))) {
499                         return hr;
500                 }
501
502                 // \83\8a\83X\83g\83{\83b\83N\83X\82É\95\8e\9a\97ñ\82ð\92Ç\89Á\82·\82é
503                 int nIdx = SendMessage(m_hWnd, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR)buf);
504
505                 // \83\8a\83X\83g\83{\83b\83N\83X\82Ì\83A\83C\83e\83\80\82É\98A\91z\94z\97ñ\82ð\83o\83C\83\93\83h\82·\82é.
506                 ::SendMessage(m_hWnd, LB_SETITEMDATA, nIdx, (LPARAM)pMapUnk);
507                 ret = (short)nIdx;
508         }
509         else if (!lstrcmp(m_classname, WC_LISTVIEW)) {
510                 // \83\8a\83X\83g\83r\83\85\81[\82É\95\8e\9a\97ñ\82ð\92Ç\89Á\82·\82é
511                 int cnt = ListView_GetItemCount(m_hWnd);
512                 LVITEM item = {0};
513                 item.mask = LVIF_TEXT;
514                 item.pszText = buf.GetBuffer();
515                 item.iItem = cnt;
516                 int nIdx = ListView_InsertItem(m_hWnd, &item);
517
518                 // \83T\83u\83J\83\89\83\80\82Í\8bó\95\82ð\96\84\82ß\82é
519                 for (int i = 1; i < m_nColumnCount; i++) {
520                         ListView_SetItemText(m_hWnd, nIdx, i, _TEXT(""));
521                 }
522
523                 // \98A\91z\94z\97ñ\83I\83u\83W\83F\83N\83g\82ð\83o\83C\83\93\83h\82·\82é
524                 CComObject<CObjectMap>* pMap = NULL;
525                 if (FAILED(hr = CComObject<CObjectMap>::CreateInstance(&pMap))) {
526                         return hr;
527                 }
528
529                 IUnknown* pUnk = NULL;
530                 if (FAILED(hr = pMap->QueryInterface(IID_IUnknown, (void**)&pUnk))) {
531                         return hr;
532                 }
533
534                 LVITEM itm = { 0 };
535                 itm.iItem = nIdx;
536                 itm.mask = LVIF_PARAM;
537                 itm.lParam = (LPARAM)pUnk;
538                 ListView_SetItem(m_hWnd, &itm);
539                 ret = (short)nIdx;
540         }
541         else if (!lstrcmp(m_classname, WC_TREEVIEW)) {
542                 // \83c\83\8a\81[\83r\83\85\81[\82Ì\83\8b\81[\83g\82É\83A\83C\83e\83\80\82ð\8dì\90¬\82·\82é
543                 CComPtr<IUnknown> pUnk;
544                 HRESULT hr;
545                 if (FAILED(hr = CTreeItem::CreateTreeItem(m_hWnd, TVI_ROOT, buf, &pUnk))) {
546                         return hr;
547                 }
548                 if (pUnk != NULL) {
549                         ret = pUnk; // pUnk\82ÍVariant\91ã\93ü\8e\9e\82ÉAddRef\82³\82ê\82é\82Ì\82ÅDetach\82Í\95s\97v.
550                 }
551         }
552         else {
553                 // \82»\82ê\88È\8aO\82Í\83T\83|\81[\83g\8aO
554                 return Error(IDS_ERR_NOTSUPPORTCONTROL);
555         }
556         return ret.Detach(pRet);
557 }
558
559 STDMETHODIMP CControl::SetColumnText(VARIANT item, VARIANT col, VARIANT text)
560 {
561         if (!m_hParent || !m_hWnd) {
562                 return Error(IDS_ERR_DESTROYED);
563         }
564
565         int nIdx = -1;
566         int nCol = -1;
567         CComVariant varIdx, varCol;
568         if (SUCCEEDED(varIdx.ChangeType(VT_I2, &item))) {
569                 nIdx = varIdx.iVal;
570         }
571         if (SUCCEEDED(varCol.ChangeType(VT_I2, &col))) {
572                 nCol = varCol.iVal;
573         }
574         if (nIdx < 0 || nCol < 0) {
575                 // \8ds\81E\8c\85\82ª\8eæ\93¾\82Å\82«\82È\82©\82Á\82½\8fê\8d\87
576                 return DISP_E_TYPEMISMATCH;
577         }
578
579         ATL::CString buf;
580         HRESULT hr = ConvertVariantToString(text, buf);
581         if (FAILED(hr)) {
582                 return hr;
583         }
584
585         if (!lstrcmp(m_classname, WC_LISTVIEW)) {
586                 int mx = ListView_GetItemCount(m_hWnd);
587                 if (nIdx >= mx || nCol >= m_nColumnCount) {
588                         // \8ds\82Ü\82½\82Í\8c\85\82ª\83I\81[\83o\81[\82µ\82Ä\82¢\82é\8fê\8d\87
589                         return Error(IDS_ERR_RANDEOUT);
590                 }
591                 else {
592                         // \83\8a\83X\83g\83r\83\85\81[\82É\95\8e\9a\97ñ\82ð\92Ç\89Á\82·\82é
593                         ListView_SetItemText(m_hWnd, nIdx, nCol, buf.GetBuffer());
594                 }
595         }
596         else {
597                 // \82»\82ê\88È\8aO\82Í\83T\83|\81[\83g\8aO
598                 return Error(IDS_ERR_NOTSUPPORTCONTROL);
599         }
600         return S_OK;
601 }
602
603 STDMETHODIMP CControl::GetColumnText(VARIANT idx, VARIANT col, VARIANT *pText)
604 {
605         CComVariant ret;
606         if (!m_hParent || !m_hWnd) {
607                 return Error(IDS_ERR_DESTROYED);
608         }
609
610         int nIdx = -1;
611         int nCol = -1;
612         CComVariant varIdx, varCol;
613         if (SUCCEEDED(varIdx.ChangeType(VT_I2, &idx))) {
614                 nIdx = varIdx.iVal;
615         }
616         if (SUCCEEDED(varCol.ChangeType(VT_I2, &col))) {
617                 nCol = varCol.iVal;
618         }
619
620         if (nIdx < 0 || nCol < 0) {
621                 return DISP_E_BADINDEX;
622         }
623
624         if (!lstrcmp(m_classname, WC_LISTVIEW)) {
625                 // \83C\83\93\83f\83b\83N\83X\82ð\92²\8d¸
626                 int mx = ListView_GetItemCount(m_hWnd);
627                 if (nIdx >= mx || nCol >= m_nColumnCount) {
628                         return Error(IDS_ERR_RANDEOUT);
629                 }
630
631                 // \83\8a\83X\83g\83r\83\85\81[\82©\82ç\95\8e\9a\97ñ\82ð\8eæ\93¾\82·\82é
632                 ATL::CString buf;
633                 LPTSTR pBuf = buf.GetBufferSetLength(MAX_PATH);
634                 ListView_GetItemText(m_hWnd, nIdx, nCol, pBuf, MAX_PATH);
635                 ret = pBuf;
636         }
637         else {
638                 // \82»\82ê\88È\8aO\82Í\83T\83|\81[\83g\8aO
639                 return Error(IDS_ERR_NOTSUPPORTCONTROL);
640         }
641         return ret.Detach(pText);
642 }
643
644 STDMETHODIMP CControl::get_ItemObject(VARIANT idx, VARIANT *pVal)
645 {
646         ::VariantInit(pVal);
647         if (!m_hParent || !m_hWnd) {
648                 return Error(IDS_ERR_DESTROYED);
649         }
650
651         int nIdx = -1;
652         CComVariant varIdx;
653         if (SUCCEEDED(varIdx.ChangeType(VT_I2, &idx))) {
654                 nIdx = varIdx.iVal;
655         }
656
657         if (nIdx < 0) {
658                 return DISP_E_BADINDEX;
659         }
660
661         IUnknown* pUnk = NULL;
662         if (!lstrcmp(m_classname, _TEXT("LISTBOX"))) {
663                 // \83\8a\83X\83g\83{\83b\83N\83X\82©\82ç\98A\91z\94z\97ñ\83I\83u\83W\83F\83N\83g\82ð\8eæ\93¾\82·\82é
664                 int mx = ::SendMessage(m_hWnd, LB_GETCOUNT, 0, 0);
665                 if (nIdx >= mx) {
666                         return Error(IDS_ERR_RANDEOUT);
667                 }
668                 LRESULT data = ::SendMessage(m_hWnd, LB_GETITEMDATA, nIdx, 0);
669                 if (data != LB_ERR && data) {
670                         pUnk = (IUnknown*)data;
671                 }
672         }
673         else if (!lstrcmp(m_classname, WC_LISTVIEW)) {
674                 // \83\8a\83X\83g\83r\83\85\81[\82©\82ç\98A\91z\94z\97ñ\83I\83u\83W\83F\83N\83g\82ð\8eæ\93¾\82·\82é
675                 int mx = ListView_GetItemCount(m_hWnd);
676                 if (nIdx >= mx) {
677                         return Error(IDS_ERR_RANDEOUT);
678                 }
679
680                 LVITEM itm = {0};
681                 itm.mask = LVIF_PARAM;
682                 itm.iItem = nIdx;
683                 if (ListView_GetItem(m_hWnd, &itm)) {
684                         if (itm.lParam) {
685                                 pUnk = (IUnknown*)itm.lParam;
686                         }
687                 }
688         }
689         else {
690                 // \82»\82ê\88È\8aO\82Í\83T\83|\81[\83g\8aO
691                 return Error(IDS_ERR_NOTSUPPORTCONTROL);
692         }
693
694         if (pUnk) {
695                 CComVariant tmp(pUnk);
696                 return tmp.Detach(pVal);
697         }
698         return S_OK;
699 }
700
701 STDMETHODIMP CControl::DeleteAllItems()
702 {
703         if (!m_hParent || !m_hWnd) {
704                 return Error(IDS_ERR_DESTROYED);
705         }
706         // \83R\83\93\83g\83\8d\81[\83\8b\82Ì\93à\95\94\83A\83C\83e\83\80\82É\8aÖ\98A\95t\82¯\82ç\82ê\82Ä\82¢\82½\98A\91z\94z\97ñ\83I\83u\83W\83F\83N\83g\82ð\89ð\95ú\82·\82é
707         if (!lstrcmp(m_classname, _TEXT("LISTBOX"))) {
708                 // \83\8a\83X\83g\82Ì\89ð\95ú
709                 int mx = ::SendMessage(m_hWnd, CB_GETCOUNT, 0, 0);
710                 for (int i = 0; i < mx; i++) {
711                         LRESULT data = ::SendMessage(m_hWnd, LB_GETITEMDATA, i, 0);
712                         if (data != LB_ERR && data) {
713                                 ((IUnknown*)data)->Release();
714                         }
715                 }
716         }
717         else if (!lstrcmp(m_classname, WC_LISTVIEW)) {
718                 // \83\8a\83X\83g\83r\83\85\81[\82Ì\98A\91z\94z\97ñ\82Ì\89ð\95ú
719                 int mx = ListView_GetItemCount(m_hWnd);
720                 LVITEM itm = {0};
721                 for (int i = 0; i < mx; i++) {
722                         itm.mask = LVIF_PARAM;
723                         itm.iItem = i;
724                         if (ListView_GetItem(m_hWnd, &itm)) {
725                                 if (itm.lParam) {
726                                         ((IUnknown*)itm.lParam)->Release();
727                                 }
728                         }
729                 }
730         }
731         else if (!lstrcmp(m_classname, WC_TREEVIEW)) {
732                 // \83c\83\8a\81[\83r\83\85\81[\82Ì\98A\91z\94z\97ñ\82Ì\89ð\95ú
733                 HTREEITEM hItem = TreeView_GetRoot(m_hWnd);
734                 while (hItem) {
735                         HTREEITEM hNextItem = TreeView_GetNextSibling(m_hWnd, hItem);
736                         CTreeItem::DeleteTreeItemWithData(m_hWnd, hItem);
737                         hItem = hNextItem;
738                 }
739         }
740         // \98A\91z\94z\97ñ\82ð\82à\82½\82È\82¢\83R\83\93\83g\83\8d\81[\83\8b\82Ì\8f\89\8aú\89»
741         else if (!lstrcmp(m_classname, _TEXT("COMBOBOX"))) {
742                 // COMBOBOX
743                 int cnt = ::SendMessage(m_hWnd, CB_GETCOUNT, 0, 0);
744                 while (cnt > 0) {
745                         ::SendMessage(m_hWnd, CB_DELETESTRING, 0, 0);
746                         cnt--;
747                 }
748         }
749         else if (!lstrcmp(m_classname, _TEXT("EDIT"))) {
750                 // Edit\81B
751                 CComVariant dmy(L"");
752                 put_Text(dmy.bstrVal);
753         }
754         return S_OK;
755 }
756 STDMETHODIMP CControl::DeleteString(VARIANT idx, VARIANT *pRet)
757 {
758         ::VariantInit(pRet);
759
760         if (!m_hParent || !m_hWnd) {
761                 return Error(IDS_ERR_DESTROYED);
762         }
763
764         int nIdx = -1;
765         CComVariant varIdx;
766         if (SUCCEEDED(varIdx.ChangeType(VT_I2, &idx))) {
767                 nIdx = varIdx.iVal;
768         }
769         if (nIdx < 0) {
770                 return DISP_E_BADINDEX;
771         }
772
773         CComVariant ret;
774         if (!lstrcmp(m_classname, _TEXT("COMBOBOX"))) {
775                 // \83R\83\93\83{\83{\83b\83N\83X\82©\82ç\95\8e\9a\97ñ\82ð\8dí\8f\9c\82·\82é
776                 int mx = ::SendMessage(m_hWnd, CB_GETCOUNT, 0, 0);
777                 if (nIdx >= mx) {
778                         return Error(IDS_ERR_RANDEOUT);
779                 }
780                 int result = ::SendMessage(m_hWnd, CB_DELETESTRING, nIdx, 0);
781                 ret = (bool)(result != LB_ERR);
782         }
783         else if (!lstrcmp(m_classname, _TEXT("LISTBOX"))) {
784                 // \83\8a\83X\83g\83{\83b\83N\83X\82©\82ç\95\8e\9a\97ñ\82ð\8dí\8f\9c\82·\82é
785                 int mx = ::SendMessage(m_hWnd, LB_GETCOUNT, 0, 0);
786                 if (nIdx >= mx) {
787                         return Error(IDS_ERR_RANDEOUT);
788                 }
789
790                 // \98A\91z\94z\97ñ\83I\83u\83W\83F\83N\83g\82ð\94j\8aü\82·\82é
791                 LRESULT data = ::SendMessage(m_hWnd, LB_GETITEMDATA, nIdx, 0);
792                 if (data != LB_ERR && data) {
793                         ((IUnknown*)data)->Release();
794                 }
795
796                 // \8dí\8f\9c
797                 int result = ::SendMessage(m_hWnd, LB_DELETESTRING, nIdx, 0);
798                 ret = (bool)(result != LB_ERR);
799         }
800         else if (!lstrcmp(m_classname, WC_LISTVIEW)) {
801                 // \83\8a\83X\83g\83r\83\85\81[\82©\82ç\95\8e\9a\97ñ\82ð\8dí\8f\9c\82·\82é
802                 int mx = ListView_GetItemCount(m_hWnd);
803                 if (nIdx >= mx) {
804                         return Error(IDS_ERR_RANDEOUT);
805                 }
806
807                 // \98A\91z\94z\97ñ\83I\83u\83W\83F\83N\83g\82ð\94j\8aü\82·\82é
808                 LVITEM itm = {0};
809                 itm.mask = LVIF_PARAM;
810                 itm.iItem = nIdx;
811                 if (ListView_GetItem(m_hWnd, &itm)) {
812                         if (itm.lParam) {
813                                 ((IUnknown*)itm.lParam)->Release();
814                         }
815                 }
816
817                 // \8dí\8f\9c
818                 ret = ListView_DeleteItem(m_hWnd, nIdx) ? true : false;
819         }
820         else {
821                 // \82»\82ê\88È\8aO\82Í\83T\83|\81[\83g\8aO
822                 return Error(IDS_ERR_NOTSUPPORTCONTROL);
823         }
824
825         return ret.Detach(pRet);
826 }
827
828 STDMETHODIMP CControl::GetCount(VARIANT *pRet)
829 {
830         ::VariantInit(pRet);
831
832         if (!m_hParent || !m_hWnd) {
833                 return Error(IDS_ERR_DESTROYED);
834         }
835
836         CComVariant ret;
837         if (!lstrcmp(m_classname, _TEXT("COMBOBOX"))) {
838                 // \83\8a\83X\83g\83{\83b\83N\83X\82Ì\83J\83E\83\93\83g
839                 int mx = ::SendMessage(m_hWnd, CB_GETCOUNT, 0, 0);
840                 if (mx == LB_ERR) {
841                         mx = 0;
842                 }
843                 ret = (short)mx;
844         }
845         else if (!lstrcmp(m_classname, _TEXT("LISTBOX"))) {
846                 // \83\8a\83X\83g\83{\83b\83N\83X\82Ì\83J\83E\83\93\83g
847                 int mx = ::SendMessage(m_hWnd, LB_GETCOUNT, 0, 0);
848                 if (mx == LB_ERR) {
849                         mx = 0;
850                 }
851                 ret = (short)mx;
852         }
853         else if (!lstrcmp(m_classname, WC_LISTVIEW)) {
854                 // \83\8a\83X\83g\83r\83\85\81[\82Ì\83J\83E\83\93\83g
855                 ret = (short)ListView_GetItemCount(m_hWnd);
856         }
857         else {
858                 // \82»\82ê\88È\8aO\82Í\83T\83|\81[\83g\8aO
859                 return Error(IDS_ERR_NOTSUPPORTCONTROL);
860         }
861         return ret.Detach(pRet);
862 }
863
864 STDMETHODIMP CControl::get_CurrentSelectedItem(VARIANT *pVal)
865 {
866         ::VariantInit(pVal);
867
868         if (!m_hParent || !m_hWnd) {
869                 return Error(IDS_ERR_DESTROYED);
870         }
871
872         CComVariant ret;
873         if (!lstrcmp(m_classname, _TEXT("COMBOBOX"))) {
874                 // \83R\83\93\83{\83{\83b\83N\83X\82Ì\8c»\8dÝ\82Ì\91I\91ð\82ð\95Ô\82·
875                 ret = (long)::SendMessage(m_hWnd, CB_GETCURSEL, 0, 0);
876         }
877         else if (!lstrcmp(m_classname, _TEXT("LISTBOX"))) {
878                 // \83\8a\83X\83g\83{\83b\83N\83X\82Ì\8c»\8dÝ\82Ì\91I\91ð\83A\83C\83e\83\80\82ð\95Ô\82·
879                 if (!(m_style & LBS_MULTIPLESEL)) {
880                         // \83V\83\93\83O\83\8b\83Z\83\8c\83N\83g\82Ì\8fê\8d\87
881                         ret = (long)::SendMessage(m_hWnd, LB_GETCURSEL, 0, 0);
882                 }
883                 else {
884                         // \83}\83\8b\83`\83Z\83\8c\83N\83g\82Ì\8fê\8d\87\82Í\8dÅ\8f\89\82Ì\91I\91ð\83A\83C\83e\83\80\82ð\95Ô\82·
885                         ret = (long)-1;
886                         int mx = ::SendMessage(m_hWnd, LB_GETCOUNT, 0, 0);
887                         if (mx > 0) {
888                                 std::vector<long> buf(mx + 1);
889                                 long* pBuf = &buf[0];
890                                 int cnt = ::SendMessage(m_hWnd, LB_GETSELITEMS, mx, (LPARAM)pBuf);
891                                 if (cnt != LB_ERR && cnt > 0) {
892                                         ret = buf[0];
893                                 }
894                         }
895                 }
896         }
897         else if (!lstrcmp(m_classname, WC_LISTVIEW)) {
898                 // \83\8a\83X\83g\83r\83\85\81[\82Ì\8dÅ\8f\89\82Ì\91I\91ð\83A\83C\83e\83\80\82ð\92T\82·
899                 ret = (long)ListView_GetNextItem(m_hWnd, -1, LVNI_SELECTED);
900         }
901         else if (!lstrcmp(m_classname, WC_TREEVIEW)) {
902                 // \83c\83\8a\81[\83r\83\85\81[\82Ì\8ew\92è\83A\83C\83e\83\80\82Ì\91®\90«\82ð\92²\82×\82é
903                 HTREEITEM hItem = TreeView_GetSelection(m_hWnd);
904                 if (hItem) {
905                         CComObject<CTreeItem>* pItem = NULL;
906                         HRESULT hr;
907                         if (FAILED(hr = CComObject<CTreeItem>::CreateInstance(&pItem))) {
908                                 return hr;
909                         }
910
911                         IUnknown* pUnk = NULL;
912                         if (FAILED(hr = pItem->QueryInterface(&pUnk))) {
913                                 delete pItem;
914                                 return hr;
915                         }
916
917                         //FIXME: \95s\97v\82Ì\82Í\82¸ pItem->AddRef();
918                         pItem->SetParam(m_hWnd, hItem);
919                         ret = pUnk;
920                 }
921         }
922         else {
923                 // \82»\82ê\88È\8aO\82Í\83T\83|\81[\83g\8aO
924                 return Error(IDS_ERR_NOTSUPPORTCONTROL);
925         }
926         return ret.Detach(pVal);
927 }
928
929 STDMETHODIMP CControl::put_CurrentSelectedItem(VARIANT newVal)
930 {
931         if (!m_hParent || !m_hWnd) {
932                 return Error(IDS_ERR_DESTROYED);
933         }
934
935         long nIdx = -1;
936         CComVariant varIdx;
937         if (SUCCEEDED(varIdx.ChangeType(VT_I4, &newVal))) {
938                 nIdx = varIdx.lVal;
939         }
940
941         if (!lstrcmp(m_classname, _TEXT("COMBOBOX"))) {
942                 // \83R\83\93\83{\83{\83b\83N\83X\82ð\91I\91ð\82ð\8ew\92è\82·\82é
943                 ::SendMessage(m_hWnd, CB_SETCURSEL, nIdx, 0);
944         }
945         else if (!lstrcmp(m_classname, _TEXT("LISTBOX"))) {
946                 // \83\8a\83X\83g\83{\83b\83N\83X\82Ì\91I\91ð
947                 if (!(m_style & LBS_MULTIPLESEL)) {
948                         // \83V\83\93\83O\83\8b\83Z\83\8c\83N\83g\82Ì\8fê\8d\87
949                         ::SendMessage(m_hWnd, LB_SETCURSEL, nIdx, 0);
950                 }
951                 else {
952                         // \83}\83\8b\83`\83Z\83\8c\83N\83g\82Ì\8fê\8d\87
953                         int mx = ::SendMessage(m_hWnd, LB_GETCOUNT, 0, 0);
954                         for (int i = 0; i < mx; i++) {
955                                 ::SendMessage(m_hWnd, LB_SETSEL, FALSE, i);
956                         }
957                         if (nIdx >= 0 && nIdx < mx) {
958                                 ::SendMessage(m_hWnd, LB_SETSEL, TRUE, nIdx);
959                         }
960                 }
961         }
962         else if (!lstrcmp(m_classname, WC_LISTVIEW)) {
963                 // \83\8a\83X\83g\83r\83\85\81[\82Ì\91I\91ð
964                 int mx = ListView_GetItemCount(m_hWnd);
965                 ListView_SetItemState(m_hWnd, -1, LVIS_SELECTED, 0);
966                 if (nIdx >= 0 && nIdx < mx) {
967                         ListView_SetItemState(m_hWnd, nIdx, LVIS_SELECTED, LVIS_SELECTED);
968                 }
969         }
970         else {
971                 // \82»\82ê\88È\8aO\82Í\83T\83|\81[\83g\8aO
972                 return Error(IDS_ERR_NOTSUPPORTCONTROL);
973         }
974         return S_OK;
975 }
976
977 STDMETHODIMP CControl::get__NewEnum(IUnknown **pVal)
978 {
979         *pVal = NULL;
980
981         if (!m_hParent || !m_hWnd) {
982                 return Error(IDS_ERR_DESTROYED);
983         }
984
985         std::vector<VARIANT> varArray;
986         int mx = 0;
987
988         if (!lstrcmp(m_classname, _TEXT("COMBOBOX"))) {
989                 // \83R\83\93\83{\83{\83b\83N\83X\82Ì\8c»\8dÝ\82Ì\91I\91ð\82ð\95Ô\82·
990                 int nIdx = ::SendMessage(m_hWnd, CB_GETCURSEL, 0, 0);
991                 mx = 1;
992                 varArray.resize(1);
993                 ::VariantInit(&varArray[0]);
994                 varArray[0].vt = VT_I2;
995                 varArray[0].iVal = nIdx;
996         }
997         else if (!lstrcmp(m_classname, _TEXT("LISTBOX"))) {
998                 // \83\8a\83X\83g\83{\83b\83N\83X\82Ì\8c»\8dÝ\82Ì\91I\91ð\83A\83C\83e\83\80\82ð\95Ô\82·
999                 if (!(m_style & LBS_MULTIPLESEL)) {
1000                         // \83V\83\93\83O\83\8b\83Z\83\8c\83N\83g\82Ì\8fê\8d\87
1001                         int nIdx = ::SendMessage(m_hWnd, LB_GETCURSEL, 0, 0);
1002                         mx = 1;
1003                         varArray.resize(1);
1004                         ::VariantInit(&varArray[0]);
1005                         varArray[0].vt = VT_I2;
1006                         varArray[0].iVal = nIdx;
1007                 }
1008                 else {
1009                         // \83}\83\8b\83`\83Z\83\8c\83N\83g\82Ì\8fê\8d\87\82Í\8dÅ\8f\89\82Ì\91I\91ð\83A\83C\83e\83\80\82ð\95Ô\82·
1010                         int sz = ::SendMessage(m_hWnd, LB_GETCOUNT, 0, 0);
1011                         std::vector<long> buf(sz + 1);
1012                         long* pBuf = &buf[0];
1013                         mx = ::SendMessage(m_hWnd, LB_GETSELITEMS, sz, (LPARAM)pBuf);
1014                         if (mx != LB_ERR) {
1015                                 // \91I\91ð\82ª\95Ô\82³\82ê\82½\8fê\8d\87
1016                                 varArray.resize(mx + 1);
1017                                 for (int i = 0; i < mx; i++) {
1018                                         ::VariantInit(&varArray[i]);
1019                                         varArray[i].vt = VT_I2;
1020                                         varArray[i].iVal = (short)pBuf[i];
1021                                 }
1022                         }
1023                 }
1024         }
1025         else if (!lstrcmp(m_classname, WC_LISTVIEW)) {
1026                 // \83\8a\83X\83g\83r\83\85\81[\82Ì\8dÅ\8f\89\82Ì\91I\91ð\83A\83C\83e\83\80\82ð\92T\82·
1027                 mx = ListView_GetSelectedCount(m_hWnd);
1028                 varArray.resize(mx + 1);
1029                 int nIdx = -1;
1030                 int i = 0;
1031                 while ((nIdx = ListView_GetNextItem(m_hWnd, nIdx, LVNI_SELECTED)) != -1
1032                         && i < mx) {
1033                         ::VariantInit(&varArray[i]);
1034                         varArray[i].vt = VT_I2;
1035                         varArray[i].iVal = (short)nIdx;
1036                         i++;
1037                 }
1038         }
1039         else {
1040                 // \82»\82ê\88È\8aO\82Í\83T\83|\81[\83g\8aO
1041                 return Error(IDS_ERR_NOTSUPPORTCONTROL);
1042         }
1043
1044         // \97ñ\8b\93\83C\83\93\83^\81[\83t\83F\83C\83X\82Ì\90\90¬
1045         CComObject<CComEnumVARIANT>* pCol = NULL;
1046         HRESULT hr;
1047         if (FAILED(hr = CComObject<CComEnumVARIANT>::CreateInstance(&pCol))) {
1048                 return hr;
1049         }
1050         pCol->Init(&varArray[0], &varArray[mx], pCol, AtlFlagCopy);
1051
1052         return pCol->QueryInterface(pVal);
1053 }
1054
1055
1056 STDMETHODIMP CControl::get_ItemSelectState(VARIANT idx, VARIANT *pVal)
1057 {
1058         ::VariantInit(pVal);
1059         CComVariant ret;
1060
1061         if (!m_hParent || !m_hWnd) {
1062                 return Error(IDS_ERR_DESTROYED);
1063         }
1064
1065         int nIdx = -1;
1066         CComVariant varIdx;
1067         if (SUCCEEDED(varIdx.ChangeType(VT_I2, &idx))) {
1068                 nIdx = idx.iVal;
1069         }
1070
1071         if (!lstrcmp(m_classname, _TEXT("COMBOBOX"))) {
1072                 // \83R\83\93\83{\83{\83b\83N\83X\82Ì\8c»\8dÝ\82Ì\91I\91ð\82ð\95Ô\82·
1073                 int nSel = ::SendMessage(m_hWnd, CB_GETCURSEL, 0, 0);
1074                 // \8ew\92è\82µ\82½\83A\83C\83e\83\80\82Æ\91I\91ð\82ª\88ê\92v\82µ\82Ä\82¢\82ê\82Îtrue
1075                 ret = (bool)((nSel == nIdx) ? true : false);
1076         }
1077         else if (!lstrcmp(m_classname, _TEXT("LISTBOX"))) {
1078                 // \83\8a\83X\83g\83{\83b\83N\83X\82Ì\8c»\8dÝ\82Ì\91I\91ð\83A\83C\83e\83\80\82ð\95Ô\82·
1079                 if (!(m_style & LBS_MULTIPLESEL)) {
1080                         // \83V\83\93\83O\83\8b\83Z\83\8c\83N\83g\82Ì\8fê\8d\87
1081                         int nSel = ::SendMessage(m_hWnd, LB_GETCURSEL, 0, 0);
1082                         // \8ew\92è\82µ\82½\83A\83C\83e\83\80\82Æ\91I\91ð\82ª\88ê\92v\82µ\82Ä\82¢\82ê\82Îtrue
1083                         ret = (nSel == nIdx);
1084                 }
1085                 else {
1086                         // \83}\83\8b\83`\83Z\83\8c\83N\83g\82Ì\8fê\8d\87
1087                         ret = ::SendMessage(m_hWnd, LB_GETSEL, nIdx, 0) > 0;
1088                 }
1089         }
1090         else if (!lstrcmp(m_classname, WC_LISTVIEW)) {
1091                 // \83\8a\83X\83g\83r\83\85\81[\82Ì\8ew\92è\83A\83C\83e\83\80\82Ì\91®\90«\82ð\92²\82×\82é
1092                 int mx = ListView_GetItemCount(m_hWnd);
1093                 if (nIdx >= 0 && nIdx < mx) {
1094                         UINT state = ListView_GetItemState(m_hWnd, nIdx, LVNI_SELECTED);
1095                         ret = (state & LVNI_SELECTED) != 0;
1096                 }
1097         }
1098         else {
1099                 // \82»\82ê\88È\8aO\82Í\83T\83|\81[\83g\8aO
1100                 return Error(IDS_ERR_NOTSUPPORTCONTROL);
1101         }
1102         ret.Detach(pVal);
1103         return S_OK;
1104 }
1105
1106 STDMETHODIMP CControl::put_ItemSelectState(VARIANT idx, VARIANT newVal)
1107 {
1108         if (!m_hParent || !m_hWnd) {
1109                 return Error(IDS_ERR_DESTROYED);
1110         }
1111
1112         int nIdx = -1;
1113         CComVariant varIdx;
1114         if (SUCCEEDED(varIdx.ChangeType(VT_I2, &idx))) {
1115                 nIdx = idx.iVal;
1116         }
1117
1118         bool bSelected = false;
1119         CComVariant varSelected;
1120         if (SUCCEEDED(varSelected.ChangeType(VT_I2, &newVal))) {
1121                 bSelected = newVal.iVal != 0;
1122         }
1123
1124         if (!lstrcmp(m_classname, _TEXT("COMBOBOX"))) {
1125                 // \83R\83\93\83{\83{\83b\83N\83X\82Ì\8c»\8dÝ\82Ì\91I\91ð\82ð\95Ï\8dX\82·\82é
1126                 ::SendMessage(m_hWnd, CB_SETCURSEL, bSelected ? nIdx : -1, 0);
1127         }
1128         else if (!lstrcmp(m_classname, _TEXT("LISTBOX"))) {
1129                 // \83\8a\83X\83g\83{\83b\83N\83X\82Ì\8c»\8dÝ\82Ì\91I\91ð\83A\83C\83e\83\80\82ð\95Ô\82·
1130                 if (!(m_style & LBS_MULTIPLESEL)) {
1131                         // \83V\83\93\83O\83\8b\83Z\83\8c\83N\83g\82Ì\8fê\8d\87
1132                         ::SendMessage(m_hWnd, LB_SETCURSEL, bSelected ? nIdx : -1, 0);
1133                 }
1134                 else {
1135                         // \83}\83\8b\83`\83Z\83\8c\83N\83g
1136                         ::SendMessage(m_hWnd, LB_SETSEL, nIdx, bSelected);
1137                 }
1138         }
1139         else if (!lstrcmp(m_classname, WC_LISTVIEW)) {
1140                 // \83\8a\83X\83g\83r\83\85\81[\82Ì\8ew\92è\83A\83C\83e\83\80\82Ì\91®\90«\82ð\92²\82×\82é
1141                 int mx = ListView_GetItemCount(m_hWnd);
1142                 if (nIdx >= 0 && nIdx < mx) {
1143                         ListView_SetItemState(m_hWnd, nIdx, bSelected ? LVNI_SELECTED : 0, LVNI_SELECTED);
1144                 }
1145         }
1146         else {
1147                 // \82»\82ê\88È\8aO\82Í\83T\83|\81[\83g\8aO
1148                 return Error(IDS_ERR_NOTSUPPORTCONTROL);
1149         }
1150         return S_OK;
1151 }
1152
1153 STDMETHODIMP CControl::get_SelectedCount(short *pVal)
1154 {
1155         *pVal = 0;
1156         if (!m_hParent || !m_hWnd) {
1157                 return Error(IDS_ERR_DESTROYED);
1158         }
1159
1160         if (!lstrcmp(m_classname, _TEXT("COMBOBOX"))) {
1161                 // \83\8a\83X\83g\83{\83b\83N\83X\82Ì\83J\83E\83\93\83g
1162                 int nIdx = ::SendMessage(m_hWnd, CB_GETCURSEL, 0, 0);
1163                 *pVal = (short)(nIdx >= 0 ? 1 : 0);
1164         }
1165         else if (!lstrcmp(m_classname, _TEXT("LISTBOX"))) {
1166                 // \83\8a\83X\83g\83{\83b\83N\83X\82Ì\83J\83E\83\93\83g
1167                 if (!(m_style & LBS_MULTIPLESEL)) {
1168                         int nIdx = ::SendMessage(m_hWnd, LB_GETCURSEL, 0, 0);
1169                         *pVal = (short)(nIdx >= 0 ? 1 : 0);
1170                 }
1171                 else {
1172                         // \83}\83\8b\83`\83Z\83\8c\83N\83g
1173                         *pVal = (short)::SendMessage(m_hWnd, LB_GETSELCOUNT, 0, 0);
1174                 }
1175         }
1176         else if (!lstrcmp(m_classname, WC_LISTVIEW)) {
1177                 // \83\8a\83X\83g\83r\83\85\81[\82Ì\83J\83E\83\93\83g
1178                 *pVal = (short)ListView_GetSelectedCount(m_hWnd);
1179         }
1180         else {
1181                 // \82»\82ê\88È\8aO\82Í\83T\83|\81[\83g\8aO
1182                 return Error(IDS_ERR_NOTSUPPORTCONTROL);
1183         }
1184         return S_OK;
1185 }
1186
1187 STDMETHODIMP CControl::get_TreeRoot(VARIANT *pVal)
1188 {
1189         if (!m_hParent || !m_hWnd) {
1190                 return Error(IDS_ERR_DESTROYED);
1191         }
1192         ::VariantInit(pVal);
1193         if (!lstrcmp(m_classname, WC_TREEVIEW)) {
1194                 CComObject<CTreeItem>* pItem = NULL;
1195                 HRESULT hr;
1196                 if (FAILED(hr = CComObject<CTreeItem>::CreateInstance(&pItem))) {
1197                         return hr;
1198                 }
1199
1200                 HTREEITEM hItem = TreeView_GetRoot(m_hWnd);
1201                 pItem->SetParam(m_hWnd, hItem);
1202
1203                 IUnknown* pUnk = NULL;
1204                 if (FAILED(hr = pItem->QueryInterface(IID_IUnknown, (void**)&pUnk))) {
1205                         delete pItem;
1206                         return hr;
1207                 }
1208                 pVal->vt = VT_UNKNOWN;
1209                 pVal->punkVal = pUnk;
1210         }
1211         return S_OK;
1212 }
1213
1214 void CControl::ListSort(int column)
1215 {
1216         if (!m_hParent || !m_hWnd) {
1217                 return;
1218         }
1219
1220         // \82¨\82È\82\83J\83\89\83\80\82ð\83\\81[\83g\82µ\82½\8fê\8d\87\82Í\8bt\8f\87\82Æ\82·\82é
1221         if (m_dLastSortColumn == column) {
1222                 m_bSortReverse = !m_bSortReverse;
1223         }
1224         else {
1225                 m_bSortReverse = false;
1226         }
1227
1228         m_dLastSortColumn = column;
1229         m_typCompare = VT_EMPTY;
1230         // \83\\81[\83g\82ð\8cÄ\82Ñ\8fo\82·
1231         ListView_SortItems(m_hWnd, CompareFunc, (LPARAM)this);
1232 }
1233
1234 int CControl::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
1235 {
1236         if (!lParam1 || !lParam2) {
1237                 // \83C\83\8c\83M\83\85\83\89\81[\81B\83f\81[\83^\81[\82ª\82È\82¢\82Ì\82Å\94ä\8ar\95s\89Â\94\
1238                 return 0;
1239         }
1240
1241         CControl* me = (CControl*)lParamSort;
1242
1243         IObjectMap* pMap1 = (IObjectMap*)lParam1;
1244         IObjectMap* pMap2 = (IObjectMap*)lParam2;
1245
1246         TCHAR mes[16];
1247         wsprintf(mes, _TEXT("SORT%d"), me->m_dLastSortColumn);
1248         CComVariant key(mes);
1249
1250         CComVariant val1, val2;
1251         if (!me->m_bSortReverse) {
1252                 pMap1->get_Value(key, &val1);
1253                 pMap2->get_Value(key, &val2);
1254         }
1255         else {
1256                 pMap1->get_Value(key, &val2);
1257                 pMap2->get_Value(key, &val1);
1258         }
1259
1260         if (me->m_typCompare == VT_EMPTY) {
1261                 // \82Ü\82¾\94ä\8ar\82ð\8aJ\8en\82µ\82Ä\82¢\82È\82¢\82È\82ç\94ä\8ar\83^\83C\83v\82ð\8c\88\92è\82·\82é
1262                 me->m_typCompare = val1.vt;
1263                 if (val1.vt != val2.vt) {
1264                         me->m_typCompare = VT_BSTR;
1265                 }
1266         }
1267
1268         int ret = 0;
1269         switch (me->m_typCompare) {
1270                 case VT_UI1:
1271                 {
1272                         val1.ChangeType(VT_UI1);
1273                         val2.ChangeType(VT_UI1);
1274                         ret = val1.bVal - val2.bVal;
1275                         break;
1276                 }
1277                 case VT_I2:
1278                 {
1279                         val1.ChangeType(VT_I2);
1280                         val2.ChangeType(VT_I2);
1281                         ret = val1.iVal - val2.iVal;
1282                         break;
1283                 }
1284                 case VT_I4:
1285                 {
1286                         val1.ChangeType(VT_I4);
1287                         val2.ChangeType(VT_I4);
1288                         ret = val1.lVal - val2.lVal;
1289                         break;
1290                 }
1291                 case VT_R4:
1292                 {
1293                         val1.ChangeType(VT_R4);
1294                         val2.ChangeType(VT_R4);
1295                         ret = val1.fltVal > val2.fltVal;
1296                         break;
1297                 }
1298                 case VT_R8:
1299                 {
1300                         val1.ChangeType(VT_R8);
1301                         val2.ChangeType(VT_R8);
1302                         ret = val1.dblVal > val2.dblVal;
1303                         break;
1304                 }
1305                 case VT_CY:
1306                 {
1307                         val1.ChangeType(VT_CY);
1308                         val2.ChangeType(VT_CY);
1309                         ret = (int)(val1.cyVal.int64 - val2.cyVal.int64); //FIXME: \82æ\82ë\82µ\82­\82È\82¢\81B\8c¸\8eZ\8c\8b\89Ê\82ª\8c\85\82 \82Ó\82ê\82µ\82½\8fê\8d\87\81A\94ä\8ar\8aÖ\90\94\82ª\94j\92]\82·\82é\81B\82È\82¨\82³\82Ë\82Î\81B
1310                         break;
1311                 }
1312                 case VT_DATE:
1313                 {
1314                         val1.ChangeType(VT_DATE);
1315                         val2.ChangeType(VT_DATE);
1316                         ret = val1.date > val2.date;
1317                         break;
1318                 }
1319                 case VT_BSTR:
1320                 {
1321                         if (SUCCEEDED(val1.ChangeType(VT_BSTR)) &&
1322                                 SUCCEEDED(val2.ChangeType(VT_BSTR))) {
1323                                 ret = lstrcmpW(val1.bstrVal, val2.bstrVal);
1324                         }
1325                         break;
1326                 }
1327                 default:
1328                 break;
1329         }
1330         return ret;
1331 }
1332
1333 void CControl::OnRClick()
1334 {
1335         if (!m_hParent || !m_hWnd) {
1336                 return;
1337         }
1338
1339         if (!lstrcmp(m_classname, WC_TREEVIEW)) {
1340                 // \83c\83\8a\81[\83r\83\85\81[\82Å\82 \82ê\82Î\83h\83\8d\83b\83v\83n\83C\83\89\83C\83g\82ð\91I\91ð\82É\82·\82é
1341                 HTREEITEM hItem = TreeView_GetDropHilight(m_hWnd);
1342                 if (hItem) {
1343                         TreeView_SelectItem(m_hWnd, hItem);
1344                 }
1345         }
1346 }
1347
1348
1349 STDMETHODIMP CControl::get_ItemCheckState(VARIANT idx, BOOL *pVal)
1350 {
1351         if (!m_hParent || !m_hWnd) {
1352                 return Error(IDS_ERR_DESTROYED);
1353         }
1354
1355         if (lstrcmp(m_classname, WC_LISTVIEW)) {
1356                 // \83\8a\83X\83g\83r\83\85\81[\88È\8aO\82Í\83T\83|\81[\83g\8aO
1357                 return Error(IDS_ERR_NOTSUPPORTCONTROL);
1358         }
1359
1360         CComVariant varIdx;
1361         HRESULT hr = varIdx.ChangeType(VT_I2, &idx);
1362         if (FAILED(hr)) {
1363                 return hr;
1364         }
1365
1366         *pVal = VB_FALSE;
1367         if (m_afterstyle & LVS_EX_CHECKBOXES) {
1368                 *pVal = ListView_GetCheckState(m_hWnd, varIdx.iVal) ? VB_TRUE : VB_FALSE;
1369         }
1370         return S_OK;
1371 }
1372
1373 STDMETHODIMP CControl::put_ItemCheckState(VARIANT idx, BOOL newVal)
1374 {
1375         if (!m_hParent || !m_hWnd) {
1376                 return Error(IDS_ERR_DESTROYED);
1377         }
1378
1379         if (lstrcmp(m_classname, WC_LISTVIEW)) {
1380                 // \83\8a\83X\83g\83r\83\85\81[\88È\8aO\82Í\83T\83|\81[\83g\8aO
1381                 return Error(IDS_ERR_NOTSUPPORTCONTROL);
1382         }
1383
1384         CComVariant varIdx;
1385         HRESULT hr = varIdx.ChangeType(VT_I2, &idx);
1386         if (FAILED(hr)) {
1387                 return hr;
1388         }
1389
1390         if (m_afterstyle & LVS_EX_CHECKBOXES) {
1391                 ListView_SetCheckState(m_hWnd, varIdx.iVal, newVal);
1392         }
1393         return S_OK;
1394 }
1395
1396 STDMETHODIMP CControl::DeleteSelectedItem()
1397 {
1398         if (!m_hParent || !m_hWnd) {
1399                 return Error(IDS_ERR_DESTROYED);
1400         }
1401
1402         if (!lstrcmp(m_classname, _TEXT("LISTBOX"))) {
1403                 // \83\8a\83X\83g\83{\83b\83N\83X\82Ì\91I\91ð\8dí\8f\9c
1404                 CComVariant varRet, dmy;
1405                 while (SUCCEEDED(get_CurrentSelectedItem(&varRet)) && varRet.vt != VT_EMPTY) {
1406                         varRet.ChangeType(VT_I4);
1407                         if (varRet.lVal < 0) {
1408                                 break;
1409                         }
1410                         DeleteString(varRet, &dmy);
1411                 }
1412         }
1413         else if (!lstrcmp(m_classname, WC_LISTVIEW)) {
1414                 // \83\8a\83X\83g\83r\83\85\81[\82Ì\8dí\8f\9c
1415                 int nIdx = -1;
1416                 while ((nIdx = ListView_GetNextItem(m_hWnd, nIdx, LVNI_SELECTED)) != -1) {
1417                         CComVariant varIdx((long)nIdx), dmy;
1418                         DeleteString(varIdx, &dmy);
1419                         nIdx = -1;
1420                 }
1421         }
1422         else {
1423                 // \82»\82ê\88È\8aO\82Í\83T\83|\81[\83g\8aO
1424                 return Error(IDS_ERR_NOTSUPPORTCONTROL);
1425         }
1426         return S_OK;
1427 }
1428
1429 STDMETHODIMP CControl::get_ItemText(VARIANT idx, BSTR *pVal)
1430 {
1431         if (!m_hParent || !m_hWnd) {
1432                 return Error(IDS_ERR_DESTROYED);
1433         }
1434
1435         int nIdx = -1;
1436         CComVariant varIdx;
1437         if (SUCCEEDED(varIdx.ChangeType(VT_I2, &idx))) {
1438                 nIdx = varIdx.iVal;
1439         }
1440
1441         if (nIdx < 0) {
1442                 return DISP_E_TYPEMISMATCH;
1443         }
1444
1445         CComBSTR ret;
1446         if (!lstrcmp(m_classname, _TEXT("COMBOBOX"))) {
1447                 // \83R\83\93\83z\83{\83b\83N\83X\82©\82ç\95\8e\9a\97ñ\82ð\8eæ\93¾\82·\82é
1448                 int siz = ::SendMessage(m_hWnd, CB_GETLBTEXTLEN, nIdx, 0);
1449                 if (siz > 0) {
1450                         ATL::CString tmp;
1451                         LPTSTR p = tmp.GetBufferSetLength(siz + 1);
1452                         if (::SendMessage(m_hWnd, CB_GETLBTEXT, nIdx, (LPARAM)p) > 0) {
1453                                 ret = p;
1454                         }
1455                 }
1456         }
1457         else if (!lstrcmp(m_classname, _TEXT("LISTBOX"))) {
1458                 // \83\8a\83X\83g\82©\82ç\95\8e\9a\97ñ\82ð\8eæ\93¾\82·\82é
1459                 int siz = ::SendMessage(m_hWnd, LB_GETTEXTLEN, nIdx, 0);
1460                 if (siz > 0) {
1461                         ATL::CString tmp;
1462                         LPTSTR p = tmp.GetBufferSetLength(siz + 1);
1463                         if (::SendMessage(m_hWnd, LB_GETTEXT, nIdx, (LPARAM)p) > 0) {
1464                                 ret = p;
1465                         }
1466                 }
1467         }
1468         else if (!lstrcmp(m_classname, WC_LISTVIEW)) {
1469                 CComVariant arg, text;
1470                 arg = (long)0;
1471                 HRESULT hr;
1472                 if (SUCCEEDED(GetColumnText(idx, arg, &text))) {
1473                         if (SUCCEEDED(text.ChangeType(VT_BSTR))) {
1474                                 ret = text.bstrVal;
1475                         }
1476                 }
1477         }
1478         else {
1479                 // \82»\82ê\88È\8aO\82Í\83T\83|\81[\83g\8aO
1480                 return Error(IDS_ERR_NOTSUPPORTCONTROL);
1481         }
1482         *pVal = ret.Detach();
1483         return S_OK;
1484 }
1485
1486 STDMETHODIMP CControl::put_ItemText(VARIANT idx, BSTR newVal)
1487 {
1488         if (!m_hParent || !m_hWnd) {
1489                 return Error(IDS_ERR_DESTROYED);
1490         }
1491
1492         int nIdx = -1;
1493         CComVariant varIdx;
1494         if (SUCCEEDED(varIdx.ChangeType(VT_I2, &idx))) {
1495                 nIdx = varIdx.iVal;
1496         }
1497
1498         if (nIdx < 0) {
1499                 return DISP_E_BADINDEX;
1500         }
1501
1502         if (!lstrcmp(m_classname, WC_LISTVIEW)) {
1503                 CComVariant arg, text;
1504                 arg = (long)0;
1505                 text = (BSTR)newVal;
1506                 return SetColumnText(idx, arg, text);
1507         }
1508
1509         // \82»\82ê\88È\8aO\82Í\83T\83|\81[\83g\8aO
1510         return Error(IDS_ERR_NOTSUPPORTCONTROL);
1511 }
1512
1513 STDMETHODIMP CControl::SetClassEvent(BSTR name, VARIANT* pvarUnk)
1514 {
1515         m_bstrClassEvent = name;
1516         GetThisInterface(pvarUnk);
1517         return S_OK;
1518 }
1519
1520 void CControl::GetClassEvent(BSTR *pEventName)
1521 {
1522         *pEventName = m_bstrClassEvent.copy();
1523 }
1524
1525 STDMETHODIMP CControl::CreateChild(VARIANT text, VARIANT varItem, VARIANT* pvarUnk)
1526 {
1527         ::VariantInit(pvarUnk);
1528         if (!m_hParent || !m_hWnd) {
1529                 return Error(IDS_ERR_DESTROYED);
1530         }
1531
1532         // \83A\83C\83e\83\80\82Ì\8c\9f\8fØ
1533         CComVariant tmp;
1534         if (SUCCEEDED(tmp.ChangeType(VT_UNKNOWN, &varItem))) {
1535                 ITreeItem * pItem = NULL;
1536                 if (tmp.punkVal->QueryInterface(IID_ITreeItem, (void**)&pItem) != S_OK) {
1537                         return DISP_E_UNKNOWNINTERFACE;
1538                 }
1539
1540                 IUnknown* pUnk = NULL;
1541                 if (SUCCEEDED(pItem->Create(text, &pUnk))) {
1542                         pvarUnk->vt = VT_UNKNOWN;
1543                         pvarUnk->punkVal = pUnk;
1544                 }
1545                 pItem->Release();
1546         }
1547         else {
1548                 tmp.ChangeType(VT_VARIANT, &varItem);
1549                 if (tmp.vt == VT_ERROR || tmp.vt == VT_NULL || tmp.vt == VT_EMPTY) {
1550                         // \83\8b\81[\83g\8fã\82É\83A\83C\83e\83\80\82ð\8dì\90¬\82·\82é
1551                         AddString(text, pvarUnk);
1552                 }
1553                 else {
1554                         return DISP_E_TYPEMISMATCH;
1555                 }
1556         }
1557         return S_OK;
1558 }