home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
-
- main.c
- ------
-
- This is the entry module for the TextView demonstration application. The
- program shows you how you can use TextView to add a real-time tracing
- facility to an application, so that you can write debug messages to
- the screen as easily as you could using printf() in a DOS application.
-
- The program sets up a main window that contains a 'Trace' menu. Items in
- this menu enable you to turn the tracing facility on and off, and to
- simulate your application writing messages to the trace window and
- manipulating it.
-
- This source is Copyright (c) Alan Phillips 1991. It may be freely used
- and adapted for non-commercial applications. Commercial and ShareWare
- authors should first obtain the written permission of the author.
-
- The source is edited with a tab size of 4.
-
- *****************************************************************************/
-
- #define MAINDEF
- #include "stdhead.h"
- #include "ident.h"
-
- /*****************************************************************************
-
- Local Procedures
- ----------------
-
- *****************************************************************************/
-
- static BOOL process_command(HWND,unsigned,WORD,LONG);
-
-
- /*****************************************************************************
-
- WinMain
- -------
-
- This is the entry point from Windows
-
- reply = WinMain(hInstance,hPrevInstance,lpCmdLine,nCmdShow)
-
- int reply; Reply to Windows
- HANDLE hInstance; Handle of this instance
- HANDLE hPrevInstance; Handle of previous instance
- LPSTR lpCmdLine; Ptr to command line
- int nCmdShow; ShowWindow() param
-
- *****************************************************************************/
-
- int PASCAL WinMain(HANDLE hInstance,HANDLE hPrevInstance,
- LPSTR lpCmdLine, int nCmdShow)
-
- {
- WNDCLASS wc; /* window class struct */
- MSG msg; /* message from Windows */
-
- /* Save our instance handle in global data */
-
- hInst = hInstance;
-
- /* Set up a window class for the main window. Since the window is not
- * going to be used for anything in this demonstration, we don't need
- * to set up anything special
- */
-
- if ( hPrevInstance == NULL )
- {
- /* Set up class struct for the main window */
-
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = WndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon(hInstance,"MAIN_ICON");
- wc.hCursor = LoadCursor(NULL,IDC_ARROW);
- wc.hbrBackground = GetStockObject(WHITE_BRUSH);
- wc.lpszMenuName = "MAIN_MENU";
- wc.lpszClassName = "TR_Window";
-
- /* And register it */
-
- RegisterClass(&wc);
-
- }
-
- /* Create the main window. We make it fairly small as it doesn't have
- * to do anything
- */
-
- hMainWnd = CreateWindow( "TR_Window",
- "TextView DLL Demo",
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- 300,
- 150,
- NULL,
- NULL,
- hInstance,
- NULL );
-
- if ( hMainWnd == NULL )
- return(FALSE);
-
- /* Make the main window visible and update the client area */
-
- ShowWindow(hMainWnd,nCmdShow);
- UpdateWindow(hMainWnd);
-
- /* In order to create TextView windows, you need to call a TextView
- * routine to register one or more window classes. The information passed
- * is a subset of the information you set up for a call to RegisterClass;
- * most of the details are supplied by TextView itself. Here you can
- * specify an icon handle, and the background brush.
- *
- * Note that this routine is not in the TextView DLL itself, but is
- * in the import library TEXTVIEW.LIB
- */
-
- TVRegisterClass(hInstance,"TRACE_WINDOW",LoadIcon(hInstance,"MAIN_ICON"),
- GetStockObject(WHITE_BRUSH));
-
- /* And now we can enter the message loop and wait for the user to do
- * something
- */
-
- while ( GetMessage(&msg,NULL,0,0) )
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- /* And when we get here, that's it */
-
- return( msg.wParam );
-
- }
-
-
-
- /*****************************************************************************
-
- WndProc
- -------
-
- This is the Windows function to receive messages for the main window
-
- reply = WndProc(hWnd,iMessage,wParam,lParam)
-
- long reply; Reply to Windows
- HWND hWnd; Handle to window
- unsigned iMessage; Message id
- WORD wParam; Message parameter
- LONG lParam; Message parameter
-
- *****************************************************************************/
-
- long FAR PASCAL Wndproc(HWND hWnd, unsigned iMessage,WORD wParam,
- LONG lParam)
-
- {
- /* Switch on the message type */
-
- switch ( iMessage )
- {
-
- case WM_DESTROY: /* window has gone */
-
- PostQuitMessage(0);
- return(0);
-
- case WM_COMMAND: /* command */
-
- /* Pass the command down to a separate routine to avoid
- * this switch getting horrendously large
- */
-
- if ( process_command(hWnd,iMessage,wParam,lParam) )
- break;
- else
- return(0);
-
- default: /* anything else */
-
- break;
- }
-
- return( DefWindowProc(hWnd,iMessage,wParam,lParam) );
-
- }
-
-
- /*****************************************************************************
-
- process_command
- ---------------
-
- Processes one command from a WM_COMMAND message to the main window. This
- is done in a separate routine to keep the main message loop switch a
- reasonable size
-
- reply = process_command(hWnd,iMessage,wParam,lParam)
-
- BOOL reply; TRUE if message handled here
- HWND hWnd; Handle to window
- unsigned iMessage; Message id
- WORD wParam; Message parameter
- LONG lParam; Message parameter
-
- *****************************************************************************/
-
- static BOOL process_command(HWND hWnd,unsigned iMessage,WORD wParam,
- LONG lParam)
-
- {
- static int trace_count = 1; /* test trace counts */
-
- int i; /* work variable */
- FARPROC lpAbout; /* about dialog proc instance */
- HMENU hMenu; /* handle to main window menu */
-
- /* Switch on the WM_COMMAND parameter */
-
- switch ( wParam )
- {
-
- case IDM_HELP_ABOUT: /* About... */
-
- /* Run the "about" dialog */
-
- lpAbout = MakeProcInstance(AboutDlgProc,hInst);
- DialogBox( hInst,
- "ABOUT_DLG",
- hWnd,
- lpAbout);
- FreeProcInstance(lpAbout);
- break;
-
- case IDM_TRACE_ON: /* Trace start */
-
- /* Start tracing, creating a trace window if we
- * don't already have one
- */
-
- start_tracing(hWnd);
- break;
-
- case IDM_TRACE_OFF: /* Trace stop */
-
- /* Here we just set our 'tracing' flag to FALSE, so
- * that the trace() routine does nothing. We leave the
- * trace window open, and adjust items in our menu
- */
-
- tracing = FALSE;
- EnableMenuItem(GetMenu(hWnd),IDM_TRACE_OFF,
- MF_GRAYED | MF_BYCOMMAND);
- EnableMenuItem(GetMenu(hWnd),IDM_TRACE_ON,
- MF_ENABLED | MF_BYCOMMAND);
- break;
-
- case IDM_TRACE_KILLWND: /* Trace kill window */
-
- /* Here we actually destroy the trace window and lose
- * all its contents
- */
-
- kill_trace_window(hWnd);
-
- /* Reset our private message counter to the start again */
-
- trace_count = 1;
- break;
-
- case IDM_TRACE_TEST: /* Trace write message */
-
- /* Call the trace routine to write one line to
- * the trace window. Note that this menu option is
- * always enabled, to demonstrate how lines are
- * ignored if tracing is not active
- */
-
- trace("Test message %d",RGB(0,128,128),
- trace_count);
- trace_count++;
- break;
-
- case IDM_TRACE_MTEST: /* trace write batch */
-
- /* Call the trace routine to write a batch of lines to
- * the trace window. Note that this menu option is
- * always enabled, to demonstrate how lines are
- * ignored if tracing is not active
- *
- * For this option, the lines are written to the
- * trace window as they are sent, so that the process
- * is relatively slow
- *
- */
-
- hourglass_on(hWnd);
-
- for ( i = 1; i <= 200; i++ )
- {
- if ( !trace("Test message %d",RGB(128,0,128),trace_count) )
- break;
-
- trace_count++;
- }
-
- hourglass_off();
-
- break;
-
- case IDM_TRACE_MTESTF: /* trace write batch fast */
-
- /* Call the trace routine to write a batch of lines to
- * the trace window.
- *
- * For this option, we disable redrawing the trace
- * window before we start, and enable it when we've
- * done. This inhibits TextView from writing to the
- * screen and scrolling the window, so the process
- * is much faster that the option above.
- *
- *
- * Note that since this option is always available,
- * we need to check ourselves that the trace window
- * exists.
- */
-
- if ( hTraceWnd == NULL )
- break;
-
- /* The window exists, so disable redrawing */
-
- TVSetRedraw(hTraceWnd,FALSE);
-
- /* And send a block of messages */
-
- hourglass_on(hWnd);
-
- for ( i = 1; i <= 200; i++ )
- {
- if ( !trace("Test message %d",RGB(0,255,0),trace_count) )
- break;
-
- trace_count++;
- }
-
- /* Now re-enable redrawing, which will cause TextView
- * to show the last screen-full of lines
- */
-
- TVSetRedraw(hTraceWnd,TRUE);
-
- hourglass_off();
-
- break;
-
- case IDM_TRACE_RESET: /* trace reset */
-
- /* Here we discard any contents in the trace window */
-
- reset_tracing(hWnd);
-
- /* And reset our private message count */
-
- trace_count = 1;
- break;
-
- case IDM_TRACE_SHOW: /* trace show window */
-
- /* Here we use the trace window handle to manipulate
- * the window ourselves. There is no need to interact
- * with the TextView DLL to do things like this
- */
-
- if ( IsIconic(hTraceWnd) )
- ShowWindow(hTraceWnd,SW_SHOWNORMAL);
- else
- BringWindowToTop(hTraceWnd);
- break;
-
- case IDM_TRACE_STATUS: /* trace status */
-
- /* Tell the user the state of the trace window */
-
- report_trace_status();
- break;
-
- case IDM_TRACE_SCR_AUTO: /* trace scroll auto */
-
- /* Call the DLL to set the scroll state */
-
- TVSetScrollState(hTraceWnd,TV_SCR_AUTO);
-
- /* And adjust our menu to match */
-
- hMenu = GetMenu(hMainWnd);
-
- CheckMenuItem(hMenu,IDM_TRACE_SCR_AUTO,
- MF_CHECKED|MF_BYCOMMAND);
- CheckMenuItem(hMenu,IDM_TRACE_SCR_MAN,
- MF_UNCHECKED|MF_BYCOMMAND);
- break;
-
- case IDM_TRACE_SCR_MAN: /* trace scroll manual */
-
- /* Call the DLL to set the new state */
-
- TVSetScrollState(hTraceWnd,TV_SCR_MANUAL);
-
- /* And set our menu to match */
-
- hMenu = GetMenu(hMainWnd);
-
- CheckMenuItem(hMenu,IDM_TRACE_SCR_MAN,
- MF_CHECKED|MF_BYCOMMAND);
- CheckMenuItem(hMenu,IDM_TRACE_SCR_AUTO,
- MF_UNCHECKED|MF_BYCOMMAND);
- break;
-
- case IDM_TRACE_COPY: /* trace copy trace window */
-
- /* This takes a little time, so put up an hourglass
- * cursor
- */
-
- hourglass_on(hWnd);
-
- /* Do the copy */
-
- copy_trace_window(hWnd);
-
- /* And restore the previous cursor */
-
- hourglass_off();
-
- break;
-
- default: /* anything else */
-
- /* Pass command to Windows */
-
- return(FALSE);
- }
-
- /* If we get here, we processed the message, so tell caller not to pass
- * it to Windows
- */
-
- return(TRUE);
-
- }
-
-
- /*****************************************************************************
-
- AboutDlgProc
- -------------
-
- This proc handles the "about" box dialog
-
- reply = AboutDlgProc(hDlg,message,wParam,lParam)
-
- BOOL reply; Reply to Windows
- HWND hDlg; Handle to dialog box
- unsigned nMessage; Message type
- WORD wParam; Message parameter
- LONG lParam; Message parameter
-
- *****************************************************************************/
-
- BOOL FAR PASCAL AboutDlgProc(HWND hDlg,unsigned nMessage,
- WORD wParam, LONG lParam)
-
- {
- char buffer[32]; /* buffer for id strings */
- int mark, /* id numbers of sub-systems */
- version,
- cycle;
-
- /* Switch on the message type */
-
- switch ( nMessage )
- {
- case WM_INITDIALOG:
-
- /* Write our id string to the text box */
-
- wsprintf(buffer,"DemoProg %d.%02d.%03d",
- MARK, VERSION, CYCLE);
- SetDlgItemText(hDlg,ID_ABOUT_VN,buffer);
-
- /* Then that of the TextView DLL */
-
- TVVersion(&mark,&version,&cycle);
- wsprintf(buffer,"TextView DLL %d.%02d.%03d",
- mark,version,cycle);
- SetDlgItemText(hDlg,ID_TV_VERSION,buffer);
-
- break;
-
- case WM_COMMAND:
-
- if ( wParam == ID_OK_BUTTON )
- {
- EndDialog(hDlg,TRUE);
- return(TRUE);
- }
-
- break;
-
- default:
-
- break;
- }
-
- /* We didn't process the message here */
-
- return(FALSE);
-
- }
-