Files
TeslaRel410/BORLAND/BDE/EXAMPLES/SNIPIT/SNIPMAIN.C
T
CydandClaude Fable 5 63312e07f9 source410: literal 4.10 source reconstruction + BC++ 4.52 fleet toolchain archived
- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
  is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
  Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
  (extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
  BT game source (never mixed into CODE/). Round 1-3 state:
  * 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
    (BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
    since 1996.
  * BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
    its binary-recorded line 400 exactly.
  * BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
    (Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
    TeamScore=12 flagged [T4]).
  * MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
    (VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
    the period compiler is the drift detector).
  * Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
    (per-TU verification sweep under authentic OPT.MAK flags).
  * README: corrected roadmap - MECH.HPP is the capstone grown with the mech
    TU reconstructions; BTREG.CPP green = the header-family milestone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 07:33:26 -05:00

1540 lines
53 KiB
C++

// BDE - (C) Copyright 1995 by Borland International
#include "snipit.h"
#include <ctype.h>
#include <ctl3d.h>
#include <commdlg.h>
#define FILEHANDLESNEEDED 40
// Prototypes for static functions.
static void CreateResources(HINSTANCE hInstance, HWND hWnd);
static void InitMainWnd(HWND hWnd);
static BOOL InitApp(int nCmdShow, HINSTANCE hInst);
static void get_search_text(void);
//===================================================================
// Function:
// WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
//
// Input: hInstance - The handle that represents the
// application's unique instance ID
// hPrevInstance - Indicates if this is the first instance
// of the application
// lpCmdLine - Command line parameters (it is the
// application's responsibility to parse them)
// nCmdShow - TRUE = Show as non-icon application
//
// Return: int - Success?
//
// Description:
// Application entry point. Init the app, main window, and
// global variables.
//===================================================================
int PASCAL
WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
HACCEL hAccel;
// Avoid warning: Parameter not used
lpCmdLine = lpCmdLine;
// Make this a single instance program
if (hPrevInstance)
{
MessageBox(GetFocus(), "This application is already running!",
"Windows Driver", MB_OK);
return FALSE;
}
// Register CTL3D
Ctl3dRegister(hInstance);
Ctl3dAutoSubclass(hInstance);
Ctl3dColorChange();
// Start the application
if (InitApp(nCmdShow, hInstance) == FALSE)
return FALSE;
// Load the keyboard accelerators
hAccel = LoadAccelerators(hInstance, "MenuAccel");
// Process all event driven messages...
while (GetMessage(&msg, NULL, NULL, NULL))
{
if ((! TranslateAccelerator(hMainWnd, hAccel, &msg)) &&
(! IsDialogMessage(hMainWnd, &msg)))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// Clean up and return
if (GlobBuf)
{
free(GlobBuf);
}
if (Search.pText)
{
free(Search.pText);
}
if (Search.pSearchStr)
{
free(Search.pSearchStr);
}
DestroyWindow(hMainWnd);
// Unregister CTL3D
Ctl3dUnregister(hInstance);
return msg.wParam;
}
//===================================================================
// Function:
// get_array_offset(void);
//
// Input: None.
//
// Return: The array element -OR-
// -1 if the element is not found
//
// Description:
// Return the array element for InputData[]. The element
// returned is determined by scanning the array for the
// currently selected code sample.
//===================================================================
INT16
get_array_offset (void)
{
INT32 Index;
INT16 i;
INT16 ret = -1;
// Get the currently selected code sample
Index = SendMsg(IDL_SELECT_CODE, LB_GETCURSEL, 0, 0);
SendMsg(IDL_SELECT_CODE, LB_GETTEXT, (WORD) Index,
(LONG)(LPSTR)GlobBuf);
// Search for the text in the input array
if (GlobBuf[0])
{
for (i = 0; i < MAX_VIEW_CODE_MODULES; i++)
{
// Scan for a match
if (lstrcmp(InputData[i].pCodeName, GlobBuf) ==
GOOD_STR_COMPARE)
{
ret = i;
i = MAX_VIEW_CODE_MODULES; // End the loop...
}
}
}
return ret;
}
//===================================================================
// Function:
// yield_control(void);
//
// Input: None.
//
// Return: None.
//
// Description:
// This routine will give Windows a chance to yield control
// of the CPU to other applications.
//===================================================================
void
yield_control (void)
{
MSG msg;
// Process all messages for the suite "dialog"
while (PeekMessage(&msg, hMainWnd, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
//===================================================================
// Function:
// clear_multi_line_edit_box(hWnd, EditId);
//
// Input: hWnd - The dialog handle
// EditId - The edit box to clear
//
// Return: None.
//
// Description:
// Clear the specified multi-line edit box selected code. If
// no description is available, then the text box will be left
// blank.
//===================================================================
void
clear_multi_line_edit_box (HWND hWnd, INT16 EditId)
{
// Select all text in the edit box, then replace it with ""
SendDlgItemMessage(hWnd, EditId, EM_SETSEL, (WPARAM)(UINT) 1,
MAKELPARAM(0, -1));
SendDlgItemMessage(hWnd, EditId, EM_REPLACESEL, 0,
(LPARAM)(LPCSTR)"");
// Allow Windows to process above messages
yield_control();
}
//===================================================================
// Function:
// fill_in_description(void);
//
// Input: None.
//
// Return: None.
//
// Description:
// Fill in the brief description for the currently selected
// code. If no description is available, then the text box
// will be left blank.
//===================================================================
void
fill_in_description (void)
{
INT16 Offset;
// First clear the text
SendMsg(IDE_DESCRIBE_CODE, WM_SETTEXT, (WPARAM) 0,
(LPARAM)(LPCSTR)"");
// Get the array offset of the code selected
Offset = get_array_offset();
if ((Offset != -1) && (InputData[Offset].CodeDescId > 0))
{
// Display the text if it loads
if (LoadString(hInst, InputData[Offset].CodeDescId,
(LPSTR) GlobBuf, 256) > 0)
{
SendMsg(IDE_DESCRIBE_CODE, WM_SETTEXT, (WPARAM) 0,
(LPARAM)(LPCSTR) GlobBuf);
}
// Display the sample code file
SendMsg(IDT_FILE_NAME, WM_SETTEXT, (WPARAM) 0,
(LPARAM)(LPCSTR) InputData[Offset].pSourceFile);
}
}
//===================================================================
// Function:
// get_search_text(void);
//
// Input: None.
//
// Return: None.
//
// Description:
// Retrieve the text from the main edit box. The text will
// be used during the "Search First" and "Search Next" calls.
//===================================================================
static void
get_search_text (void)
{
UINT16 TextLen;
// Allocate buffer for edit box text (add extra space just
// in case)
if (Search.pText)
{
free(Search.pText);
}
TextLen = (UINT16) SendMsg(IDE_VIEWER_OUTPUT, WM_GETTEXTLENGTH, 0, 0);
Search.pText = (char *)malloc(TextLen + 10);
// Retrieve the edit box text (used for searching)
SendMsg(IDE_VIEWER_OUTPUT, WM_GETTEXT, (WPARAM)(TextLen + 1),
(LPARAM)(LPCSTR) Search.pText);
// Reset the "last search" pointer
Search.pLastSearch = Search.pText;
}
//===================================================================
// Function:
// run_sample_code(void);
//
// Input: None.
//
// Return: None.
//
// Description:
// Fill in the brief description for the currently selected
// code. If no description is available, then the text box
// will be left blank.
//===================================================================
void
run_sample_code (void)
{
INT16 Offset;
Offset = get_array_offset();
if ((Offset != -1) && InputData[Offset].pFunc)
{
// Set the header
SendMsg(IDT_OUTPUT_HEADER, WM_SETTEXT, (WPARAM) 0,
(LPARAM)(LPCSTR) "Sample Code Output");
// Run the sample code
(*InputData[Offset].pFunc)();
// Cache the program output (for searching)
get_search_text();
}
}
//===================================================================
// Function:
// view_sample_code(void);
//
// Input: None.
//
// Return: None.
//
// Description:
// Put a copy of the sample code into the edit box.
//===================================================================
void
view_sample_code (void)
{
pCHAR pBuf;
HFILE hFile;
INT16 Offset;
UINT16 BytesRead;
Offset = get_array_offset();
if ((Offset != -1) && InputData[Offset].pSourceFile)
{
// Open the file in question
hFile = _lopen(InputData[Offset].pSourceFile, OF_READ);
if (hFile >= 0)
{
SendMsg(IDT_OUTPUT_HEADER, WM_SETTEXT, 0,
(LPARAM)(LPCSTR) "Sample Code Viewer");
// Allocate a 64k buffer
pBuf = (pCHAR) malloc(64000U);
// Read in a chunk of file data and get rid of EOF
BytesRead = _lread(hFile, pBuf, (UINT) 64000U);
pBuf[BytesRead] = '\0';
// Echo the code to the screen
SendMsg(IDE_VIEWER_OUTPUT, WM_SETTEXT, 0,
(LPARAM)(LPCSTR) pBuf);
// Trap for any possible errors
if (BytesRead == 64000U)
{
WinMsg("Sample code has been trimmed (too large to fit).",
MSG_INFO, BTN_OK);
}
// Clean up and return
free(pBuf);
_lclose(hFile);
// Cache the program output (for searching)
get_search_text();
}
else
{
WinMsg("Could not open sample code file.", MSG_STOP, BTN_OK);
}
}
}
//===================================================================
// Function:
// resize_resources(MainWidth, MainHeight);
//
// Input: MainWidth - Height of the main window
// MainHeight - Width of the main window
//
// Return: None.
//
// Description:
// The size of the main window has changed. Go ahead and
// resize the child windows.
//===================================================================
void
resize_resources (int MainWidth, int MainHeight)
{
BOOL ResizeMe;
INT16 i, Offset, X1, Y1, X2, Y2;
// Scan through the resources and resize specific ones. Note that the
// starting X and Y positions will never change. Resizing will only
// occur on the right and bottom borders.
for (i = 0; i < NUM_RESOURCES; i++)
{
ResizeMe = FALSE;
switch (MainRes[i].Id)
{
case IDT_HEADER_1:
case IDT_FILE_NAME:
case IDE_DESCRIBE_CODE:
Offset = 9;
ResizeMe = TRUE;
X1 = (MainRes[i].X1 * DialogWidthUnits);
X2 = ((MainWidth - (Offset * DialogWidthUnits)) - X1);
Y1 = (MainRes[i].Y1 * DialogHeightUnits);
Y2 = (MainRes[i].Y2 * DialogHeightUnits);
break;
case IDS_SHADE:
case IDT_HEADER_2:
case IDT_OUTPUT_HEADER:
Offset = 3;
ResizeMe = TRUE;
X1 = (MainRes[i].X1 * DialogWidthUnits);
X2 = ((MainWidth - (Offset * DialogWidthUnits)) - X1);
Y1 = (MainRes[i].Y1 * DialogHeightUnits);
Y2 = (MainRes[i].Y2 * DialogHeightUnits);
break;
case IDE_VIEWER_OUTPUT:
Offset = 6;
ResizeMe = TRUE;
X1 = (MainRes[i].X1 * DialogWidthUnits);
X2 = (MainWidth - (Offset * DialogWidthUnits));
Y1 = (MainRes[i].Y1 * DialogHeightUnits);
Y2 = ((MainHeight - (4 * DialogHeightUnits)) - Y1);
break;
}
if (ResizeMe)
{
MoveWindow(GetDlgItem(hMainWnd, MainRes[i].Id),
X1, Y1, X2, Y2, TRUE);
}
}
}
//===================================================================
// Function:
// search_text(hWnd, bSearchFirst);
//
// Input: hWnd - A dialog handle
// bSearchFirst - TRUE means "define the search" before you
// start the search
//
// Return: None.
//
// Description:
// Search the edit box for the first instance of a specific
// string.
//===================================================================
void
search_text (HWND hWnd, BOOL bSearchFirst)
{
FARPROC lpTempProc;
LONG iStart, iEnd;
// Make sure the search text is available
if (Search.pText == NULL)
{
WinMsg("You must VIEW or RUN sample code before you can search.",
MSG_INFO, BTN_OK);
return;
}
// Define the search criteria
if (bSearchFirst || (Search.pSearchStr == NULL))
{
// Define the search criteria
lpTempProc = MakeProcInstance((FARPROC) SearchDlgProc, hInst);
DialogBox(hInst, "SearchDlg", hWnd, (DLGPROC) lpTempProc);
FreeProcInstance((FARPROC) lpTempProc);
// Return if the "Cancel" button was pressed
if (Search.bCancelPressed)
return;
}
// Only search if the search string is defined
if (Search.pSearchStr)
{
if (!Search.pLastSearch)
{
WinMsg("Search string not found!", MSG_INFO, BTN_OK);
return;
}
if (!bSearchFirst)
Search.pLastSearch += strlen(Search.pSearchStr);
Search.pLastSearch = StrStr(Search.pLastSearch, Search.pSearchStr);
if (!Search.pLastSearch)
{
WinMsg("Search string not found!", MSG_INFO, BTN_OK);
return;
}
else
{
iStart = (Search.pLastSearch - Search.pText);
iEnd = (iStart + strlen(Search.pSearchStr));
SendDlgItemMessage(hWnd, IDE_VIEWER_OUTPUT, EM_SETSEL, 0,
MAKELPARAM((UINT16) iStart, (UINT16) iEnd));
}
}
else
WinMsg("Search string not defined!", MSG_INFO, BTN_OK);
}
//===================================================================
// Function:
// StrStr(pSourceString, pSearchString);
//
// Input: pSourceString - A pointer to the source string
// pSearchString - A pointer to the search string
//
// Return: A pointer to the string found in the source string.
//
// Description:
// Find the search string in the source string.
//===================================================================
char *
StrStr (pCHAR pSourceString, pCHAR pSearchString)
{
pCHAR ptrSource = NULL, ptrSearch = NULL;
// bCaseSens is TRUE
if (Search.bCaseSens)
{
return strstr(pSourceString, pSearchString);
}
// bCaseSens is not TRUE
for( ; *pSourceString ; pSourceString++ )
{
if (CaseInsensitiveCompare(*pSourceString, *pSearchString))
{
ptrSource = pSourceString + 1;
ptrSearch = pSearchString + 1;
for ( ; *ptrSearch ; ptrSearch ++, ptrSource++ )
{
if (!CaseInsensitiveCompare(*ptrSource, *ptrSearch))
{
break;
}
}
if (!(*ptrSearch))
{
return pSourceString;
}
}
}
return NULL;
}
//===================================================================
// Function:
// CaseInsensitiveCompare(Char1, Char2);
//
// Input: Char1 - A character
// Char2 - A character
//
// Return: Boolean TRUE/FALSE.
//
// Description:
// Compare these two characters case insensitively.
//===================================================================
BOOL
CaseInsensitiveCompare (CHAR Char1, CHAR Char2)
{
if (isalpha(Char1))
{
if (isupper(Char1))
{
return(((Char1 == Char2) || (Char1 == Char2 - 32)) ? TRUE : FALSE);
}
else
{
return(((Char1 == Char2) || (Char1 == Char2 + 32)) ? TRUE : FALSE);
}
}
else
{
return ((Char1 == Char2) ? TRUE : FALSE);
}
}
//===================================================================
// Function:
// setup_tab_edit_box(hDlg, EditId);
//
// Input: hWnd - A dialog handle
// EditId - The edit box that is to be customized
//
// Return: The newly assigned procedure pointer
//
// Description:
// Set up an edit box so that tab keys change focus to
// another resource.
//===================================================================
FARPROC
setup_tab_edit_box (HWND hWnd, int EditId)
{
HWND hTempWnd; // Handle of the Edit control
FARPROC EditProc; // The TabEditBox Windows procedure
// If the standard edit box function has not yet been saved, save it.
hTempWnd = GetDlgItem(hWnd, EditId);
if (fpStdEditBoxProc == NULL)
fpStdEditBoxProc = (WNDPROC) GetWindowLong(hTempWnd, GWL_WNDPROC);
// Force the edit box processing to the sub-class function
EditProc = (FARPROC) MakeProcInstance((FARPROC) TabEditBox, hInst);
SetWindowLong(hTempWnd, GWL_WNDPROC, (LONG) EditProc);
// Return the variable created by MakeProcInstance()
return EditProc;
}
//===================================================================
// Function:
// TabEditBox(hDlg, msg, wParam, lParam);
//
// Input: hWnd - The Window handle
// msg - Message to process
// wParam - Word Parameter
// lParam - Long Parameter
//
// Return: Long - Value returned from Message - depends on
// message.
//
// Description:
// This routine will change focus away from the edit box when
// a TAB, or BACKTAB, is hit.
//===================================================================
long FAR PASCAL _export
TabEditBox (HWND hWnd, UINT msg, WORD wParam, LONG lParam)
{
int Id; // ID of currently selected control
long ret = FALSE; // Return value
// Check for special cases
switch (msg)
{
case WM_GETDLGCODE:
return DLGC_WANTMESSAGE;
case WM_CHAR:
if (wParam == VK_TAB)
{
ret = TRUE;
Id = GetDlgCtrlID(hWnd);
if (GetKeyState(VK_SHIFT) < 0)
{
if (Id == IDE_DESCRIBE_CODE)
Id = IDL_SELECT_CODE;
else
Id = IDE_DESCRIBE_CODE;
}
else // Standard TAB
{
if (Id == IDE_DESCRIBE_CODE)
Id = IDE_VIEWER_OUTPUT;
else
Id = IDB_VIEW_CODE;
}
// Change resource focus
SetFocus(GetDlgItem(hMainWnd, Id));
}
// Don't want to exit the app on escape.
if (wParam == VK_ESCAPE)
{
MessageBeep(1);
}
break;
}
// Send unprocessed messages to standard edit box processor
if (ret == FALSE)
ret = CallWindowProc(fpStdEditBoxProc, hWnd, msg, wParam, lParam);
return ret;
}
//===================================================================
// Function:
// SendMsg(Id, Msg, wParam, lParam);
//
// Input: Id - Child ID to send the message to
// Msg - Windows message (i.e. EM_SETSEL)
// wParam - Message Parameter
// lParam - Message parameter
//
// Return: None
//
// Description:
// Send a message to a child of the main window.
//===================================================================
LRESULT
SendMsg (int Id, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return SendMessage(GetDlgItem(hMainWnd, Id), Msg, wParam, lParam);
}
//===================================================================
// Name: CreateResources(hInstance, hWnd);
//
// Input: hInstance - Application instance handle
// hWnd - Handle for the main window
//
// Return: None
//
// Description:
// Create child resources on main window.
//===================================================================
static void
CreateResources (HINSTANCE hInstance, HWND hWnd)
{
HWND hResWnd; // Window Handle to the resource
char TypeRes[20]; // Type of the resource
int i; // Loop counter - iterate throught the
// number of resources
int X1; // Horizontal position of top left
int X2; // Horizontal position of bottom right
int Y1; // Vertical position of top left
int Y2; // Vertical position of bottom right
HINSTANCE hTempPtr; // Pointer used in creating an edit control
// which dynamically allocates memory
HGLOBAL TextAlloc; // Global handle to memory - used in
// creating a 64K edit control
void* TextPtr; // Pointer used in allocating space for the
// large (64K) edit control
UINT16 uTextBufferSize;// The number of bytes in the 64K edit
// control.
hTempPtr = hInstance; // Use the application instance in all cases
// except when creating an edit control to not
// use the heap.
// Create all resources
for (i = 0; i < NUM_RESOURCES; i++)
{
switch (MainRes[i].Res)
{
case resBUTTON:
strcpy(TypeRes, "BUTTON");
break;
case resCOMBOBOX:
strcpy(TypeRes, "COMBOBOX");
break;
case resEDIT:
strcpy(TypeRes, "EDIT");
break;
case resEDIT64:
strcpy(TypeRes, "EDIT");
// Allow the edit control to contain up to 64000 bytes of
// information.
uTextBufferSize = 64000U; // Set the size of the buffer
// Allocate the memory for the edit control.
// Edit control takes ownership of this memory, so
// this memory is not released explicitly by this
// application.
// WARNING! A GPF will occur if the application is
// terminated after the memory is freed.
TextAlloc = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE,
uTextBufferSize);
TextPtr = GlobalLock(TextAlloc);
LocalInit(HIWORD((LONG) TextPtr), 0,
(WORD) GlobalSize(TextAlloc) - 16);
UnlockSegment(HIWORD((LONG) TextPtr));
hTempPtr = (HINSTANCE) HIWORD(TextPtr); // Set the hInstance
// for the edit control.
break;
case resGROUP:
strcpy(TypeRes, "BUTTON");
break;
case resLISTBOX:
strcpy(TypeRes, "LISTBOX");
break;
case resSTATIC:
strcpy(TypeRes, "STATIC");
break;
case resSHADE:
strcpy(TypeRes, "BorShade");
break;
default:
return;
}
// Adjust resource size with standard dialog units
X1 = (MainRes[i].X1 * DialogWidthUnits);
X2 = (MainRes[i].X2 * DialogWidthUnits);
Y1 = (MainRes[i].Y1 * DialogHeightUnits);
Y2 = (MainRes[i].Y2 * DialogHeightUnits);
// Create the child window
hResWnd = CreateWindow(TypeRes, MainRes[i].Text, MainRes[i].Attrib,
X1, Y1, X2, Y2, hWnd, (HMENU)MainRes[i].Id,
hTempPtr, NULL);
if (hResWnd)
{
ShowWindow(hResWnd, SW_SHOW);
// Sub-class the edit boxes
if (MainRes[i].Id == IDE_VIEWER_OUTPUT)
{
hViewEdit = hResWnd;
fnTabEditBox[0] =
(WNDPROC)setup_tab_edit_box(hWnd,
IDE_VIEWER_OUTPUT);
}
else if (MainRes[i].Id == IDE_DESCRIBE_CODE)
{
hDescEdit = hResWnd;
fnTabEditBox[1] =
(WNDPROC)setup_tab_edit_box(hWnd,
IDE_DESCRIBE_CODE);
}
}
else
i = NUM_RESOURCES; // End the loop...
}
}
//===================================================================
// Function:
// InitMainWnd(hWnd);
//
// Input: hWnd - Handle for main window
//
// Return: None
//
// Description:
// Init the main window. Fill list boxes, set the focus of
// the default window.
//===================================================================
static void
InitMainWnd (HWND hWnd)
{
INT16 i; // Loop counter - iterate through the number of
// resources
HFONT hFont; // Handle to the font
// Fill the list box with the code available
for (i = 0; i < MAX_VIEW_CODE_MODULES; i++)
{
if (InputData[i].pCodeName[0])
{
SendDlgItemMessage(hWnd, IDL_SELECT_CODE, LB_ADDSTRING, 0,
(LPARAM)(LPCSTR) InputData[i].pCodeName);
}
else
i = MAX_VIEW_CODE_MODULES; // No more code mods;
// end the loop...
}
// Select the first item of the list box
SendDlgItemMessage(hWnd, IDL_SELECT_CODE, LB_SETCURSEL, 0, 0);
// Use a non-proportional font in the main edit box
hFont = (HFONT) GetStockObject(ANSI_FIXED_FONT);
SendDlgItemMessage(hWnd, IDE_VIEWER_OUTPUT, WM_SETFONT,
(WPARAM) hFont, FALSE);
// Set the focus to the dialog to the "select code" list box
SetFocus(GetDlgItem(hWnd, IDL_SELECT_CODE));
// Set the description for the first item
fill_in_description();
}
//=================================================================
// Function:
// InitApp(nCmdShow, hInst);
//
// Input: nCmdShow - Whether to show the window after it is created
// hInst - The current instance for the application
//
// Return: TRUE - Init worked
// FALSE - Init failed
//
// Description:
// Create the application window (in this case a dialog).
//================================================================
static BOOL
InitApp (int nCmdShow, HINSTANCE hInstance)
{
WNDCLASS wc; // Window class
HWND hWnd; // Handle to the main window
BOOL ret = TRUE; // Return value
unsigned uCount; // Number of available file handles
char szMessage[DBIMAXMSGLEN * 2 + 1]; // Allocate enough space for
// the message.
// The directory relative to the SNIPIT directory which contains the
// tables.
CHAR szRelativeTblDirectory[DBIMAXPATHLEN+1];
// Init the application and create the needed windows
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(1100));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
wc.lpszMenuName = "MainMenu";
wc.lpszClassName = "SnipIt";
if (! RegisterClass(&wc))
{
MessageBox(NULL, "RegisterClass failed!", "System Error",
MB_OK | MB_ICONHAND);
return FALSE;
}
// Get the base horizontal and vertical dialog units
DialogWidthUnits = (LOWORD(GetDialogBaseUnits()) / 4);
DialogHeightUnits = (HIWORD(GetDialogBaseUnits()) / 8);
// Create windows used for I/O
GetWindowRect(GetDesktopWindow(), &DeskRect);
MinWidth = (BASE_MIN_WIDTH * DialogWidthUnits);
MinHeight = (BASE_MIN_HEIGHT * DialogHeightUnits);
hWnd = CreateWindow("SnipIt", "SnipIt Code Viewer",
WS_OVERLAPPEDWINDOW,
DeskRect.left, DeskRect.top,
DeskRect.right, DeskRect.bottom,
NULL, NULL, hInstance, NULL);
if (hWnd)
{
hMainWnd = hWnd;
hInst = hInstance;
GlobBuf = (pCHAR) malloc(1024);
ShowWindow(hMainWnd, nCmdShow);
UpdateWindow(hMainWnd);
InitMainWnd(hMainWnd);
}
else
{
MessageBox(NULL, "CreateWindow failed!", "System Error",
MB_OK | MB_ICONHAND);
ret = FALSE;
}
// Increase the number of file handles that are available to the
// system.
uCount = SetHandleCount(FILEHANDLESNEEDED);
if (uCount < FILEHANDLESNEEDED)
{
MessageBox(NULL, "Not enough file handles available. 'Set files=40' in"
" CONFIG.SYS.", "System Error", MB_OK | MB_ICONHAND);
return FALSE;
}
// Get the directory which contains the tables.
GetPrivateProfileString("SNIPIT", "TblDir",
"..\\TABLES",
(LPSTR)szRelativeTblDirectory,
sizeof(szRelativeTblDirectory),
"bde.ini");
// Create a fully qualified path for the table directory.
if (MakeFullPath(szTblDirectory, szRelativeTblDirectory))
{
sprintf(szMessage, "Working Directory does not exist: %s",
szTblDirectory);
MessageBox(NULL, szMessage, "System Error", MB_OK | MB_ICONHAND);
return FALSE;
}
// Get the Private directory.
GetPrivateProfileString("SNIPIT", "PrivateDir",
".",
(LPSTR)szRelativeTblDirectory,
sizeof(szRelativeTblDirectory),
"bde.ini");
// Create a fully qualified path for the private directory.
if (MakeFullPath(szPrivDirectory, szRelativeTblDirectory))
{
sprintf(szMessage, "Private Directory does not exist: %s",
szPrivDirectory);
MessageBox(NULL, szMessage, "System Error", MB_OK | MB_ICONHAND);
return FALSE;
}
return ret;
}
//===================================================================
// Function:
// MainWndProc(hWnd, msg, wParam, lParam);
//
// Input: hWnd - The Window handle
// msg - Message to handle
// wParam - Word Parameter
// lParam - Long Parameter
//
// Return: BOOL - Was message handled?
//
// Description:
// This routine will process all messages for
// the primary application window. Included in this are all
// menu commands.
//===================================================================
long FAR PASCAL _export
MainWndProc (HWND hWnd, UINT msg, UINT wParam,
LONG lParam)
{
HWND hFocus; // Child window which currently has
// focus.
HWND hwnd; // Variable used to iterate through
// list of child windows
MINMAXINFO* pMinMax; // Used to determine the minimum and
// maximum size of the window
FARPROC lpTempProc; // Temporary windows procedure used
// for child dialogs and windows
INT32 ret = FALSE; // Return Value
HBRUSH hBrush; // Handle to the brush
long lMinMax; // Contains both starting and ending
// selected positions in edit
// control
unsigned int iStart; // Starting position of selected text
unsigned int iEnd; // Ending position of selected text
switch (msg)
{
case WM_CREATE:
CreateResources(((LPCREATESTRUCT) lParam)->hInstance, hWnd);
hwnd = GetWindow(hWnd, GW_CHILD);
while (hwnd != NULL)
{
Ctl3dSubclassCtl(hwnd);
hwnd = GetWindow(hwnd, GW_HWNDNEXT);
}
break;
case WM_CTLCOLOR:
hBrush = Ctl3dCtlColorEx(msg, wParam, lParam);
if (hBrush != (HBRUSH)0)
{
return (long)(WORD)hBrush;
}
else
{
return DefWindowProc(hWnd, msg, wParam, lParam);
}
case WM_SYSCOLORCHANGE:
Ctl3dColorChange();
return TRUE;
case WM_NCPAINT:
case WM_NCACTIVATE:
case WM_SETTEXT:
return Ctl3dDlgFramePaint(hWnd, msg, wParam, lParam);
case WM_SETFOCUS:
SetFocus(GetDlgItem(hWnd, IDL_SELECT_CODE));
break;
case WM_GETMINMAXINFO:
pMinMax = (MINMAXINFO *) lParam;
pMinMax->ptMinTrackSize.x = MinWidth;
pMinMax->ptMinTrackSize.y = MinHeight;
ret = DefWindowProc(hWnd, msg, wParam, lParam);
break;
case WM_SIZE:
resize_resources(LOWORD(lParam), HIWORD(lParam));
break;
case WM_COMMAND:
// Process the menu commands
hFocus = GetFocus();
switch(wParam)
{
case IDL_SELECT_CODE:
if (HIWORD(lParam) == LBN_SELCHANGE)
fill_in_description();
else if (HIWORD(lParam) == LBN_DBLCLK)
view_sample_code();
break;
case IDB_RUN_CODE:
case IDM_RUN_CODE:
clear_multi_line_edit_box(hWnd, IDE_VIEWER_OUTPUT);
run_sample_code();
break;
case IDB_VIEW_CODE:
case IDM_VIEW_CODE:
clear_multi_line_edit_box(hWnd, IDE_VIEWER_OUTPUT);
view_sample_code();
break;
case IDB_COPY:
case IDM_COPY:
// Determine which characters are selected
lMinMax = SendDlgItemMessage(hWnd, IDE_VIEWER_OUTPUT,
EM_GETSEL, 0, 0L);
// Get the first and last selected character
iStart = LOWORD(lMinMax);
iEnd = HIWORD(lMinMax);
// If nothing is selected, select all
if (iStart == iEnd)
{
SendDlgItemMessage(hWnd, IDE_VIEWER_OUTPUT,
EM_SETSEL, 0, 0xfffeL);
}
SendDlgItemMessage(hWnd, IDE_VIEWER_OUTPUT, WM_COPY,
0, 0L);
break;
case IDM_SEARCH_FIRST:
case IDB_SEARCH_TEXT:
hFocus = GetDlgItem(hWnd, IDE_VIEWER_OUTPUT);
search_text(hWnd, TRUE);
break;
case IDM_SEARCH_NEXT:
hFocus = GetDlgItem(hWnd, IDE_VIEWER_OUTPUT);
search_text(hWnd, FALSE);
break;
case IDM_ABOUT:
lpTempProc =
MakeProcInstance((FARPROC) AboutDlgProc, hInst);
DialogBox(hInst, "AboutDlg", hMainWnd,
(DLGPROC)lpTempProc);
FreeProcInstance((FARPROC) lpTempProc);
break;
case IDM_EXIT:
PostQuitMessage(0);
break;
default:
ret = DefWindowProc(hWnd, msg, wParam, lParam);
break;
}
SetFocus(hFocus);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
ret = DefWindowProc(hWnd, msg, wParam, lParam);
break;
}
return ret;
}
//===============================================================
// Function:
// About(hDlg, msg, wParam, lParam);
//
// Input: hDlg - The dialog handle
// msg - Message to handle
// wParam - Word Parameter
// lParam - Long Parameter
//
// Return: BOOL - Was message handled?
//
// Description: This routine will process all I/O for the
// ABOUT dialog.
//================================================================
BOOL FAR PASCAL _export
AboutDlgProc (HWND hDlg, WORD msg, WORD wParam,
LONG lParam)
{
int ret = FALSE;
lParam = lParam; // Avoid warning - Parameter not used
switch (msg)
{
case WM_INITDIALOG:
ret = TRUE;
break;
case WM_COMMAND:
switch (wParam)
{
case IDOK:
case IDCANCEL:
EndDialog(hDlg, TRUE);
ret = TRUE;
break;
}
break;
}
return ret;
}
//===================================================================
// Fuction:
// reset_connect_dialog(hWnd, bResetAll);
//
// Input: hWnd - The dialog handle
// bResetAll - TRUE means to repaint the entire dialog
// FALSE means to repaint alias information
//
// Return: None
//
// Description: Reset the "connect to the database" dialog based
// on the current driver selected.
//===================================================================
void
reset_connect_dialog (HWND hWnd, BOOL bResetAll)
{
hDBICur hList;
DBDesc DbData;
pFLDDesc pCfgInfo;
WORD ListIndex;
pCHAR pCfgRecBuf;
pCHAR Driver;
pCHAR Alias;
pCHAR CfgPath;
// Allocate resources
Alias = (pCHAR) malloc((DBIMAXSCFLDLEN + 1) * sizeof(CHAR));
Driver = (pCHAR) malloc((DBIMAXSCFLDLEN + 1) * sizeof(CHAR));
CfgPath = (pCHAR) malloc((DBIMAXPATHLEN + 1) * sizeof(CHAR));
pCfgRecBuf = (pCHAR) malloc((DBIMAXSCRECSIZE + 1) * sizeof(CHAR));
pCfgInfo = (pFLDDesc) malloc(sizeof(FLDDesc) * DBIMAXSCFIELDS);
// Get the driver currently selected
ListIndex = (WORD) SendDlgItemMessage(hWnd, IDL_DRIVERS, LB_GETCURSEL,
0,0);
SendDlgItemMessage(hWnd, IDL_DRIVERS, LB_GETTEXT, (WPARAM) ListIndex,
(LPARAM) Driver);
// Reset the driver to "STANDARD" if Paradox or dBASE
if ((strncmp(Driver, szDBASE, DBIMAXSCFLDLEN) == GOOD_STR_COMPARE) ||
(strncmp(Driver, szPARADOX, DBIMAXSCFLDLEN) == GOOD_STR_COMPARE))
{
strcpy(Driver, "STANDARD");
}
// Leave the alias list alone if not resetting entire listbox
if (bResetAll)
{
// Reset info displayed (based on the driver type)
if (strncmp(Driver, "STANDARD", DBIMAXSCFLDLEN) == GOOD_STR_COMPARE)
{
// Remove the user name and password if alias is STANDARD
ShowWindow(GetDlgItem(hWnd, IDE_PASSWORD), SW_HIDE);
ShowWindow(GetDlgItem(hWnd, IDT_PASSWORD_HDR), SW_HIDE);
}
else
{
// Make sure all is displayed
ShowWindow(GetDlgItem(hWnd, IDE_PASSWORD), SW_SHOW);
ShowWindow(GetDlgItem(hWnd, IDT_PASSWORD_HDR), SW_SHOW);
}
// Clear and fill the alias listbox
SendDlgItemMessage(hWnd, IDL_ALIASES, LB_RESETCONTENT, 0, 0);
if (DbiOpenDatabaseList(&hList) == DBIERR_NONE)
{
// Scan the list of aliases for matching drivers
while (DbiGetNextRecord(hList, dbiNOLOCK, (pBYTE) &DbData,
NULL) == DBIERR_NONE)
{
if (strncmp(DbData.szDbType, Driver, DBIMAXSCFLDLEN) == GOOD_STR_COMPARE)
{
SendDlgItemMessage(hWnd, IDL_ALIASES, LB_INSERTSTRING,
0, (LPARAM) DbData.szName);
}
}
DbiCloseCursor(&hList);
SendDlgItemMessage(hWnd, IDL_ALIASES, LB_SETCURSEL, 0, 0);
}
}
// Free resources used
free(Alias);
free(Driver);
free(CfgPath);
free(pCfgRecBuf);
free((pCHAR) pCfgInfo);
}
//===================================================================
// Function:
// ConnectDlgProc(hDlg, msg, wParam, lParam);
//
// Input: hDlg - The dialog handle
// msg - Message to handle
// wParam - Word Parameter
// lParam - Long Parameter
//
// Return: BOOL - Was message handled?
//
// Description: This routine will make a connection
// to a database (setting a global handle).
//===================================================================
BOOL FAR PASCAL _export
ConnectDlgProc (HWND hDlg, WORD msg, WORD wParam,
LONG lParam)
{
DBIResult rslt;
hDBICur hList;
WORD ListIndex;
int ret = FALSE;
pCHAR Driver;
pCHAR Alias;
pCHAR Password;
pCHAR Message;
DBIMSG dbi_status;
DBIErrInfo ErrInfo;
// Process dialog
switch (msg)
{
case WM_INITDIALOG:
// This code assumes that IDAPI is already initialized.
// Fill the listbox with the drivers available
ret = TRUE;
Driver = (pCHAR) malloc(DBIMAXSCFLDLEN + 1);
if (Driver)
{
if (DbiOpenDriverList(&hList) == DBIERR_NONE)
{
while (DbiGetNextRecord(hList, dbiNOLOCK, (pBYTE)Driver,
NULL) == DBIERR_NONE)
{
// Make certain driver name is terminated -
// max driver length is DBIMAXNAMELEN (32)
Driver[DBIMAXNAMELEN] = 0;
SendDlgItemMessage(hDlg, IDL_DRIVERS,
LB_INSERTSTRING, 0,
(LPARAM) Driver);
}
DbiCloseCursor(&hList);
}
free(Driver);
}
// Select the first items of the list boxes
SendDlgItemMessage(hDlg, IDL_DRIVERS, LB_SETCURSEL, 0, 0);
// Fill the listbox with the aliases
reset_connect_dialog(hDlg, TRUE);
break;
case WM_COMMAND:
switch (wParam)
{
case IDL_DRIVERS:
if (HIWORD(lParam) == LBN_SELCHANGE)
reset_connect_dialog(hDlg, TRUE);
break;
case IDL_ALIASES:
if (HIWORD(lParam) == LBN_SELCHANGE)
reset_connect_dialog(hDlg, FALSE);
break;
case IDOK:
// Init the strings
Alias = (pCHAR) malloc(DBIMAXSCFLDLEN * sizeof(BYTE));
Driver = (pCHAR) malloc(DBIMAXSCFLDLEN * sizeof(BYTE));
Password = (pCHAR) malloc(DBIMAXSCFLDLEN * sizeof(BYTE));
Alias[0] = '\0';
Driver[0] = '\0';
Password[0] = '\0';
// Get the selected driver
ListIndex =
(WORD) SendDlgItemMessage(hDlg, IDL_DRIVERS,
LB_GETCURSEL, 0, 0);
SendDlgItemMessage(hDlg, IDL_DRIVERS, LB_GETTEXT,
(WPARAM) ListIndex, (LPARAM) Driver);
if ((strncmp(Driver, szDBASE, DBIMAXSCFLDLEN) == GOOD_STR_COMPARE) ||
(strncmp(Driver, szPARADOX, DBIMAXSCFLDLEN) == GOOD_STR_COMPARE))
{
Driver[0] = '\0';
ListIndex =
(WORD) SendDlgItemMessage(hDlg, IDL_ALIASES,
LB_GETCURSEL, 0, 0);
SendDlgItemMessage(hDlg, IDL_ALIASES, LB_GETTEXT,
(WPARAM) ListIndex,
(LPARAM)Alias);
}
else // SQL database...
{
// SQL database needs the alias & password
ListIndex =
(WORD) SendDlgItemMessage(hDlg, IDL_ALIASES,
LB_GETCURSEL, 0, 0);
SendDlgItemMessage(hDlg, IDL_ALIASES, LB_GETTEXT,
(WPARAM) ListIndex,
(LPARAM)Alias);
SendDlgItemMessage(hDlg, IDE_PASSWORD, WM_GETTEXT,
80, (LPARAM) Password);
}
// Try to open the database
SetCursor(LoadCursor(NULL, IDC_WAIT));
SnipItDb = NULL;
rslt = DbiOpenDatabase(Alias, Driver, dbiREADWRITE,
dbiOPENSHARED, Password, 0,
NULL, NULL, &SnipItDb);
SetCursor(LoadCursor(NULL, IDC_ARROW));
if (rslt == DBIERR_NONE)
{
ret = TRUE;
EndDialog(hDlg, TRUE);
}
else
{
// Make certain to allocate enough space for all the
// Error contexts
Message = (pCHAR)malloc(8 * DBIMAXMSGLEN *
sizeof(BYTE));
if (!Message)
{
MessageBox(hDlg, "Out of memory!", "Initialization"
" Error", MB_OK | MB_ICONSTOP);
}
else
{
// Get as much error information as possible
DbiGetErrorInfo(TRUE, &ErrInfo);
// Make certain information is returned on the
// correct error
if (ErrInfo.iError == rslt)
{
wsprintf(Message, "Cat:Code = [%xh:%xh]\r\n%s",
ErrCat(ErrInfo.iError),
ErrCode(ErrInfo.iError),
ErrInfo.szErrCode);
if (strncmp(ErrInfo.szContext1, "", DBIMAXMSGLEN))
{
strcat(Message, ErrInfo.szContext1);
}
if (strncmp(ErrInfo.szContext2, "", DBIMAXMSGLEN))
{
strcat(Message, ErrInfo.szContext2);
}
if (strncmp(ErrInfo.szContext3, "", DBIMAXMSGLEN))
{
strcat(Message, ErrInfo.szContext3);
}
if (strncmp(ErrInfo.szContext4, "", DBIMAXMSGLEN))
{
strcat(Message, ErrInfo.szContext4);
}
}
else
{
DbiGetErrorString(rslt, dbi_status);
wsprintf(Message, "%s\r\nCat:Code = [%xh:%xh]"
"\r\n\r\n %s", "Failed to connect!",
ErrCat(rslt), ErrCode(rslt),
dbi_status);
}
MessageBox(hDlg, (LPSTR) Message, "Initialization"
" Error", MB_OK | MB_ICONSTOP);
free(Message);
}
}
// Free up resources
free(Alias);
free(Driver);
free(Password);
break;
case IDCANCEL:
ret = TRUE;
SnipItDb = NULL;
EndDialog(hDlg, TRUE);
break;
}
break;
}
return ret;
}
//===================================================================
// Function:
// SearchDlgProc(hDlg, msg, wParam, lParam);
//
// Input: hDlg - The dialog handle
// msg - Message to handle
// wParam - Word Parameter
// lParam - Long Parameter
//
// Return: BOOL - Was message handled?
//
// Description: This routine will process all messages for the
// dialog used to define search criteria.
//===================================================================
BOOL FAR PASCAL _export
SearchDlgProc (HWND hDlg, WORD msg, WORD wParam, LONG lParam)
{
INT16 len;
BOOL ret = FALSE;
// Avoid warning: Parameter not used
lParam = lParam;
// Process dialog
switch (msg)
{
case WM_INITDIALOG:
// Set search value to what it was previously
if (Search.pSearchStr)
{
SendDlgItemMessage(hDlg, IDE_SEARCH_TEXT, WM_SETTEXT, 0,
(LPARAM)(LPCSTR) Search.pSearchStr);
}
else
{
SendDlgItemMessage(hDlg, IDE_SEARCH_TEXT, WM_SETTEXT, 0,
(LPARAM)(LPCSTR) "Dbi");
}
// Set check boxes to previous values
SendDlgItemMessage(hDlg, IDCHK_CASE_SENS, BM_SETCHECK,
(WPARAM) Search.bCaseSens, (LPARAM) 0);
// Set the "Cancel" flag before returning
ret = TRUE;
Search.bCancelPressed = TRUE;
break;
case WM_COMMAND:
switch (wParam)
{
case IDOK:
// Get the search string
if (Search.pSearchStr)
{
free(Search.pSearchStr);
}
len = (INT16) SendDlgItemMessage(hDlg, IDE_SEARCH_TEXT,
WM_GETTEXTLENGTH, 0, 0);
Search.pSearchStr = (char *)malloc(len + 10);
SendDlgItemMessage(hDlg, IDE_SEARCH_TEXT, WM_GETTEXT,
(WPARAM) (len + 1),
(LPARAM)(LPCSTR) Search.pSearchStr);
Search.pLastSearch = Search.pText;
// Get the search options
Search.bCaseSens =
(BOOL) SendDlgItemMessage(hDlg, IDCHK_CASE_SENS,
BM_GETCHECK, 0, 0);
// End the dialog
ret = TRUE;
Search.bCancelPressed = FALSE;
EndDialog(hDlg, TRUE);
break;
case IDCANCEL:
ret = TRUE;
EndDialog(hDlg, TRUE);
break;
}
break;
}
return ret;
}