00001
00002 #include "vgui_win32.h"
00003
00004 #include <vgui/vgui_gl.h>
00005 #include <vcl_iostream.h>
00006 #include <vcl_cassert.h>
00007 #include <vcl_cstring.h>
00008 #include "vgui_win32_window.h"
00009 #include "vgui_win32_dialog_impl.h"
00010
00011 vgui_win32* vgui_win32::instance_ = 0;
00012
00013
00014 vgui_win32* vgui_win32::instance()
00015 {
00016 if ( instance_ == 0 )
00017 instance_ = new vgui_win32();
00018
00019 return instance_;
00020 }
00021
00022 vgui_win32::vgui_win32()
00023 {
00024 hInstance_ = GetModuleHandle(NULL);
00025 hPrevInstance_ = NULL;
00026 szCmdLine_ = NULL;
00027 iCmdShow_ = SW_SHOW;
00028
00029 szAppName_ = NULL;
00030
00031 windows_to_delete.clear();
00032 current_window = NULL;
00033 dialogs_to_delete.clear();
00034 current_dialog = NULL;
00035 }
00036
00037 vgui_win32::~vgui_win32()
00038 {
00039 }
00040
00041
00042
00043 BOOL vgui_win32::ProcessShellCommand(int argc, char **argv)
00044 {
00045
00046 char *p, *q = argv[0];
00047
00048
00049 while ( p = vcl_strchr(q, '\\') ) q = ++p;
00050
00051 p = vcl_strstr(q, ".exe");
00052
00053 if (p)
00054 szAppName_ = (char *)malloc(sizeof(char)*(p-q+1));
00055 else
00056 szAppName_ = (char *)malloc(sizeof(char)*(1+vcl_strlen(q)));
00057
00058 if ( szAppName_ == NULL )
00059 return FALSE;
00060 if (p) *p = 0;
00061 vcl_strcpy(szAppName_, q);
00062
00063
00064 szCmdLine_ = GetCommandLine();
00065
00066 return TRUE;
00067 }
00068
00069 void vgui_win32::init(int &argc, char **argv)
00070 {
00071 ProcessShellCommand(argc, argv);
00072
00073 WNDCLASS wndclass;
00074 wndclass.style = CS_HREDRAW | CS_VREDRAW;
00075 wndclass.lpfnWndProc = globalWndProc;
00076 wndclass.cbClsExtra = 0;
00077 wndclass.cbWndExtra = 0;
00078 wndclass.hInstance = hInstance_;
00079 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
00080 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
00081 wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
00082 wndclass.lpszMenuName = szAppName_;
00083 wndclass.lpszClassName = szAppName_;
00084
00085 if ( !RegisterClass(&wndclass) ) {
00086 vcl_cerr << "Fail to register window class for main window.\n";
00087 assert(false);
00088 }
00089
00090
00091 wndclass.style = CS_HREDRAW | CS_VREDRAW;
00092 wndclass.lpfnWndProc = globalDialogProc;
00093 wndclass.cbClsExtra = 0;
00094 wndclass.cbWndExtra = 0;
00095 wndclass.hInstance = hInstance_;
00096 wndclass.hIcon = LoadIcon(hInstance_, IDI_APPLICATION);
00097 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
00098 wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
00099 wndclass.lpszMenuName = NULL;
00100 wndclass.lpszClassName = TEXT("vgui_win32_dialog");
00101
00102 if ( !RegisterClass(&wndclass) ) {
00103 MessageBox(NULL, TEXT("Fail to register window class for dialog box!"),
00104 NULL, MB_ICONERROR);
00105 assert(false);
00106 }
00107
00108
00109 wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
00110 wndclass.lpfnWndProc = globalTableauProc;
00111 wndclass.cbClsExtra = 0;
00112 wndclass.cbWndExtra = 0;
00113 wndclass.hInstance = hInstance_;
00114 wndclass.hIcon = LoadIcon(hInstance_, IDI_APPLICATION);
00115 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
00116 wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
00117 wndclass.lpszMenuName = NULL;
00118 wndclass.lpszClassName = TEXT("vgui_win32_inline_tab");
00119
00120 if ( !RegisterClass(&wndclass) ) {
00121 MessageBox(NULL, TEXT("Fail to register window class for inline tableau control!"),
00122 NULL, MB_ICONERROR);
00123 assert(false);
00124 }
00125 }
00126
00127 void vgui_win32::uninit()
00128 {
00129 for (unsigned i=0; i<windows_to_delete.size(); i++)
00130 delete windows_to_delete[i];
00131
00132
00133 }
00134
00135 vgui_window* vgui_win32::produce_window(int width, int height,
00136 vgui_menu const &menubar,
00137 char const *title)
00138 {
00139 vgui_window* a_window = new vgui_win32_window(hInstance_, szAppName_, width, height, menubar, title);
00140 windows_to_delete.push_back(a_window);
00141 current_window = a_window;
00142 return a_window;
00143 }
00144
00145 vgui_window* vgui_win32::produce_window(int width, int height,
00146 char const *title)
00147 {
00148 vgui_window* a_window = new vgui_win32_window(hInstance_, szAppName_, width, height, title);
00149 windows_to_delete.push_back(a_window);
00150 current_window = a_window;
00151 return a_window;
00152 }
00153
00154 vgui_dialog_impl* vgui_win32::produce_dialog(char const *name)
00155 {
00156 vgui_window *win = get_current_window();
00157
00158 current_dialog = new vgui_win32_dialog_impl(name,
00159 win ? ((vgui_win32_window*)win)->getWindowHandle() : NULL);
00160 dialogs_to_delete.push_back(current_dialog);
00161 return current_dialog;
00162 }
00163
00164 vgui_dialog_extensions_impl* vgui_win32::produce_dialog_extension(char const *name)
00165 {
00166
00167 return 0;
00168 }
00169
00170
00171 void vgui_win32::run()
00172 {
00173 MSG msg;
00174
00175 while ( GetMessage(&msg, NULL, 0, 0) ) {
00176 vgui_win32_window *pwin = (vgui_win32_window*)get_current_window();
00177 if (pwin) {
00178 HWND hwnd = pwin->getWindowHandle();
00179 HACCEL hAccel = pwin->getAccelHandle();
00180 if ( !(hAccel && TranslateAccelerator(hwnd, hAccel, &msg)) ) {
00181 TranslateMessage(&msg);
00182 DispatchMessage(&msg);
00183 }
00184 }
00185 else {
00186 TranslateMessage(&msg);
00187 DispatchMessage(&msg);
00188 }
00189 }
00190 }
00191
00192
00193 void vgui_win32::run_one_event()
00194 {
00195 if ( !PumpMessage() )
00196 PostQuitMessage(0);
00197 }
00198
00199
00200 void vgui_win32::run_till_idle()
00201 {
00202 MSG msg;
00203
00204 while ( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ) {
00205 if ( !PumpMessage() ) {
00206 PostQuitMessage(0);
00207 break;
00208 }
00209 }
00210 }
00211
00212
00213
00214
00215 void vgui_win32::flush()
00216 {
00217 glFlush();
00218 run_till_idle();
00219 }
00220
00221
00222
00223 void vgui_win32::add_event(vgui_event const &e)
00224 {
00225
00226 }
00227
00228
00229 void vgui_win32::quit()
00230 {
00231 PostQuitMessage(0);
00232 }
00233
00234
00235
00236 BOOL vgui_win32::PumpMessage()
00237 {
00238 MSG msg;
00239
00240 if ( !GetMessage(&msg, NULL, 0, 0) )
00241 return FALSE;
00242
00243 TranslateMessage(&msg);
00244 DispatchMessage(&msg);
00245
00246 return TRUE;
00247 }
00248
00249
00250 inline int vgui_win32::find_window(HWND hwnd)
00251 {
00252 int i;
00253 vcl_vector<vgui_window*>::const_iterator it;
00254 for ( i = 0, it = windows_to_delete.begin();
00255 it != windows_to_delete.end(); it++, i++ ) {
00256 HWND the_hwnd = ((vgui_win32_window*)(*it))->getWindowHandle();
00257 if ( the_hwnd == hwnd )
00258 return i;
00259 }
00260
00261 return -1;
00262 }
00263
00264 inline void vgui_win32::dump_window_stack()
00265 {
00266 vcl_cout << "z-top of window stack: ";
00267
00268 vcl_vector<vgui_window*>::const_iterator it;
00269 for ( it = windows_to_delete.begin();
00270 it != windows_to_delete.end(); it++ )
00271 vcl_cout << ((vgui_win32_window*)(*it))->getWindowHandle() << ',';
00272 vcl_cout << vcl_endl;
00273 }
00274
00275
00276
00277
00278 void vgui_win32::set_current_window(HWND hwnd)
00279 {
00280 int n = find_window(hwnd);
00281 if ( n == -1 || windows_to_delete[n] == current_window )
00282 return;
00283
00284 current_window = windows_to_delete[n];
00285 windows_to_delete.erase(windows_to_delete.begin()+n);
00286 windows_to_delete.push_back(current_window);
00287
00288 }
00289
00290
00291
00292 void vgui_win32::remove_current_window()
00293 {
00294 windows_to_delete.pop_back();
00295 delete current_window;
00296 current_window = windows_to_delete.empty() ? NULL : windows_to_delete.back();
00297
00298 }
00299
00300 void vgui_win32::remove_current_dialog()
00301 {
00302 dialogs_to_delete.pop_back();
00303 current_dialog = dialogs_to_delete.empty() ? NULL : dialogs_to_delete.back();
00304 }
00305
00306 LRESULT CALLBACK globalWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
00307 {
00308 LRESULT lResult = 0;
00309 vgui_win32_window* pwin;
00310
00311
00312
00313 vgui_win32::instance()->set_current_window(hwnd);
00314
00315 if ( message == WM_DESTROY ) {
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 vgui_win32::instance()->remove_current_window();
00326
00327
00328 pwin = (vgui_win32_window*)vgui_win32::instance()->get_current_window();
00329 if ( pwin) pwin->get_adaptor()->post_redraw();
00330
00331
00332 return 1;
00333 }
00334
00335 pwin = (vgui_win32_window*)vgui_win32::instance()->get_current_window();
00336 if ( pwin )
00337 lResult = pwin->WndProc(hwnd, message, wParam, lParam);
00338
00339 return lResult ? lResult : DefWindowProc(hwnd, message, wParam, lParam);
00340 }
00341
00342 LRESULT CALLBACK globalDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
00343 {
00344 LRESULT lResult = 0;
00345 vgui_win32_window* pwin;
00346 vgui_win32_dialog_impl *dlg;
00347
00348
00349 dlg = (vgui_win32_dialog_impl *)vgui_win32::instance()->get_current_dialog();
00350 if ( dlg )
00351 lResult = dlg->DialogProc(hDlg, message, wParam, lParam);
00352
00353 if ( message == WM_DESTROY ) {
00354
00355 pwin = (vgui_win32_window*)vgui_win32::instance()->get_current_window();
00356 pwin->get_adaptor()->post_redraw();
00357
00358
00359 (vgui_win32::instance())->remove_current_dialog();
00360 }
00361
00362 return lResult ? lResult : DefWindowProc(hDlg, message, wParam, lParam);
00363 }
00364
00365 LRESULT CALLBACK globalTableauProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
00366 {
00367 vgui_win32_dialog_impl *dlg;
00368
00369
00370 dlg = (vgui_win32_dialog_impl *)vgui_win32::instance()->get_current_dialog();
00371
00372 if ( dlg && dlg->get_inline_tableau_size() > 0 )
00373 dlg->get_current_tab()->OnCmdMsg(message, wParam, lParam);
00374
00375 return DefWindowProc(hDlg, message, wParam, lParam);
00376 }