1 //--- K.I.LIB ---
2 // kl_wnd.h : window information manager
3
4 #ifndef AFX_KIWINDOW_H__26105B94_1E36_42FA_8916_C2F7FB9EF994__INCLUDED_
5 #define AFX_KIWINDOW_H__26105B94_1E36_42FA_8916_C2F7FB9EF994__INCLUDED_
6
7 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
8 // kiWindow : Windowの簡単な管理
9
10 class kiWindow
11 {
12 friend void kilib_startUp();
13
14 private: //-- グローバルな初期化処理など ---------------------
15
16 static void init();
17 static void finish();
18
19 public: //-- 外向きインターフェイス --------------------------
20
21 // 関連付けられているHWND
22 HWND hwnd()
23 {
24 return m_hWnd;
25 }
26
27 // そのWindow用にアクセラレータをロード
28 void loadAccel( UINT id );
29
30 // ウインドウがまだ残っているかどうかチェック
31 bool isAlive()
32 {
33 if( !m_hWnd )
34 return false;
35 if( ::IsWindow(m_hWnd) )
36 return true;
37 m_hWnd = NULL;
38 return false;
39 }
40
41 // 親
42 kiWindow* parent()
43 {
44 return kiwnd( ::GetParent( hwnd() ) );
45 }
46
47 // メッセージ送信
48 int sendMsg( UINT msg, WPARAM wp=0, LPARAM lp=0 )
49 {
50 return ::SendMessage( hwnd(), msg, wp, lp );
51 }
52
53 // [static] キューにあるメッセージを全て処理
54 static void msg();
55
56 // [static] メッセージループをまわす。
57 enum msglooptype {PEEK, GET};
58 static void msgLoop( msglooptype type = GET );
59
60 // [static] Windowを強制的に front へ
61 static void setFront( HWND wnd );
62
63 // [static] Windowを中央へ
64 static void setCenter( HWND wnd, HWND rel=NULL );
65
66 // [static] HWND -> kiWindow ( もしあれば )
67 static kiWindow* kiwnd( HWND wnd )
68 {
69 kiWindow* ptr = (kiWindow*)::GetWindowLong( wnd, GWL_USERDATA );
70 if( !ptr ) return NULL;
71 if( ::IsBadCodePtr((FARPROC)&ptr) ) return NULL;
72 return ptr;
73 }
74
75 protected: //-- 派生クラス向け -----------------------------
76
77 // 派生クラスは、作成直前にコレを呼ぶこと。
78 static void preCreate( kiWindow* wnd )
79 { st_pCurInit = wnd; }
80 // 破棄直前にコレを呼ぶこと。
81 void detachHwnd();
82 // いったんGET/POSTメッセージループを停止
83 static void loopbreak()
84 {
85 loopbreaker = true;
86 }
87
88 private: //-- 内部処理 -------------------------------------
89
90 // ウインドウハンドル設定
91 static LRESULT CALLBACK CBTProc( int code, WPARAM wp, LPARAM lp );
92 static HHOOK st_hHook;
93 static kiWindow* st_pCurInit;
94 void setHwnd( HWND wnd )
95 {
96 m_hWnd = wnd;
97 }
98
99 // ウインドウ情報保持用変数
100 HWND m_hWnd;
101 HACCEL m_hAccel;
102 // ダイアログメッセージ
103 virtual bool isDlgMsg( MSG* msg )
104 { return false; }
105 // GETループ一時抜けだし
106 static bool loopbreaker;
107
108 protected:
109 kiWindow();
110 public:
111 virtual ~kiWindow();
112 };
113
114 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
115 // kiDialog : DialogをkiWindowとして管理する
116
117 class kiDialog : public kiWindow
118 {
119 public: //-- 外向きインターフェイス --------------------------
120
121 // モーダルダイアログとして実行
122 virtual void doModal( HWND parent=NULL );
123
124 // モードレスダイアログとして作成
125 virtual void createModeless( HWND parent=NULL );
126
127 // 終了コード取得
128 UINT getEndCode()
129 {
130 return m_EndCode;
131 }
132
133 // モーダルか否か
134 bool isModal()
135 {
136 return m_bStateModal;
137 }
138
139 // ダイアログアイテム
140 int sendMsgToItem( UINT id, UINT msg, WPARAM wp=0, LPARAM lp=0 )
141 {
142 return ::SendDlgItemMessage( hwnd(), id, msg, wp, lp );
143 }
144 HWND item( UINT id )
145 {
146 return ::GetDlgItem( hwnd(), id );
147 }
148
149 protected: //-- 派生クラス向け -----------------------------
150
151 // リソースIDで初期化
152 kiDialog( UINT id );
153
154 // リソースID取得
155 UINT getRsrcID()
156 {
157 return m_Rsrc;
158 }
159
160 // 終了コードをセット
161 void setEndCode( UINT endcode )
162 {
163 m_EndCode = endcode;
164 }
165
166 // モーダルか否かのフラグ"のみ"を切替
167 void setState( bool modal )
168 {
169 m_bStateModal = modal;
170 }
171
172 // 終了コードをセットして、終了する( IDOK を渡しても onOK() は呼ばれないことに注意! )
173 virtual void end( UINT endcode );
174
175 // コマンド・メッセージ発生時に呼ばれる
176
177 // OK -> onOK -> if true end(IDOK)
178 virtual bool onOK() {return true;}
179 // 取消 -> onCancel -> if true end(IDCANCEL)
180 virtual bool onCancel() {return true;}
181 // WM_INITDIALOG -> onInit
182 virtual BOOL onInit() {return FALSE;}
183 // WM_???? -> proc
184 virtual BOOL CALLBACK proc( UINT msg, WPARAM wp, LPARAM lp ) {return FALSE;}
185
186 private: //-- 内部処理 -------------------------------------
187
188 UINT m_EndCode;
189 UINT m_Rsrc;
190 bool m_bStateModal;
191 bool isDlgMsg( MSG* msg )
192 {
193 return (!!::IsDialogMessage( hwnd(), msg ));
194 }
195 static BOOL CALLBACK commonDlg( HWND dlg, UINT msg, WPARAM wp, LPARAM lp );
196 };
197
198 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
199 // kiPropSheet : PropertySheetをkiWindowとして管理する。
200
201 #define IDAPPLY (0x3021)
202 #define ID_KIPS_HELP (0x0009)
203
204 class kiPropSheetPage : public kiDialog
205 {
206 friend class kiPropSheet;
207
208 protected: //-- 派生クラス向け ----------------------------
209
210 // ダイアログやアイコンのIDで初期化
211 kiPropSheetPage( UINT dlgid )
212 : kiDialog( dlgid ), m_hIcon( NULL ) {}
213 void setIcon( HICON h )
214 { m_hIcon = h; }
215
216 // OK/適用 -> page::onOK -> sheet::onOK -> (if ok 終了)
217 // virtual bool onOK()
218 // WM_INITDIALOG
219 // virtual BOOL onInit()
220 // その他
221 // virtual BOOL CALLBACK proc( UINT msg, WPARAM wp, LPARAM lp )
222
223 private: //-- 内部処理 -------------------------------------
224
225 void end( UINT endcode ) {}
226 void setInfo( PROPSHEETPAGE* p );
227 HICON m_hIcon;
228 };
229
230 class kiPropSheet : public kiDialog
231 {
232 friend class kiPropSheetPage;
233
234 public: //-- 外向きインターフェイス --------------------------
235
236 // モーダルダイアログとして実行
237 void doModal( HWND parent );
238
239 // モードレスダイアログとして作成
240 void createModeless( HWND parent );
241
242 protected: //-- 派生クラス向け ----------------------------
243
244 // コンストラクタ辺りで↓これをいじるべし
245 PROPSHEETHEADER m_Header;
246 kiArray<kiPropSheetPage*> m_Pages;
247
248 // 終了
249 void end( UINT endcode );
250 //
251 void sendOK2All()
252 {
253 for( unsigned int i=0;i!=m_Pages.len(); i++ )
254 if( m_Pages[i]->isAlive() )
255 m_Pages[i]->onOK();
256 }
257
258 // OK/適用 -> page::onOK -> sheet::onOK -> (if ok 終了)
259 // virtual void onOK()
260 // キャンセル -> sheet::onCancel -> 終了
261 // virtual void onCancel()
262 // PSCB_INITIALIZED
263 // virtual BOOL onInit()
264 // 適用
265 virtual void onApply() {}
266 // ヘルプ
267 virtual void onHelp() {}
268 // その他コマンド
269 virtual void onCommand( UINT id ) {}
270 // ファイルドロップ
271 virtual void onDrop( HDROP hdrop ) {}
272
273 private: //-- 内部処理 ---------------------------------------
274
275 void begin();
276 bool m_bStateModal;
277
278 static kiPropSheet* st_CurInitPS;
279 WNDPROC m_DefProc;
280 bool isDlgMsg( MSG* msg )
281 { return !!PropSheet_IsDialogMessage( hwnd(),msg ); }
282 static int CALLBACK main_initProc( HWND dlg, UINT msg, LPARAM lp );
283 static LRESULT CALLBACK main_cmmnProc( HWND dlg, UINT msg, WPARAM wp, LPARAM lp );
284 static BOOL CALLBACK page_cmmnProc( HWND dlg, UINT msg, WPARAM wp, LPARAM lp );
285 static UINT CALLBACK page_initProc( HWND dlg, UINT msg, LPPROPSHEETPAGE ppsp );
286
287 protected:
288 kiPropSheet();
289 public:
290 ~kiPropSheet()
291 { for( unsigned int i=0; i!=m_Pages.len(); i++ ) delete m_Pages[i]; }
292 };
293
294 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
295 // kiListView : ListViewコントロールの簡単なラッパ
296
297 class kiListView
298 {
299 public:
300 kiListView( kiDialog* dlg, UINT id )
301 {
302 m_hWnd = ::GetDlgItem( dlg->hwnd(), id );
303 }
304
305 void insertColumn( int y, const char* title,
306 int width=100, int fmt=LVCFMT_LEFT )
307 {
308 LVCOLUMN col;
309 col.mask = LVCF_TEXT | LVCF_FMT | LVCF_WIDTH;
310 col.pszText = const_cast<char*>(title);
311 col.cx = width;
312 col.fmt = fmt;
313 ::SendMessage( m_hWnd, LVM_INSERTCOLUMN, y, (LPARAM)&col );
314 }
315
316 void insertItem( int x, const char* str, LPARAM param=0, int iImage=-1 )
317 {
318 LVITEM item;
319 item.mask = LVIF_TEXT | LVIF_PARAM | (iImage!=-1 ? LVIF_IMAGE : 0);
320 item.pszText = const_cast<char*>(str);
321 item.iItem = x;
322 item.iSubItem = 0;
323 item.iImage = iImage;
324 item.lParam = param;
325 ::SendMessage( m_hWnd, LVM_INSERTITEM, 0, (LPARAM)&item );
326 }
327
328 void setSubItem( int x, int y, const char* str )
329 {
330 LVITEM item;
331 item.mask = LVIF_TEXT;
332 item.pszText = const_cast<char*>(str);
333 item.iItem = x;
334 item.iSubItem = y;
335 ::SendMessage( m_hWnd, LVM_SETITEM, 0, (LPARAM)&item );
336 }
337
338 void setImageList( HIMAGELIST Large, HIMAGELIST Small )
339 {
340 ::SendMessage( m_hWnd, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)Large );
341 ::SendMessage( m_hWnd, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)Small );
342 }
343
344 private:
345 HWND m_hWnd;
346 };
347
348 #endif