OSDN Git Service

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