home *** CD-ROM | disk | FTP | other *** search
- /*
- ┌──────────────────────────────────────────────────────────────────────────┐
- │ vxBase xbase for Visual Basic library │
- │ Copyright 1992 vxBase (512523 Alberta Ltd.) │
- ├────────────────┬──────┬────────────┬────────┬───────────────┬────────────┤
- │ SYSTEM │ VX │ PROGRAM ID │ VXSAMP │ CREATION DATE │ 02/29/92 │
- ├────────────────┼──────┴────────────┴────────┴───────────────┴────────────┤
- │ PROGRAM TITLE │ sample c program using vxbase functions from vxbase.dll│
- ├─────┬──────┬───┴┬───────────────────────────┬────────────────────────────┤
- │ REV │ DATE │ BY │ DESCRIPTION │ Written by T. Orletsky │
- ├─────┼──────┼────┼───────────────────────────┴────────────────────────────┤
- │ │ │ │ │
- └─────┴──────┴────┴────────────────────────────────────────────────────────┘
-
- This sample code and all other supplied sample files should be
- loaded into \vb\vxc to use the .def and project files
- for compilation under Turbo c++ for Windows (ver 3.0).
-
- If using a non-Borland compiler, remove the "pragma argsused"
- directives.
-
- !!! ALWAYS COMPILE UNDER THE LARGE MODEL !!!
-
- */
-
- #include <windows.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dos.h>
- #include "vxb.h"
- #include "vxsamp.h"
-
-
- /* ********************************************************* */
- /* global vars defined */
- /* ********************************************************* */
-
- HWND hgWnd; //Global Window Handle.
- HANDLE hgInst; //Global Instance Handle.
-
- int DbfArea1; //vxbase dbf area 1
- int NtxArea1; //vxbase ntx area 1
- int DbfArea2; //vxbase dbf area 2
- int NtxArea2; //vxbase ntx area 2
- long RetVal; //vxbrowse return value
- char szBuffer[81]; //miscellaneous buffer
- char szBuffer2[81]; //miscellaneous buffer 2
-
- /*
- * Array of pointers to strings loaded from the resource file.
- * Pointers can be near since LocalAlloc will be used to get
- * the string space.
- */
-
- char NEAR *rgpsz[CSTRINGS];
-
-
- /*
- * WinMain
- *
- * Purpose:
- * Main entry point of application. Should register the app class
- * if a previous instance has not done so and do any other one-time
- * initializations.
- *
- * Parameters:
- * See Windows SDK Guide to Programming, page 2-3
- *
- * Return Value:
- * Value to return to Windows--termination code.
- *
- */
-
-
- int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
- LPSTR lpszCmdLine, int nCmdShow)
- {
- WNDCLASS wndClass;
- HANDLE hStringMem;
- HWND hWnd;
- MSG msg;
-
- hgInst = hInstance;
-
- /*
- * InitApp allocates local memory for strings. WinMain must free.
- * If this fails, we should quit BEFORE any classes are registered
- * or do anything else that uses up USER or GDI resources.
- */
- hStringMem = HLoadAppStrings();
-
- if (hStringMem == NULL)
- {
- LocalFree(hStringMem);
- return FALSE;
- }
-
- if (!hPrevInstance)
- {
- wndClass.style = CS_HREDRAW | CS_VREDRAW;
- wndClass.lpfnWndProc = vxWndProc;
- wndClass.cbClsExtra = 0;
- wndClass.cbWndExtra = 0;
- wndClass.hInstance = hInstance;
- wndClass.hIcon = LoadIcon(hInstance, "vxIcon");
- wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndClass.hbrBackground = COLOR_BTNFACE + 1;
- wndClass.lpszMenuName = "vxMenu";
- wndClass.lpszClassName = "vxSamp";
-
- if (!RegisterClass(&wndClass))
- return FALSE;
- }
-
- hWnd = CreateWindow("vxSamp",
- rgpsz[IDS_CAPTION],
- WS_MINIMIZEBOX | WS_OVERLAPPEDWINDOW,
- 50, 50, 500, 300,
- NULL,
- NULL,
- hInstance,
- NULL);
-
- hgWnd = hWnd;
- ShowWindow(hWnd, nCmdShow);
- UpdateWindow(hWnd);
-
-
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- LocalFree(hStringMem);
- return msg.wParam;
- }
-
- /*
- * vxWndProc
- *
- * Purpose:
- * Window class procedure. Standard callback.
- *
- * Parameters:
- * The standard. See Section 2.4 Windows SDK Guide to Programming,
- * page 2-4.
- *
- * Return Value:
- * See Parameters, above.
- *
- */
-
- long FAR PASCAL vxWndProc(HWND hWnd, UINT iMessage,
- WORD wParam, LONG lParam)
- {
- HMENU hMenu; // handle to main menu
- int j; // work integer
- PAINTSTRUCT ps; // paint structure
-
- switch (iMessage)
- {
-
- /* handle vxBase initialization procedures when window */
- /* creation message is received */
- /* *************************************************** */
- case WM_CREATE:
- vxInit(); // register in multitask list
- vxCtlGraySet(); // set up gray scale
- vxBrowseCase(VX_UPPER); // default browse case
- vxSetString(VX_ASCIIZ); // set string types to c strings
- break;
-
- /* on exit, reset system gray and post quit */
- /* **************************************** */
- case WM_DESTROY:
- vxCtlGrayReset(); // reset system grays
- PostQuitMessage(0); // kill
- break;
-
- /* on paint, draw frame around window */
- /* ********************************** */
- case WM_PAINT:
- BeginPaint(hWnd, &ps);
- vxFormFrame(hWnd);
- EndPaint(hWnd, &ps);
- break;
-
-
- /* ******************************************* */
- /* If user closes from system menu, ensure */
- /* that multitask closure sequence is correct. */
- /* The first vxbase task loaded MUST be the */
- /* last one unloaded because it controls the */
- /* vxbase shareable memory. If the first task */
- /* is closed, the memory goes with it and any */
- /* other tasks using vxbase will terminate */
- /* with an Unrecoverable Application error. */
- /* ******************************************* */
- case WM_SYSCOMMAND:
- switch (wParam & 0xFFF0)
- {
- case SC_CLOSE:
- /* vxDeallocate will issue a task closure */
- /* sequence error if this task cannot be */
- /* shut down */
- /* ************************************** */
- if (!vxDeallocate())
- return(TRUE);
-
- /* we could use this switch set to test for */
- /* other options selcted from the system menu */
- /* ****************************************** */
- default:
- return(DefWindowProc(hWnd, iMessage, wParam, lParam));
- }
-
-
- /* process menu commands */
- /* ********************* */
- case WM_COMMAND:
- switch (wParam)
-
- {
- case IDM_BROWSE:
-
- // disable menu items
- hMenu = GetMenu(hWnd);
- EnableMenuItem(hMenu, IDM_BROWSE, MF_GRAYED);
- EnableMenuItem(hMenu, IDM_JOIN, MF_GRAYED);
- EnableMenuItem(hMenu, IDM_PACK, MF_GRAYED);
- RetVal = 0;
-
-
- // set up do loop and keep browsing if edit
- // dialog returns a BROWSE_USER value
- while (TRUE)
- {
-
- // if browse went ok, vxTypeBrowse returns nonzero
- if (vxTypeBrowse())
- {
- if (RetVal != BROWSE_USER)
- {
- MessageBox(hWnd,
- rgpsz[IDS_BROWSE],
- rgpsz[IDS_CAPTION],
- MB_OK | MB_ICONEXCLAMATION);
- break;
- }
- }
-
- // otherwise an error occurred
- else
- {
- MessageBox(hWnd,
- rgpsz[IDE_BROWSE],
- rgpsz[IDS_CAPTION],
- MB_OK | MB_ICONEXCLAMATION);
- break;
- }
- }
-
- // re-enable menu items
- hMenu = GetMenu(hWnd);
- EnableMenuItem(hMenu, IDM_BROWSE, MF_ENABLED);
- EnableMenuItem(hMenu, IDM_JOIN, MF_ENABLED);
- EnableMenuItem(hMenu, IDM_PACK, MF_ENABLED);
-
- vxWindowDereg(hWnd);
-
- break;
-
-
- case IDM_JOIN:
-
- // disable menu items
- hMenu = GetMenu(hWnd);
- EnableMenuItem(hMenu, IDM_BROWSE, MF_GRAYED);
- EnableMenuItem(hMenu, IDM_JOIN, MF_GRAYED);
- EnableMenuItem(hMenu, IDM_PACK, MF_GRAYED);
- RetVal = 0;
-
-
- // Demonstration of setting up visual relationships
- // with the vxJoin command. What we have is a file of buyers
- // categorized by type of aircraft they are interested in.
- // What we are going to do is display a browse table of
- // these buyer records and link any buyer record to
- // another browse table of aircraft that match the the
- // buyer aircraft type field.
- // --------------------------------------------------------
-
- // open file that will control the join
- // ------------------------------------
- DbfArea1 = vxUseDbf("\\vb\\vxbtest\\airbuyer.dbf");
- NtxArea1 = vxUseNtx("\\vb\\vxbtest\\airbuy2.ntx");
- // this index is on aircraft type
- // ------------------------------
-
- // define table to show data we are interested in
- // ----------------------------------------------
- vxTableDeclare(VX_BLUE, NULL, NULL, 0, 1, 5);
- vxTableField(1, "Type", "b_cat", VX_FIELD);
- vxTableField(2, "Description", "left(b_desc,20)", VX_EXPR);
- vxTableField(3, "Low", "b_low", VX_FIELD);
- vxTableField(4, "High", "b_high", VX_FIELD);
- vxTableField(5, "Customer", "b_code", VX_FIELD);
-
- // now open secondary file and define its table
- // --------------------------------------------
- DbfArea2 = vxUseDbf("\\vb\\vxbtest\\aircraft.dbf");
- NtxArea2 = vxUseNtx("\\vb\\vxbtest\\aircraf2.ntx");
-
- vxTableDeclare(VX_RED, NULL, NULL, 0, 1, 5);
- vxTableField(1, "Type", "c_cat", VX_FIELD);
- vxTableField(2, "Code", "c_code", VX_FIELD);
- vxTableField(3, "Price", "c_price", VX_FIELD);
- vxTableField(4, "Year", "c_year", VX_FIELD);
- vxTableField(5, "TTSN", "c_ttsn", VX_FIELD);
-
- // reselect the master file and set up the join
- // --------------------------------------------
- vxSelectDbf(DbfArea1);
- vxJoin(DbfArea2, NtxArea2, "b_cat", VX_FIELD, "Possible Sales");
-
- // this joins the Aircraft file using the index selected for
- // it to the buyer file. The "b_cat" param is the field we
- // will use as a key into the aircraft file and the VX_FIELD
- // item tells vxBase that it is a field and not an expression.
- // The last item in the call is a title for the join window.
- // -----------------------------------------------------------
-
- // now set up and execute the browse. The JOIN menu item is
- // automatically enabled.
- // ---------------------------------------------------------
- vxBrowse(hWnd, DbfArea1, NtxArea1, FALSE, TRUE, FALSE, 0, "Buyer Details", &RetVal);
-
- // when we return from the browse we can ignore anything
- // vxBase sent back to us in the RetVal param
- // -----------------------------------------------------
- vxClose();
- vxSelectDbf(DbfArea2);
- vxClose();
- vxWindowDereg(hgWnd);
-
- // re-enable menu items
- hMenu = GetMenu(hWnd);
- EnableMenuItem(hMenu, IDM_BROWSE, MF_ENABLED);
- EnableMenuItem(hMenu, IDM_JOIN, MF_ENABLED);
- EnableMenuItem(hMenu, IDM_PACK, MF_ENABLED);
-
- MessageBox(hgWnd,
- rgpsz[IDS_JOIN],
- rgpsz[IDS_CAPTION],
- MB_OK | MB_ICONEXCLAMATION);
-
- break;
-
-
- case IDM_PACK:
- // disable menu items
- hMenu = GetMenu(hWnd);
- EnableMenuItem(hMenu, IDM_BROWSE, MF_GRAYED);
- EnableMenuItem(hMenu, IDM_JOIN, MF_GRAYED);
- EnableMenuItem(hMenu, IDM_PACK, MF_GRAYED);
-
-
- // only pack if file is not in use
- j = vxAreaDbf("\\vb\vxbtest\\airtypes.dbf");
-
- if (!j)
- {
- DbfArea1 = vxUseDbf("\\vb\\vxbtest\\airtypes.dbf");
- NtxArea1 = vxUseNtx("\\vb\\vxbtest\\airtypes.ntx");
- vxPack(hWnd);
- vxClose();
- MessageBox(hgWnd,
- rgpsz[IDS_PACK],
- rgpsz[IDS_CAPTION],
- MB_OK | MB_ICONEXCLAMATION);
- }
- else
- MessageBox(hgWnd,
- rgpsz[IDE_PACK],
- rgpsz[IDS_CAPTION],
- MB_OK | MB_ICONEXCLAMATION);
-
- // re-enable menu items
- hMenu = GetMenu(hWnd);
- EnableMenuItem(hMenu, IDM_BROWSE, MF_ENABLED);
- EnableMenuItem(hMenu, IDM_JOIN, MF_ENABLED);
- EnableMenuItem(hMenu, IDM_PACK, MF_ENABLED);
-
- break;
-
-
- /* see WM_SYSCOMMAND above for explanation of */
- /* why we test vxDeallocate before we allow */
- /* this task to be closed */
- /* ****************************************** */
- case IDM_EXIT:
- if (!vxDeallocate())
- break;
- PostMessage(hWnd, WM_CLOSE, 0, 0L);
- break;
- }
- default:
- return (DefWindowProc(hWnd, iMessage, wParam, lParam));
- }
-
- return 0L;
- }
-
-
- /* ***************** */
- /* browse types file */
- /* ***************** */
- int NEAR PASCAL vxTypeBrowse()
- {
- FARPROC lpProc; // discardable proc instance
-
- // open dbf file
- DbfArea1 = vxUseDbf("\\vb\\vxbtest\\airtypes.dbf");
- if (!DbfArea1)
- return (FALSE);
-
- // open index file
- NtxArea1 = vxUseNtx("\\vb\\vxbtest\\airtypes.ntx");
- if (!NtxArea1)
- return (FALSE);
-
- // declare browse table
- vxTableDeclare(VX_RED, NULL, NULL, 0, 1, 2);
- vxTableField(1, "Type", "category", VX_FIELD);
- vxTableField(2, "Description", "catname", VX_FIELD);
-
- // set up initial browse position
- vxBrowsePos(20, 10, 50, 15);
-
- // call the browse
- vxBrowse(hgWnd, DbfArea1, NtxArea1, TRUE, TRUE, TRUE, 0L, "Aircraft Types", &RetVal);
-
- // if user closed, exit TRUE
- if (RetVal == BROWSE_CLOSED)
- return (TRUE);
-
- // if browse had error, exit FALSE
- if (RetVal == BROWSE_ERROR)
- return (FALSE);
-
- // if user picked anything else, do file edit dialog
- // NOTE: RetVal is global so it will be accessible to
- // the edit dialog
- lpProc = MakeProcInstance(vxTypeEditDlg, hgInst);
- DialogBox (hgInst,
- MAKEINTRESOURCE (IDD_TYPEDIT),
- hgWnd,
- lpProc);
- FreeProcInstance(lpProc);
-
- // if user clicks browse button from dialog, retval
- // is set to BROWSE_USER so calling rtn
- // from wm_command can test if this is to be done again
-
- // close file (first ensure registered)
- vxSelectDbf(DbfArea1);
- vxClose();
-
- return (TRUE);
- }
-
-
- /* ********************************************************** */
- /* Edit type file record dialog */
- /* ********************************************************** */
- BOOL FAR PASCAL vxTypeEditDlg(HWND hdlg, WORD wMsg, WORD wParam, LONG lParam)
- {
- HWND hwndDI; /* handle to dialog item */
- int j; /* general integer */
- static long RecNum; /* current record number */
- static BOOL IsChanged; /* set if anything changes */
- static BOOL IsDeleting; /* set on if deleting */
-
- switch (wMsg)
- {
-
- // initialization routine
- // **********************
- case WM_INITDIALOG:
-
- // register database select area with this window
- vxSelectDbf(DbfArea1);
-
- // set control lengths
- SendDlgItemMessage(hdlg, IDD_TYPE,
- EM_LIMITTEXT, (WORD)vxFieldSize("category"), 0L);
- SendDlgItemMessage(hdlg, IDD_DESC,
- EM_LIMITTEXT, (WORD)vxFieldSize("catname"), 0L);
- SendDlgItemMessage(hdlg, IDD_STAT,
- EM_LIMITTEXT, (WORD)64, 0L);
-
- // disable status bar
- hwndDI = GetDlgItem(hdlg, IDD_STAT);
- EnableWindow(hwndDI, FALSE);
-
- // other init stuff
- RecNum = vxRecNo(); // save record number
- szBuffer[0] = '\0'; // clear work buffer
- IsChanged = FALSE; // default change val
-
- // analyze browse return value and fill controls accordingly
-
- // if user pressed enter key to select record for edit
- if (RetVal > 0)
- RetVal = BROWSE_EDIT;
-
- // if adding, show empty record
- if (RetVal == BROWSE_ADD)
- {
- SetDlgItemText(hdlg, IDD_TYPE, (LPSTR)szBuffer);
- SetDlgItemText(hdlg, IDD_DESC, (LPSTR)szBuffer);
- SetDlgItemText(hdlg, IDD_STAT, (LPSTR)rgpsz[IDS_ADDING]);
-
- // disable add and delete buttons
- hwndDI = GetDlgItem(hdlg, IDD_ADD);
- EnableWindow(hwndDI, FALSE);
- hwndDI = GetDlgItem(hdlg, IDD_DELETE);
- EnableWindow(hwndDI, FALSE);
- }
-
- // if deleting or editing, show record
- else
- {
- // with any vxbase string function, always copy
- // the result to an internal buffer as below
- // ********************************************
- lstrcpy(szBuffer, (LPSTR)vxField("category"));
- vxbTrim(szBuffer, sizeof(szBuffer));
- SetDlgItemText(hdlg, IDD_TYPE, (LPSTR)szBuffer);
-
- lstrcpy(szBuffer, (LPSTR)vxField("catname"));
- vxbTrim(szBuffer, sizeof(szBuffer));
- SetDlgItemText(hdlg, IDD_DESC, (LPSTR)szBuffer);
-
- if (RetVal == BROWSE_DELETE)
- wsprintf(szBuffer, "%s %ld", (LPSTR)rgpsz[IDS_DELE], RecNum);
- else
- {
- wsprintf(szBuffer, "%s %ld", (LPSTR)rgpsz[IDS_EDIT], RecNum);
- vxUnlock(); // unlock if editing for multiusers
- }
- SetDlgItemText(hdlg, IDD_STAT, (LPSTR)szBuffer);
- }
-
- // if deleting, set switch to send delete
- // button click after form has been painted
- if (RetVal == BROWSE_DELETE)
- IsDeleting = TRUE;
-
- // we can't send the WM_COMMAND message here
- // because the dialog box hasn't been
- // painted yet and we want the user to see
- // the record he is deleting
-
-
- // format control
- hwndDI = GetDlgItem(hdlg, IDD_TYPE);
- SetFocus(hwndDI);
- vxCtlFormat(3, 0, 0); // vx_upper
-
- // after formatting a series of controls (using the
- // three code lines above as a template), remember
- // to reset the focus to the FIRST control and
- // return FALSE because the focus has been set
- // ------------------------------------------------
- return (FALSE);
-
-
- // the wm_ctlcolor, wm_paint, and wm_3dpaint create
- // 3d style controls on a gray background
- // ************************************************
- case WM_CTLCOLOR:
- return (Control3dColor(hdlg,wParam));
-
- case WM_PAINT:
- PostMessage(hdlg,WM_3DPAINT,0,0L);
- return (FALSE);
-
- case WM_3DPAINT:
- // frame
- Draw3dFrame(hdlg,OUTSIDE_FRAME);
-
- // edit controls
- Draw3dBorder(hdlg,IDD_TYPE,RECESSED,2);
- Draw3dBorder(hdlg,IDD_DESC,RECESSED,2);
- Draw3dBorder(hdlg,IDD_STAT,RAISED,2);
-
- // buttons
- Draw3dBorder(hdlg,IDD_SAVE,RECESSED,2);
- Draw3dBorder(hdlg,IDD_CANCEL,RECESSED,2);
- Draw3dBorder(hdlg,IDD_ADD,RECESSED,2);
- Draw3dBorder(hdlg,IDD_DELETE,RECESSED,2);
- Draw3dBorder(hdlg,IDD_NEXT,RECESSED,2);
- Draw3dBorder(hdlg,IDD_PREV,RECESSED,2);
- Draw3dBorder(hdlg,IDD_BROWSE,RECESSED,2);
- Draw3dBorder(hdlg,IDD_EXIT,RECESSED,2);
-
- // if deleting, we send a message as if user punched
- // delete button and we process in wm_command
- if (IsDeleting)
- {
- IsDeleting = FALSE;
- hwndDI = GetDlgItem(hdlg, IDD_DELETE);
- lParam = MAKELONG(hwndDI, BN_CLICKED);
- SendMessage(hdlg, WM_COMMAND, IDD_DELETE, lParam);
- }
-
- return (TRUE);
-
- // user pressed a button
- // *********************
- case WM_COMMAND:
- {
- switch (wParam)
- {
- /* *********** */
- /* save button */
- /* *********** */
- case IDD_SAVE:
-
- // get control item "category"
- GetDlgItemText(hdlg, IDD_TYPE, szBuffer, (vxFieldSize("category") + 1));
-
- // convert to upper case and redisplay
- if (lstrlen(szBuffer))
- {
- AnsiUpper(szBuffer);
- SetDlgItemText(hdlg, IDD_TYPE, (LPSTR)szBuffer);
- }
- else
- {
- MessageBox(hdlg,
- rgpsz[IDS_BADKEY],
- rgpsz[IDS_CAPTION],
- MB_ICONSTOP | MB_OK);
- hwndDI = GetDlgItem(hdlg, IDD_TYPE);
- SetFocus(hwndDI);
- return (FALSE);
- }
-
- // if new item, test for duplicate key
- if (RetVal == BROWSE_ADD)
- {
- if (vxSeek(szBuffer))
- {
- vxUnlock();
- MessageBox(hdlg,
- rgpsz[IDS_DUPKEY],
- rgpsz[IDS_CAPTION],
- MB_ICONSTOP | MB_OK);
- hwndDI = GetDlgItem(hdlg, IDD_TYPE);
- SetFocus(hwndDI);
- return (FALSE);
- }
-
- // otherwise add an empty record
- else
- vxAppendBlank();
- }
-
- // if editing position pointer and lock record
- else
- vxGo(RecNum);
-
- // get catname field data and put fields away
- GetDlgItemText(hdlg, IDD_DESC, szBuffer2, (vxFieldSize("catname") + 1));
- vxReplString("category", szBuffer);
- vxReplString("catname", szBuffer2);
- vxWrite();
-
- // update status box
- RecNum = vxRecNo();
- if (RetVal == BROWSE_ADD)
- wsprintf(szBuffer, "Record %ld appended", RecNum);
- else
- wsprintf(szBuffer, "Record %ld saved", RecNum);
- SetDlgItemText(hdlg, IDD_STAT, (LPSTR)szBuffer);
-
- // update buttons
- hwndDI = GetDlgItem(hdlg, IDD_SAVE);
- EnableWindow(hwndDI, TRUE);
- hwndDI = GetDlgItem(hdlg, IDD_CANCEL);
- EnableWindow(hwndDI, TRUE);
- hwndDI = GetDlgItem(hdlg, IDD_ADD);
- EnableWindow(hwndDI, TRUE);
- hwndDI = GetDlgItem(hdlg, IDD_DELETE);
- EnableWindow(hwndDI, TRUE);
-
- // unlock record
- vxUnlock();
-
- // change status to edit mode
- RetVal = BROWSE_EDIT;
-
- return (TRUE);
-
-
- /* ************* */
- /* cancel button */
- /* ************* */
- case IDD_CANCEL:
-
- // clear form data and reset buttons
- szBuffer[0] = '\0'; // clear work buffer
- SetDlgItemText(hdlg, IDD_TYPE, (LPSTR)szBuffer);
- SetDlgItemText(hdlg, IDD_DESC, (LPSTR)szBuffer);
- SetDlgItemText(hdlg, IDD_STAT, (LPSTR)rgpsz[IDS_CANC]);
-
- hwndDI = GetDlgItem(hdlg, IDD_SAVE);
- EnableWindow(hwndDI, FALSE);
- hwndDI = GetDlgItem(hdlg, IDD_CANCEL);
- EnableWindow(hwndDI, FALSE);
- hwndDI = GetDlgItem(hdlg, IDD_ADD);
- EnableWindow(hwndDI, TRUE);
- hwndDI = GetDlgItem(hdlg, IDD_DELETE);
- EnableWindow(hwndDI, FALSE);
-
- // disable data entry
- hwndDI = GetDlgItem(hdlg, IDD_TYPE);
- EnableWindow(hwndDI, TRUE);
- hwndDI = GetDlgItem(hdlg, IDD_DESC);
- EnableWindow(hwndDI, TRUE);
-
- return (TRUE);
-
- /* ********** */
- /* add button */
- /* ********** */
- case IDD_ADD:
- // test if current stuff has changed
- for (j=IDD_TYPE; j<IDD_DESC; j++)
- if (SendDlgItemMessage(hdlg, j, EM_GETMODIFY, 0, 0L))
- IsChanged = TRUE;
- if (IsChanged)
- {
- IsChanged = FALSE;
- if (IDNO == (MessageBox(hdlg, "Current record changed. Abandon?",
- rgpsz[IDS_CAPTION],
- MB_ICONQUESTION | MB_YESNO)))
- return (TRUE);
-
- }
- IsChanged = FALSE;
-
- // clear controls
- szBuffer[0] = '\0'; // clear work buffer
- SetDlgItemText(hdlg, IDD_TYPE, (LPSTR)szBuffer);
- SetDlgItemText(hdlg, IDD_DESC, (LPSTR)szBuffer);
- SetDlgItemText(hdlg, IDD_STAT, (LPSTR)rgpsz[IDS_ADDING]);
-
- // disable add and delete buttons
- hwndDI = GetDlgItem(hdlg, IDD_ADD);
- EnableWindow(hwndDI, FALSE);
- hwndDI = GetDlgItem(hdlg, IDD_DELETE);
- EnableWindow(hwndDI, FALSE);
-
- // enable data entry
- hwndDI = GetDlgItem(hdlg, IDD_TYPE);
- EnableWindow(hwndDI, TRUE);
- hwndDI = GetDlgItem(hdlg, IDD_DESC);
- EnableWindow(hwndDI, TRUE);
-
-
- // set add mode
- RetVal = BROWSE_ADD;
-
- // set focus to code
- hwndDI = GetDlgItem(hdlg, IDD_TYPE);
- SetFocus(hwndDI);
-
- // when setting focus, always return false
- return (FALSE);
-
-
- /* ************* */
- /* delete button */
- /* ************* */
- case IDD_DELETE:
-
- // confirm deletion
- if (IDNO == (MessageBox(hdlg,
- rgpsz[IDS_CDELE],
- rgpsz[IDS_CAPTION],
- MB_ICONQUESTION | MB_YESNO)))
- {
- SetDlgItemText(hdlg, IDD_STAT, "Delete cancelled");
- RetVal = BROWSE_EDIT;
- return (TRUE);
- }
-
- vxLockRecord();
- vxDeleteRec();
- wsprintf(szBuffer, "Record %ld deleted", RecNum);
- SetDlgItemText(hdlg, IDD_STAT, (LPSTR)szBuffer);
-
- // clear data and reset buttons
- szBuffer[0] = '\0'; // clear work buffer
- SetDlgItemText(hdlg, IDD_TYPE, (LPSTR)szBuffer);
- SetDlgItemText(hdlg, IDD_DESC, (LPSTR)szBuffer);
-
- hwndDI = GetDlgItem(hdlg, IDD_SAVE);
- EnableWindow(hwndDI, FALSE);
- hwndDI = GetDlgItem(hdlg, IDD_CANCEL);
- EnableWindow(hwndDI, FALSE);
- hwndDI = GetDlgItem(hdlg, IDD_ADD);
- EnableWindow(hwndDI, TRUE);
- hwndDI = GetDlgItem(hdlg, IDD_DELETE);
- EnableWindow(hwndDI, FALSE);
-
- // disable data entry
- hwndDI = GetDlgItem(hdlg, IDD_TYPE);
- EnableWindow(hwndDI, TRUE);
- hwndDI = GetDlgItem(hdlg, IDD_DESC);
- EnableWindow(hwndDI, TRUE);
-
- RetVal = 0;
- vxUnlock();
- return (TRUE);
-
-
- /* *********** */
- /* next button */
- /* *********** */
- case IDD_NEXT:
- // first test if current rec has changed
- for (j=IDD_TYPE; j<IDD_DESC; j++)
- if (SendDlgItemMessage(hdlg, j, EM_GETMODIFY, 0, 0L))
- IsChanged = TRUE;
- if (IsChanged)
- {
- IsChanged = FALSE;
- if (IDNO == (MessageBox(hdlg, "Current record changed. Abandon?",
- rgpsz[IDS_CAPTION],
- MB_ICONQUESTION | MB_YESNO)))
- return (TRUE);
-
- }
- IsChanged = FALSE;
-
- // skip unless eof; ignore deleted records
- while (TRUE)
- {
- vxSkip(1L);
- if (vxEof())
- break;
- if (!vxDeleted())
- break;
- }
-
- if (vxEof())
- {
- MessageBeep(0);
- SetDlgItemText(hdlg, IDD_STAT, "End of file");
- vxBottom();
- RecNum = vxRecNo();
- }
- else
- {
- RecNum = vxRecNo();
- wsprintf(szBuffer, "Skipped to record %ld", RecNum);
- SetDlgItemText(hdlg, IDD_STAT, (LPSTR)szBuffer);
- }
-
- lstrcpy(szBuffer, (LPSTR)vxField("category"));
- vxbTrim(szBuffer, sizeof(szBuffer));
- SetDlgItemText(hdlg, IDD_TYPE, (LPSTR)szBuffer);
-
- lstrcpy(szBuffer, (LPSTR)vxField("catname"));
- vxbTrim(szBuffer, sizeof(szBuffer));
- SetDlgItemText(hdlg, IDD_DESC, (LPSTR)szBuffer);
-
- RetVal = BROWSE_EDIT;
-
- hwndDI = GetDlgItem(hdlg, IDD_SAVE);
- EnableWindow(hwndDI, TRUE);
- hwndDI = GetDlgItem(hdlg, IDD_CANCEL);
- EnableWindow(hwndDI, TRUE);
- hwndDI = GetDlgItem(hdlg, IDD_ADD);
- EnableWindow(hwndDI, TRUE);
- hwndDI = GetDlgItem(hdlg, IDD_DELETE);
- EnableWindow(hwndDI, TRUE);
-
- // set focus to code
- hwndDI = GetDlgItem(hdlg, IDD_TYPE);
- SetFocus(hwndDI);
- return (FALSE);
-
-
- /* *********** */
- /* prev button */
- /* *********** */
- case IDD_PREV:
- // first test if current rec has changed
- for (j=IDD_TYPE; j<IDD_DESC; j++)
- if (SendDlgItemMessage(hdlg, j, EM_GETMODIFY, 0, 0L))
- IsChanged = TRUE;
- if (IsChanged)
- {
- IsChanged = FALSE;
- if (IDNO == (MessageBox(hdlg, "Current record changed. Abandon?",
- rgpsz[IDS_CAPTION],
- MB_ICONQUESTION | MB_YESNO)))
- return (TRUE);
-
- }
- IsChanged = FALSE;
-
- // skip unless bof; ignore deleted records
- while (TRUE)
- {
- vxSkip(-1L);
- if (vxBof())
- break;
- if (!vxDeleted())
- break;
- }
-
- if (vxBof())
- {
- MessageBeep(0);
- SetDlgItemText(hdlg, IDD_STAT, "Beginning of file");
- vxTop();
- RecNum = vxRecNo();
- }
- else
- {
- RecNum = vxRecNo();
- wsprintf(szBuffer, "Skipped to record %ld", RecNum);
- SetDlgItemText(hdlg, IDD_STAT, (LPSTR)szBuffer);
- }
-
- // load data
- lstrcpy(szBuffer, (LPSTR)vxField("category"));
- vxbTrim(szBuffer, sizeof(szBuffer));
- SetDlgItemText(hdlg, IDD_TYPE, (LPSTR)szBuffer);
-
- lstrcpy(szBuffer, (LPSTR)vxField("catname"));
- vxbTrim(szBuffer, sizeof(szBuffer));
- SetDlgItemText(hdlg, IDD_DESC, (LPSTR)szBuffer);
-
- RetVal = BROWSE_EDIT;
-
- // reset buttons
- hwndDI = GetDlgItem(hdlg, IDD_SAVE);
- EnableWindow(hwndDI, TRUE);
- hwndDI = GetDlgItem(hdlg, IDD_CANCEL);
- EnableWindow(hwndDI, TRUE);
- hwndDI = GetDlgItem(hdlg, IDD_ADD);
- EnableWindow(hwndDI, TRUE);
- hwndDI = GetDlgItem(hdlg, IDD_DELETE);
- EnableWindow(hwndDI, TRUE);
-
- // set focus to code
- hwndDI = GetDlgItem(hdlg, IDD_TYPE);
- SetFocus(hwndDI);
- return (FALSE);
-
-
- /* ************* */
- /* browse button */
- /* ************* */
- case IDD_BROWSE:
- // first test if current rec has changed
- for (j=IDD_TYPE; j<IDD_DESC; j++)
- if (SendDlgItemMessage(hdlg, j, EM_GETMODIFY, 0, 0L))
- IsChanged = TRUE;
- if (IsChanged)
- {
- IsChanged = FALSE;
- if (IDNO == (MessageBox(hdlg, "Current record changed. Abandon?",
- rgpsz[IDS_CAPTION],
- MB_ICONQUESTION | MB_YESNO)))
- return (TRUE);
-
- }
- RetVal = BROWSE_USER;
- EndDialog(hdlg, TRUE);
- return (TRUE);
-
-
- /* *********** */
- /* exit button */
- /* *********** */
- case IDD_EXIT:
- // first test if current rec has changed
- for (j=IDD_TYPE; j<IDD_DESC; j++)
- if (SendDlgItemMessage(hdlg, j, EM_GETMODIFY, 0, 0L))
- IsChanged = TRUE;
- if (IsChanged)
- {
- IsChanged = FALSE;
- if (IDNO == (MessageBox(hdlg, "Current record changed. Abandon?",
- rgpsz[IDS_CAPTION],
- MB_ICONQUESTION | MB_YESNO)))
- return (TRUE);
-
- }
- RetVal = 0; // clear RetVal before return
- vxWindowDereg(hdlg); // deregister window
- EndDialog(hdlg, TRUE);
- return (TRUE);
- }
- }
-
- default:
- break;
- }
- return (FALSE);
- }
-
-
-
- /* ************************************************************
- * HLoadAppStrings
- *
- * Purpose:
- * Allocates FIXED local memory and reads the applications
- * string resources into that memory. Each string's pointer
- * is available with rgpsz[i] where i is the ID value of the
- * string. The strings must have sequential IDs.
- *
- * Parameters:
- * none
- *
- * Return Value:
- * HANDLE Handle to the local memory. NULL if memory could
- * not be allocated.
- *
- * ************************************************************ */
-
- HANDLE NEAR PASCAL HLoadAppStrings(void)
- {
- HANDLE hLocalMem;
- char NEAR *pch;
- WORD cchUsed = 0;
- WORD cch;
- short i;
-
- /*
- * Allocate memory and load strings. NOTE! The LPTR style
- * specifies FIXED memory. This should not be a big deal
- * since this is an early allocation into the local heap.
- * But it should be watched if the number of strings becomes
- * large.
- */
- hLocalMem = LocalAlloc(LPTR, CSTRINGS*CCHSTRINGMAX);
-
- if (hLocalMem == NULL)
- return (HANDLE)NULL;
-
- /*
- * This operation is only valid for FIXED memory. Otherwise use
- * LocalLock.
- */
- pch = (char *)hLocalMem;
-
- /*
- * Load the strings into the memory and retain the specific
- * pointer to that string.
- */
- for (i = 0; i < CSTRINGS; i++)
- {
- cch = LoadString(hgInst, i, (LPSTR)(pch + cchUsed), CCHSTRINGMAX - 1);
- rgpsz[i] = (char *)(pch + cchUsed);
-
- /*
- * One is added to cch to include a NULL. The memory was ZEROINITed
- * on allocation so by skipping a byte we get the NULL.
- */
- cchUsed += (cch + 1);
- }
-
- /*
- * It is assumed that no string is over CCHSTRINGMAX, and therefore
- * not all the allocated memory was used. Therefore LocalReAlloc
- * will only SHRINK the block, never expand it. So if it fails, there's
- * no problem--all the strings are still there, with some wasted
- * space.
- */
- LocalReAlloc(hLocalMem, cchUsed+1, LPTR);
-
- return hLocalMem;
- }
-
- /*
- ┌──────────────────────────────────────────────────────────────────────────┐
- │ END │
- └──────────────────────────────────────────────────────────────────────────┘
- */
-