Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

WinGUI.cxx

Go to the documentation of this file.
00001 //   $Header: /nfs/slac/g/glast/ground/cvs/gui/src/WinGUI.cxx,v 1.3 2001/05/08 03:28:50 burnett Exp $
00002 // Implementation of the GUI interface for MS Windows95/NT
00003 #ifdef WIN32
00004 
00005 #include "WinGUI.h"
00006 #include "WinGUIostream.h"
00007 #include "WinScene.h"
00008 #include "resource.h"
00009 #include <iostream>
00010 #include <strstream>
00011 #include "gui/SubMenu.h"
00012 
00013 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00014 HINSTANCE   WinGUI::s_instance =0;
00015 WinGUI*     WinGUI::s_gui=0;
00016 HWND        WinGUI::s_hwnd=0;     // windows handle to the window
00017 WinScene*   WinGUI::s_graphics_window=0;
00018 WinScene*   WinGUI::s_2d_window=0;
00019 bool        WinGUI::s_quitting = false;
00020 WinGUIostream* WinGUI::s_text_window=0;
00021 
00022 static char *szAppName = "WinGUI";
00023 
00024 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00025 // This enforces the global singleton
00026 namespace gui {
00027 GUI* GUI::createGUI(const char* nameOfApp, const char* title)
00028 {
00029     if (WinGUI::s_gui!=0 && title!=0 ) ::SetWindowText(WinGUI::s_hwnd, title);
00030     if (WinGUI::s_gui==0)  WinGUI::s_gui =new WinGUI(nameOfApp, title);
00031     GUI::instance(WinGUI::s_gui);  // setup instance()
00032     GUI::s_instance = WinGUI::s_gui;
00033     return WinGUI::s_gui;
00034 }
00035 }
00036 bool GUI::running=false; // needed to check that display enabled 
00037 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00038 //              constructor
00039 WinGUI::WinGUI(const char* nameOfApp, const char* title)
00040 :   GUI(title)
00041 ,   m_menuId(0)
00042 ,   m_text_window(0)
00043 {
00044     // now create the main window, using the registered windows class
00045     if( s_hwnd==0 )
00046         s_hwnd = CreateWindow(szAppName, 
00047         title,
00048         (WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX |
00049         WS_MAXIMIZEBOX | WS_THICKFRAME | WS_SYSMENU),//WS_OVERLAPPEDWINDOW,
00050         20,  20, //CW_USEDEFAULT, 0,
00051         500, 500, //CW_USEDEFAULT, 0,
00052         NULL, NULL, 
00053         s_instance, 
00054         NULL);
00055     else setTitle(title);
00056     
00057     // create toplevel menu bar, set handles to it
00058     m_menuBar = m_currentMenu = ::CreateMenu ();
00059 }
00060 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00061 WinGUI::~WinGUI()
00062 {
00063     CommandList::iterator pcmd = m_owned_commands.begin();
00064     while (pcmd != m_owned_commands.end() )
00065         delete (*pcmd++);
00066     delete m_text_window;
00067 }
00068 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00069 WinGUI::Menu*
00070 WinGUI::beginPullDownMenu(const char * name, WinGUI::Menu* parent)
00071 {
00072     m_currentMenu = ::CreatePopupMenu();
00073     ::AppendMenu( parent? (HMENU)parent: m_menuBar, MF_POPUP, (UINT)m_currentMenu, name);
00074     return (Menu*)m_currentMenu;
00075 }
00076 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00077 void
00078 WinGUI::restorePullDownMenu(Menu * oldMenu)
00079 {
00080     m_currentMenu = (HMENU)oldMenu;
00081 }
00082 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00083 void
00084 WinGUI::endPullDownMenu(){m_currentMenu = m_menuBar;}
00085 
00086 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00087 void
00088 WinGUI::addToMenu(const char* name, Command* cmd)
00089 {
00090     ::AppendMenu(m_currentMenu, MF_STRING, cmdOffset+(m_menuId++), name);
00091     m_commands.push_back(cmd);
00092 }
00093 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00094 class WinGUI::Toggle : public GUI::Toggle
00095 { 
00096     friend class WinGUI;
00097     Toggle(HMENU hMenu, UINT uPos,  Command* cmd1, Command*cmd2, bool state)
00098         : m_hMenu(hMenu), m_uPos(uPos)
00099         , m_cmd1(cmd1)
00100         , m_cmd2(cmd2)
00101         , m_state(state)
00102     {}
00103     void execute() {
00104         if( m_state){  m_cmd2->execute();   m_state=FALSE;}
00105         else        {  m_cmd1->execute();   m_state=TRUE;       }
00106         ::CheckMenuItem(m_hMenu, m_uPos, m_state? MF_CHECKED : MF_UNCHECKED);
00107     }
00108     bool state()const{return m_state;}
00109 
00110     HMENU m_hMenu; UINT m_uPos;
00111     Command *m_cmd1;
00112     Command *m_cmd2;
00113     bool m_state;
00114 };
00115 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00116 void WinGUI::menuSeparator()
00117 {
00118     ::AppendMenu(m_currentMenu, MF_SEPARATOR, 0, 0);
00119 }
00120 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00121 GUI::Toggle* WinGUI::addToggleToMenu(const char* name, bool state,  Command* cmd1, Command* cmd2)
00122 {
00123     UINT uPos = cmdOffset+(m_menuId++);
00124     GUI::Toggle* t = new Toggle(m_currentMenu, uPos, cmd1,cmd2,state);
00125     m_commands.push_back(t);
00126     m_owned_commands.push_back(t);
00127     ::AppendMenu(m_currentMenu, MF_STRING | (state? MF_CHECKED : MF_UNCHECKED ), uPos,  name);
00128     return t;
00129 }
00130 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00131 void WinGUI::execute(WPARAM cmdindex)
00132 {
00133     m_commands[cmdindex-cmdOffset]->execute();
00134 }
00135 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00136 void WinGUI::setTitle(const char* newtitle)
00137 {
00138     ::SetWindowText(s_hwnd, newtitle);
00139 }
00140 
00141 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00142 //                     commands
00143 void WinGUI::start()
00144 {
00145     static bool first=true;
00146     if( first ) {
00147         // first-time setup. Allow message loop to be recalled as a result of a message
00148         ::SetMenu(s_hwnd,m_menuBar);
00149     
00150         int cmdShow=SW_SHOWDEFAULT      ;
00151         ::ShowWindow(s_hwnd, cmdShow);
00152         first = false;
00153     }
00154     running = true;
00155 
00156 }
00157 void CALLBACK MyTimerProc(HWND hwnd, UINT uMsg, UINT idEvnet, DWORD dwTIme)
00158 {
00159         GUI::running = false;
00160 }
00161 void WinGUI::run(int pause_interval)
00162 {
00163     start(); // make sure windows set up
00164     MSG         msg;
00165         const UINT uIDEevnt=1;
00166         if(pause_interval==0) return; 
00167         if( pause_interval>0 )  ::SetTimer(s_hwnd, uIDEevnt, pause_interval, MyTimerProc);
00168         
00169     // note that the loop can be stopped, with return from this function,
00170     // by setting GUI::running to false.
00171     while( running && ::GetMessage(&msg, NULL, 0, 0)) {
00172         ::TranslateMessage(&msg);
00173         ::DispatchMessage(&msg);
00174     }
00175         if( pause_interval>0) ::KillTimer(s_hwnd, uIDEevnt);
00176     // unless it is a quit message, reset when leave so main loop does not exit 
00177     if( !s_quitting ) running = true;  
00178     
00179 }
00180 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00181 void WinGUI::processMessages()
00182 {
00183     // used to check that messages are processed
00184     MSG msg;
00185     
00186     while( ::PeekMessage(&msg, 0,0,0,PM_REMOVE))
00187     {
00188         ::TranslateMessage(&msg);
00189         ::DispatchMessage(&msg);
00190     }
00191 }
00192 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00193 void WinGUI::quit(){::PostQuitMessage(0); s_quitting=true; running=false;}
00194 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00195 //                     graphics
00196 // return pointer to a SceneControl sub class that will write into the main window
00197 gui::SceneControl*
00198 WinGUI::graphicsWindow(float size, int initial_view)
00199 {
00200     if( s_graphics_window==0)  
00201         return s_graphics_window = new WinScene(s_hwnd, size, initial_view);
00202 
00203     // second window: use same class
00204     HWND hwnd = ::CreateWindow(szAppName, 
00205         "plots",
00206         ( WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_POPUP | WS_SYSMENU
00207         | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_VISIBLE),
00208         50,  50, //CW_USEDEFAULT, 0,
00209         500, 500, //CW_USEDEFAULT, 0,
00210         NULL, NULL, 
00211         s_instance, 
00212         NULL);
00213     return s_2d_window = new WinScene(hwnd, size);
00214 
00215 }
00216 
00217 
00218 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00219 //          text output
00220 std::ostream*
00221 WinGUI::textWindow(const char* name)
00222 {
00223     if( m_text_window==0) {
00224         if( s_text_window ==0 ) s_text_window = new WinGUIostream( name, s_hwnd, s_instance);
00225         m_text_window = s_text_window;
00226     }
00227     return m_text_window;
00228 }
00229 
00230 
00231 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00232 //         file name dialog
00233 #include <commdlg.h>
00234 char *
00235 WinGUI::askForFileName(const char* startDir , const char* label, const char* filter)
00236 {
00237     static OPENFILENAME ofn;
00238 
00239     char szDirName[256];
00240     char szFile[256], szFileTitle[256];
00241     char  szFilter[256];
00242     
00243     strncpy(szFilter, filter, sizeof(szFilter));
00244     szFile[0] = '\0';
00245     
00246     // get startDir, strip after last "\" character, since it is the last file;
00247     strncpy(szDirName, startDir, sizeof(szDirName));
00248     int lpos=0; 
00249     for( int pos = 0; szDirName[pos]!='\0' ; ++pos ) {
00250         if( szDirName[pos]=='\\')lpos=pos;
00251     }
00252     if( lpos) szDirName[lpos]='\0';
00253     
00254     UINT cbString = strlen(szFilter);
00255     char  chReplace = szFilter[cbString - 1]; /* retrieve wild character */
00256     
00257     for (UINT i = 0; szFilter[i] != '\0'; i++) {
00258         if (szFilter[i] == chReplace)
00259             szFilter[i] = '\0';
00260     }
00261     
00262     
00263     /* Set all structure members to zero. */
00264     
00265     memset(&ofn, 0, sizeof(OPENFILENAME));
00266     
00267     ofn.lStructSize = sizeof(OPENFILENAME);
00268     ofn.hwndOwner = s_hwnd;
00269     ofn.lpstrFilter = szFilter;
00270     ofn.nFilterIndex = 1;
00271     
00272     ofn.lpstrTitle= label; 
00273     ofn.lpstrFile= szFile;
00274     ofn.nMaxFile = sizeof(szFile);
00275     ofn.lpstrFileTitle = szFileTitle;
00276     ofn.nMaxFileTitle = sizeof(szFileTitle);
00277     ofn.lpstrInitialDir = szDirName;
00278     ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY ; //OFN_SHOWHELP | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
00279     
00280     int result =::GetOpenFileName(&ofn);
00281     
00282     // convert backslashes
00283     /*   for (i = 0; ofn.lpstrFile[i] != '\0'; i++) {
00284     if (ofn.lpstrFile[i] == '\\')
00285     ofn.lpstrFile[i] = '/';
00286 }*/
00287     return result ? ofn.lpstrFile : 0;
00288     
00289 }
00290 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00291 //                   askuser dialog box
00292 static char userAnswer[80];
00293 static const char* defString;
00294 static const char* prmpt;
00295 BOOL APIENTRY AskUserProc(HWND hdlg, UINT wMsg,
00296                           WPARAM wParam, LPARAM lParam)
00297 {
00298     HWND textBox = ::GetDlgItem(hdlg,IDC_ASKUSER);
00299     switch( wMsg )
00300     {
00301     case WM_INITDIALOG:
00302         // set prompt in title bar and default in text box
00303         ::SendMessage(textBox, WM_SETTEXT, 0, (LPARAM)defString);
00304         
00305         // this should select the text just set
00306         ::SendMessage(textBox,EM_SETSEL,0, -1);
00307         
00308         ::SendMessage(hdlg,WM_SETTEXT, 0, (LPARAM)prmpt);
00309         return TRUE;
00310         
00311     case WM_COMMAND:
00312         switch (wParam )
00313         {
00314         case IDOK:
00315             ::SendMessage(textBox, WM_GETTEXT, sizeof(userAnswer), (LPARAM)userAnswer);
00316             ::EndDialog(hdlg, TRUE);
00317             return TRUE;
00318         case IDCANCEL:
00319             ::EndDialog(hdlg, FALSE);
00320             return TRUE;
00321         }
00322         return TRUE;
00323         default:
00324             return FALSE;
00325     }
00326 }
00327 char*
00328 WinGUI::askUser(const char* promptString, const char* defaultString)
00329 {
00330     userAnswer[0]='\0';
00331     defString = defaultString;
00332     prmpt = promptString;
00333     int status = ::DialogBox( s_instance,MAKEINTRESOURCE(IDD_ASKUSER), s_hwnd, AskUserProc);
00334     return  userAnswer;
00335 }
00336 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00337 //                   message
00338 void
00339 WinGUI::inform(const char* msg)
00340 {
00341     ::MessageBox(s_hwnd, (char*)msg, "Inform", MB_OK);
00342 }
00343 
00344 #endif

Generated at Mon Nov 26 18:18:11 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000