/****************************************************************************** winx.cpp Windows utility procedures Copyright (C) Microsoft Corporation, 1997 - 1998 All rights reserved Notes: THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. ******************************************************************************/ #include "stillvue.h" #include // pow // WINERROR.H - GetLastError errors STRINGTABLE StWinerror[] = { ERROR_SUCCESS, "ERROR_SUCCESS",0, ERROR_FILE_NOT_FOUND, "ERROR_FILE_NOT_FOUND",0, ERROR_PATH_NOT_FOUND, "ERROR_PATH_NOT_FOUND",0, ERROR_INVALID_FUNCTION, "ERROR_INVALID_FUNCTION",0, ERROR_ACCESS_DENIED, "ERROR_ACCESS_DENIED",0, ERROR_INVALID_HANDLE, "ERROR_INVALID_HANDLE",0, ERROR_INVALID_PARAMETER, "ERROR_INVALID_PARAMETER",0, ERROR_CALL_NOT_IMPLEMENTED, "ERROR_CALL_NOT_IMPLEMENTED",0, ERROR_ALREADY_EXISTS, "ERROR_ALREADY_EXISTS",0, ERROR_INVALID_FLAGS, "ERROR_INVALID_FLAGS",0, ERROR_INVALID_CATEGORY, "ERROR_INVALID_CATEGORY",0, RPC_S_SERVER_UNAVAILABLE, "RPC_S_SERVER_UNAVAILABLE",0, 0, "See WINERROR.H",-1 }; /****************************************************************************** ULONG atox(LPSTR lpHex) Convert string to hexadecimal value. ******************************************************************************/ ULONG atox(LPSTR lpHex) { char *p; int x; double y; ULONG z,ulHex = 0l; for (p = lpHex,x = 0;p[x];x++) ; for (x--,y = 0.0;lpHex <= (p + x);x--,y++) { z = (ULONG) pow(16.0,y); if ((p[x] >= '0')&&(p[x] <= '9')) ulHex += ((p[x] - '0') * z); if ((p[x] >= 'A')&&(p[x] <= 'F')) ulHex += ((p[x] - 'A' + 10) * z); if ((p[x] >= 'a')&&(p[x] <= 'f')) ulHex += ((p[x] - 'a' + 10) * z); } return (ulHex); } #ifdef _DEBUG /****************************************************************************** void DisplayDebug(LPSTR sz,...) Output text to debugger. ******************************************************************************/ void DisplayDebug(LPSTR sz,...) { char Buffer[512]; va_list list; va_start(list,sz); vsprintf(Buffer,sz,list); OutputDebugString(Buffer); OutputDebugString("\n"); return; } #else /****************************************************************************** void DisplayDebug(LPSTR sz,...) Output text to debugger - nonfunctional retail version.. ******************************************************************************/ void DisplayDebug(LPSTR sz,...) { return; } #endif /****************************************************************************** BOOL ErrorMsg(HWND, LPSTR, LPSTR, BOOL) Display an error message and send WM_QUIT if error is fatal. Parameters: handle to current window, long pointer to string with error message, long pointer to string with message box caption, error (Fatal if TRUE) Shut down app if bFatal is TRUE, continue if FALSE. ******************************************************************************/ BOOL ErrorMsg(HWND hWnd, LPSTR lpzMsg, LPSTR lpzCaption, BOOL bFatal) { MessageBox(hWnd, lpzMsg, lpzCaption, MB_ICONEXCLAMATION | MB_OK); if (bFatal) PostMessage (hWnd, WM_QUIT, 0, 0L); return (bFatal); } /****************************************************************************** fDialog(id,hwnd,fpfn) Description: This function displays a dialog box and returns the exit code. the function passed will have a proc instance made for it. Parameters: id resource id of dialog to display hwnd parent window of dialog fpfn dialog message function Returns: exit code of dialog (what was passed to EndDialog) ******************************************************************************/ BOOL fDialog(int id,HWND hWnd,FARPROC fPfn) { BOOL f; HINSTANCE hInst; hInst = (HINSTANCE) GetWindowLong(hWnd,GWL_HINSTANCE); fPfn = MakeProcInstance(fPfn,hInst); f = DialogBox(hInst,MAKEINTRESOURCE(id),hWnd,(DLGPROC)fPfn); FreeProcInstance(fPfn); return (f); } /****************************************************************************** void FormatHex(unsigned char *szSource, char *szDest) take first 16 bytes from szSource, format into a hex dump string, then copy the string into szDest szDest must have room for at least 66 bytes sample code fragment showing use: char szOut[128], // output string // print header sprintf(szOut, "Offset --------------------- hex --------------------- ---- ascii -----"); puts(szOut); // dump 512 bytes (32 lines, 16 bytes per line) for (i = 0; i < 32; i++) { // get next 16 bytes _fmemcpy(szDbgMsg,fpSector + (i*16),16); // get current offset into data block sprintf(szOut,"%03xh(%03d) ",i*16,i*16); // append debug string after data block offset message FormatHex(szDbgMsg, szOut + strlen(szOut)); puts(szOut); } ******************************************************************************/ void FormatHex(unsigned char *szSource, char *szDest) { unsigned short j; sprintf(szDest, "%02x %02x %02x %02x %02x %02x %02x %02x:"\ "%02x %02x %02x %02x %02x %02x %02x %02x ", szSource[0], szSource[1], szSource[2], szSource[3], szSource[4], szSource[5], szSource[6], szSource[7], szSource[8], szSource[9], szSource[10], szSource[11], szSource[12], szSource[13], szSource[14], szSource[15]); // replace bytes with undesirable Sprintf side effects with SPACE for (j = 0; j < 16; j++) { if ((0x00 == szSource[j]) || (0x07 == szSource[j]) || (0x09 == szSource[j]) || (0x0a == szSource[j]) || (0x0d == szSource[j]) || (0x1a == szSource[j])) szSource[j] = 0x20; } sprintf(szDest + strlen(szDest), "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", szSource[0], szSource[1], szSource[2], szSource[3], szSource[4], szSource[5], szSource[6], szSource[7], szSource[8], szSource[9], szSource[10], szSource[11], szSource[12], szSource[13], szSource[14], szSource[15]); return; } /****************************************************************************** BOOL GetFinalWindow(HANDLE, LPRECT, LPSTR, LPSTR) Retrieve the last window size & location from a private INI Parameters: handle to current instance, long pointer to a rectangle with window size/shape, string with INI filename, string with Section name Returns: success/failure (never fails) Get display size in pixels and private INI saved width and height. Default width (for no previous INI) is 1/3 display width. Default height (for no previous INI) is 1/3 display height. If saved size or postion would put part or all the window off the desktop, first change the position then the size until the window is completely on the desktop. ******************************************************************************/ BOOL GetFinalWindow (HANDLE hInst, LPRECT lprRect, LPSTR lpzINI, LPSTR lpzSection) { int x, nDisplayWidth, nDisplayHeight; RECT rect; nDisplayWidth = GetSystemMetrics(SM_CXSCREEN); nDisplayHeight = GetSystemMetrics(SM_CYSCREEN); rect.left = GetPrivateProfileInt(lpzSection, "Left", (nDisplayWidth/10) * 7,lpzINI); rect.top = GetPrivateProfileInt(lpzSection, "Top", (nDisplayHeight/10) * 8,lpzINI); rect.right = GetPrivateProfileInt(lpzSection, "Right", nDisplayWidth,lpzINI); rect.bottom = GetPrivateProfileInt(lpzSection, "Bottom", nDisplayHeight,lpzINI); /*///////////////////////////////////////////////////////////////////////////// if window hangs off top or left of display, change location to edge of display and preserve size. /////////////////////////////////////////////////////////////////////////////*/ if (rect.top < 0) { rect.bottom += rect.top * -1; rect.top = 0; } if (rect.left < 0) { rect.right += rect.left * -1; rect.left = 0; } /*///////////////////////////////////////////////////////////////////////////// if window hangs off bottom or right of display, change location to bring it back onscreen. If window dimension is greater than display, reduce to size of display. /////////////////////////////////////////////////////////////////////////////*/ if (rect.bottom > nDisplayHeight) { if (rect.bottom > nDisplayHeight * 2) { rect.top = 0; rect.bottom = nDisplayHeight; } else { x = rect.bottom - nDisplayHeight; rect.bottom -= x; rect.top -= x; } } if (rect.right > nDisplayWidth) { if (rect.right > nDisplayWidth * 2) { rect.left = 0; rect.right = nDisplayWidth; } else { x = rect.right - nDisplayWidth; rect.right -= x; rect.left -= x; } } /*///////////////////////////////////////////////////////////////////////////// GetWindowRect() returns a rect where right and bottom are absolute (measured from 0,0 of display). However, CreateWindow requires right and bottom to be relative (measured from 0,0 of the window to be created). SaveFinalWindow saves an absolute rect, and GetFinalRect converts these to relative measurements. /////////////////////////////////////////////////////////////////////////////*/ SetRect(lprRect, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); return (TRUE); } /****************************************************************************** BOOL LastError(BOOL) Calls GetLastError and displays result in a nice string Parameters: bNewOnly == TRUE if you only want changed error displayed Returns: TRUE if it found an error, else FALSE ******************************************************************************/ BOOL LastError(BOOL bNewOnly) { static DWORD dwLast = 0; DWORD dwError; if (dwError = GetLastError()) { // if user asked for only new errors if (bNewOnly) { // not a new error if (dwLast == dwError) return FALSE; // new error, save it dwLast = dwError; } DisplayOutput("*GetLastError %xh %d \"%s\"", dwError,dwError,StrFromTable(dwError,StWinerror)); return (TRUE); } return (FALSE); } /****************************************************************************** int NextToken(char *pDest,char *pSrc) Return next token from a command line string. ******************************************************************************/ int NextToken(char *pDest,char *pSrc) { char *pA,*pB; int x; // point pArg to start of token in string pSrc for (pA = pSrc;*pA && isspace((int) *pA);pA++) ; // find end of token in string pSrc for (pB = pA;((*pB) && (! isspace((int) *pB)));pB++) ; // count of chars to next token or end of string x = (min((pB - pA),(int) strlen(pSrc))) + 1; // pszDest now contains the arg lstrcpyn(pDest,pA,x); // return sizeof token return (x); } /****************************************************************************** BOOL SaveFinalWindow(HANDLE, HWND, LPSTR, LPSTR) Save the current window size & location to a private INI Parameters: handle to current instance, handle to current window, string with INI filename, string with Section name Returns: success/failure (fails if window is MIN or MAX) ******************************************************************************/ BOOL SaveFinalWindow (HANDLE hInst, HWND hWnd, LPSTR lpzINI, LPSTR lpzSection) { PSTR pszValue; RECT rectWnd, rectINI; // if the window is minimized OR maximised, don't save anything if (IsIconic(hWnd) || IsZoomed(hWnd)) return (FALSE); GetWindowRect (hWnd, &rectWnd); // get INI data. If there isn't any, we'll get the default and // save the current Window data. rectINI.left = GetPrivateProfileInt(lpzSection, "Left", 0, lpzINI); rectINI.top = GetPrivateProfileInt(lpzSection, "Top", 0, lpzINI); rectINI.right = GetPrivateProfileInt(lpzSection, "Right", 0, lpzINI); rectINI.bottom = GetPrivateProfileInt(lpzSection, "Bottom", 0, lpzINI); // if current window is same as in INI, don't change INI if ( rectINI.left == rectWnd.left && rectINI.top == rectWnd.top && rectINI.right == rectWnd.right && rectINI.bottom == rectWnd.bottom) return (TRUE); // EXIT if we can't local alloc our string stuffer if ((pszValue = (PSTR) LocalAlloc(LPTR, 80)) == NULL) return (FALSE); // it's different, so save sprintf(pszValue, "%d", rectWnd.left); WritePrivateProfileString(lpzSection, "Left", pszValue, lpzINI); sprintf(pszValue, "%d", rectWnd.top); WritePrivateProfileString(lpzSection, "Top", pszValue, lpzINI); sprintf(pszValue, "%d", rectWnd.right); WritePrivateProfileString(lpzSection, "Right", pszValue, lpzINI); sprintf(pszValue, "%d", rectWnd.bottom); WritePrivateProfileString(lpzSection, "Bottom", pszValue, lpzINI); LocalFree((HANDLE) pszValue); return (TRUE); } /****************************************************************************** char * StrFromTable(long number,PSTRINGTABLE pstrTable) Return string associated with a value from a string table. ******************************************************************************/ char * StrFromTable(long number,PSTRINGTABLE pstrTable) { for (;pstrTable->end != -1;pstrTable++) { if (number == pstrTable->number) break; } return (pstrTable->szString); } /****************************************************************************** BOOL Wait32(DWORD) wait DWORD milliseconds, then return ******************************************************************************/ BOOL Wait32(DWORD dwTime) { DWORD dwNewTime, dwOldTime; // wait dwTime, then exit dwOldTime = GetCurrentTime(); while (TRUE) { dwNewTime = GetCurrentTime(); if (dwNewTime > dwOldTime + dwTime) break; } return (0); }