Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

Win_main.cpp

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 ===========================================================================
00021 */
00022 #include "stdafx.h"
00023 #include "qe3.h"
00024 #include <process.h>
00025 #include "mru.h"
00026 #include "entityw.h"
00027 #include "PrefsDlg.h"
00028 
00029 static HWND      s_hwndToolbar;
00030 
00031 BOOL SaveRegistryInfo(const char *pszName, void *pvBuf, long lSize);
00032 BOOL LoadRegistryInfo(const char *pszName, void *pvBuf, long *plSize);
00033 
00034 static HWND CreateMyStatusWindow(HINSTANCE hInst);
00035 static HWND CreateToolBar(HINSTANCE hinst);
00036 
00037 extern void WXY_Print( void );
00038 
00039 /*
00040 ==============================================================================
00041 
00042   MENU
00043 
00044 ==============================================================================
00045 */
00046 
00047 void OpenDialog (void);
00048 void SaveAsDialog (bool bRegion);
00049 qboolean ConfirmModified (void);
00050 void  Select_Ungroup (void);
00051 
00052 void QE_ExpandBspString (char *bspaction, char *out, char *mapname, bool useTemps)
00053 {
00054     char    *in;
00055     char    src[2048];
00056     char    rsh[2048];
00057     char    base[2048];
00058 
00059     strcpy(src, mapname);
00060     strlwr(src);
00061     in = strstr(src, "maps/");
00062     if (!in)
00063     {
00064         in = strstr(src, "maps\\");
00065     }
00066     if (in)
00067     {
00068         in += 5;
00069         strcpy(base, in);
00070         in = base;
00071         while (*in)
00072         {
00073             if (*in == '\\')
00074             {
00075                 *in = '/';
00076             }
00077             in++;
00078         }
00079     }
00080     else
00081     {
00082         ExtractFileName (mapname, base);
00083     }
00084 
00085   if (useTemps) {
00086     CString str;
00087     CString strExt = "map";
00088     if ( strstr(mapname, ".reg") ) {
00089       strExt = "reg";
00090     }
00091     str.Format("%s/maps/%i.%s", ValueForKey(g_qeglobals.d_project_entity, "remotebasepath"), ::GetTickCount(), strExt);
00092     CopyFile(mapname, str, FALSE);
00093       sprintf (src, "-tempname %s %s/maps/%s", str, ValueForKey(g_qeglobals.d_project_entity, "remotebasepath"), base);
00094   } else {
00095       sprintf (src, "%s/maps/%s", ValueForKey(g_qeglobals.d_project_entity, "remotebasepath"), base);
00096   }
00097     strcpy (rsh, ValueForKey(g_qeglobals.d_project_entity, "rshcmd"));
00098 
00099   QE_ConvertDOSToUnixName(src, src);
00100 
00101     in = ValueForKey( g_qeglobals.d_project_entity, bspaction );
00102     while (*in)
00103     {
00104         if (in[0] == '!')
00105         {
00106             strcpy (out, rsh);
00107             out += strlen(rsh);
00108             in++;
00109             continue;
00110         }
00111         if (in[0] == '$')
00112         {
00113             strcpy (out, src);
00114             out += strlen(src);
00115             in++;
00116             continue;
00117         }
00118         if (in[0] == '@')
00119         {
00120             *out++ = '"';
00121             in++;
00122             continue;
00123         }
00124         *out++ = *in++;
00125     }
00126     *out = 0;
00127 }
00128 
00129 void FindReplace(CString& strContents, const char* pTag, const char* pValue)
00130 {
00131   if (strcmp(pTag, pValue) == 0)
00132     return;
00133   for (int nPos = strContents.Find(pTag); nPos >= 0; nPos = strContents.Find(pTag))
00134   {
00135     int nRightLen = strContents.GetLength() - strlen(pTag) - nPos;
00136     CString strLeft = strContents.Left(nPos);
00137     CString strRight = strContents.Right(nRightLen);
00138     strLeft += pValue;
00139     strLeft += strRight;
00140     strContents = strLeft;
00141   }
00142 }
00143 
00144 
00145 
00146 HWND g_hWnd = NULL;
00147 HANDLE g_hToolThread = NULL;
00148 CString g_strParams;
00149 
00150 UINT ToolThread(LPVOID pParam)
00151 {
00152   char* p = reinterpret_cast<char*>(pParam);
00153   if (g_PrefsDlg.m_bPAK)
00154     RunTools(p, g_hWnd, g_PrefsDlg.m_strPAKFile);
00155   else
00156     RunTools(p, g_hWnd, "");
00157   g_hToolThread = NULL;
00158   delete []p;
00159   return 0;
00160 }
00161 
00162 void ThreadTools(char* p)
00163 {
00164   CWinThread* pThread = AfxBeginThread(ToolThread, reinterpret_cast<LPVOID>(p));
00165   g_hToolThread = pThread->m_hThread;
00166 }
00167 
00168 HWND g_hwndFoundIt = NULL;
00169 
00170 BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam) {
00171   char buff[1024];
00172   const char* p = reinterpret_cast<const char*>(lParam);
00173   GetWindowText(hwnd, buff, 1024);
00174   if (!strcmpi(p, buff)) {
00175     g_hwndFoundIt = hwnd;
00176     return 1;
00177   }
00178   return 1;
00179 }
00180 
00181 
00182 HWND FindAnyWindow(const char *pTitle) {
00183   HWND hwndDesktop = GetDesktopWindow();
00184   g_hwndFoundIt = NULL;
00185   if ( hwndDesktop ) {
00186     EnumChildWindows(hwndDesktop, (WNDENUMPROC)EnumChildProc, reinterpret_cast<LPARAM>(pTitle));
00187   }
00188   return g_hwndFoundIt;
00189 }
00190 
00191 
00192 const UINT wm_AddCommand = RegisterWindowMessage( "Q3MPC_AddCommand" );
00193 
00194 CTime g_tBegin;
00195 void RunBsp (char *command)
00196 {
00197     char    sys[2048];
00198     char    batpath[2048];
00199     char    outputpath[2048];
00200     char    temppath[1024];
00201     char    name[2048];
00202     char    cWork[2048];
00203     FILE    *hFile;
00204     BOOL    ret;
00205     PROCESS_INFORMATION ProcessInformation;
00206     STARTUPINFO startupinfo;
00207   HWND hwndPClient = NULL;
00208 
00209   g_hWnd = g_pParentWnd->GetSafeHwnd();
00210     SetInspectorMode(W_CONSOLE);
00211   g_tBegin = CTime::GetCurrentTime();
00212 
00213     
00214     DWORD   dwExitcode;
00215   ret = GetExitCodeProcess (g_hToolThread, &dwExitcode);
00216   if (dwExitcode != STILL_ACTIVE)
00217     g_hToolThread = NULL;
00218 
00219     if (bsp_process || g_hToolThread)
00220     {
00221         Sys_Printf ("BSP is still going...\n");
00222         return;
00223     }
00224 
00225   outputpath[0] = '\0';
00226     GetTempPath(512, temppath);
00227 
00228   CString strOutFile = temppath;
00229   AddSlash(strOutFile);
00230   strOutFile += "junk.txt";
00231 
00232     sprintf (outputpath, " >>%s\r\n", strOutFile);
00233 
00234   strcpy (name, currentmap);
00235     if (region_active)
00236     {
00237         Map_SaveFile (name, false);
00238         StripExtension (name);
00239         strcat (name, ".reg");
00240     }
00241 
00242     Map_SaveFile (name, region_active);
00243 
00244   // FIXME: this code just gets worse and worse
00245   CString strPath, strFile;
00246 
00247   char *rsh = ValueForKey(g_qeglobals.d_project_entity, "rshcmd");
00248   if (rsh == NULL)
00249   {
00250     ExtractPath_and_Filename(name, strPath, strFile);
00251     AddSlash(strPath);
00252     BuildShortPathName(strPath, cWork, 1024);
00253     strcat(cWork, strFile);
00254   }
00255   else
00256   {
00257     strcpy(cWork, name);
00258   }
00259 
00260   hwndPClient = FindWindow(NULL, "Q3Map Process Client");
00261   if ( hwndPClient == NULL ) {
00262     hwndPClient = FindAnyWindow("Q3Map Process Client");
00263   }
00264 
00265   Sys_Printf("Window info for Process Client %i\n", reinterpret_cast<int>(hwndPClient));
00266 
00267   bool processServer = (rsh && strlen(rsh) > 0 && hwndPClient);
00268 
00269   QE_ExpandBspString (command, sys, cWork, processServer);
00270 
00271   // if we can find the q3map process server running 
00272   // we will submit maps to it instead of via createprocess
00273   //
00274   if (processServer)
00275   {
00276     CString str;
00277     char cBuff[2048];
00278     char *pStart = sys;
00279     char *pEnd = strstr(pStart, "&&");
00280     while (pEnd)
00281     {
00282       int nLen = pEnd-pStart-1;
00283       strncpy(cBuff, pStart, nLen);
00284       cBuff[nLen] = 0;
00285       str = cBuff;
00286       FindReplace(str, rsh, "");
00287       str.TrimLeft(' ');
00288       str.TrimRight(' ');
00289       ATOM a = GlobalAddAtom(str);
00290       PostMessage(hwndPClient, wm_AddCommand, 0, (LPARAM)a);
00291       pStart = pEnd+2;
00292       pEnd = strstr(pStart, "&&");
00293     }
00294     str = pStart;
00295     FindReplace(str, rsh, "");
00296     str.TrimLeft(' ');
00297     str.TrimRight(' ');
00298     ATOM a = GlobalAddAtom(str);
00299     PostMessage(hwndPClient, wm_AddCommand, 0, (LPARAM)a);
00300     Sys_Printf("Commands sent to Q3Map Process Client\n");
00301     return;
00302   }
00303 
00304   CString strSys = sys;
00305 
00306   FindReplace(strSys, "&&", outputpath);
00307   strcpy(sys, strSys);
00308   strcat(sys, outputpath);
00309 
00310   if (g_PrefsDlg.m_bInternalBSP)
00311   {
00312     g_tBegin = CTime::GetCurrentTime();
00313     strSys.MakeLower();
00314     char* p = new char[strSys.GetLength()+1];
00315     strcpy(p, strSys.GetBuffer(0));
00316     ThreadTools(p);
00317   }
00318   else
00319   {
00320       Sys_ClearPrintf ();
00321       Sys_Printf ("==================\nRunning bsp command...\n");
00322       Sys_Printf ("\n%s\n", sys);
00323 
00324       //++timo removed the old way BSP commands .. dumping to junk.txt doesn't work on my win98 box
00325       // FIXME : will most likely break Quake2 BSP commands, is fitted to a one-lined sys command
00326       //
00327       // write qe3bsp.bat
00328       //
00329 
00330       sprintf (batpath, "%sqe3bsp.bat", temppath);
00331       hFile = fopen(batpath, "w");
00332       if (!hFile)
00333           Error ("Can't write to %s", batpath);
00334       fprintf (hFile, sys);
00335       fclose (hFile);
00336 
00337       Pointfile_Delete ();
00338 
00339       // delete junk.txt file
00340       remove(strOutFile);
00341 
00342       GetStartupInfo (&startupinfo);
00343 
00344       ret = CreateProcess(
00345           batpath,
00346           NULL,
00347           NULL,
00348           NULL,
00349           FALSE,
00350           0,
00351           NULL,
00352           NULL,
00353           &startupinfo,
00354           &ProcessInformation
00355           );
00356 
00357       if (!ret)
00358           Error ("CreateProcess failed");
00359 
00360       bsp_process = ProcessInformation.hProcess;
00361 
00362       Sleep (100);  // give the new process a chance to open it's window
00363 
00364       BringWindowToTop( g_qeglobals.d_hwndMain );   // pop us back on top
00365 #if 0
00366       //
00367       // write qe3bsp.bat
00368       //
00369       sprintf (batpath, "%sqe3bsp.bat", temppath);
00370       hFile = fopen(batpath, "w");
00371       if (!hFile)
00372           Error ("Can't write to %s", batpath);
00373       fprintf (hFile, sys);
00374       fclose (hFile);
00375 
00376       //
00377       // write qe3bsp2.bat
00378       //
00379       sprintf (batpath, "%sqe3bsp2.bat", temppath);
00380       hFile = fopen(batpath, "w");
00381       if (!hFile)
00382           Error ("Can't write to %s", batpath);
00383       fprintf (hFile, "%sqe3bsp.bat > %s", temppath, outputpath);
00384       fclose (hFile);
00385 
00386       Pointfile_Delete ();
00387 
00388       GetStartupInfo (&startupinfo);
00389 
00390       ret = CreateProcess(
00391       batpath,      // pointer to name of executable module 
00392       NULL,         // pointer to command line string
00393       NULL,         // pointer to process security attributes 
00394       NULL,         // pointer to thread security attributes 
00395       FALSE,            // handle inheritance flag 
00396       0 /*DETACHED_PROCESS*/,       // creation flags
00397       NULL,         // pointer to new environment block 
00398       NULL,         // pointer to current directory name 
00399       &startupinfo, // pointer to STARTUPINFO 
00400       &ProcessInformation   // pointer to PROCESS_INFORMATION  
00401      );
00402 
00403       if (!ret)
00404           Error ("CreateProcess failed");
00405 
00406       bsp_process = ProcessInformation.hProcess;
00407 
00408       Sleep (100);  // give the new process a chance to open it's window
00409 
00410       //BringWindowToTop( g_qeglobals.d_hwndMain ); // pop us back on top
00411       //SetFocus (g_qeglobals.d_hwndCamera);
00412 #endif
00413   }
00414 }
00415 
00416 void DLLBuildDone()
00417 {
00418   g_hToolThread = NULL;
00419   CTime tEnd = CTime::GetCurrentTime();
00420   CTimeSpan tElapsed = tEnd - g_tBegin;
00421   CString strElapsed;
00422   strElapsed.Format("Run time was %i hours, %i minutes and %i seconds", tElapsed.GetHours(), tElapsed.GetMinutes(), tElapsed.GetSeconds());
00423     Sys_Printf(strElapsed.GetBuffer(0));
00424     Pointfile_Check();
00425 
00426   if (g_PrefsDlg.m_bRunQuake == TRUE)
00427   {
00428     char cCurDir[1024];
00429     GetCurrentDirectory(1024, cCurDir);
00430     CString strExePath = g_PrefsDlg.m_strQuake2;
00431     CString strOrgPath;
00432     CString strOrgFile;
00433     ExtractPath_and_Filename(currentmap, strOrgPath, strOrgFile);
00434     if (g_PrefsDlg.m_bSetGame == TRUE) // run in place with set game.. don't copy map
00435     {
00436         CString strBasePath = ValueForKey(g_qeglobals.d_project_entity, "basepath");
00437       strExePath += " +set game ";
00438       strExePath += strBasePath;
00439       WinExec(strExePath, SW_SHOW);
00440     }
00441     else
00442     {
00443       CString strCopyPath = strExePath;
00444       char* pBuffer = strCopyPath.GetBufferSetLength(_MAX_PATH + 1);
00445       pBuffer[strCopyPath.ReverseFind('\\') + 1] = '\0';
00446       strCopyPath.ReleaseBuffer();
00447       SetCurrentDirectory(strCopyPath);
00448       CString strOrgPath;
00449       CString strOrgFile;
00450       ExtractPath_and_Filename(currentmap, strOrgPath, strOrgFile);
00451       AddSlash(strCopyPath);
00452       FindReplace(strOrgFile, ".map", ".bsp");
00453       strCopyPath += "\\baseq2\\maps\\";
00454       strCopyPath += strOrgFile;
00455       AddSlash(strOrgPath);
00456       strOrgPath += strOrgFile;
00457       bool bRun = (strOrgPath.CompareNoCase(strCopyPath) == 0);
00458       if (!bRun)
00459         bRun = (CopyFile(strOrgPath, strCopyPath, FALSE) == TRUE);
00460       if (bRun)
00461       {
00462         FindReplace(strOrgFile, ".bsp", "");
00463         strExePath += " +map ";
00464         strExePath += strOrgFile;
00465         WinExec(strExePath, SW_SHOW);
00466       }
00467     }
00468     SetCurrentDirectory(cCurDir);
00469   }
00470 
00471 }
00472 
00473 /*
00474 =============
00475 DoColor
00476 
00477 =============
00478 */
00479 
00480 class CMyColorDialog : public CColorDialog 
00481 {
00482   DECLARE_DYNCREATE(CMyColorDialog);
00483      // Construction
00484 public:
00485      CMyColorDialog( COLORREF clrInit = 0, DWORD dwFlags = 0, CWnd*
00486 pParentWnd = NULL );
00487      // Statics
00488 protected:
00489      enum { NCUSTCOLORS = 16 };
00490      static COLORREF c_CustColors[NCUSTCOLORS];
00491      static COLORREF c_LastCustColors[NCUSTCOLORS];
00492      static bool c_NeedToInitCustColors;
00493 protected:
00494      static void InitCustColors();
00495      static void SaveCustColors();
00496      // Dialog Data
00497 protected:
00498      //{{AFX_DATA(CMyColorDialog)
00499      //}}AFX_DATA
00500      // Overrides
00501 protected:
00502      // ClassWizard generate virtual function overrides
00503      //{{AFX_VIRTUAL(CMyColorDialog)
00504 public:
00505      virtual int DoModal();
00506 protected:
00507      virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
00508      //}}AFX_VIRTUAL
00509      // Implementation
00510 protected:
00511      // Generated message map functions
00512      //{{AFX_MSG(CMyColorDialog)
00513      //}}AFX_MSG
00514      DECLARE_MESSAGE_MAP()
00515 };
00516 
00517 IMPLEMENT_DYNCREATE(CMyColorDialog, CColorDialog)
00518 
00519 bool CMyColorDialog::c_NeedToInitCustColors = true;
00520 COLORREF CMyColorDialog::c_CustColors[];
00521 COLORREF CMyColorDialog::c_LastCustColors[];
00522 
00523 #define SECTION _T("Custom Colors")
00524 
00525 void CMyColorDialog::InitCustColors() {
00526      for (int i = 0; i < NCUSTCOLORS; i++) {
00527           CString entry; entry.Format("%d",i);
00528           c_LastCustColors[i] = c_CustColors[i] =
00529         ::AfxGetApp()->GetProfileInt(SECTION,entry,RGB(255,255,255));
00530      }
00531      c_NeedToInitCustColors= false;
00532 }
00533 
00534 void CMyColorDialog::SaveCustColors() {
00535      for (int i = 0; i < NCUSTCOLORS; i++) {
00536           if (c_LastCustColors[i] != c_CustColors[i]) {
00537                CString entry; entry.Format("%d",i);
00538                if (c_CustColors[i] == RGB(255,255,255)) {
00539                     ::AfxGetApp()->WriteProfileString(SECTION,entry,NULL);
00540                } else {
00541                     ::AfxGetApp()->WriteProfileInt(SECTION, entry,c_CustColors[i]);
00542                }
00543                c_LastCustColors[i] = c_CustColors[i];
00544           }
00545      }
00546 }
00547 
00548 CMyColorDialog::CMyColorDialog( COLORREF clrInit, DWORD dwFlags, 
00549         CWnd* pParentWnd) : CColorDialog(clrInit,dwFlags,pParentWnd)
00550 {
00551      //{{AFX_DATA_INIT(CMyColorDialog)
00552      //}}AFX_DATA_INIT
00553      if (c_NeedToInitCustColors) {
00554           InitCustColors();
00555      }
00556      m_cc.lpCustColors = c_CustColors;
00557 }
00558 
00559 int CMyColorDialog::DoModal() {
00560      int code = CColorDialog::DoModal();
00561      SaveCustColors();
00562      return code;
00563 }
00564 
00565 void CMyColorDialog::DoDataExchange(CDataExchange* pDX) {
00566      // overridden (calls this base class)
00567      CColorDialog::DoDataExchange(pDX);
00568      //{{AFX_DATA_MAP(CMyColorDialog)
00569      //}}AFX_DATA_MAP
00570 }
00571 
00572 BEGIN_MESSAGE_MAP(CMyColorDialog, CColorDialog)
00573 //{{AFX_MSG_MAP(CMyColorDialog)
00574 //}}AFX_MSG_MAP
00575 END_MESSAGE_MAP()
00576 
00577 void DoNewColor(int* i1, int* i2, int* i3)
00578 {
00579     COLORREF cr = (*i1) +
00580                 ((*i2) <<8) +
00581                     ((*i3) <<16);
00582   CMyColorDialog dlg(cr, CC_FULLOPEN | CC_RGBINIT);
00583   if (dlg.DoModal() == IDOK)
00584   {
00585       *i1 = (dlg.m_cc.rgbResult & 255);
00586       *i2 = ((dlg.m_cc.rgbResult >> 8) & 255);
00587       *i3 = ((dlg.m_cc.rgbResult >> 16) & 255);
00588   }
00589 
00590 }
00591 
00592 
00593 qboolean DoColor(int iIndex)
00594 {
00595 
00596     COLORREF cr = (int)(g_qeglobals.d_savedinfo.colors[iIndex][0]*255) +
00597                 (((int)(g_qeglobals.d_savedinfo.colors[iIndex][1]*255))<<8) +
00598                     (((int)(g_qeglobals.d_savedinfo.colors[iIndex][2]*255))<<16);
00599   CMyColorDialog dlg(cr, CC_FULLOPEN | CC_RGBINIT);
00600   if (dlg.DoModal() == IDOK)
00601   {
00602       g_qeglobals.d_savedinfo.colors[iIndex][0] = (dlg.m_cc.rgbResult&255)/255.0;
00603       g_qeglobals.d_savedinfo.colors[iIndex][1] = ((dlg.m_cc.rgbResult>>8)&255)/255.0;
00604       g_qeglobals.d_savedinfo.colors[iIndex][2] = ((dlg.m_cc.rgbResult>>16)&255)/255.0;
00605 
00606       /* 
00607       ** scale colors so that at least one component is at 1.0F 
00608       ** if this is meant to select an entity color
00609       */
00610       if ( iIndex == COLOR_ENTITY )
00611       {
00612           float largest = 0.0F;
00613 
00614           if ( g_qeglobals.d_savedinfo.colors[iIndex][0] > largest )
00615               largest = g_qeglobals.d_savedinfo.colors[iIndex][0];
00616           if ( g_qeglobals.d_savedinfo.colors[iIndex][1] > largest )
00617               largest = g_qeglobals.d_savedinfo.colors[iIndex][1];
00618           if ( g_qeglobals.d_savedinfo.colors[iIndex][2] > largest )
00619               largest = g_qeglobals.d_savedinfo.colors[iIndex][2];
00620 
00621           if ( largest == 0.0F )
00622           {
00623               g_qeglobals.d_savedinfo.colors[iIndex][0] = 1.0F;
00624               g_qeglobals.d_savedinfo.colors[iIndex][1] = 1.0F;
00625               g_qeglobals.d_savedinfo.colors[iIndex][2] = 1.0F;
00626           }
00627           else
00628           {
00629               float scaler = 1.0F / largest;
00630 
00631               g_qeglobals.d_savedinfo.colors[iIndex][0] *= scaler;
00632               g_qeglobals.d_savedinfo.colors[iIndex][1] *= scaler;
00633               g_qeglobals.d_savedinfo.colors[iIndex][2] *= scaler;
00634           }
00635       }
00636 
00637       Sys_UpdateWindows (W_ALL);
00638       return true;
00639   }
00640   else return false;
00641 
00642 }
00643 
00644 
00645 /* Copied from MSDN */
00646 
00647 BOOL DoMru(HWND hWnd,WORD wId)
00648 {
00649     char szFileName[128];
00650     OFSTRUCT of;
00651     BOOL fExist;
00652 
00653     GetMenuItem(g_qeglobals.d_lpMruMenu, wId, TRUE, szFileName, sizeof(szFileName));
00654 
00655     // Test if the file exists.
00656 
00657     fExist = OpenFile(szFileName ,&of,OF_EXIST) != HFILE_ERROR;
00658 
00659     if (fExist) {
00660 
00661         // Place the file on the top of MRU.
00662         AddNewItem(g_qeglobals.d_lpMruMenu,(LPSTR)szFileName);
00663 
00664         // Now perform opening this file !!!
00665         Map_LoadFile (szFileName);  
00666     }
00667     else
00668         // Remove the file on MRU.
00669         DelMenuItem(g_qeglobals.d_lpMruMenu,wId,TRUE);
00670 
00671     // Refresh the File menu.
00672     PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu,GetSubMenu(GetMenu(hWnd),0),
00673             ID_FILE_EXIT);
00674 
00675     return fExist;
00676 }
00677 
00678 
00679 
00680 /*
00681 ==============
00682 Main_Create
00683 ==============
00684 */
00685 
00686 void MFCCreate (HINSTANCE hInstance)
00687 {
00688     HMENU hMenu = NULL;
00689     int i = sizeof(g_qeglobals.d_savedinfo);
00690   long l = i;
00691 
00692   g_qeglobals.d_savedinfo.exclude |= (EXCLUDE_HINT | EXCLUDE_CLIP);
00693     LoadRegistryInfo("SavedInfo", &g_qeglobals.d_savedinfo, &l);
00694 
00695   int nOldSize = g_qeglobals.d_savedinfo.iSize;
00696     if (g_qeglobals.d_savedinfo.iSize != sizeof(g_qeglobals.d_savedinfo))
00697     {
00698         // fill in new defaults
00699         g_qeglobals.d_savedinfo.iSize = sizeof(g_qeglobals.d_savedinfo);
00700         g_qeglobals.d_savedinfo.fGamma = 1.0;
00701         g_qeglobals.d_savedinfo.iTexMenu = ID_VIEW_BILINEARMIPMAP;
00702     g_qeglobals.d_savedinfo.m_nTextureTweak = 1;
00703   
00704         //g_qeglobals.d_savedinfo.exclude = INCLUDE_EASY | INCLUDE_NORMAL | INCLUDE_HARD | INCLUDE_DEATHMATCH;
00705         g_qeglobals.d_savedinfo.show_coordinates = true;
00706         g_qeglobals.d_savedinfo.show_names       = false;
00707 
00708         for (i=0 ; i<3 ; i++)
00709         {
00710             g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][i] = 0.25;
00711             g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][i] = 1.0;
00712             g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR][i] = 0.75;
00713             g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][i] = 0.5;
00714             g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][i] = 0.25;
00715         }
00716 
00717         g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][0] = 0.0;
00718         g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][1] = 0.0;
00719         g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][2] = 1.0;
00720 
00721         g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][0] = 0.0;
00722         g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][1] = 0.0;
00723         g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][2] = 0.0;
00724 
00725         g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0] = 1.0;
00726         g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1] = 0.0;
00727         g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2] = 0.0;
00728 
00729         g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][0] = 0.0;
00730         g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][1] = 0.0;
00731         g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][2] = 1.0;
00732 
00733         g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][0] = 0.0;
00734         g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][1] = 0.0;
00735         g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][2] = 0.0;
00736 
00737         g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][0] = 0.5;
00738         g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][1] = 0.0;
00739         g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][2] = 0.75;
00740 
00741 
00742     // old size was smaller, reload original prefs
00743     if (nOldSize < sizeof(g_qeglobals.d_savedinfo))
00744     {
00745       long l = nOldSize;
00746         LoadRegistryInfo("SavedInfo", &g_qeglobals.d_savedinfo, &l);
00747     }
00748 
00749     }
00750     if ( ( hMenu = GetMenu( g_qeglobals.d_hwndMain ) ) != 0 )
00751     {
00752         // by default all of these are checked because that's how they're defined in the menu editor
00753         if ( !g_qeglobals.d_savedinfo.show_names )
00754             CheckMenuItem( hMenu, ID_VIEW_SHOWNAMES, MF_BYCOMMAND | MF_UNCHECKED );
00755         if ( !g_qeglobals.d_savedinfo.show_coordinates )
00756             CheckMenuItem( hMenu, ID_VIEW_SHOWCOORDINATES, MF_BYCOMMAND | MF_UNCHECKED );
00757 
00758         if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTS )
00759             CheckMenuItem( hMenu, ID_VIEW_SHOWLIGHTS, MF_BYCOMMAND | MF_UNCHECKED );
00760         if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_ENT )
00761             CheckMenuItem( hMenu, ID_VIEW_ENTITY, MF_BYCOMMAND | MF_UNCHECKED );
00762         if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS )
00763             CheckMenuItem( hMenu, ID_VIEW_SHOWPATH, MF_BYCOMMAND | MF_UNCHECKED );
00764         if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_WATER )
00765             CheckMenuItem( hMenu, ID_VIEW_SHOWWATER, MF_BYCOMMAND | MF_UNCHECKED );
00766         if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_WORLD )
00767             CheckMenuItem( hMenu, ID_VIEW_SHOWWORLD, MF_BYCOMMAND | MF_UNCHECKED );
00768         if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLIP )
00769             CheckMenuItem( hMenu, ID_VIEW_SHOWCLIP, MF_BYCOMMAND | MF_UNCHECKED );
00770         if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_HINT )
00771             CheckMenuItem( hMenu, ID_VIEW_SHOWHINT, MF_BYCOMMAND | MF_UNCHECKED );
00772         if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_CAULK )
00773             CheckMenuItem( hMenu, ID_VIEW_SHOWCAULK, MF_BYCOMMAND | MF_UNCHECKED );
00774     }
00775 
00776 }
00777 
00778 
00779 /*
00780 =============================================================
00781 
00782 REGISTRY INFO
00783 
00784 =============================================================
00785 */
00786 
00787 BOOL SaveRegistryInfo(const char *pszName, void *pvBuf, long lSize)
00788 {
00789     LONG lres;
00790     DWORD dwDisp;
00791     HKEY  hKeyId;
00792 
00793     if (g_qeglobals.use_ini)
00794     {
00795         lres = RegCreateKeyEx(HKEY_CURRENT_USER, g_qeglobals.use_ini_registry, 0, NULL,
00796             REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyId, &dwDisp);
00797     }
00798     else
00799     {
00800         lres = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Q3Radiant\\Q3Radiant", 0, NULL, 
00801                 REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyId, &dwDisp);
00802     }
00803     
00804     if (lres != ERROR_SUCCESS)
00805         return FALSE;
00806 
00807     lres = RegSetValueEx(hKeyId, pszName, 0, REG_BINARY, (unsigned char*)pvBuf, lSize);
00808     
00809     RegCloseKey(hKeyId);
00810 
00811     if (lres != ERROR_SUCCESS)
00812         return FALSE;
00813 
00814     return TRUE;
00815 }
00816 
00817 BOOL LoadRegistryInfo(const char *pszName, void *pvBuf, long *plSize)
00818 {
00819     HKEY  hKey;
00820     long lres, lType, lSize;
00821 
00822     if (plSize == NULL)
00823         plSize = &lSize;
00824 
00825     if (g_qeglobals.use_ini)
00826     {
00827         lres = RegOpenKeyEx(HKEY_CURRENT_USER, g_qeglobals.use_ini_registry, 0, KEY_READ, &hKey);
00828     }
00829     else
00830     {
00831         lres = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Q3Radiant\\Q3Radiant", 0, KEY_READ, &hKey);
00832   }
00833 
00834     lres = RegQueryValueEx(hKey, pszName, NULL, (unsigned long*)&lType, (unsigned char*)pvBuf, (unsigned long*)plSize);
00835 
00836     RegCloseKey(hKey);
00837 
00838     if (lres != ERROR_SUCCESS)
00839     {
00840 #ifdef _DEBUG
00841         char Message[1024];
00842         FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, lres, 0, &(Message[0]), 1024, NULL );
00843         Sys_Printf( "WARNING: RegQueryValueEx failed in LoadRegistryInfo for %s : %s", pszName, Message );
00844 #endif
00845         return FALSE;
00846     }
00847 
00848     return TRUE;
00849 }
00850 
00851 BOOL SaveWindowState(HWND hWnd, const char *pszName)
00852 {
00853     RECT rc;
00854     GetWindowRect(hWnd, &rc);
00855     if (hWnd != g_qeglobals.d_hwndMain) // && g_pParentWnd->CurrentStyle() == QR_QE4)
00856   {
00857     if (::GetParent(hWnd) != g_qeglobals.d_hwndMain)
00858     {
00859       ::SetParent(hWnd, g_qeglobals.d_hwndMain);
00860     }
00861         MapWindowPoints(NULL, g_qeglobals.d_hwndMain, (POINT *)&rc, 2);
00862 
00863   }
00864     BOOL b = SaveRegistryInfo(pszName, &rc, sizeof(rc));
00865   return b;
00866 }
00867 
00868 
00869 BOOL LoadWindowState(HWND hWnd, const char *pszName)
00870 {
00871     RECT rc;
00872   LONG lSize = sizeof(rc);
00873 
00874     if (LoadRegistryInfo(pszName, &rc, &lSize))
00875     {
00876         if (rc.left < 0)
00877             rc.left = 0;
00878         if (rc.top < 0)
00879             rc.top = 0;
00880         if (rc.right < rc.left + 16)
00881             rc.right = rc.left + 16;
00882         if (rc.bottom < rc.top + 16)
00883             rc.bottom = rc.top + 16;
00884 
00885         MoveWindow(hWnd, rc.left, rc.top, rc.right - rc.left, 
00886                 rc.bottom - rc.top, FALSE);
00887         return TRUE;
00888     }
00889 
00890     return FALSE;
00891 }
00892 
00893 /*
00894 ===============================================================
00895 
00896   STATUS WINDOW
00897 
00898 ===============================================================
00899 */
00900 
00901 void Sys_UpdateStatusBar( void )
00902 {
00903     extern int   g_numbrushes, g_numentities;
00904 
00905     char numbrushbuffer[100]="";
00906 
00907     sprintf( numbrushbuffer, "Brushes: %d Entities: %d", g_numbrushes, g_numentities );
00908   g_pParentWnd->SetStatusText(2, numbrushbuffer);
00909     //Sys_Status( numbrushbuffer, 2 );
00910 }
00911 
00912 void Sys_Status(const char *psz, int part )
00913 {
00914     SendMessage(g_qeglobals.d_hwndStatus, SB_SETTEXT, part, (LPARAM)psz);
00915 }
00916 
00917 static HWND CreateMyStatusWindow(HINSTANCE hInst)
00918 {
00919     HWND hWnd;
00920     int partsize[3] = { 300, 1100, -1 };
00921 
00922     hWnd = CreateWindowEx( WS_EX_TOPMOST, // no extended styles
00923             STATUSCLASSNAME,                 // status bar
00924             "",                              // no text 
00925             WS_CHILD | WS_BORDER | WS_VISIBLE,  // styles
00926             -100, -100, 10, 10,              // x, y, cx, cy
00927             g_qeglobals.d_hwndMain,          // parent window
00928             (HMENU)100,                      // window ID
00929             hInst,                           // instance
00930             NULL);                           // window data
00931 
00932     SendMessage( hWnd, SB_SETPARTS, 3, ( long ) partsize );
00933     
00934     return hWnd;
00935 }
00936 
00937 //==============================================================
00938 
00939 #define NUMBUTTONS 15
00940 HWND CreateToolBar(HINSTANCE hinst)
00941 { 
00942     HWND hwndTB; 
00943     TBADDBITMAP tbab; 
00944     TBBUTTON tbb[NUMBUTTONS]; 
00945     
00946      // Ensure that the common control DLL is loaded. 
00947 
00948     InitCommonControls(); 
00949  
00950     // Create a toolbar that the user can customize and that has a 
00951     // tooltip associated with it. 
00952 
00953     hwndTB = CreateWindowEx(0, TOOLBARCLASSNAME, (LPSTR) NULL, 
00954         WS_CHILD | TBSTYLE_TOOLTIPS | CCS_ADJUSTABLE | WS_BORDER, 
00955         0, 0, 0, 0, g_qeglobals.d_hwndMain, (HMENU) IDR_TOOLBAR1, hinst, NULL); 
00956  
00957     // Send the TB_BUTTONSTRUCTSIZE message, which is required for 
00958     // backward compatibility. 
00959 
00960     SendMessage(hwndTB, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);
00961  
00962     // Add the bitmap containing button images to the toolbar. 
00963 
00964     tbab.hInst = hinst; 
00965     tbab.nID   = IDR_TOOLBAR1; 
00966     SendMessage(hwndTB, TB_ADDBITMAP, (WPARAM)NUMBUTTONS, (WPARAM) &tbab); 
00967  
00968     // Fill the TBBUTTON array with button information, and add the 
00969     // buttons to the toolbar. 
00970 
00971     tbb[0].iBitmap = 0; 
00972     tbb[0].idCommand = ID_BRUSH_FLIPX; 
00973     tbb[0].fsState = TBSTATE_ENABLED; 
00974     tbb[0].fsStyle = TBSTYLE_BUTTON; 
00975     tbb[0].dwData = 0; 
00976     tbb[0].iString = 0; 
00977  
00978     tbb[1].iBitmap = 2; 
00979     tbb[1].idCommand = ID_BRUSH_FLIPY; 
00980     tbb[1].fsState = TBSTATE_ENABLED; 
00981     tbb[1].fsStyle = TBSTYLE_BUTTON; 
00982     tbb[1].dwData = 0; 
00983     tbb[1].iString = 0; 
00984  
00985     tbb[2].iBitmap = 4; 
00986     tbb[2].idCommand = ID_BRUSH_FLIPZ; 
00987     tbb[2].fsState = TBSTATE_ENABLED;
00988     tbb[2].fsStyle = TBSTYLE_BUTTON; 
00989     tbb[2].dwData = 0; 
00990     tbb[2].iString = 0; 
00991  
00992     tbb[3].iBitmap = 1; 
00993     tbb[3].idCommand = ID_BRUSH_ROTATEX; 
00994     tbb[3].fsState = TBSTATE_ENABLED; 
00995     tbb[3].fsStyle = TBSTYLE_BUTTON; 
00996     tbb[3].dwData = 0; 
00997     tbb[3].iString = 0; 
00998  
00999     tbb[4].iBitmap = 3; 
01000     tbb[4].idCommand = ID_BRUSH_ROTATEY; 
01001     tbb[4].fsState = TBSTATE_ENABLED; 
01002     tbb[4].fsStyle = TBSTYLE_BUTTON; 
01003     tbb[4].dwData = 0; 
01004     tbb[4].iString = 0; 
01005 
01006     tbb[5].iBitmap = 5; 
01007     tbb[5].idCommand = ID_BRUSH_ROTATEZ; 
01008     tbb[5].fsState = TBSTATE_ENABLED; 
01009     tbb[5].fsStyle = TBSTYLE_BUTTON; 
01010     tbb[5].dwData = 0; 
01011     tbb[5].iString = 0; 
01012 
01013     tbb[6].iBitmap = 6; 
01014     tbb[6].idCommand = ID_SELECTION_SELECTCOMPLETETALL; 
01015     tbb[6].fsState = TBSTATE_ENABLED; 
01016     tbb[6].fsStyle = TBSTYLE_BUTTON; 
01017     tbb[6].dwData = 0; 
01018     tbb[6].iString = 0; 
01019 
01020     tbb[7].iBitmap = 7; 
01021     tbb[7].idCommand = ID_SELECTION_SELECTTOUCHING; 
01022     tbb[7].fsState = TBSTATE_ENABLED; 
01023     tbb[7].fsStyle = TBSTYLE_BUTTON; 
01024     tbb[7].dwData = 0; 
01025     tbb[7].iString = 0; 
01026 
01027     tbb[8].iBitmap = 8; 
01028     tbb[8].idCommand = ID_SELECTION_SELECTPARTIALTALL; 
01029     tbb[8].fsState = TBSTATE_ENABLED; 
01030     tbb[8].fsStyle = TBSTYLE_BUTTON; 
01031     tbb[8].dwData = 0; 
01032     tbb[8].iString = 0; 
01033 
01034 
01035     tbb[9].iBitmap = 9; 
01036     tbb[9].idCommand = ID_SELECTION_SELECTINSIDE; 
01037     tbb[9].fsState = TBSTATE_ENABLED; 
01038     tbb[9].fsStyle = TBSTYLE_BUTTON; 
01039     tbb[9].dwData = 0; 
01040     tbb[9].iString = 0; 
01041 
01042     tbb[10].iBitmap = 10; 
01043     tbb[10].idCommand = ID_SELECTION_CSGSUBTRACT; 
01044     tbb[10].fsState = TBSTATE_ENABLED; 
01045     tbb[10].fsStyle = TBSTYLE_BUTTON; 
01046     tbb[10].dwData = 0; 
01047     tbb[10].iString = 0; 
01048 
01049 
01050     tbb[11].iBitmap = 11;
01051     tbb[11].idCommand = ID_SELECTION_MAKEHOLLOW; 
01052     tbb[11].fsState = TBSTATE_ENABLED; 
01053     tbb[11].fsStyle = TBSTYLE_BUTTON; 
01054     tbb[11].dwData = 0; 
01055     tbb[11].iString = 0; 
01056 
01057     tbb[12].iBitmap = 12;
01058     tbb[12].idCommand = ID_TEXTURES_WIREFRAME; 
01059     tbb[12].fsState = TBSTATE_ENABLED; 
01060     tbb[12].fsStyle = TBSTYLE_BUTTON; 
01061     tbb[12].dwData = 0; 
01062     tbb[12].iString = 0; 
01063 
01064     tbb[13].iBitmap = 13;
01065     tbb[13].idCommand = ID_TEXTURES_FLATSHADE; 
01066     tbb[13].fsState = TBSTATE_ENABLED; 
01067     tbb[13].fsStyle = TBSTYLE_BUTTON; 
01068     tbb[13].dwData = 0; 
01069     tbb[13].iString = 0; 
01070 
01071     tbb[14].iBitmap = 14;
01072     tbb[14].idCommand = ID_VIEW_TRILINEAR; 
01073     tbb[14].fsState = TBSTATE_ENABLED; 
01074     tbb[14].fsStyle = TBSTYLE_BUTTON; 
01075     tbb[14].dwData = 0; 
01076     tbb[14].iString = 0; 
01077 
01078     SendMessage(hwndTB, TB_ADDBUTTONS, (WPARAM)NUMBUTTONS,
01079         (LPARAM) (LPTBBUTTON) &tbb); 
01080  
01081     ShowWindow(hwndTB, SW_SHOW); 
01082 
01083     return hwndTB; 
01084 } 
01085 

Generated on Thu Aug 25 12:38:42 2005 for Quake III Arena by  doxygen 1.3.9.1