home *** CD-ROM | disk | FTP | other *** search
/ PC World 1998 June / PCWorld_1998-06_cd.bin / software / sharware / grafika / EROICA32 / _SETUP.5 / Group5 / DEMO.C next >
C/C++ Source or Header  |  1998-01-15  |  29KB  |  865 lines

  1. /*-------------------------- Parallax Standard C_File ----------------------------
  2.    
  3.    C_File   : demo.c
  4.               
  5.    Purpose  : C API sample program source file. Use for the reference about
  6.               writing own C-API based programs.
  7.  
  8.  
  9. --------------------------------------------------------------------------------
  10.           Copyright (c)1996 Parallax Software , All rights reserved.            
  11. ------------------------------------------------------------------------------*/
  12.  
  13. #pragma warning ( disable:4115 )       /* type name definition in parenthesis */
  14. #pragma warning ( disable:4201 )       /* nonstandard extension used: nameless struct/union */
  15. #pragma warning ( disable:4214 )       /* nonstandard extension used: bit field types other than int */
  16. #pragma warning ( disable:4514 )       /* unreferenced inline/local function has been removed */
  17.  
  18.  
  19. #include <windows.h>
  20. #include <commdlg.h>
  21. #include <in_api.h>
  22. #include <stdlib.h>
  23. #include <malloc.h>
  24.  
  25. #include "resource.h"
  26.  
  27. #ifdef _WIN32
  28.  
  29. #define EXPORT( ret )      __declspec( dllexport ) ret WINAPI
  30. #define MALLOC(x)          malloc(x)
  31. #define FREE(x)            free(x)
  32. #define SWALLOW_ARG(x)     {if(x);}
  33.  
  34. #else
  35.  
  36. #define EXPORT( ret )      ret FAR PASCAL __export
  37. #define MALLOC(x)          _fmalloc(x)
  38. #define FREE(x)            _ffree(x)
  39. #define SWALLOW_ARG(x)     {if(x);}
  40.  
  41. #endif
  42.  
  43.  
  44. /* Function prototypes */
  45.  
  46. /* window functions */
  47. EXPORT(LRESULT)    MainWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
  48. EXPORT(LRESULT)    ExternalWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
  49. EXPORT(LRESULT)    EroicaExtWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
  50.  
  51. /* callbacks for notifications */
  52. EXPORT(void)       NFY_CloseDocwin( IN_DOCWIN docwinID );
  53. EXPORT(void)       NFY_MenuIntercept( IN_DOCWIN docwinID, unsigned menuID );
  54. EXPORT(BOOL)       QRY_CloseDocwin( IN_DOCWIN docwinID, BOOL FAR *pCanClose );
  55.  
  56. /* static functions */
  57. static BOOL        _InitApplication( HINSTANCE hInstance );
  58. static BOOL        _InitInstance( HINSTANCE hInstance, int nCmdShow );
  59. static void        _LogMessage( LPCSTR message );
  60. static void        _FileOpen( HWND hWnd, WPARAM mode );
  61. static void        _DumpWindows( void );
  62. static void        _EroicaVersion( void );
  63. static int         _NewLayer( IN_DOCWIN docwinID );
  64. static int         _SetTool( IN_DOCWIN docwinID, UINT toolType );
  65. static int         _SetToolMenuCheck( HWND hWnd, UINT menuID );
  66. static void        _DumpLayer( IN_DOCWIN docwin, IN_PAGE page, int layerNumber, IN_LAYER layer );
  67. static void        _DumpPage( IN_DOCWIN docwin, IN_PAGE page );
  68. static void        _DumpWindow( IN_DOCWIN docwin );
  69.  
  70.  
  71. /* Logging macros */
  72. #define _FMTMSG(fmt,v)               { char m[1024]; wsprintf(m,fmt,v); _LogMessage(m); }
  73. #define _FMTMSG2(fmt,v1,v2)          { char m[1024]; wsprintf(m,fmt,v1,v2); _LogMessage(m); }
  74. #define _FMTMSG3(fmt,v1,v2,v3)       { char m[1024]; wsprintf(m,fmt,v1,v2,v3); _LogMessage(m); }
  75. #define _FMTMSG4(fmt,v1,v2,v3,v4)    { char m[1024]; wsprintf(m,fmt,v1,v2,v3,v4); _LogMessage(m); }
  76. #define _FMTMSG5(fmt,v1,v2,v3,v4,v5) { char m[1024]; wsprintf(m,fmt,v1,v2,v3,v4,v5); _LogMessage(m); }
  77.  
  78.  
  79. /* Window classes */
  80. #define FRAME_CLASS_NAME         "CAPIDemo:Frame"
  81. #define EXTERNAL_CLASS_NAME      "CAPIDemo:External"
  82. #define EROICA_EXT_CLASS_NAME    "CAPIDemo:EroicaExternal"
  83.  
  84.  
  85. /* Application globals */
  86. HINSTANCE  hInst;
  87. HWND       hFrameWnd;
  88. HWND       hLogWnd;
  89. HMENU      mainMenu;
  90.  
  91.  
  92. /* Functions for advise callbacks */
  93. FARPROC  lpfnNotifyMenuIntercept;
  94. FARPROC  lpfnNotifyCloseDocwin;
  95. FARPROC  lpfnQueryCloseDocwin;
  96.  
  97.  
  98. /* main program entry point */
  99.  
  100. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
  101. {
  102.    MSG  msg;
  103.    int  error;
  104.  
  105.    /* dummy parameter check */
  106.    SWALLOW_ARG( lpCmdLine );
  107.  
  108.    /* hPrevInstace has no effect in WIN32 */
  109. #ifdef _WIN32
  110.    SWALLOW_ARG( hPrevInstance );
  111. #else
  112.    if ( hPrevInstance ) {
  113.       return( FALSE );
  114.    }
  115. #endif
  116.  
  117.    
  118.    /* Initialize application startup */
  119.    hInst = hInstance;
  120.    if (!_InitApplication( hInstance )) {
  121.       return( FALSE );
  122.    }
  123.  
  124.    hFrameWnd = NULL;
  125.    hLogWnd   = NULL;
  126.    lpfnNotifyCloseDocwin   = NULL;
  127.    lpfnNotifyMenuIntercept = NULL;
  128.    lpfnQueryCloseDocwin    = NULL;
  129.  
  130.    /* Start API */
  131.    error = IN_Startup( hInstance );
  132.    if ( error < 0 ) {
  133.        MessageBox( NULL, "Couldn't connect Eroiica. Check if Eroiica is running and not busy.", "Application Error", MB_ICONSTOP | MB_OK );
  134.        return( FALSE );
  135.    }
  136.  
  137.    /* Initialize specific instance startup */
  138.    if (!_InitInstance( hInstance, nCmdShow )) {
  139.       MessageBox( NULL, "Couldn't initialize instance", "Application Error", MB_ICONSTOP | MB_OK );
  140.       return( FALSE );
  141.    }
  142.  
  143.    /* Message loop */
  144.    while (GetMessage( &msg, (HWND)NULL, (UINT)NULL, (UINT)NULL )) {
  145.       TranslateMessage( &msg );
  146.       DispatchMessage( &msg );
  147.    }
  148.  
  149.    /* Unregister any notifies */
  150.    if ((error = IN_UnregisterNotify( IN_NFY_MENU_INTERCEPT, 0, (ULONG) lpfnNotifyMenuIntercept )) != IN_ERR_SUCCESS)
  151.       _FMTMSG( "Can't unregister menu intercept notify for docwin %lu", 0 );
  152.       
  153.    /* Release resources */
  154.    if (lpfnNotifyCloseDocwin)
  155.       FreeProcInstance( lpfnNotifyCloseDocwin );
  156.    if (lpfnQueryCloseDocwin)
  157.       FreeProcInstance( lpfnQueryCloseDocwin );
  158.    if (lpfnNotifyMenuIntercept)
  159.       FreeProcInstance( lpfnNotifyMenuIntercept );
  160.  
  161.    return( msg.wParam );
  162. }
  163.  
  164.  
  165.  
  166. /* Initialize the application */
  167.  
  168. BOOL _InitApplication( HINSTANCE hInstance )
  169. {
  170.    WNDCLASS  wc;
  171.  
  172.    /* Frame window */
  173.    wc.style         = (UINT)NULL;
  174.    wc.lpfnWndProc   = (WNDPROC)MainWndProc;
  175.    wc.cbClsExtra    = 0;
  176.    wc.cbWndExtra    = 0;
  177.    wc.hInstance     = hInstance;
  178.    wc.hIcon         = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_APP_ICON ) );
  179.    wc.hCursor       = LoadCursor( NULL, IDC_ARROW );
  180.    wc.hbrBackground = GetStockObject( WHITE_BRUSH );
  181.    wc.lpszMenuName  = "CAPIDemoMainMenu";
  182.    wc.lpszClassName = FRAME_CLASS_NAME;
  183.  
  184.    if (!RegisterClass( &wc ))
  185.       return( FALSE );
  186.  
  187.    /* External window controlled by Eroica */
  188.    wc.style         = (UINT)NULL;
  189.    wc.lpfnWndProc   = (WNDPROC) EroicaExtWndProc;
  190.    wc.cbClsExtra    = 0;
  191.    wc.cbWndExtra    = 4;
  192.    wc.hInstance     = hInstance;
  193.    wc.hIcon         = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_APP_ICON ) );
  194.    wc.hCursor       = LoadCursor( NULL, IDC_ARROW );
  195.    wc.hbrBackground = GetStockObject( WHITE_BRUSH );
  196.    wc.lpszMenuName  = "CAPIDemoIntControlMenu";
  197.    wc.lpszClassName = EROICA_EXT_CLASS_NAME;
  198.  
  199.    if (!RegisterClass( &wc ))
  200.       return( FALSE );
  201.  
  202.    /* External window controlled by us */
  203.    wc.style         = (UINT)NULL;
  204.    wc.lpfnWndProc   = (WNDPROC) ExternalWndProc;
  205.    wc.cbClsExtra    = 0;
  206.    wc.cbWndExtra    = 4;
  207.    wc.hInstance     = hInstance;
  208.    wc.hIcon         = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_APP_ICON ) );
  209.    wc.hCursor       = LoadCursor( NULL, IDC_ARROW );
  210.    wc.hbrBackground = GetStockObject( WHITE_BRUSH );
  211.    wc.lpszMenuName  = "CAPIDemoExtControlMenu";
  212.    wc.lpszClassName = EXTERNAL_CLASS_NAME;
  213.  
  214.    if (!RegisterClass( &wc ))
  215.       return( FALSE );
  216.  
  217.    return( TRUE );
  218. }
  219.  
  220.  
  221.  
  222. /* Initialize the current instance of the application */
  223.  
  224. static BOOL _InitInstance( HINSTANCE hInstance, int nCmdShow )
  225. {
  226.    RECT  rect;
  227.    int   error;
  228.  
  229.    /* Create the frame window */
  230.    hFrameWnd = CreateWindow( FRAME_CLASS_NAME, "Eroica C-API Demo",
  231.                             WS_OVERLAPPEDWINDOW | WS_BORDER | WS_SYSMENU,
  232.                             0, 0, 600, 400,
  233.                             NULL, NULL, hInstance, NULL );
  234.    if (!hFrameWnd)
  235.       return( FALSE );
  236.  
  237.    /* Make the window visible */
  238.    ShowWindow( hFrameWnd, nCmdShow );
  239.    UpdateWindow( hFrameWnd );
  240.  
  241.    /* Get the mainMenu handle */
  242.    mainMenu = GetMenu( hFrameWnd );
  243.  
  244.    /* Tell Eroica to send notifications to us */
  245.    IN_SetAdviseHWnd( hFrameWnd );
  246.  
  247.    /* Locate advise functions */
  248.    lpfnNotifyCloseDocwin   = MakeProcInstance( (FARPROC) NFY_CloseDocwin, hInstance );
  249.    lpfnNotifyMenuIntercept = MakeProcInstance( (FARPROC) NFY_MenuIntercept, hInstance );
  250.    lpfnQueryCloseDocwin    = MakeProcInstance( (FARPROC) QRY_CloseDocwin, hInstance );
  251.  
  252.    /* Set up a notify on menu intercepts */
  253.    if ((error = IN_RegisterNotify( IN_NFY_MENU_INTERCEPT, 0, (ULONG) lpfnNotifyMenuIntercept )) != IN_ERR_SUCCESS)
  254.       _FMTMSG( "Can't register menu intercept notify for docwin %lu", 0 );
  255.  
  256.    /* Tell Eroica which menuIDs to intercept */
  257.    if ((error = IN_InterceptMenuAction( IN_CMD_FILE_SAVE, TRUE )) != IN_ERR_SUCCESS)
  258.       _LogMessage ( "Can't register menu intercept for FILE | SAVE " );
  259.    if ((error = IN_InterceptMenuAction( IN_CMD_FILE_SAVEAS, TRUE )) != IN_ERR_SUCCESS)
  260.       _LogMessage ( "Can't register menu intercept for FILE | SAVE AS" );
  261.  
  262.    
  263.    /* Open up the log window */
  264.    GetClientRect( hFrameWnd, &rect );
  265.    hLogWnd = CreateWindow( "listbox", NULL,
  266.                           WS_CHILDWINDOW | WS_VISIBLE | WS_BORDER | WS_VSCROLL | LBS_NOINTEGRALHEIGHT,
  267.                           0, 0, rect.right - rect.left, rect.bottom - rect.top,
  268.                           hFrameWnd, NULL, hInstance, NULL );
  269.  
  270.    return( TRUE );
  271. }
  272.  
  273.  
  274.  
  275. /* Frame window message handler */
  276.  
  277. EXPORT(LRESULT) MainWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
  278. {
  279.    LRESULT  result;
  280.  
  281.    /* Give Eroica a crack at the message */
  282.    if (IN_MessageHook( hWnd, message, wParam, lParam, &result ))
  283.       return( result );
  284.  
  285.    switch (message) {
  286.       case WM_COMMAND:
  287.          switch (wParam) {
  288.             case IDM_FILE_OPEN_INT_EROICA:
  289.             case IDM_FILE_OPEN_EXT_LOCAL:
  290.             case IDM_FILE_OPEN_EXT_EROICA:
  291.                _FileOpen( hWnd, wParam );
  292.                return( 1 );
  293.  
  294.             case IDM_FILE_DUMP_WINDOWS:
  295.                _DumpWindows();
  296.                return( 1 );
  297.  
  298.             case IDM_EDIT_CLEAR:
  299.                SendMessage( hLogWnd, LB_RESETCONTENT, 0, 0 );
  300.                return( 1 );
  301.  
  302.             case IDM_MARKUP_NEWLAYER:
  303.                _NewLayer( 0 );
  304.                return( 1 );
  305.  
  306.             case IDM_MARKUP_TOOL_CIRCLE:
  307.                if (_SetTool( 0, IN_TOOL_CIRCLE ))
  308.                   _SetToolMenuCheck( hWnd, IDM_MARKUP_TOOL_CIRCLE );
  309.                return( 1 );
  310.  
  311.             case IDM_MARKUP_TOOL_LINE:
  312.                if (_SetTool( 0, IN_TOOL_LINE ))
  313.                   _SetToolMenuCheck( hWnd, IDM_MARKUP_TOOL_LINE );
  314.                return( 1 );
  315.  
  316.             case IDM_MARKUP_TOOL_BOX:
  317.                if (_SetTool( 0, IN_TOOL_BOX ))
  318.                   _SetToolMenuCheck( hWnd, IDM_MARKUP_TOOL_BOX );
  319.                return( 1 );
  320.  
  321.             case IDM_MARKUP_TOOL_TEXT:
  322.                if (_SetTool( 0, IN_TOOL_TEXT ))
  323.                   _SetToolMenuCheck( hWnd, IDM_MARKUP_TOOL_TEXT );
  324.                return( 1 );
  325.  
  326.             case IDM_HELP_VERSION:
  327.                _EroicaVersion();
  328.                return( 1 );
  329.  
  330.             case IDM_EXIT:
  331.                PostMessage( hWnd, WM_CLOSE, 0, 0L );
  332.                return( 1 );
  333.          }
  334.          break;
  335.  
  336.       case WM_DESTROY:
  337.          IN_Shutdown();
  338.          PostQuitMessage( 0 );
  339.          return( 0 );
  340.    }
  341.  
  342.    return( DefWindowProc( hWnd, message, wParam, lParam ) );
  343. }
  344.  
  345.  
  346.  
  347. /* Add a string to the window output */
  348.  
  349. static void _LogMessage( LPCSTR message )
  350. {
  351.    LONG  index;
  352.  
  353.    index = (LONG)SendMessage( hLogWnd, LB_ADDSTRING, 0, (LONG)(LPSTR) message );
  354.    SendMessage( hLogWnd, LB_SETCURSEL, (WPARAM) index, 0 );
  355.    SendMessage( hLogWnd, LB_SETCURSEL, (WPARAM) -1, 0 );
  356. }
  357.  
  358.  
  359.  
  360. /* File|Open:  Open a file in Eroica and then attach two advises       */
  361. /* to the opened document.  We want to know when the user requests to  */
  362. /* close the document, as well as when it actually gets closed         */
  363.  
  364. static void _FileOpen( HWND hWnd, WPARAM mode )
  365. {
  366.    OPENFILENAME  ofn;
  367.    char          filename[512];
  368.    char          title[81];
  369.    int           error;
  370.    SHORT         docwinCount;
  371.    IN_DOCWIN     docwins[1];
  372.  
  373.    filename[0] = '\0';
  374.  
  375.    /* Common file-open dialog initialization */
  376.    ofn.lStructSize       = sizeof( ofn );
  377.    ofn.hwndOwner         = hWnd;
  378.    ofn.hInstance         = NULL;
  379.    ofn.lpstrFilter       = "All Files\0*.*\0";
  380.    ofn.lpstrCustomFilter = NULL;
  381.    ofn.nMaxCustFilter    = 0;
  382.    ofn.nFilterIndex      = 0;
  383.    ofn.lpstrFile         = filename;
  384.    ofn.nMaxFile          = sizeof( filename ) - 1;
  385.    ofn.lpstrFileTitle    = title;
  386.    ofn.nMaxFileTitle     = sizeof( title ) - 1;
  387.    ofn.lpstrInitialDir   = NULL;
  388.    ofn.lpstrTitle        = "Open File In Eroica";
  389.    ofn.Flags             = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
  390.    ofn.lpstrDefExt       = NULL;
  391.    ofn.lCustData         = (DWORD)NULL;
  392.    ofn.lpfnHook          = NULL;
  393.    ofn.lpTemplateName    = NULL;
  394.  
  395.    if (GetOpenFileName( &ofn )) {
  396.  
  397.       switch (mode) {
  398.          case IDM_FILE_OPEN_INT_EROICA:
  399.             error = IN_OpenDocumentWindow( IN_LOCN_DISK, filename, 1, &docwinCount, docwins );
  400.  
  401.             /* Set up advises */
  402.             if (error == IN_ERR_SUCCESS) {
  403.                _FMTMSG2( "%s opened in docwin %lu", (LPCSTR) filename, docwins[0] );
  404.  
  405.                /* Tell us when it closes */
  406.                error = IN_RegisterNotify( IN_NFY_CLOSE_DOCWIN, docwins[0], (ULONG) lpfnNotifyCloseDocwin );
  407.                if (error != IN_ERR_SUCCESS)
  408.                   _FMTMSG( "Can't register close notify for docwin %lu", docwins[0] );
  409.  
  410.                /* Ask us if we should close it */
  411.                error = IN_RegisterQuery( IN_QRY_CLOSE_DOCWIN, docwins[0], (ULONG) lpfnQueryCloseDocwin );
  412.                if (error != IN_ERR_SUCCESS)
  413.                   _FMTMSG( "Can't register close query for docwin %lu", docwins[0] );
  414.             } else {
  415.                _FMTMSG2( "Error code %d when trying to open %s", error, (LPCSTR) filename );
  416.             }
  417.             break;
  418.  
  419.          case IDM_FILE_OPEN_EXT_LOCAL:
  420.          {
  421.             HWND  hDocWnd;
  422.  
  423.             if ((hDocWnd =  CreateWindow( EXTERNAL_CLASS_NAME, "Locally Controlled Document", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
  424.                                          CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  425.                                          hWnd, NULL, hInst, NULL)) != NULL) {
  426.                SetWindowLong( hDocWnd, 0, 0 );
  427.                if ((error = IN_RegisterExternalDocumentWindow( hDocWnd, docwins )) == IN_ERR_SUCCESS) {
  428.                   SetWindowLong( hDocWnd, 0, docwins[0] );
  429.                   if ((error = IN_OpenExternalDocumentWindow( docwins[0], IN_LOCN_DISK, filename, "External Document Window", IN_FLAG_SCROLLBAR_BOTH )) == IN_ERR_SUCCESS) {
  430.                      docwinCount = 1;
  431.                      InvalidateRect( hDocWnd, NULL, FALSE );
  432.                      UpdateWindow( hDocWnd );
  433.                   } else
  434.                      PostMessage( hDocWnd, WM_CLOSE, 0, 0 );
  435.                } else {
  436.                   PostMessage( hDocWnd, WM_CLOSE, 0, 0 );
  437.                }
  438.             } else {
  439. #ifdef _WIN32
  440.                 error = GetLastError();
  441. #else
  442.                 error = 126;
  443. #endif
  444.                 _FMTMSG( "Windows Error %d, cannot redirect window to Eroiica (WIN32 barrier).", error );
  445.             }
  446.                
  447.             break;
  448.          }
  449.  
  450.          case IDM_FILE_OPEN_EXT_EROICA:
  451.          {
  452.             HWND  hDocWnd;
  453.  
  454.             if ((hDocWnd =  CreateWindow( EROICA_EXT_CLASS_NAME, "Eroica Controlled Document", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
  455.                                          CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  456.                                          hWnd, NULL, hInst, NULL)) != NULL) {
  457.                SetWindowLong( hDocWnd, 0, 0 );
  458.                if ((error = IN_RegisterExternalDocumentWindow( hDocWnd, docwins )) == IN_ERR_SUCCESS) {
  459.                   if ((error = IN_OpenExternalDocumentWindow( docwins[0], IN_LOCN_DISK, filename, "External Document Window", IN_FLAG_SCROLLBAR_BOTH )) == IN_ERR_SUCCESS) {
  460.                      IN_HandleExternalDocumentWindow( docwins[0], IN_EXTMODE_ALL );
  461.                      SetWindowLong( hDocWnd, 0, docwins[0] );
  462.                      docwinCount = 1;
  463.                      InvalidateRect( hDocWnd, NULL, FALSE );
  464.                      UpdateWindow( hDocWnd );
  465.                   } else
  466.                      PostMessage( hDocWnd, WM_CLOSE, 0, 0 );
  467.                } else
  468.                   PostMessage( hDocWnd, WM_CLOSE, 0, 0 );
  469.             } else {
  470. #ifdef _WIN32
  471.                error = GetLastError();
  472. #else
  473.                error = 126;
  474. #endif
  475.                _FMTMSG( "Error %d, cannot create controlled window.", error );
  476.             }
  477.             break;
  478.          }
  479.       }
  480.    }
  481. }
  482.  
  483.  
  484.  
  485. /* Dump some information we know about the layer */
  486.  
  487. static void _DumpLayer( IN_DOCWIN docwin, IN_PAGE page, int layerNumber, IN_LAYER layer )
  488. {
  489.    char  title[100];
  490.    
  491.    SWALLOW_ARG( docwin );
  492.    SWALLOW_ARG( page );
  493.    
  494.    if (IN_GetTitle( layer, 100, title ) == IN_ERR_SUCCESS)
  495.       _FMTMSG3( "    Layer %u: '%s', ID=%lu", layerNumber, (LPCSTR) title, layer );
  496. }
  497.  
  498.  
  499.  
  500. /* Create a new layer on the active document window  */
  501.  
  502. static int _NewLayer( IN_DOCWIN docwinID )
  503. {
  504.    IN_PAGE   activePage;
  505.    IN_LAYER  NewLayerID;
  506.    char      errorBuffer[64];
  507.    int       error;
  508.    
  509.    /* Get the active page for the active document window */
  510.    if ((error = IN_GetPageID( docwinID, 0, &activePage )) != IN_ERR_SUCCESS) {
  511.       MessageBox( hFrameWnd, "Unable to get the pageID for the active document window", "Error Message", MB_APPLMODAL );
  512.       return( FALSE );
  513.    }
  514.   
  515.    /* Add a new layer to the active page */
  516.    if ((error = IN_NewLayer( activePage, IN_LAYER_FULLEDIT, &NewLayerID )) != IN_ERR_SUCCESS) {
  517.       wsprintf( errorBuffer, "Unable to add a layer to page (PAGEID:%lu)", activePage );
  518.       MessageBox( hFrameWnd, (LPCSTR)errorBuffer, (LPCSTR)"Error Message", MB_APPLMODAL );
  519.       return( FALSE );
  520.    }
  521.    
  522.    return( TRUE );  
  523. }
  524.  
  525.  
  526. /* Dump the layers on this page as well as some information we know */
  527. /* about the page */
  528.  
  529. static void _DumpPage( IN_DOCWIN docwin, IN_PAGE page )
  530. {
  531.    SHORT         numberLayers;
  532.    SHORT         pageNumber;
  533.    char          title[100];
  534.    int           error;
  535.    SHORT         tmp;
  536.    IN_LAYER_PTR  layers;
  537.    IN_PAGE       activePage;
  538.  
  539.    /* Get some information about this page */
  540.    IN_GetPageNumber( page, &pageNumber );
  541.    IN_GetTitle( page, 100, title );
  542.    IN_GetNumberLayers( docwin, page, &numberLayers );
  543.    IN_GetPageID( docwin, 0, &activePage );
  544.    _FMTMSG5( "  Page %u: '%s', ID=%lu,%s Layer count: %u", pageNumber, (LPCSTR) title, page, activePage == page ? (LPCSTR) " Active," : (LPCSTR) "", numberLayers );
  545.  
  546.    if (numberLayers) {
  547.       if ((layers = (IN_LAYER_PTR) MALLOC( numberLayers * sizeof( IN_LAYER ) )) != NULL) {
  548.          error = IN_GetLayerIDs( page, numberLayers, &tmp, layers );
  549.          if (error == IN_ERR_SUCCESS)
  550.             for (tmp = 0; tmp < numberLayers; ++tmp)
  551.                _DumpLayer( docwin, page, tmp+1, layers[tmp] );
  552.          FREE( layers );
  553.       }
  554.    }
  555. }
  556.  
  557.  
  558.  
  559. /* Dump the pages that are displayed in this document, as well as some */
  560. /* information we know about the document window */
  561.  
  562. static void _DumpWindow( IN_DOCWIN docwin )
  563. {
  564.    SHORT        numberPages;
  565.    char         title[100];
  566.    int          error;
  567.    IN_PAGE_PTR  pages;
  568.    IN_DOCWIN    activeDocwin;
  569.    SHORT        tmp;
  570.  
  571.    /* Get the title of the window */
  572.    title[0] = '\0';
  573.    IN_GetTitle( docwin, 100, title );
  574.    IN_GetActiveDocumentWindow( &activeDocwin );
  575.    IN_GetNumberPages( docwin, &numberPages );
  576.    _FMTMSG4( "Document Window ID %lu: '%s',%s Page count: %u", docwin, (LPCSTR) title, activeDocwin == docwin ? (LPCSTR) " Active," : (LPCSTR) "", numberPages );
  577.  
  578.    /* Get the pages in the window */
  579.    if (numberPages)
  580.       if ((pages = (IN_PAGE_PTR) MALLOC( numberPages * sizeof( IN_PAGE ) )) != NULL) {
  581.          error = IN_GetPageIDs( docwin, numberPages, &tmp, pages );
  582.          if (error == IN_ERR_SUCCESS)
  583.             for (tmp = 0; tmp < numberPages; ++tmp)
  584.                _DumpPage( docwin, pages[tmp] );
  585.          FREE( pages );
  586.       }
  587. }
  588.  
  589.  
  590.  
  591. /* Dump information about all of the document windows that are currently */
  592. /* open in Eroica */
  593.  
  594. static void _DumpWindows( void )
  595. {
  596.    SHORT          docwinCount;
  597.    IN_DOCWIN_PTR  docwins;
  598.    int            error;
  599.    int            i;
  600.  
  601.    /* Get the document windows that are currently open */
  602.    error = IN_GetNumberDocumentWindows( &docwinCount );
  603.    if (error == IN_ERR_SUCCESS) {
  604.       _FMTMSG( " %u document windows found", docwinCount );
  605.       if (docwinCount)
  606.          if ((docwins = (IN_DOCWIN_PTR) MALLOC( docwinCount * sizeof( IN_DOCWIN ) )) != NULL) {
  607.             error = IN_GetDocumentWindows( 100, &docwinCount, docwins );
  608.             if (error == IN_ERR_SUCCESS)
  609.                for (i = 0; i < docwinCount; ++i)
  610.                   _DumpWindow( docwins[i] );
  611.             FREE( docwins );
  612.          }
  613.    } else {
  614.       _FMTMSG( "Couldn't get window count.  Error %d", error );
  615.    }
  616. }
  617.  
  618.  
  619.  
  620. /* Get and display the version of Eroica that we are attached to */
  621.  
  622. static void _EroicaVersion( void )
  623. {
  624.    int      error;
  625.    SHORT    major, minor, build;
  626.    char     szVersion[24];
  627.  
  628.    error = IN_GetIMVersion( &major, &minor, &build, sizeof( szVersion ), szVersion );
  629.    if (error == IN_ERR_SUCCESS) {
  630.       _FMTMSG4( "Eroica Version %u.%u.%u (%s)", major, minor, build, (LPCSTR) szVersion );
  631.    } else {
  632.       _FMTMSG( "Can't get Eroica version.  Error %d", error );
  633.    }
  634. }
  635.  
  636.  
  637.  
  638. /* This function is called when a menu item has been activated and */ 
  639. /* an IN_NFY_MENU_INTERCEPT advise has been sent out */
  640.  
  641. EXPORT(void) NFY_MenuIntercept( IN_DOCWIN docwinID, unsigned menuID )
  642. {
  643.    char  message[256];
  644.   
  645.    switch (menuID) {
  646.       case IN_CMD_FILE_SAVE:
  647.          wsprintf( message, "Someone has select the FILE|SAVE menu option in Eroica for docwinID %lu.  Enter user intercept function here", docwinID );
  648.          MessageBox( hFrameWnd, (LPCSTR)message, (LPCSTR)"Menu Item Intercepted", MB_APPLMODAL );
  649.          break;
  650.       
  651.       case IN_CMD_FILE_SAVEAS:
  652.          wsprintf( message, "Someone has select the FILE|SAVE AS menu option in Eroica for docwinID %lu.  Enter user intercept function here", docwinID );
  653.          MessageBox( hFrameWnd, (LPCSTR)message, (LPCSTR)"Menu Item Intercepted", MB_APPLMODAL );
  654.          break;
  655.          
  656.       default: 
  657.          break;
  658.    } 
  659. }
  660.  
  661.  
  662.  
  663. /* This function is called when a document window that we have placed */
  664. /* an IN_NFY_CLOSE_DOCWIN advise request on has closed */
  665.  
  666. EXPORT(void) NFY_CloseDocwin( IN_DOCWIN docwinID )
  667. {
  668.    _FMTMSG( "CloseDocwin %ld", docwinID );
  669. }
  670.  
  671.  
  672.  
  673. /* This function sets the appropriate tool item to checked */
  674. static int _SetTool( IN_DOCWIN docwinID, UINT toolType )
  675. {
  676.    int       error;
  677.  
  678.    /* Set the tool type */
  679.    if ((error = IN_SetTool( docwinID, toolType )) != IN_ERR_SUCCESS) {
  680.       _FMTMSG( "Tool type was not set (TOOL:%d)", toolType );
  681.    }
  682.      
  683.    return( TRUE );
  684. }
  685.  
  686.  
  687.    
  688. /* This function sets the appropriate tool item to checked */
  689. static int _SetToolMenuCheck( HWND hWnd, UINT menuID )
  690. {
  691.    HMENU  hMenu = GetMenu( hWnd );
  692.  
  693.    /* Turn all the checks off */
  694.    CheckMenuItem( hMenu, IDM_MARKUP_TOOL_CIRCLE, MF_UNCHECKED );
  695.    CheckMenuItem( hMenu, IDM_MARKUP_TOOL_LINE, MF_UNCHECKED );
  696.    CheckMenuItem( hMenu, IDM_MARKUP_TOOL_BOX, MF_UNCHECKED );
  697.    CheckMenuItem( hMenu, IDM_MARKUP_TOOL_TEXT, MF_UNCHECKED );
  698.    
  699.    /* Now set the onen active */
  700.    CheckMenuItem( hMenu, menuID, MF_CHECKED );
  701.    
  702.    return( TRUE );
  703. }
  704.  
  705.  
  706.  
  707. /* This function is called when a document window that we have placed
  708.  * an IN_QRY_CLOSE_DOCWIN advise request been requested to close.
  709.  *
  710.  * The user is presented with a Yes/No/Cancel dialog asking whether the
  711.  * document window should be closed or not.
  712.  *
  713.  * Yes    indicates that the window can close
  714.  * No     indicates that the window shouldn't close
  715.  * Cancel indicates that we have no opinion and let it close if nobody
  716.  *        else wants it to stay open
  717.  */
  718.  
  719. EXPORT(BOOL) QRY_CloseDocwin( IN_DOCWIN docwinID, BOOL FAR *pCanClose )
  720. {
  721.    char  msgText[50];
  722.    BOOL  msgProcessed;
  723.  
  724.    wsprintf( msgText, "Close Docwin ID %lu?", docwinID );
  725.    switch (MessageBox( hFrameWnd, msgText, "Close DocwinID Query", MB_YESNOCANCEL )) {
  726.       case IDYES:
  727.          *pCanClose   = TRUE;
  728.          msgProcessed = TRUE;
  729.          _FMTMSG( "CloseDocwin(%lu)? Yes", docwinID );
  730.          break;
  731.  
  732.       case IDNO:
  733.          *pCanClose   = FALSE;
  734.          msgProcessed = TRUE;
  735.          _FMTMSG( "CloseDocwin(%lu)? No", docwinID );
  736.          break;
  737.  
  738.       case IDCANCEL:
  739.       default:
  740.          msgProcessed = FALSE;
  741.          _FMTMSG( "CloseDocwin(%lu)? Ignored", docwinID );
  742.          break;
  743.    }
  744.    
  745.    return( msgProcessed );
  746. }
  747.  
  748.  
  749.  
  750. /* This function is the callback for the external window that we control */
  751. /* by giving Eroica explicitly a chance at processing the message */
  752.  
  753. EXPORT(LRESULT) ExternalWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
  754. {
  755.    IN_DOCWIN  docwinID = GetWindowLong( hWnd, 0 );
  756.  
  757.    /* Give Eroica a chance at the message */
  758.    if (message != WM_COMMAND || (wParam < FIRST_MENU_COMMAND_ID || wParam > LAST_MENU_COMMAND_ID))
  759.       if (IN_ProcessExternalWindowMessage( hWnd, message, wParam, lParam ))
  760.          return( 0 );
  761.  
  762.    switch (message) {
  763.       case WM_CLOSE:
  764.          IN_UnregisterExternalDocumentWindow( docwinID );
  765.          break;
  766.  
  767.       case WM_COMMAND:
  768.          switch (wParam) {
  769.             case IDM_EXIT:
  770.                PostMessage( hWnd, WM_CLOSE, 0, 0 );
  771.                return( 1 );
  772.  
  773.             case IDM_VIEW_FIT:
  774.                IN_SetZoom( docwinID, 3 );
  775.                return( 1 );
  776.  
  777.             case IDM_MARKUP_NEWLAYER:
  778.                _NewLayer( docwinID );
  779.                return( 1 );
  780.  
  781.             case IDM_MARKUP_TOOL_CIRCLE:
  782.                if (_SetTool( docwinID, IN_TOOL_CIRCLE ))
  783.                   _SetToolMenuCheck( hWnd, IDM_MARKUP_TOOL_CIRCLE );
  784.                return( 1 );
  785.  
  786.             case IDM_MARKUP_TOOL_LINE:
  787.                if (_SetTool( docwinID, IN_TOOL_LINE ))
  788.                   _SetToolMenuCheck( hWnd, IDM_MARKUP_TOOL_LINE );
  789.                return( 1 );
  790.  
  791.             case IDM_MARKUP_TOOL_BOX:
  792.                if (_SetTool( docwinID, IN_TOOL_BOX ))
  793.                   _SetToolMenuCheck( hWnd, IDM_MARKUP_TOOL_BOX );
  794.                return( 1 );
  795.  
  796.             case IDM_MARKUP_TOOL_TEXT:
  797.                if (_SetTool( docwinID, IN_TOOL_TEXT ))
  798.                   _SetToolMenuCheck( hWnd, IDM_MARKUP_TOOL_TEXT );
  799.                return( 1 );
  800.          }
  801.    }
  802.  
  803.    return( DefWindowProc( hWnd, message, wParam, lParam ) );
  804. }
  805.  
  806.  
  807.  
  808. /* This function is the callback for the external window that
  809. /*  we let Eroica control */
  810.  
  811. EXPORT(LRESULT) EroicaExtWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
  812. {
  813.    IN_DOCWIN  docwinID = GetWindowLong( hWnd, 0 );
  814.    /* int        mode; */
  815.  
  816.    switch (message) {
  817.       case WM_CLOSE:
  818.          if (docwinID)
  819.             IN_UnregisterExternalDocumentWindow( docwinID );
  820.          break;
  821.  
  822.       case WM_SIZE:
  823.          switch (wParam) {
  824.             case SIZE_MAXIMIZED:
  825.             case SIZE_MINIMIZED:
  826.             case SIZE_RESTORED:
  827.                if (docwinID)
  828.                   IN_ResetExternalDocumentWindowSize( docwinID );
  829.                break;
  830.          }
  831.          break;
  832.  
  833.       case WM_COMMAND:
  834.          switch (wParam) {
  835.             case IDM_EXIT:
  836.                PostMessage( hWnd, WM_CLOSE, 0, 0 );
  837.                return( 0 );
  838.  
  839.             case IDM_VIEW_FIT:
  840.                if (docwinID)
  841.                   IN_SetZoom( docwinID, 3 );
  842.                return( 1 );
  843.  
  844.             case IDM_VIEW_ZOOMIN:
  845.                if (docwinID)
  846.                   IN_SetZoom( docwinID, 1 );
  847.                return( 1 );
  848.  
  849.             case IDM_VIEW_ZOOMOUT:
  850.                if (docwinID)
  851.                   IN_SetZoom( docwinID, 2 );
  852.                return( 1 );
  853.  
  854.          }
  855.    }
  856.  
  857.    return( DefWindowProc( hWnd, message, wParam, lParam ) );
  858. }
  859.  
  860.  
  861. /* DEMO.C */
  862. /* end of file */
  863.  
  864.  
  865.