rtoss - Blame information for rev 159

Subversion Repositories:
Rev:
Rev Author Line No. Line
89 roytam 1 #include "stdafx.h"
2 #include "app.h"
3 #include "window.h"
4 using namespace ki;
5  
6  
7  
8 //=========================================================================
9 // IMEに関するあれこれ
10 //=========================================================================
11  
12 IMEManager* IMEManager::pUniqueInstance_;
13  
14 IMEManager::IMEManager()
15 #ifdef USEGLOBALIME
16         : immApp_( NULL )
17         , immMsg_( NULL )
18 #endif
19 {
20         #ifdef USEGLOBALIME
21                 // 色々面倒なのでWin95ではGlobalIME無し
22                 if( !app().isWin95() )
23                 {
24                         app().InitModule( App::OLE );
25                         if( S_OK == ::CoCreateInstance(
26                                         CLSID_CActiveIMM, NULL, CLSCTX_INPROC_SERVER,
27                                         IID_IActiveIMMApp, (void**)&immApp_ ) )
28                         {
29                                 immApp_->QueryInterface(
30                                         IID_IActiveIMMMessagePumpOwner, (void**)&immMsg_ );
31                         }
32                 }
33         #endif
34  
35         // 唯一のインスタンスは私です
36         pUniqueInstance_ = this;
37 }
38  
39 IMEManager::~IMEManager()
40 {
41         #ifdef USEGLOBALIME
42                 if( immMsg_ != NULL )
142 roytam 43                 {
89 roytam 44                         immMsg_->Release();
142 roytam 45                         immMsg_ = NULL;
46                 }
89 roytam 47                 if( immApp_ != NULL )
142 roytam 48                 {
49                         immApp_->Deactivate();
89 roytam 50                         immApp_->Release();
142 roytam 51                         immApp_ = NULL;
52                 }
89 roytam 53         #endif
54 }
55  
56 void IMEManager::EnableGlobalIME( bool enable )
57 {
58         #ifdef USEGLOBALIME
59                 if( immApp_ )
60                         if( enable ) immApp_->Activate( TRUE );
61                         else         immApp_->Deactivate();
62         #endif
63 }
64  
158 roytam 65 BOOL IMEManager::IsIME()
66 {
67 #if !defined(TARGET_VER) || (defined(TARGET_VER) && TARGET_VER>310)
68         HKL hKL = GetKeyboardLayout(GetCurrentThreadId());
69         #ifdef USEGLOBALIME
70                 if( immApp_ )
71                 {
72                         return immApp_->IsIME( hKL );
73                 }
74                 else
75         #endif
76                 {
77                         return ::ImmIsIME( hKL );
78                 }
79 #else
80         return FALSE;
81 #endif
82 }
83  
159 roytam 84 BOOL IMEManager::CanReconv()
85 {
86 #if !defined(TARGET_VER) || (defined(TARGET_VER) && TARGET_VER>310)
87         HKL hKL = GetKeyboardLayout(GetCurrentThreadId());
88         DWORD nImeProps = ImmGetProperty( GetKeyboardLayout( 0 ), IGP_SETCOMPSTR );
89         #ifdef USEGLOBALIME
90                 if( immApp_ )
91                 {
92                         immApp_->GetProperty( hKL, IGP_SETCOMPSTR, &nImeProps );
93                 }
94                 else
95         #endif
96                 {
97                         nImeProps = ::ImmGetProperty( hKL, IGP_SETCOMPSTR );
98                 }
99                 return (nImeProps & SCS_CAP_SETRECONVERTSTRING) != 0;
100 #else
101         return FALSE;
102 #endif
103 }
104  
158 roytam 105 BOOL IMEManager::GetState( HWND wnd )
106 {
107         BOOL imeStatus = FALSE;
108 #if !defined(TARGET_VER) || (defined(TARGET_VER) && TARGET_VER>310)
109         HIMC ime;
110         #ifdef USEGLOBALIME
111                 if( immApp_ )
112                 {
113                         immApp_->GetContext( wnd, &ime );
114                         imeStatus = immApp_->GetOpenStatus( ime );
115                         immApp_->ReleaseContext( wnd, ime );
116                 }
117                 else
118         #endif
119                 {
120                         ime = ::ImmGetContext( wnd );
121                         imeStatus = ::ImmGetOpenStatus(ime );
122                         ::ImmReleaseContext( wnd, ime );
123                 }
124 #endif
125         return imeStatus;
126 }
127  
128 void IMEManager::SetState( HWND wnd, bool enable )
129 {
130 #if !defined(TARGET_VER) || (defined(TARGET_VER) && TARGET_VER>310)
131         HIMC ime;
132         #ifdef USEGLOBALIME
133                 if( immApp_ )
134                 {
135                         immApp_->GetContext( wnd, &ime );
136                         immApp_->SetOpenStatus( ime, (enable ? TRUE : FALSE) );
137                         immApp_->ReleaseContext( wnd, ime );
138                 }
139                 else
140         #endif
141                 {
142                         ime = ::ImmGetContext( wnd );
143                         ::ImmSetOpenStatus(ime, (enable ? TRUE : FALSE) );
144                         ::ImmReleaseContext( wnd, ime );
145                 }
146 #endif
147 }
148  
89 roytam 149 void IMEManager::FilterWindows( ATOM* lst, UINT siz )
150 {
151         #ifdef USEGLOBALIME
152                 if( immApp_ )
153                         immApp_->FilterClientWindows( lst, siz );
154         #endif
155 }
156  
157 inline void IMEManager::TranslateMsg( MSG* msg )
158 {
159         #ifdef USEGLOBALIME
160                 if( immMsg_ )
161                         if( S_OK == immMsg_->OnTranslateMessage( msg ) )
162                                 return;
163         #endif
164         ::TranslateMessage( msg );
165 }
166  
167 inline LRESULT IMEManager::DefProc( HWND h, UINT m, WPARAM w, LPARAM l )
168 {
169         #ifdef USEGLOBALIME
170                 if( immApp_ )
171                 {
172                         LRESULT res;
173                         if( S_OK == immApp_->OnDefWindowProc( h,m,w,l,&res ) )
174                                 return res;
175                 }
176         #endif
177         return ::DefWindowProc( h, m, w, l );
178 }
179  
180 inline void IMEManager::MsgLoopBegin()
181 {
182         #ifdef USEGLOBALIME
183                 if( immMsg_ )
184                         immMsg_->Start();
185         #endif
186 }
187  
188 inline void IMEManager::MsgLoopEnd()
189 {
190         #ifdef USEGLOBALIME
191                 if( immMsg_ )
192                         immMsg_->End();
193         #endif
194 }
195  
196 void IMEManager::SetFont( HWND wnd, const LOGFONT& lf )
197 {
158 roytam 198 #if !defined(TARGET_VER) || (defined(TARGET_VER) && TARGET_VER>310)
89 roytam 199         HIMC ime;
200         LOGFONT* plf = const_cast<LOGFONT*>(&lf);
201  
202         #ifdef USEGLOBALIME
203         if( immApp_ )
204         {
205                 immApp_->GetContext( wnd, &ime );
206                 #ifdef _UNICODE
207                         immApp_->SetCompositionFontW( ime, plf );
208                 #else
209                         immApp_->SetCompositionFontA( ime, plf );
210                 #endif
211                 immApp_->ReleaseContext( wnd, ime );
212         }
213         else
214         #endif
215         {
216                 ime = ::ImmGetContext( wnd );
217                 ::ImmSetCompositionFont( ime, plf );
218                 ::ImmReleaseContext( wnd, ime );
158 roytam 219         }
124 roytam 220 #endif
89 roytam 221 }
222  
223 void IMEManager::SetPos( HWND wnd, int x, int y )
224 {
158 roytam 225 #if !defined(TARGET_VER) || (defined(TARGET_VER) && TARGET_VER>310)
89 roytam 226         HIMC ime;
227         COMPOSITIONFORM cf;
228         cf.dwStyle = CFS_POINT;
229         cf.ptCurrentPos.x  = x;
230         cf.ptCurrentPos.y  = y;
231  
232         #ifdef USEGLOBALIME
233         if( immApp_ )
234         {
235                 immApp_->GetContext( wnd, &ime );
236                 immApp_->SetCompositionWindow( ime, &cf );
237                 immApp_->ReleaseContext( wnd, ime );
238         }
239         else
240         #endif
241         {
242                 ime = ::ImmGetContext( wnd );
243                 ::ImmSetCompositionWindow( ime, &cf );
244                 ::ImmReleaseContext( wnd, ime );
158 roytam 245         }
124 roytam 246 #endif
89 roytam 247 }
248  
249 void IMEManager::GetString( HWND wnd, unicode** str, ulong* len )
250 {
158 roytam 251 #if !defined(TARGET_VER) || (defined(TARGET_VER) && TARGET_VER>310)
89 roytam 252         *str = NULL;
253         HIMC ime;
254  
255         #ifdef USEGLOBALIME
256         if( immApp_ )
257         {
258                 long s=0;
259                 immApp_->GetContext( wnd, &ime );
260                 immApp_->GetCompositionStringW( ime, GCS_RESULTSTR, 0, &s, NULL );
261                 *str = new unicode[ (*len=s/2)+1 ];
262                 immApp_->GetCompositionStringW( ime, GCS_RESULTSTR, s, &s, *str );
263                 immApp_->ReleaseContext( wnd, ime );
264         }
265         else
266         #endif
267         {
268                 ime = ::ImmGetContext( wnd );
269                 long s = ::ImmGetCompositionStringW( ime,GCS_RESULTSTR,NULL,0 );
270  
271                 #ifndef _UNICODE
272                         if( s <= 0 )
273                         {
274                                 s = ::ImmGetCompositionStringA(ime,GCS_RESULTSTR,NULL,0);
275                                 if( s > 0 )
276                                 {
277                                         char* tmp = new char[s];
278                                         *str = new unicode[*len=s*2];
279                                         ::ImmGetCompositionStringA( ime,GCS_RESULTSTR,tmp,s );
280                                         *len = ::MultiByteToWideChar(
281                                                 CP_ACP, MB_PRECOMPOSED, tmp, s, *str, *len );
282                                         delete [] tmp;
283                                 }
284                         }
285                         else
286                 #endif
287                         {
288                                 *str = new unicode[ (*len=s/2)+1 ];
289                                 ::ImmGetCompositionStringW( ime, GCS_RESULTSTR, *str, s );
290                         }
291  
292                 ::ImmReleaseContext( wnd, ime );
158 roytam 293         }
124 roytam 294 #endif
158 roytam 295 }
296  
297 void IMEManager::SetString( HWND wnd, unicode* str, ulong len )
298 {
299 #if !defined(TARGET_VER) || (defined(TARGET_VER) && TARGET_VER>310)
300         HIMC ime;
301  
302         #ifdef USEGLOBALIME
303         if( immApp_ )
304         {
305                 long s=0;
306                 immApp_->GetContext( wnd, &ime );
307                 immApp_->SetCompositionStringW( ime, SCS_SETSTR, str, len*sizeof(unicode), NULL, 0 );
308                 immApp_->NotifyIME( ime, NI_COMPOSITIONSTR, CPS_CONVERT, 0 );
309                 immApp_->NotifyIME( ime, NI_OPENCANDIDATE, 0, 0 );
310                 immApp_->ReleaseContext( wnd, ime );
89 roytam 311         }
158 roytam 312         else
313         #endif
314         {
315                 ime = ::ImmGetContext( wnd );
316                 long s = ::ImmSetCompositionStringW( ime,SCS_SETSTR,str,len*sizeof(unicode),NULL,0 );
317  
318                 #ifndef _UNICODE
319                         if( s == 0 )
320                         {
321                                 len = ::WideCharToMultiByte( CP_ACP,MB_PRECOMPOSED,str,-1,NULL,NULL,TRUE );
322                                 char* tmp = new char[len];
323  
324                                 ::WideCharToMultiByte( CP_ACP, MB_PRECOMPOSED, str, -1, tmp, &len,TRUE );
325                                 s = ::ImmSetCompositionStringA(ime,SCS_SETSTR,tmp,len,NULL,0);
326                                 delete [] tmp;
327                         }
328                         else
329                 #endif
330  
331                 ::ImmNotifyIME( ime, NI_COMPOSITIONSTR, CPS_CONVERT, 0); // 変換実行
332                 ::ImmNotifyIME( ime, NI_OPENCANDIDATE, 0, 0 ); // 変換候補リスト表示
333                 ::ImmReleaseContext( wnd, ime );
334         }
335 #endif
89 roytam 336 }
337  
338  
339  
340 //=========================================================================
341 // Windowに関するあれこれ
342 //=========================================================================
343  
344 Window::Window()
345         : wnd_      (NULL)
346         , isLooping_(false)
347 {
348 }
349  
350 void Window::SetHwnd( HWND wnd )
351 {
352         wnd_ = wnd;
353 }
354  
355 void Window::MsgLoop()
356 {
357         // thisをメインウインドウとして、
358         // メインメッセ[ジル[プを回す
359         isLooping_ = true;
360         ime().MsgLoopBegin();
361  
362         for( MSG msg; ::GetMessage( &msg, NULL, 0, 0 ); )
363                 if( !PreTranslateMessage( &msg ) )
364                 {
365                         ime().TranslateMsg( &msg );
366                         ::DispatchMessage( &msg );
367                 }
368  
369         ime().MsgLoopEnd();
370         isLooping_ = false;
371 }
372  
373 void Window::ProcessMsg()
374 {
375         // こっちはグロ[バル関数。
376         // 未処理メッセ[ジを一掃
377  
378         ime().MsgLoopBegin();
379         for( MSG msg; ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ); )
380         {
381                 ime().TranslateMsg( &msg );
382                 ::DispatchMessage( &msg );
383         }
384         ime().MsgLoopEnd();
385 }
386  
387  
388  
389 //-------------------------------------------------------------------------
390  
391 void Window::SetCenter( HWND hwnd, HWND rel )
392 {
393         // 自分のサイズを取得
394         RECT rc,pr;
395         ::GetWindowRect( hwnd, &rc );
396  
397         // 親の位置、ないしは全画面の位置を取得
398         if( rel != NULL )
399                 ::GetWindowRect( rel, &pr );
400         else
401                 ::SystemParametersInfo( SPI_GETWORKAREA, 0, &pr, 0 );
402  
403         // 中央を計算
404         ::SetWindowPos( hwnd, 0,
405                 pr.left + ( (pr.right-pr.left)-(rc.right-rc.left) )/2,
406                 pr.top  + ( (pr.bottom-pr.top)-(rc.bottom-rc.top) )/2,
407                 0, 0, SWP_NOSIZE|SWP_NOZORDER );
408 }
409  
410 void Window::SetFront( HWND hwnd )
411 {
412         // kazubon氏の TClock のソ[スを参考にしました。感謝!
413  
414         if( app().isNewTypeWindows() )
415         {
416                 DWORD pid;
417                 HWND  fore= ::GetForegroundWindow();
418                 DWORD th1 = ::GetWindowThreadProcessId( fore, &pid );
419                 DWORD th2 = ::GetCurrentThreadId();
420                 ::AttachThreadInput( th2, th1, TRUE );
421                 ::SetForegroundWindow( hwnd );
422                 ::AttachThreadInput( th2, th1, FALSE );
423                 ::BringWindowToTop( hwnd );
424         }
425         else
426         {
427                 ::SetForegroundWindow( hwnd );
428         }
429 }
430  
431 //=========================================================================
432  
433 WndImpl::WndImpl( LPCTSTR className, DWORD style, DWORD styleEx )
434         : className_( className )
435         , style_    ( style )
436         , styleEx_  ( styleEx )
437         , thunk_    ( static_cast<byte*>(
438                         ::VirtualAlloc( NULL, THUNK_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE )) )
439 {
440 }
441  
442 WndImpl::~WndImpl()
443 {
444         // ウインドウを破棄し忘れてたら閉じる
445         // …が、この時点で既に vtable は破棄されかかっているので
446         // 正しい on_destroy が呼ばれる保証は全くない。あくまで
447         // 緊急脱出用(^^; と考えること。
448         Destroy();
449         ::VirtualFree( thunk_, 0, MEM_RELEASE );
450 }
451  
452 void WndImpl::Destroy()
453 {
454         if( hwnd() != NULL )
455                 ::DestroyWindow( hwnd() );
456 }
457  
123 roytam 458 #if !defined(TARGET_VER) || TARGET_VER>350
89 roytam 459 ATOM WndImpl::Register( WNDCLASSEX* cls )
123 roytam 460 #else
461 ATOM WndImpl::Register( WNDCLASS* cls )
462 #endif
89 roytam 463 {
464         // WndImpl派生クラスで使うWndClassを登録。
465         // プロシ[ジャはkilib謹製のものに書き換えちゃいます。
123 roytam 466 #if !defined(TARGET_VER) || TARGET_VER>350
89 roytam 467         cls->cbSize      = sizeof(WNDCLASSEX);
123 roytam 468 #endif
89 roytam 469         cls->hInstance   = app().hinst();
470         cls->lpfnWndProc = StartProc;
123 roytam 471 #if !defined(TARGET_VER) || TARGET_VER>350
89 roytam 472         return ::RegisterClassEx( cls );
123 roytam 473 #else
474         return ::RegisterClass( cls );
475 #endif
89 roytam 476 }
477  
478 struct ThisAndParam
479 {
480         // ユ[ザ指定のパラメ[タ以外にも渡したいモノが少々…
481         WndImpl* pThis;
482         void*   pParam;
483 };
484  
485 bool WndImpl::Create(
486         LPCTSTR wndName, HWND parent, int x, int y, int w, int h, void* param )
487 {
488         // ここでthisポインタを忍び込ませておく
489         ThisAndParam z = { this, param };
490  
491         LOGGER("WndImpl::Create before CreateWindowEx API call");
492  
493         return (NULL != ::CreateWindowEx(
494                 styleEx_, className_, wndName, style_,
495                 x, y, w, h, parent, NULL, app().hinst(), &z
496         ));
497 }
498  
499  
500  
501 //-------------------------------------------------------------------------
502  
503 LRESULT CALLBACK WndImpl::StartProc(
504         HWND wnd, UINT msg, WPARAM wp, LPARAM lp )
505 {
506         // WM_CREATE以外はスル[の方針で
507         if( msg != WM_CREATE )
508                 return ::DefWindowProc( wnd, msg, wp, lp );
509  
510         LOGGER("WndImpl::StartProc WM_CREATE kitaaaaa!!");
511  
512         // 忍ばせて置いたthisポインタを取り出し
513         CREATESTRUCT* cs   = reinterpret_cast<CREATESTRUCT*>(lp);
514         ThisAndParam* pz   = static_cast<ThisAndParam*>(cs->lpCreateParams);
515         WndImpl*   pThis   = pz->pThis;
516         cs->lpCreateParams = pz->pParam;
517  
518         // サンク
519         pThis->SetUpThunk( wnd );
520  
521         // WM_CREATE用メッセ[ジを呼ぶ
522         pThis->on_create( cs );
523         return 0;
524 }
525  
526 void WndImpl::SetUpThunk( HWND wnd )
527 {
528         SetHwnd( wnd );
529  
530         // ここで動的にx86の命令列
531         //   | mov dword ptr [esp+4] this
532         //   | jmp MainProc
533         // あるいはAMD64の命令列
534         //   | mov rcx this
535         //   | mov rax MainProc
536         //   | jmp rax
537         // を生成し、メッセ[ジプロシ[ジャとして差し替える。
538         //
539         // これで次回からは、第一引数が hwnd のかわりに
540         // thisポインタになった状態でMainProcが呼ばれる
541         // …と見なしたプログラムが書ける。
542         //
543         // 参考資料:ATLのソ[ス
544  
545 #ifdef _M_AMD64
546         *reinterpret_cast<dbyte*>   (thunk_+ 0) = 0xb948;
547         *reinterpret_cast<WndImpl**>(thunk_+ 2) = this;
548         *reinterpret_cast<dbyte*>   (thunk_+10) = 0xb848;
549         *reinterpret_cast<void**>   (thunk_+12) = MainProc;
550         *reinterpret_cast<dbyte*>   (thunk_+20) = 0xe0ff;
551 #else
552         *reinterpret_cast<qbyte*>   (thunk_+0) = 0x042444C7;
553         *reinterpret_cast<WndImpl**>(thunk_+4) = this;
554         *reinterpret_cast< byte*>   (thunk_+8) = 0xE9;
555         *reinterpret_cast<qbyte*>   (thunk_+9) =
556                 reinterpret_cast<byte*>((void*)MainProc)-(thunk_+13);
557 #endif
558  
559         ::FlushInstructionCache( ::GetCurrentProcess(), thunk_, THUNK_SIZE );
560         ::SetWindowLongPtr( wnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&thunk_[0]) );
561 }
562  
563 LRESULT CALLBACK WndImpl::MainProc(
564         WndImpl* ptr, UINT msg, WPARAM wp, LPARAM lp )
565 {
566         if( msg == WM_COMMAND )
567         {
568                 if( !ptr->on_command( LOWORD(wp), (HWND)lp ) )
569                         return ::DefWindowProc( ptr->hwnd(), msg, wp, lp );
570         }
571         else if( msg == WM_DESTROY )
572         {
573                 ptr->on_destroy();
574                 ::SetWindowLongPtr( ptr->hwnd(), GWLP_WNDPROC,
575                         reinterpret_cast<LONG_PTR>(StartProc) );
576                 if( ptr->isMainWnd() )
577                         ::PostQuitMessage( 0 );
578                 ptr->SetHwnd(NULL);
579         }
580         else
581         {
582                 return ptr->on_message( msg, wp, lp );
583         }
584  
585         return 0;
586 }
587  
588  
589  
590 //-------------------------------------------------------------------------
591  
592 void WndImpl::on_create( CREATESTRUCT* cs )
593 {
594         // 何もしない
595 }
596  
597 void WndImpl::on_destroy()
598 {
599         // 何もしない
600 }
601  
602 bool WndImpl::on_command( UINT, HWND )
603 {
604         // 何もしない
605         return false;
606 }
607  
608 LRESULT WndImpl::on_message( UINT msg, WPARAM wp, LPARAM lp )
609 {
610         // 何もしない
611         return ime().DefProc( hwnd(), msg, wp, lp );
612 }
613  
614 bool WndImpl::PreTranslateMessage( MSG* )
615 {
616         // 何もしない
617         return false;
618 }
619  
620  
621  
622 //=========================================================================
623  
624 DlgImpl::DlgImpl( UINT id )
625         : rsrcID_( id )
626 {
627 }
628  
629 DlgImpl::~DlgImpl()
630 {
631         // ウインドウを破棄し忘れてたら閉じる
632         if( hwnd() != NULL )
633                 End( IDCANCEL );
634 }
635  
636 void DlgImpl::End( UINT code )
637 {
638         endCode_ = code;
639  
640         if( type() == MODAL )
641                 ::EndDialog( hwnd(), code );
642         else
643                 ::DestroyWindow( hwnd() );
644 }
645  
646 void DlgImpl::GoModal( HWND parent )
647 {
648         type_ = MODAL;
649         ::DialogBoxParam( app().hinst(), MAKEINTRESOURCE(rsrcID_), parent,
650                 (DLGPROC)MainProc, reinterpret_cast<LPARAM>(this) );
651 }
652  
653 void DlgImpl::GoModeless( HWND parent )
654 {
655         type_ = MODELESS;
656         ::CreateDialogParam( app().hinst(), MAKEINTRESOURCE(rsrcID_), parent,
657                 (DLGPROC)MainProc, reinterpret_cast<LPARAM>(this) );
658 }
659  
660  
661  
662 //-------------------------------------------------------------------------
663  
664 BOOL CALLBACK DlgImpl::MainProc(
665         HWND dlg, UINT msg, WPARAM wp, LPARAM lp )
666 {
667         if( msg == WM_INITDIALOG )
668         {
669                 ::SetWindowLongPtr( dlg, GWLP_USERDATA, lp );
670  
671                 DlgImpl* ptr = reinterpret_cast<DlgImpl*>(lp);
672                 ptr->SetHwnd( dlg );
673                 ptr->on_init();
674                 return FALSE;
675         }
676  
677         DlgImpl* ptr =
678                 reinterpret_cast<DlgImpl*>(::GetWindowLongPtr(dlg,GWLP_USERDATA));
679  
680         if( ptr != NULL )
681                 switch( msg )
682                 {
683                 case WM_COMMAND:
684                         switch( LOWORD(wp) )
685                         {
686                         case IDOK:
687                                 if( ptr->on_ok() )
688                                         ptr->End( IDOK );
689                                 return TRUE;
690  
691                         case IDCANCEL:
692                                 if( ptr->on_cancel() )
693                                         ptr->End( IDCANCEL );
694                                 return TRUE;
695  
696                         default:
697                                 return ptr->on_command( HIWORD(wp), LOWORD(wp),
698                                         reinterpret_cast<HWND>(lp) ) ? TRUE : FALSE;
699                         }
700  
701                 case WM_DESTROY:
702                         ptr->on_destroy();
703                         if( ptr->isMainWnd() )
704                                 ::PostQuitMessage( 0 );
705                         ptr->SetHwnd(NULL);
706                         break;
707  
708                 default:
709                         return ptr->on_message( msg, wp, lp ) ? TRUE : FALSE;
710                 }
711  
712         return FALSE;
713 }
714  
715  
716  
717 //-------------------------------------------------------------------------
718  
719 void DlgImpl::on_init()
720 {
721         // 何もしない
722 }
723  
724 void DlgImpl::on_destroy()
725 {
726         // 何もしない
727 }
728  
729 bool DlgImpl::on_ok()
730 {
731         // 何もしない
732         return true;
733 }
734  
735 bool DlgImpl::on_cancel()
736 {
737         // 何もしない
738         return true;
739 }
740  
741 bool DlgImpl::on_command( UINT, UINT, HWND )
742 {
743         // 何もしない
744         return false;
745 }
746  
747 bool DlgImpl::on_message( UINT, WPARAM, LPARAM )
748 {
749         // 何もしない
750         return false;
751 }
752  
753 bool DlgImpl::PreTranslateMessage( MSG* msg )
754 {
755         // モ[ドレスの時用。ダイアログメッセ[ジ処理。
756         return (FALSE != ::IsDialogMessage( hwnd(), msg ));
757 }