// BDE - (C) Copyright 1995 by Borland International #include "snipit.h" #include #include #include #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; }