home *** CD-ROM | disk | FTP | other *** search
- /*==============================================================================
- DEMO.C :- FORM Demo Program (MS Windows Version)
- Sub Systems, Inc.
- Software License Agreement (1989)
- ----------------------------------
- This is a demo program. The program shows how you can utilize the Report
- Ease routines to perform develop report templates and execute the reports.
- ===============================================================================*/
-
- #include "windows.h"
- #include "stdio.h"
- #include "stdlib.h"
- #include "fcntl.h"
- #include "sys\types.h"
- #include "sys\stat.h"
- #include "io.h"
- #include "dos.h"
- #include "string.h"
- #include "math.h"
-
- #if defined(__TURBOC__)
- #include "dir.h"
- #include "mem.h"
- #else
- #include "memory.h"
- #endif
-
- /******************************************************************************
- WIN32 specific defines
- *******************************************************************************/
- #if defined (_WIN32)
- #if !defined(WIN32)
- #define WIN32
- #endif
- #endif
- #if defined (WIN32)
- #undef huge
- #define huge
- #undef FreeProcInstance
- #define FreeProcInstance(x)
- #define COMMAND_ID(wp,lp) LOWORD(wp)
- #define CONTROL_ID(wp,lp) LOWORD(wp)
- #define NOTIFY_MSG(wp,lp) HIWORD(wp)
- #undef farmalloc
- #define farmalloc malloc
- #undef farrealloc
- #define farrealloc realloc
- #undef farfree
- #define farfree free
- #else
- #define COMMAND_ID(wp,lp) (wp)
- #define CONTROL_ID(wp,lp) (wp)
- #define NOTIFY_MSG(wp,lp) HIWORD(lp)
- #endif
-
- /******************************************************************************
- DLL and demo program specific includes
- *******************************************************************************/
- #include "rep.h"
- #include "demo.h"
-
- #include "util.h" // need only by the demo program
-
- /****************************************************************************
- Main Fuction
- ******************************************************************************/
- int PASCAL WinMain(HANDLE hInstance,HANDLE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
- {
- MSG msg;
-
- hPrevInst=hPrevInstance;
- if (!hPrevInstance)
- if (!InitApplication(hInstance))
- return (FALSE);
-
- if (!InitInstance(hInstance, nCmdShow))
- return (FALSE);
-
- while (GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- return (msg.wParam);
- }
-
- /****************************************************************************
- Initialize window data and register window class
- ****************************************************************************/
-
- BOOL InitApplication(HANDLE hInstance)
- {
- WNDCLASS wc;
-
- wc.style = 0;
- wc.lpfnWndProc = (void far *)DemoWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = GetStockObject(WHITE_BRUSH);
- wc.lpszMenuName = "DemoMenu";
- wc.lpszClassName = "ReDemoClass";
-
- return (RegisterClass(&wc));
- }
-
-
- /****************************************************************************
- Save instance handle and create main window
- ****************************************************************************/
-
- BOOL InitInstance(HANDLE hInstance,int nCmdShow)
- {
- HWND hDemoWin;
- int i;
-
-
- hInst = hInstance;
-
- hDemoWin = CreateWindow(
- "ReDemoClass",
- "Report Ease Demo",
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- NULL,
- NULL,
- hInstance,
- NULL
- );
-
- if (!hDemoWin)
- return (FALSE);
-
- ShowWindow(hDemoWin, nCmdShow);
- UpdateWindow(hDemoWin);
-
- //****** initialize the structure variables *********
- FormParm.open=FALSE; // all windows closed in the beginning
- FormParm.x=0; // Initial X position of FORM edit window
- FormParm.y=0; // Initial Y position of FORM edit window
- FormParm.width=GetSystemMetrics(SM_CXSCREEN); // Initial edit window width
- FormParm.height=(GetSystemMetrics(SM_CYSCREEN)*9)/10; // Initial edit window height
- FormParm.ShowMenu=TRUE; // display menu
- FormParm.ShowVerBar=TRUE; // display vertical scroll bar
- FormParm.ShowHorBar=TRUE; // display horizontal scroll bar (N/A with word wrap)
- strcpy(FormParm.file,""); // Text file name if the input type is 'F'
- FormParm.hInst=hInst; // Current application instant handle
- FormParm.hPrevInst=hPrevInst; // Previous application instant handle
- FormParm.hParentWnd=hDemoWin; // let this be the parent of the editor window
- FormParm.style=WS_OVERLAPPEDWINDOW; // Editor window style
- strcpy(FormParm.DataSetName,"CUSTOMER");
-
-
- //***** pass the pointer to the call back routines
- /** The field selection and verification routines must be included in the
- export section of your applications definition file **/
-
- FormParm.UserSelection=(USER_SELECTION)MakeProcInstance(UserFieldSelection,hInst); // field selection routine
- FormParm.VerifyField=(VERIFY_FIELD)MakeProcInstance(VerifyField,hInst); // field verification routine
- if (!FormParm.UserSelection || !FormParm.VerifyField) return FALSE;
-
- //**** copy the parameters to the RepParam structure *********
- RepParm.hInst=FormParm.hInst;
- RepParm.hPrevInst=FormParm.hPrevInst;
- RepParm.hParentWnd=FormParm.hParentWnd;
- RepParm.style=FormParm.style;
- strcpy(RepParm.SwapDir,""); // screen page swap location
-
- RepParm.DrawPicture=(DRAW_PICTURE)MakeProcInstance(DrawPicture,hInst); // field verification routine
- if (!RepParm.DrawPicture) return FALSE;
-
- //********** read field name for the files *******************
- strcpy(DataFile[0].name,"CUSTOMER");
- strcpy(DataFile[1].name,"SALES");
-
- for (i=0;i<MAX_FILES;i++) {
- if (!ReadFields(i)) return FALSE;
- }
-
- // load the customer logo bitmap
- hLogoBM=LoadBitmap(hInst,"LogoBM");
- Bitmap2DIB(); // extract bits from the bitmap
-
- return (TRUE);
- }
-
- /****************************************************************************
- Process Main Window messages
- ****************************************************************************/
-
- long FAR PASCAL _export DemoWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
- {
- FARPROC lpProcParam;
-
-
- switch (message) {
- case WM_COMMAND:
- switch (COMMAND_ID(wParam,lParam)) {
- case IDM_EDITOR: // open a new window
- if (FormParm.open) {
- MessageBox(hDemoWin,"A Form Editor Window Already Open!",NULL,MB_OK);
- break;
- }
- CallEditor(); // call the form editor
- break;
-
- case IDM_EXECUTER: // run a form template
- if (FormParm.open) {
- MessageBox(hWnd,"A Form Editor Window Already Open!",NULL,MB_OK);
- break;
- }
- RunReport(); // run the report
- break;
-
- case IDM_OPTIONS: // accept editor window options
- if (FormParm.open) {
- MessageBox(hWnd,"A Form Editor Window Already Open!",NULL,MB_OK);
- break;
- }
-
- lpProcParam = MakeProcInstance(DemoOptions, hInst);
- DialogBox(hInst,"DemoOptions",hWnd,lpProcParam);
- FreeProcInstance(lpProcParam);
- break;
-
- case IDM_EXIT: // quit demo
- if (FormParm.open) {
- if (!SendMessage(FormParm.hFrWnd,WM_QUERYENDSESSION,0,0L)) break;
- }
- PostQuitMessage(0);
-
- default:
- return (DefWindowProc(hWnd, message, wParam, lParam));
- }
- break;
-
- case WM_DESTROY:
- if (FormParm.open) {
- if (!SendMessage(FormParm.hFrWnd,WM_QUERYENDSESSION,0,0L)) break;
- }
-
- // release demo bitmap data
- if (hLogoBM) DeleteObject(hLogoBM);
- GlobalUnlock(hImage);
- GlobalUnlock(hInfo);
- GlobalFree(hImage);
- GlobalFree(hInfo);
-
- PostQuitMessage(0);
- break;
-
- /********************************************************************
- Messages coming from the form editor Window
- *********************************************************************/
- case REP_CLOSE: // REP sends this message before closing
- FormParm.open=FALSE; // mark Report Ease as closed
- break;
-
- default:
- return (DefWindowProc(hWnd, message, wParam, lParam));
- }
- return (LRESULT)(NULL);
- }
-
- /****************************************************************************
- CallEditor:
- This function calls the form editor.
- ****************************************************************************/
- CallEditor()
- {
- int result;
- char string[80];
-
- if (GetFormSelection(FormParm.file,TRUE)>=0) { // select a form file
-
- //*** let form designer use the default fonts ******
- FormParm.FontTypeFace[0]=0; // default font type faces for report
-
- result=form(&FormParm); // call the form editor
- if (result!=0) { // print error if any
- wsprintf(string,"Error calling the form editor, code: %d",result);
- MessageBox(NULL,string,NULL,MB_OK);
- }
- }
-
- return TRUE;
- }
-
-
-
- /****************************************************************************
- DemoOptions:
- This dialog box allows the user to change the editor window options.
- ****************************************************************************/
-
- BOOL FAR PASCAL _export DemoOptions(HWND hDlg,unsigned message,WPARAM wParam,LPARAM lParam)
- {
-
-
- switch (message) {
- case WM_INITDIALOG:
- // Set initial values of the parameters
- SetDlgItemInt(hDlg,IDC_X,FormParm.x,0);
- SetDlgItemInt(hDlg,IDC_Y,FormParm.y,0);
- SetDlgItemInt(hDlg,IDC_WIDTH,FormParm.width,0);
- SetDlgItemInt(hDlg,IDC_HEIGHT,FormParm.height,0);
- SendMessage(GetDlgItem(hDlg,IDC_MENU),BM_SETCHECK, FormParm.ShowMenu, 0L);
- SendMessage(GetDlgItem(hDlg,IDC_VER_BAR),BM_SETCHECK, FormParm.ShowVerBar, 0L);
- SendMessage(GetDlgItem(hDlg,IDC_HOR_BAR),BM_SETCHECK, FormParm.ShowHorBar, 0L);
- return (TRUE);
-
- case WM_COMMAND:
- switch (CONTROL_ID(wParam,lParam)) {
- case IDOK:
- if (!GetNumVal(hDlg,IDC_X,&FormParm.x)) return (TRUE);
- if (!GetNumVal(hDlg,IDC_Y,&FormParm.y)) return (TRUE);
- if (!GetNumVal(hDlg,IDC_WIDTH,&FormParm.width)) return (TRUE);
- if (!GetNumVal(hDlg,IDC_HEIGHT,&FormParm.height)) return (TRUE);
- FormParm.ShowMenu=SendMessage(GetDlgItem(hDlg,IDC_MENU),BM_GETCHECK, 0, 0L);
- FormParm.ShowVerBar=SendMessage(GetDlgItem(hDlg,IDC_VER_BAR),BM_GETCHECK, 0, 0L);
- FormParm.ShowHorBar=SendMessage(GetDlgItem(hDlg,IDC_HOR_BAR),BM_GETCHECK, 0, 0L);
- EndDialog(hDlg, TRUE);
- return (TRUE);
-
- case IDCANCEL:
- EndDialog(hDlg, FALSE);
- return (TRUE);
- default:
- ;
- }
- break;
- }
- return (FALSE);
- }
-
- /******************************************************************************
- GetFormSelection:
- Shows available report forms and let user select one.
- In form edit mode, the user has two additional selections to
- create a new report form.
- ******************************************************************************/
- GetFormSelection(char *CurFile,int FormEdit)
- {
- int select;
- FARPROC lpProcParam;
-
- TotalForms=0;
-
- strcpy(CurFile," ");
-
- #if defined (WIN32)
- GetFormFiles("*.FPC"); // get the report form files
- #else
- GetFormFiles("*.FP"); // get the report form files
- #endif
-
- if (FormEdit) { // allow the user to create new forms
- NewReport=TotalForms; // append the new report selection
- TotalForms++;
- strcpy(FormName[NewReport],"New Report Form");
- strcpy(FormFile[NewReport]," ");
- }
- else NewReport=TotalForms;
-
- //***** show the file seletion box and let user select a file *****
- lpProcParam = MakeProcInstance(DemoForms, hInst);
- select=DialogBox(hInst,"DemoForms",hDemoWin,lpProcParam);
- FreeProcInstance(lpProcParam);
-
- if (select>=0) {
- strcpy(CurFile,"");
- if (select!=NewReport) strcpy(CurFile,FormFile[select]); // pass the file name
- }
-
- return select;
- }
-
- /****************************************************************************
- DemoForms:
- This dialog box allows the user to select a form file.
- ****************************************************************************/
-
- BOOL FAR PASCAL _export DemoForms(HWND hDlg,unsigned message,WPARAM wParam,LPARAM lParam)
- {
- int i,idx;
-
- switch (message) {
- case WM_INITDIALOG:
- // Set initial values of the parameters
- for (i=0;i<TotalForms;i++) {
- idx=(int)SendMessage(GetDlgItem(hDlg,IDC_FILE_BOX),LB_ADDSTRING, 0, (DWORD)(LPSTR)FormName[i]);
- SendMessage(GetDlgItem(hDlg,IDC_FILE_BOX),LB_SETITEMDATA, idx, i);
- }
- SendMessage(GetDlgItem(hDlg,IDC_FILE_BOX),LB_SETCURSEL, 0,0L);
- SetFocus(GetDlgItem(hDlg,IDC_FILE_BOX));
- return (FALSE);
-
- case WM_COMMAND:
- switch (CONTROL_ID(wParam,lParam)) {
- case IDC_FILE_BOX:
- if (NOTIFY_MSG(wParam,lParam)!=LBN_DBLCLK) break;
-
- case IDOK:
- i=SendMessage(GetDlgItem(hDlg,IDC_FILE_BOX),LB_GETCURSEL, 0,0L); // index into the list box
- i=SendMessage(GetDlgItem(hDlg,IDC_FILE_BOX),LB_GETITEMDATA, i,0L); // index into our table
- EndDialog(hDlg, i);
- return (TRUE);
-
- case IDCANCEL:
- EndDialog(hDlg, -1);
- return (TRUE);
- default:
- ;
- }
- break;
- }
- return (FALSE);
- }
-
- /****************************************************************************
- DemoFileField:
- This dialog box allows the user to select a data file or to select
- a field for a data file. When lParam is -1, the dialog box shows
- the data files to select from. When lParam is zero or greater than
- zero, the dialog box shows the fields for the file to select from. The
- lParam, then specifies the index of the data file to choose the
- fields from.
- ****************************************************************************/
-
- int FAR PASCAL _export DemoFileField(HWND hDlg,unsigned message,WPARAM wParam,LPARAM lParam)
- {
- int i;
-
- switch (message) {
- case WM_INITDIALOG:
- // Set initial values of the parameters
- if (lParam<0) { // stuff the list box with data file names
- SetWindowText(hDlg,"Select Data File"); // set the header
- for (i=0;i<MAX_FILES;i++) {
- SendMessage(GetDlgItem(hDlg,IDC_FILE_BOX),LB_ADDSTRING, 0, (DWORD)(LPSTR)DataFile[i].name);
- }
- }
- else { // stuff the list box with data field names
- if (GetSortField) SetWindowText(hDlg,"Select Sort Field");// set the header
- else SetWindowText(hDlg,"Select Data Field");// set the header
- for (i=0;i<DataFile[lParam].TotalFields;i++) {
- SendMessage(GetDlgItem(hDlg,IDC_FILE_BOX),LB_ADDSTRING, 0, (DWORD)(LPSTR)DataField[lParam][i].ShortName); // load the field names
- }
- }
- SendMessage(GetDlgItem(hDlg,IDC_FILE_BOX),LB_SETCURSEL, 0,0L);
- SetFocus(GetDlgItem(hDlg,IDC_FILE_BOX));
- return (FALSE);
-
- case WM_COMMAND:
- switch (CONTROL_ID(wParam,lParam)) {
- case IDC_FILE_BOX:
- if (NOTIFY_MSG(wParam,lParam)!=LBN_DBLCLK) break;
-
- case IDOK:
- i=SendMessage(GetDlgItem(hDlg,IDC_FILE_BOX),LB_GETCURSEL, 0,0L);
- EndDialog(hDlg, i);
- return (TRUE);
-
- case IDCANCEL:
- EndDialog(hDlg, -1);
- return (TRUE);
- default:
- ;
- }
- break;
- }
- return (FALSE);
- }
-
- /******************************************************************************
- GetFormFiles:
- This routine scans the current directory for the files matching the
- specified template.
- ******************************************************************************/
- GetFormFiles(char *template)
- {
- unsigned done;
- FILE *iStream;
- struct StrFormHdr hdr;
-
- #if defined (WIN32)
- HANDLE hFindFile;
- WIN32_FIND_DATA blk;
- done=FALSE;
- if (INVALID_HANDLE_VALUE==(hFindFile=FindFirstFile(template,&blk))) done=TRUE;
- #else
- #if defined(__TURBOC__)
- struct ffblk blk;
- done=findfirst(template,&blk,FA_RDONLY);
- #else
- struct find_t blk;
- done=_dos_findfirst(template,_A_NORMAL,&blk);
- #endif
- #endif
-
-
- while(!done) {
- if (TotalForms==MAX_FORMS) {
- return FALSE;
- }
-
- #if defined (WIN32)
- strcpy(FormFile[TotalForms],blk.cFileName);
- done=!FindNextFile(hFindFile,&blk);
- #else
- #if defined(__TURBOC__)
- strcpy(FormFile[TotalForms],blk.ff_name);
- done=findnext(&blk); // get the next file
- #else
- strcpy(FormFile[TotalForms],blk.name);
- done=_dos_findnext(&blk);
- #endif
- #endif
-
- //*************** get the form name ****************************
- if (NULL==(iStream=fopen(FormFile[TotalForms],"r+b"))) continue;
-
- if (fread(&hdr,sizeof(struct StrFormHdr),1,iStream)!=1
- || hdr.FormSign!=FORM_SIGN ) {
- fclose(iStream);
- continue;
- }
- fclose(iStream);
-
- strcpy(FormName[TotalForms],hdr.name);
-
- TotalForms++;
- }
-
- return TRUE;
- }
-
- /******************************************************************************
- ReadFields:
- Read the field definitions for a file. The argument specifies the index
- into the DataFile structure.
- The field definitions are stored in files with the extension .DF, whereas
- the data is stored in the files with the extension .DB.
- ******************************************************************************/
- ReadFields(int idx)
- {
- char name[64],line[300],CharReturn[300],*result;
- FILE *iStream;
- int CurLen,CurField=0,LineIdx;
- int ExtractField(char *,int *,int,char *);
-
- strcpy(name,DataFile[idx].name);
- strcat(name,".DF"); // file extension
-
- iStream=fopen(name,"r+t");
- if (iStream==NULL) {
- wsprintf(line,"Error while opening file %s ",(LPSTR)name);
- MessageBox(hDemoWin,line,NULL,MB_OK);
- return FALSE;
- }
-
- READ_LINE:
- result=fgets(line,300,iStream);
- if (ferror(iStream)) {
- wsprintf(line,"Error while reading file %s ",(LPSTR)name);
- MessageBox(hDemoWin,line,NULL,MB_OK);
- return FALSE;
- }
- if (feof(iStream)) goto END_FILE; // end of file
- if (result==NULL) {
- wsprintf(line,"Error while reading file %s ",(LPSTR)name);
- MessageBox(hDemoWin,line,NULL,MB_OK);
- return FALSE;
- }
-
- CurLen=strlen(line); // exclude new line character
- if (CurLen>0 && line[CurLen-1]==0xA) CurLen--;
- line[CurLen]=0;
-
- LineIdx=0; // prepare to scan the line
-
- // extract the field name
- if (!ExtractField(line,&LineIdx,CurLen,CharReturn)) { // extract field name
- wsprintf(line,"Invalid format, file: %s, field# %d\n",(LPSTR)name,1);
- MessageBox(hDemoWin,line,NULL,MB_OK);
- return FALSE;
- }
- StringTrim(CharReturn); // trim space
- strcpy(DataField[idx][CurField].ShortName,CharReturn);
- strcpy(DataField[idx][CurField].FullName,DataFile[idx].name);
- strcat(DataField[idx][CurField].FullName,"->");
- strcat(DataField[idx][CurField].FullName,CharReturn);
-
- // extract the field width
- if (!ExtractField(line,&LineIdx,CurLen,CharReturn)) { // extract field name
- wsprintf(line,"Invalid format, file: %s, field# %d\n",(LPSTR)name,1);
- MessageBox(hDemoWin,line,NULL,MB_OK);
- return FALSE;
- }
- DataField[idx][CurField].width=atoi(CharReturn);
-
- // extract the field type
- if (!ExtractField(line,&LineIdx,CurLen,CharReturn)) { // extract field name
- wsprintf(line,"Invalid format, file: %s, field# %d\n",(LPSTR)name,1);
- MessageBox(hDemoWin,line,NULL,MB_OK);
- return FALSE;
- }
- if (CharReturn[0]=='T') DataField[idx][CurField].type=TYPE_TEXT;
- else if (CharReturn[0]=='N') DataField[idx][CurField].type=TYPE_NUM;
- else if (CharReturn[0]=='F') DataField[idx][CurField].type=TYPE_DBL;
- else if (CharReturn[0]=='D') DataField[idx][CurField].type=TYPE_DATE;
- else if (CharReturn[0]=='L') DataField[idx][CurField].type=TYPE_LOGICAL;
- else if (CharReturn[0]=='P') DataField[idx][CurField].type=TYPE_PICT;
- else {
- wsprintf(line,"Invalid field type, file: %s, field# %d\n",(LPSTR)name,1);
- MessageBox(hDemoWin,line,NULL,MB_OK);
- return FALSE;
- }
-
- // extract the default decimal places
- if (!ExtractField(line,&LineIdx,CurLen,CharReturn)) { // extract field name
- wsprintf(line,"Invalid format, file: %s, field# %d\n",(LPSTR)name,1);
- MessageBox(hDemoWin,line,NULL,MB_OK);
- return FALSE;
- }
- DataField[idx][CurField].DecPlaces=atoi(CharReturn);
-
- CurField++;
-
- goto READ_LINE;
-
- END_FILE:
- fclose(iStream);
- DataFile[idx].TotalFields=CurField;
-
- return TRUE;
- }
-
- /******************************************************************************
- ExtractField:
- This routine scans a text line to extract the next field.
- The fields are assumed to be of character type.
- ******************************************************************************/
- ExtractField(char *line,int *idx,int LineLen,char *CharReturn)
- {
- char quote='"',comma=',',string[300],*ptr,SaveChar;
- int i,j;
-
- i=(*idx);
- while (i<LineLen && line[i]==' ') i++; // go past the spaces
-
- if (i>=LineLen) return FALSE; // past the end of the line
-
- if (line[i]==quote) {
- i++; // skip over the first quote
- if (NULL==(ptr=memchr(&line[i],quote,LineLen-i))) return FALSE;
-
- j=1;
- while (ptr[j]!=',' && ptr[j]!=0) j++;// locate the next comma
-
- SaveChar=ptr[0]; // extract the string
- ptr[0]=0;
- strcpy(string,&line[i]);
- ptr[0]=SaveChar;
- (*idx)=i+strlen(string)+1+j; // index to the next field
- }
- else {
- if (NULL==(ptr=memchr(&line[i],comma,LineLen-i))) ptr=&line[LineLen]; // field spans the end of the line
-
- SaveChar=ptr[0]; // extract the string
- ptr[0]=0;
- strcpy(string,&line[i]);
- ptr[0]=SaveChar;
- (*idx)=i+strlen(string)+1; // index to the next field
- }
-
- strcpy(CharReturn,string);
- return TRUE;
- }
-
-
- /******************************************************************************
- Call back routines.
- The following routines are called by Report Ease to select an application
- field or to verify an application field.
- ******************************************************************************/
-
- /******************************************************************************
- UserFieldSelection:
- This routine is called by the FORM_FLD module to allow user to select
- a data field. This routine can be programmed by your application in
- any way as long as it returns the data about the selected field using
- the argument pointer. If the user chose not to select a field after all,
- the function should return with a FALSE value. Otherwise it should return
- with a TRUE value.
-
- In this routine, we will allow the user to first select a file, and
- then select a field from the chosen file. The required data about the
- selected field is filled into the 'field' structure. Your program may
- also optionally fill other remaining 'field' structure variables.
-
- The first parameter contains the handle of the Form Editor window.
- The third parameter specifies the sort field number if this field will
- be used for section breaks. If your application will not sort on all
- fields, you can restrict the fields that can be selected by the user.
- For non-sort fields, this paramter is set to 0. In this demo program,
- we will allow only the fields from the primary file (CUSTOMER) to be
- used as sort fields.
- ******************************************************************************/
- int FAR PASCAL _export UserFieldSelection(HWND hWnd,struct StrField huge *field,int SortFieldNo)
- {
- int CurFile,CurField;
- FARPROC lpProc;
-
- SELECT_FILE:
- if (SortFieldNo==0) {
- lpProc = MakeProcInstance(DemoFileField, hInst);
- CurFile=DialogBoxParam(hInst,"DemoFileField",hWnd,lpProc,(long)-1);
- FreeProcInstance(lpProc); // set back the old window
- if (CurFile<0) return FALSE;
- }
- else CurFile=0; // Allow sort fields only from the customer file
-
- // SELECT FIELD
- if (SortFieldNo==0) GetSortField=FALSE; // global flag
- else GetSortField=TRUE;
-
- lpProc = MakeProcInstance(DemoFileField, hInst);
- CurField=DialogBoxParam(hInst,"DemoFileField",hWnd,lpProc,(long)CurFile);
- FreeProcInstance(lpProc); // set back the old window
-
- if (CurField<0) {
- if (GetSortField) return FALSE;
- else goto SELECT_FILE;
- }
-
- // fill the required 'field' variables
-
- lstrcpy(field->name,DataField[CurFile][CurField].FullName); // field name
- field->type=DataField[CurFile][CurField].type; // alpha/num etc
- field->width=DataField[CurFile][CurField].width; // display width
- field->DecPlaces=DataField[CurFile][CurField].DecPlaces; // decimal places for display
-
- // specify new paragraph indicator field. Used only for a word/wrapped
- // text type fields.
- field->ParaChar[0]='|';
-
- /****** fill up these OPTIONAL fields also. This information will be
- used by our report executer demo program to identfy the
- fields quickly. *****/
-
- field->FileId=CurFile; // Information only
- field->FieldId=CurField; // information only
-
- return TRUE;
- }
-
- /******************************************************************************
- VerifyField:
- This routine is called by the FORM1 module to validate a field. The field
- name is given by the 'name' variable in the StrField structure. It
- contains the full name including the file prefix (if your application allows
- it). The input field is always in the upper case. The required data about the
- current field is filled into the 'field' structure. Your program may
- also optionally fill other remaining 'field' structure variables.
-
- The second argument indicates if the field can be
- used as a sort field. This parameter indicates the sort field number.
- 1 indicates the first sort field, 2 the second, ... A zero for this
- field indicates a non-sort field. In this demo program, we will allow
- only the fields from the primary file (CUSTOMER) to be used as sort fields.
-
- The function returns TRUE if the field is valid, otherwise it returns
- a FALSE value.
- ******************************************************************************/
- int FAR PASCAL _export VerifyField(struct StrField huge *field,int SortFieldNo)
- {
- int CurFile,CurField,MaxFiles;
-
- if (SortFieldNo==0) MaxFiles=MAX_FILES;
- else MaxFiles=1; // allow sort fields from the customer file only
-
- for (CurFile=0;CurFile<MaxFiles;CurFile++) {
- for (CurField=0;CurField<DataFile[CurFile].TotalFields;CurField++) {
- if (lstrcmp(DataField[CurFile][CurField].FullName,field->name)==0) {
- //* fill up the mandatory data *
- field->type=DataField[CurFile][CurField].type; // alpha/num etc
- field->width=DataField[CurFile][CurField].width; // display width
- field->DecPlaces=DataField[CurFile][CurField].DecPlaces; // decimal places for display
-
- /****** fill up these OPTIONAL fields also. This information will be
- used by our report executer demo program to identfy the
- fields quickly. *****/
-
- field->FileId=CurFile; // Information only
- field->FieldId=CurField; // information only
-
- return TRUE;
- }
- }
- }
-
- return FALSE; // not a valid field
- }
-
- /******************************************************************************
- DrawPicture:
- This routine is called by the report executor to draw a specified
- picture type field. The first argument specifies the device context
- of the reporting device. If the report output is directed to a printer,
- this device context belongs to a printer, otherwise it specifies a
- device context for a metafile. You application should draw the picture
- on this device context within the specified rectangle (last argument).
-
- The device context is in ANISOTROPIC mode. The resolution in the X and
- Y direction is given by the UNITS_PER_INCH constant.
-
- The second argument is the picture id. The third and fourth arguments
- are the file and field id for the picture field.
-
- The function returns TRUE if successful.
-
- In this demo program, this routine draws a logo for a given picture id.
- This program uses only one bitmap, and draws different part of the same
- bitmap for different picture id.
-
- ******************************************************************************/
- int FAR PASCAL _export DrawPicture(HDC hDC, int PictId, int FileId, int FieldId, RECT far * rect)
- {
- BITMAP bm;
- int SourceWidth,SourceX;
-
- // get the bitmap information
- GetObject(hLogoBM,sizeof(BITMAP),&bm);
-
- // Select part of the bitmap to display for this picture id
- SourceWidth=bm.bmWidth/10; // divide picture into 10 equal parts
- if (PictId<1) PictId=1;
- if (PictId>10) PictId=10;
- SourceX=SourceWidth*(PictId-1);
-
- // copy the bitmap
- StretchDIBits(hDC,rect->left,rect->top,rect->right-rect->left,rect->bottom-rect->top,
- SourceX,0,SourceWidth,bm.bmHeight,pImage,(LPBITMAPINFO)pInfo,DIB_RGB_COLORS,SRCCOPY);
-
- return TRUE;
- }
-
-
- /******************************************************************************
- Report Executer Interface Routines.
- ******************************************************************************/
-
- /******************************************************************************
- RunReport: The following routines demonstrate the process of calling the
- report executor.
- ******************************************************************************/
- RunReport()
- {
- int PrintRecords(struct StrField huge *,int);
-
- if (GetFormSelection(RepParm.file,FALSE)>=0) { // select a form file
-
- //********* Initialize the argument parameters *************
- RepParm.device='A'; // ask user
-
- RepParm.x=FormParm.x; // specify the window coordinates for screen output
- RepParm.y=FormParm.y; // these fields needed only for screen output
- RepParm.width=FormParm.width;
- RepParm.height=FormParm.height;
-
- if (RepInit(&RepParm)!=0) return FALSE;// Intialize the report
-
- PrepareFile(); // sort and join files if needed
-
- PrintRecords(RepParm.field,RepParm.TotalFields); // read and print each record
-
- RepExit(); // print footers and exit
- }
-
- return TRUE;
- }
-
- /******************************************************************************
- PrepareFile: Sort and join the CUSTOMER and SALES files if needed.
- ******************************************************************************/
- PrepareFile()
- {
- int i,SalesFileUsed,SortKey[10];
- char InputFile1[80],InputFile2[80],OutputFile[80];
-
- lstrcpy(InputFile1,DataFile[0].name);
- lstrcat(InputFile1,".DB "); // apped the data file extension
-
- for (i=0;i<RepParm.TotalSortFields;i++) {// extract each sort field
- SortKey[i]=RepParm.SortField[i].FieldId+1;
- }
- FileSort(InputFile1,RepParm.TotalSortFields,SortKey);
- // the output is in the CUSTOMER.SRT file
-
- // determine if the sales file is used
- SalesFileUsed=FALSE;
- for (i=0;i<RepParm.TotalFields;i++) {
- if ((RepParm.field[i].FileId)==1) { /* id =0 is customer file, and
- id=1 is the sales file,
- see the UserFieldSeletion routine */
- SalesFileUsed=TRUE;
- break;
- }
- }
-
- if (SalesFileUsed) { // join SALES file with CUSTOMER FILE
- lstrcpy(InputFile1,DataFile[0].name);
- lstrcat(InputFile1,".SRT "); // first file
-
- lstrcpy(InputFile2,DataFile[1].name);
- lstrcat(InputFile2,".DB "); // second file
-
- lstrcpy(OutputFile,DataFile[0].name);
- lstrcat(OutputFile,".SRT "); // output file
-
- FileJoin(InputFile1,1,InputFile2,1,OutputFile);
-
- /* customer and sales file have field number 1 in common. The output
- is stored in the "CUSTOMER.SRT file.
- */
- }
-
- return TRUE;
- }
-
- /******************************************************************************
- PrintRecords:
- This routine follows these step:
- 1. Open the data set file.
- 2. For each record of data set:
- a. Initialize the fields in the field structure. IMPORTANT: Initialize
- only the fields where source = SRC_APPL. All other fields are
- for internal use of ReportEase.
- b. Parse each field from the data record and stuff into the
- field structure. One field may be stuffed in more than one
- place in field structure. Stuff only those structure fields where
- source = SRC_APPL
- c. Call the RepRec routine to print this record.
-
- This routine returns a TRUE value after all records are printed. If
- the user hit escape during printing, then the return result will be a FALSE
- value.
- ******************************************************************************/
- PrintRecords(struct StrField huge *field,int TotalFields)
- {
- FILE *iStream;
- int i,CurLen,FileNo,FieldNo,RecNo=1,LineIdx;
- char DataSetName[64],line[300],string[300],*result;
-
- //*** open the data set file ***
- strcpy(DataSetName,DataFile[0].name);
- strcat(DataSetName,".SRT");
-
- if (NULL==(iStream=fopen(DataSetName,"rt"))) {
- MessageBox(hDemoWin,"Can Not Open The Data Set File!",NULL,MB_OK);
- return FALSE;
- }
-
-
- READ_LINE:
- result=fgets(line,300,iStream);
- if (ferror(iStream)) {
- MessageBox(hDemoWin,"Error in reading file",NULL,MB_OK);return FALSE;
- }
- if (feof(iStream)) goto END_FILE; // end of file
- if (result==NULL) {
- MessageBox(hDemoWin,"Error in reading file",NULL,MB_OK);return FALSE;
- }
-
- CurLen=strlen(line); // exclude new line character
- if (CurLen>0 && line[CurLen-1]==0xA) CurLen--;
- line[CurLen]=0;
-
- //********** initialize the field structure *************
- for (i=0;i<TotalFields;i++) {
- if (field[i].source==SRC_APPL) {
- if (field[i].type==TYPE_TEXT) field[i].CharData[0]=0;
- if (field[i].type==TYPE_NUM) field[i].NumData=0;
- if (field[i].type==TYPE_PICT) field[i].NumData=0;
- if (field[i].type==TYPE_DBL) field[i].DblData=0;
- }
- }
-
- //************ parse the record to get each field ********
- FileNo=0;
- FieldNo=0;
- LineIdx=0; // prepare to scan the line
-
- while (TRUE) {
- // extract the fields
- if (!ExtractField(line,&LineIdx,CurLen,string)) break;
-
- if (FileNo>=MAX_FILES) {
- wsprintf(line,"Too many fields in the data record number: %d\n",RecNo);
- MessageBox(hDemoWin,line,NULL,MB_OK);
- goto END_FILE;
- }
-
- // stuff this field into the field structure
- for (i=0;i<TotalFields;i++) {
- if (field[i].source==SRC_APPL
- && field[i].FileId==FileNo && field[i].FieldId==FieldNo) {
- if (field[i].type==TYPE_TEXT) {
- if ((int)strlen(string)>field[i].width) string[field[i].width]=0; // truncate oversize data
- lstrcpy(field[i].CharData,string);
- }
- else if (field[i].type==TYPE_NUM) field[i].NumData=atol(string);
- else if (field[i].type==TYPE_DBL) field[i].DblData=(double)atof(string);
- else if (field[i].type==TYPE_DATE) field[i].NumData=atol(string); // date shoule be YYMMDD or YYYYMMDD
- else if (field[i].type==TYPE_PICT) field[i].NumData=atol(string); // date shoule be YYMMDD or YYYYMMDD
- else if (field[i].type==TYPE_LOGICAL) {
- if (string[0]=='Y' || string[0]=='y') field[i].NumData=1;
- else field[i].NumData=0;
- }
- }
- }
-
- // advance to the next field number
- FieldNo++;
- if (FieldNo>=DataFile[FileNo].TotalFields) {
- FieldNo=0;
- FileNo++;
- }
-
- }
-
- if (RepRec()!=0) goto END_FILE; // print this record
-
- RecNo++;
-
- goto READ_LINE;
-
- END_FILE:
- fclose(iStream);
- return TRUE;
- }
-
- /******************************************************************************
- Support Routines.
- ******************************************************************************/
-
- /*****************************************************************************
- StringTrim:
- Remove spaces from the left and right of a NULL terminated string.
- ******************************************************************************/
- void StringTrim(LPSTR string)
- {
- RightTrim(string);LeftTrim(string);
- }
-
- /******************************************************************************
- RightTrim:
- Remove spaces on the right of a string.
- ******************************************************************************/
- void RightTrim(LPSTR string)
- {
- int i,TempLen;
-
- TempLen=lstrlen(string);
- for (i=TempLen-1;i>=0 && string[i] == ' ';i--);
- string[i+1] = '\0';
- }
-
- /******************************************************************************
- LeftTrim:
- Trim initial spaces from the string.
- *******************************************************************************/
- void LeftTrim(LPSTR string)
- {
- int i,TempLen,BeginPoint;char TempStr[300];
-
- TempLen=lstrlen(string);
- for (i=0;i < TempLen && string[i] == ' ';i++);
- BeginPoint=i;
- for (i=BeginPoint;i<TempLen;i++) TempStr[i-BeginPoint]=string[i];
- TempStr[TempLen-BeginPoint] = '\0';
- lstrcpy(string,TempStr);
- }
-
- /******************************************************************************
- GetNumVal:
- Extract a numeric value from the dialog item. Display error if a non-
- numeric value is encountered and return a false result.
- *******************************************************************************/
- BOOL GetNumVal(HWND hWin,int ControlId,int *pInt)
- {
- BOOL ErrorFlag;
-
- *pInt=GetDlgItemInt(hWin,ControlId,&ErrorFlag,(BOOL) 0);
- if (!ErrorFlag) {
- MessageBox(hWin,"Must Enter a Valid Number",NULL,MB_OK);
- SetFocus(GetDlgItem(hWin,ControlId));
- return (FALSE);
- }
- return TRUE;
- }
-
- /******************************************************************************
- Bitmap2DIB:
- Extract device indepedent bits from the bitmap.
- *******************************************************************************/
- Bitmap2DIB()
- {
- DWORD InfoSize,ImageSize;
- BITMAP bm;
- HDC hDC;
-
- GetObject(hLogoBM,sizeof(BITMAP),(LPSTR)&bm); // get the dimension of bit map
-
- //********** create the device independent bitmap ***********************
- InfoSize=sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD); // create a 256 color bitmap structure
-
- if (NULL==(hInfo=GlobalAlloc(GMEM_MOVEABLE,InfoSize))
- ||NULL==(pInfo=(LPBITMAPINFOHEADER)GlobalLock(hInfo)) ) {
- MessageBox(hDemoWin,"Ran out of memory for Bitmap Info!",NULL,MB_OK);
- return -1;
- }
-
- //***** fill in the info structure ******
- pInfo->biSize=sizeof(BITMAPINFOHEADER);
- pInfo->biWidth=bm.bmWidth;
- pInfo->biHeight=bm.bmHeight;
- pInfo->biPlanes=1; // DIB have plane = 1
- pInfo->biBitCount=8; // 8 bits per pixel or color
- pInfo->biCompression=BI_RGB; // no compression - needed for compatibility for all devices
- pInfo->biSizeImage=0; // initialize to zero
- pInfo->biXPelsPerMeter=0;
- pInfo->biYPelsPerMeter=0;
- pInfo->biClrUsed=0; // depends on biBitCount
- pInfo->biClrImportant=0; // all colors important
-
- hDC=GetDC(hDemoWin);
-
- if (!GetDIBits(hDC,hLogoBM,0,bm.bmHeight,NULL,(LPBITMAPINFO)pInfo,DIB_RGB_COLORS)) {
- MessageBox(hDemoWin,"Error Creating Device Independent Bitmap Structure!",NULL,MB_OK);
- return -1;
- }
-
- ImageSize=pInfo->biSizeImage;
-
- if (NULL==(hImage=GlobalAlloc(GMEM_MOVEABLE,ImageSize))
- ||NULL==(pImage=GlobalLock(hImage)) ) {
- MessageBox(hDemoWin,"Ran out of memory for Bitmap Image!",NULL,MB_OK);
- return -1;
- }
-
- if (!GetDIBits(hDC,hLogoBM,0,bm.bmHeight,pImage,(LPBITMAPINFO)pInfo,DIB_RGB_COLORS)) {
- MessageBox(hDemoWin,"Error Creating Device Independent Bitmap Image!",NULL,MB_OK);
- return -1;
- }
-
- // release the common device context
- ReleaseDC(hDemoWin,hDC);
-
- return TRUE;
- }
-
-
- /******************************************************************************
- OurPrintf:
- This routine formats and display a given set of arguments. The format
- is given by the first argument. The argument 2 to n contain the
- arguments for the specified format. The function uses MessageBox to
- display the formatted string.
- ******************************************************************************/
- OurPrintf(LPSTR fmt,...)
- {
- LPSTR ArgStart;
- char string[256];
-
- ArgStart=(LPSTR) &fmt; // pointer to first argument
- ArgStart=&ArgStart[4]; // go past the first argument
- wvsprintf(string,fmt,ArgStart);
- if (FindWindow("DBWin",NULL)) { // debug window open
- lstrcat(string,"\n");
- OutputDebugString(string); // send to the debug terminal
- }
- else MessageBox(NULL,string,NULL,MB_OK);
- return TRUE;
- }
-
-