390 lines
8.6 KiB
C
390 lines
8.6 KiB
C
|
#include <windows.h>
|
||
|
#include "common.h"
|
||
|
|
||
|
#define BLOCKLEN 100
|
||
|
|
||
|
#ifndef DBCS
|
||
|
#define AnsiNext(x) ((x)+1)
|
||
|
#endif
|
||
|
|
||
|
extern HANDLE hInstance;
|
||
|
extern FARPROC lpOldHook;
|
||
|
extern HWND hWndMain, hWndHelp;
|
||
|
extern WORD wHelpMain;
|
||
|
|
||
|
extern char *pszLongName;
|
||
|
extern char *pszOutOfMemory;
|
||
|
|
||
|
HANDLE NEAR PASCAL StringToLocalHandle(LPSTR szStr, WORD wFlags)
|
||
|
{
|
||
|
HANDLE hStr;
|
||
|
LPSTR lpStr;
|
||
|
|
||
|
if(!(hStr=LocalAlloc(wFlags, lstrlen(szStr) + 1)))
|
||
|
goto Error1;
|
||
|
if(!(lpStr=LocalLock(hStr)))
|
||
|
goto Error2;
|
||
|
lstrcpy(lpStr, szStr);
|
||
|
LocalUnlock(hStr);
|
||
|
goto Error1;
|
||
|
|
||
|
Error2:
|
||
|
LocalFree(hStr);
|
||
|
hStr = NULL;
|
||
|
Error1:
|
||
|
return(hStr);
|
||
|
}
|
||
|
|
||
|
LPSTR NEAR _fastcall MyStrTok(LPSTR szList, char cEnd)
|
||
|
{
|
||
|
LPSTR szTemp;
|
||
|
|
||
|
/* if there are no more tokens return NULL */
|
||
|
if(!*szList)
|
||
|
return NULL;
|
||
|
|
||
|
/* find delimiter or end of string */
|
||
|
while(*szList && *szList!=cEnd)
|
||
|
szList = AnsiNext(szList);
|
||
|
|
||
|
/* if we found a delimiter insert string terminator and skip */
|
||
|
if(*szList) {
|
||
|
szTemp = szList;
|
||
|
szList = AnsiNext(szTemp);
|
||
|
*szTemp = '\0';
|
||
|
}
|
||
|
|
||
|
/* return token */
|
||
|
return(szList);
|
||
|
}
|
||
|
|
||
|
int NEAR PASCAL DoDialogBoxParam(LPCSTR lpDialog, HWND hWnd, FARPROC lpfnProc,
|
||
|
DWORD dwParam)
|
||
|
{
|
||
|
int result = -1;
|
||
|
|
||
|
if(!(lpfnProc = MakeProcInstance(lpfnProc, hInstance)))
|
||
|
goto Error1;
|
||
|
result = DialogBoxParam(hInstance, lpDialog, hWnd, lpfnProc, dwParam);
|
||
|
FreeProcInstance(lpfnProc);
|
||
|
|
||
|
Error1:
|
||
|
return(result);
|
||
|
}
|
||
|
|
||
|
int NEAR PASCAL DoDialogBox(LPCSTR lpDialog, HWND hWnd, FARPROC lpfnProc)
|
||
|
{
|
||
|
return(DoDialogBoxParam(lpDialog, hWnd, lpfnProc, 0L));
|
||
|
}
|
||
|
|
||
|
unsigned long NEAR PASCAL MyQueryValue(HKEY hKey, PSTR pSubKey, HANDLE *hBuf)
|
||
|
{
|
||
|
HANDLE hTemp;
|
||
|
PSTR pBuf;
|
||
|
WORD wBufSize = BLOCKLEN;
|
||
|
unsigned long result = ERROR_OUTOFMEMORY;
|
||
|
LONG lSize;
|
||
|
|
||
|
if(!(*hBuf=LocalAlloc(LMEM_MOVEABLE, wBufSize)))
|
||
|
goto Error1;
|
||
|
if(!(pBuf=LocalLock(*hBuf)))
|
||
|
goto Error2;
|
||
|
|
||
|
while((lSize=wBufSize, (result=RegQueryValue(hKey, pSubKey, pBuf, &lSize))
|
||
|
==ERROR_SUCCESS) && (WORD)lSize>wBufSize-10) {
|
||
|
LocalUnlock(*hBuf);
|
||
|
wBufSize += BLOCKLEN;
|
||
|
if(!(hTemp=LocalReAlloc(*hBuf, wBufSize, LMEM_MOVEABLE))) {
|
||
|
result = ERROR_OUTOFMEMORY;
|
||
|
goto Error2;
|
||
|
}
|
||
|
pBuf = LocalLock(*hBuf=hTemp);
|
||
|
}
|
||
|
LocalUnlock(*hBuf);
|
||
|
if(result!=ERROR_SUCCESS || !lSize)
|
||
|
goto Error2;
|
||
|
goto Error1;
|
||
|
|
||
|
Error2:
|
||
|
LocalFree(*hBuf);
|
||
|
*hBuf = NULL;
|
||
|
Error1:
|
||
|
return(result);
|
||
|
}
|
||
|
|
||
|
HANDLE NEAR PASCAL GetEditString(HWND hWndEdit)
|
||
|
{
|
||
|
HANDLE hEdit = NULL;
|
||
|
PSTR pEdit;
|
||
|
WORD wLen;
|
||
|
|
||
|
wLen = LOWORD(SendMessage(hWndEdit, WM_GETTEXTLENGTH, 0, 0L)) + 1;
|
||
|
if(!(hEdit=LocalAlloc(LMEM_MOVEABLE, wLen)))
|
||
|
goto Error1;
|
||
|
if(!(pEdit=LocalLock(hEdit)))
|
||
|
goto Error2;
|
||
|
|
||
|
SendMessage(hWndEdit, WM_GETTEXT, wLen, (DWORD)((LPSTR)pEdit));
|
||
|
LocalUnlock(hEdit);
|
||
|
goto Error1;
|
||
|
|
||
|
Error2:
|
||
|
LocalFree(hEdit);
|
||
|
hEdit = NULL;
|
||
|
Error1:
|
||
|
return(hEdit);
|
||
|
}
|
||
|
|
||
|
HANDLE NEAR _fastcall MyLoadString(WORD wId, WORD *pwSize, WORD wFlags)
|
||
|
{
|
||
|
char szString[258]; /* RC limits strings to 256 chars */
|
||
|
WORD wSize;
|
||
|
|
||
|
wSize = LoadString(hInstance, wId, szString, sizeof(szString));
|
||
|
if(pwSize)
|
||
|
*pwSize = wSize;
|
||
|
return(StringToLocalHandle(szString, wFlags));
|
||
|
}
|
||
|
|
||
|
int NEAR cdecl MyMessageBox(HWND hWnd, WORD wText, WORD wType, WORD wExtra, ...)
|
||
|
{
|
||
|
HANDLE hText, hRText;
|
||
|
PSTR pText, pRText;
|
||
|
WORD wSize;
|
||
|
int result = 0;
|
||
|
|
||
|
if(wText == IDS_OUTOFMEMORY)
|
||
|
goto Error1;
|
||
|
|
||
|
if(!(hText=MyLoadString(wText, &wSize, LMEM_MOVEABLE)))
|
||
|
goto Error1;
|
||
|
|
||
|
/* We allocate enough room for a bunch of numbers and the strings
|
||
|
*/
|
||
|
if(!(hRText=LocalAlloc(LMEM_MOVEABLE, 2*wSize + wExtra)))
|
||
|
goto Error2;
|
||
|
if(!(pRText=LocalLock(hRText)))
|
||
|
goto Error3;
|
||
|
|
||
|
pText = LocalLock(hText);
|
||
|
wvsprintf(pRText, pText, (LPSTR)(&wExtra+1));
|
||
|
result = MessageBox(hWnd, pRText, pszLongName, wType);
|
||
|
|
||
|
LocalUnlock(hText);
|
||
|
LocalUnlock(hRText);
|
||
|
Error3:
|
||
|
LocalFree(hRText);
|
||
|
Error2:
|
||
|
LocalFree(hText);
|
||
|
Error1:
|
||
|
if(!result) {
|
||
|
MessageBox(hWnd, pszOutOfMemory, pszLongName,
|
||
|
MB_ICONHAND | MB_SYSTEMMODAL | MB_OK);
|
||
|
}
|
||
|
|
||
|
return(result);
|
||
|
}
|
||
|
|
||
|
VOID NEAR PASCAL WriteProfileInt(WORD wAppName, WORD wKey, int nVal)
|
||
|
{
|
||
|
HANDLE hAppName, hKey;
|
||
|
char buf[10];
|
||
|
|
||
|
if(!(hAppName=MyLoadString(wAppName, NULL, LMEM_MOVEABLE)))
|
||
|
goto Error1;
|
||
|
if(!(hKey=MyLoadString(wKey, NULL, LMEM_MOVEABLE)))
|
||
|
goto Error2;
|
||
|
|
||
|
wsprintf(buf, "%d", nVal);
|
||
|
WriteProfileString(LocalLock(hAppName), LocalLock(hKey), buf);
|
||
|
|
||
|
LocalUnlock(hKey);
|
||
|
LocalUnlock(hAppName);
|
||
|
Error2:
|
||
|
LocalFree(hKey);
|
||
|
Error1:
|
||
|
LocalFree(hAppName);
|
||
|
}
|
||
|
|
||
|
int NEAR PASCAL MyGetProfileInt(WORD wAppName, WORD wKey, int nDefault)
|
||
|
{
|
||
|
HANDLE hAppName, hKey;
|
||
|
|
||
|
if(!(hAppName=MyLoadString(wAppName, NULL, LMEM_MOVEABLE)))
|
||
|
goto Error1;
|
||
|
if(!(hKey=MyLoadString(wKey, NULL, LMEM_MOVEABLE)))
|
||
|
goto Error2;
|
||
|
|
||
|
nDefault = GetProfileInt(LocalLock(hAppName), LocalLock(hKey), nDefault);
|
||
|
|
||
|
LocalUnlock(hKey);
|
||
|
LocalUnlock(hAppName);
|
||
|
Error2:
|
||
|
LocalFree(hKey);
|
||
|
Error1:
|
||
|
LocalFree(hAppName);
|
||
|
return(nDefault);
|
||
|
}
|
||
|
|
||
|
HANDLE NEAR PASCAL StringToHandle(LPSTR szStr)
|
||
|
{
|
||
|
HANDLE hStr;
|
||
|
LPSTR lpStr;
|
||
|
|
||
|
if(!(hStr=GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,
|
||
|
(DWORD)(lstrlen(szStr)+1))))
|
||
|
goto Error1;
|
||
|
if(!(lpStr=GlobalLock(hStr)))
|
||
|
goto Error2;
|
||
|
lstrcpy(lpStr, szStr);
|
||
|
GlobalUnlock(hStr);
|
||
|
goto Error1;
|
||
|
|
||
|
Error2:
|
||
|
GlobalFree(hStr);
|
||
|
hStr = NULL;
|
||
|
Error1:
|
||
|
return(hStr);
|
||
|
}
|
||
|
|
||
|
int FAR PASCAL MessageFilter(int nCode, WORD wParam, LPMSG lpMsg)
|
||
|
{
|
||
|
switch(nCode) {
|
||
|
case MSGF_MENU:
|
||
|
case MSGF_DIALOGBOX:
|
||
|
if(lpMsg->message==WM_KEYDOWN && lpMsg->wParam==VK_F1
|
||
|
&& !(lpMsg->lParam&(1L<<30)))
|
||
|
PostMessage(hWndHelp, WM_COMMAND, ID_HELP,
|
||
|
MAKELONG(lpMsg->hwnd, nCode));
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
DefHookProc(nCode, wParam, (DWORD)lpMsg, &lpOldHook);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
#ifndef NOHELP
|
||
|
|
||
|
// #define ONLYID
|
||
|
VOID NEAR PASCAL MyHelp(HWND hWnd, WORD wCommand, DWORD wId)
|
||
|
{
|
||
|
#ifdef ONLYID
|
||
|
if(wCommand != HELP_QUIT)
|
||
|
MyMessageBox(hWnd, IDS_HELP, MB_OK, 0, wId);
|
||
|
#else
|
||
|
HANDLE hHelpFile;
|
||
|
PSTR pHelpFile;
|
||
|
|
||
|
if(!(hHelpFile=MyLoadString(wHelpMain==IDW_SDKMAIN ?
|
||
|
IDS_SDKHELPFILE : IDS_HELPFILE, NULL, LMEM_MOVEABLE)))
|
||
|
return;
|
||
|
|
||
|
if(!WinHelp(hWndMain, pHelpFile=LocalLock(hHelpFile), wCommand, wId))
|
||
|
MyMessageBox(hWnd, IDS_HELPERR, MB_OK, 0);
|
||
|
else
|
||
|
WinHelp(hWndMain, pHelpFile, HELP_SETINDEX, wHelpIndex);
|
||
|
|
||
|
LocalUnlock(hHelpFile);
|
||
|
LocalFree(hHelpFile);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
HANDLE NEAR PASCAL GetListboxString(HWND hWndEdit, int nId)
|
||
|
{
|
||
|
HANDLE hEdit = NULL;
|
||
|
PSTR pEdit;
|
||
|
WORD wLen;
|
||
|
|
||
|
wLen = LOWORD(SendMessage(hWndEdit, LB_GETTEXTLEN, nId, 0L)) + 1;
|
||
|
if(!(hEdit=LocalAlloc(LMEM_MOVEABLE, wLen)))
|
||
|
goto Error1;
|
||
|
if(!(pEdit=LocalLock(hEdit)))
|
||
|
goto Error2;
|
||
|
|
||
|
SendMessage(hWndEdit, LB_GETTEXT, nId, (DWORD)((LPSTR)pEdit));
|
||
|
LocalUnlock(hEdit);
|
||
|
goto Error1;
|
||
|
|
||
|
Error2:
|
||
|
LocalFree(hEdit);
|
||
|
hEdit = NULL;
|
||
|
Error1:
|
||
|
return(hEdit);
|
||
|
}
|
||
|
|
||
|
unsigned long NEAR PASCAL MyEnumKey(HKEY hKey, WORD wIndex, HANDLE *hBuf)
|
||
|
{
|
||
|
HANDLE hTemp;
|
||
|
PSTR pBuf;
|
||
|
WORD wBufSize = BLOCKLEN, wSize;
|
||
|
unsigned long result = ERROR_OUTOFMEMORY;
|
||
|
|
||
|
if(!(*hBuf=LocalAlloc(LMEM_MOVEABLE, wBufSize)))
|
||
|
goto Error1;
|
||
|
if(!(pBuf=LocalLock(*hBuf)))
|
||
|
goto Error2;
|
||
|
|
||
|
while((result=RegEnumKey(hKey, wIndex, pBuf, (DWORD)wBufSize))
|
||
|
==ERROR_SUCCESS && (wSize=lstrlen(pBuf))>wBufSize-10) {
|
||
|
LocalUnlock(*hBuf);
|
||
|
wBufSize += BLOCKLEN;
|
||
|
if(!(hTemp=LocalReAlloc(*hBuf, wBufSize, LMEM_MOVEABLE))) {
|
||
|
result = ERROR_OUTOFMEMORY;
|
||
|
goto Error2;
|
||
|
}
|
||
|
pBuf = LocalLock(*hBuf=hTemp);
|
||
|
}
|
||
|
LocalUnlock(*hBuf);
|
||
|
if(result!=ERROR_SUCCESS || !wSize)
|
||
|
goto Error2;
|
||
|
goto Error1;
|
||
|
|
||
|
Error2:
|
||
|
LocalFree(*hBuf);
|
||
|
*hBuf = NULL;
|
||
|
Error1:
|
||
|
return(result);
|
||
|
}
|
||
|
|
||
|
static WORD wErrMsgs[] = {
|
||
|
0, IDS_BADDB, IDS_BADKEY, IDS_CANTOPENDB, IDS_CANTREADDB, IDS_CANTWRITEDB,
|
||
|
IDS_OUTOFMEMORY, IDS_INVALIDPARM
|
||
|
} ;
|
||
|
|
||
|
WORD NEAR _fastcall GetErrMsg(WORD wRet)
|
||
|
{
|
||
|
return(wRet>=sizeof(wErrMsgs)/sizeof(wErrMsgs[0]) ?
|
||
|
IDS_INVALIDPARM : wErrMsgs[wRet]);
|
||
|
}
|
||
|
|
||
|
VOID NEAR PASCAL RepeatMove(LPSTR lpDest, LPSTR lpSrc, WORD wBytes)
|
||
|
{
|
||
|
/* WARNING: This assumes that the buffers are in different segments, or
|
||
|
* the offset of the dest is less than the offset of the src
|
||
|
*/
|
||
|
|
||
|
/* Save DS, and load up ES:DI, DS:SI, and CX with the parameters */
|
||
|
_asm push ds
|
||
|
_asm les di,lpDest
|
||
|
_asm lds si,lpSrc
|
||
|
_asm mov cx,wBytes
|
||
|
_asm cld
|
||
|
|
||
|
/* Do a movsb if CX is odd, and then do movsw for CX/2 */
|
||
|
_asm shr CX,1
|
||
|
_asm jnc repm1
|
||
|
_asm movsb
|
||
|
_asm repm1:
|
||
|
_asm jcxz repm2
|
||
|
_asm rep movsw
|
||
|
_asm repm2:
|
||
|
|
||
|
/* Restore DS and return */
|
||
|
_asm pop ds
|
||
|
}
|