MRESULT khs_umCheckDBCSSupport( HWND hwnd, MPARAM mp1, MPARAM mp2 ) { PKHSCD pkhscd = WinQueryWindowPtr( hwnd, 0 ); HWND hwndTarget = HWNDFROMMP( mp1 ); PID pid; USHORT qcp; WinQueryWindowProcess( hwndTarget, &pid, NULL ); DosGiveSharedMem( pkhscd->pCursorPos, pid, PAG_READ | PAG_WRITE ); qcp = SHORT1FROMMR( WinSendMsg( hwndTarget, WM_QUERYCONVERTPOS, MPFROMP( pkhscd->pCursorPos ), 0 )); return MRFROMLONG( qcp == QCP_CONVERT ); }
static DDESTRUCT *MakeDDEObject( HWND hwnd, char *item_name, USHORT fsStatus, USHORT usFormat, void *data, int data_len ) /****************************************************************/ { DDESTRUCT *dde; int item_len; PID pid; TID tid; if( item_name != NULL ) { item_len = strlen( item_name ) + 1; } else { item_len = 1; } if( !DosAllocSharedMem( (PPVOID)&dde, NULL, sizeof( DDESTRUCT ) + item_len + data_len, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE ) ) { WinQueryWindowProcess( hwnd, &pid, &tid ); DosGiveSharedMem( (PVOID)&dde, pid, PAG_READ | PAG_WRITE ); dde->cbData = data_len; dde->fsStatus = fsStatus; dde->usFormat = usFormat; dde->offszItemName = sizeof( DDESTRUCT ); if( (data_len != 0) && (data != NULL) ) { dde->offabData = (USHORT)(sizeof( DDESTRUCT ) + item_len); } else { dde->offabData = 0; } if( item_name != NULL ) { strcpy( (char *)DDES_PSZITEMNAME( dde ), item_name ); } else { strcpy( (char *)DDES_PSZITEMNAME( dde ), "" ); } if( data != NULL ) { memcpy( DDES_PABDATA( dde ), data, data_len ); } return( dde ); } return( NULL ); }
static PDDESTRUCT MakeDDEObject ( HWND Destination, // -> Destination window PSZ Item, // -> Item name or NULL. USHORT Status, // Status flags. USHORT Format, // Data format PVOID Data, // -> Data or NULL. ULONG DataLen // Data length in bytes. ) { ULONG ItemLen = Item ? strlen(PCHAR(Item))+1 : 1 ; PDDESTRUCT pBlock ; if ( DosAllocSharedMem ( PPVOID(&pBlock), 0, sizeof(DDESTRUCT) + ItemLen + DataLen, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE ) ) return ( 0 ) ; pBlock->cbData = DataLen ; pBlock->fsStatus = Status ; pBlock->usFormat = Format ; pBlock->offszItemName = sizeof(DDESTRUCT) ; if ( DataLen AND Data ) pBlock->offabData = USHORT ( sizeof(DDESTRUCT) + ItemLen ) ; else pBlock->offabData = 0 ; if ( Item ) strcpy ( PCHAR(DDES_PSZITEMNAME(pBlock)), PCHAR(Item) ) ; else strcpy ( PCHAR(DDES_PSZITEMNAME(pBlock)), "" ) ; if ( Data ) memcpy ( DDES_PABDATA(pBlock), Data, size_t(DataLen) ) ; PID pid ; TID tid ; WinQueryWindowProcess ( Destination, &pid, &tid ) ; DosGiveSharedMem( (PVOID)pBlock, pid, PAG_READ | PAG_WRITE) ; return ( pBlock ) ; }
static int SendExtQMsg ( USHORT usEvent, PVOID pData, ULONG ulLen ) { USHORT res; ULONG ulPID; HQUEUE hQueue; PVOID pItem; res=DosOpenQueue(&ulPID, &hQueue, szExtQueue); if (res) { printf("AM4PM not running\n"); return 2; } if (pData != NULL) { DosAllocSharedMem(&pItem, NULL, ulLen, PAG_COMMIT | OBJ_GIVEABLE | PAG_READ | PAG_WRITE); memcpy(pItem, pData, ulLen); DosGiveSharedMem(pItem, ulPID, PAG_READ | PAG_WRITE); DosFreeMem(pItem); } else pItem=NULL; res=DosWriteQueue(hQueue, usEvent, ulLen, pItem, 0); DosCloseQueue(hQueue); if (res) return 2; return 0; }
BOOL DDERequest(HWND hwndClient, PSZ pszItemString) { ULONG mem; PID pid; TID tid; PDDESTRUCT pddeStruct; PSZ pszDDEItemName; // get some sharable memory DosAllocSharedMem((PVOID)&mem, NULL, sizeof(DDESTRUCT) + 1000, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE); // get the server's ID and give it access // to the shared memory WinQueryWindowProcess(G_hServerWnd, &pid, &tid); DosGiveSharedMem(&mem, pid, PAG_READ | PAG_WRITE); /* here is definition for DDESTRUCT, for further reference: * typedef struct _DDESTRUCT { * ULONG cbData; * This is the length of data that occurs after the offabData parameter. If no * data exists, this field should contain a zero (0). * USHORT fsStatus; / Status of the data exchange. * DDE_FACK * Positive acknowledgement * DDE_FBUSY * Application is busy * DDE_FNODATA * No data transfer for advise * DDE_FACKREQ * Acknowledgements are requested * DDE_FRESPONSE * Response to WM_DDE_REQUEST * DDE_NOTPROCESSED * DDE message not understood * DDE_FAPPSTATUS * A 1-byte field of bits that are reserved for application-specific returns. * USHORT usFormat; / Data format. * USHORT offszItemName; / Offset to item name. * This is the offset to the item name from the start of this structure. Item * name is a null (0x00) terminated string. If no item name exists, there must * be a single null (0x00) character in this position. (That is, ItemName is * ALWAYS a null terminated string.) * * USHORT offabData; / Offset to beginning of data. * This is the offset to the data, from the start of this structure. This field * should be calculated regardless of the presence of data. If no data exists, * cbData must be zero (0). * * For compatibility reasons, this data should not contain embedded pointers. * Offsets should be used instead. * * -- CHAR szItemName[] / offset: offszItemName * -- BYTE abData[] / offset: offabData * } DDESTRUCT; */ // setup DDE data structures pddeStruct = (PDDESTRUCT) mem; pddeStruct->fsStatus = 0; // DDE_FACKREQ; // Status pddeStruct->usFormat = DDEFMT_TEXT; // Text format // go past end of data structure for the item name pddeStruct->offszItemName = sizeof(DDESTRUCT); pszDDEItemName = ((BYTE*)pddeStruct) + pddeStruct->offszItemName; strcpy(pszDDEItemName, pszItemString); // go past end of data structure // (plus past the name) for the data pddeStruct->offabData = strlen(pszDDEItemName) + 1; // offset to BEGINNING of data pddeStruct->cbData = 500; // length of the data ShowMessage(__FUNCTION__ ": sending request \"%s\"", pszItemString); // post our request to the server program if (G_NetscapeFound = WinDdePostMsg(G_hServerWnd, hwndClient, WM_DDE_REQUEST, pddeStruct, 0)) // WinDdePostMsg frees the shared mem! ShowMessage(" --> success"); else ShowMessage(" --> failed"); return G_NetscapeFound; }
extern int main ( int argc, char *argv[] ) { /************************************************************************** * Register self. * **************************************************************************/ Sys_RegisterThread ( ) ; /************************************************************************** * Set a default exception filter. * **************************************************************************/ REGISTER_EXCEPTION_HANDLER(0); /************************************************************************** * Start the main block (for constructors/destructors). * **************************************************************************/ { /************************************************************************** * Get the initial file path for loading files from command-line. * **************************************************************************/ char InitialPath [CCHMAXPATH] ; _fullpath ( InitialPath, ".", sizeof(InitialPath) ) ; strcat ( InitialPath, "\\" ) ; /************************************************************************** * Determine the home directory. * **************************************************************************/ char Drive [_MAX_DRIVE+1], Dir[_MAX_DIR+1], Fname[_MAX_FNAME+1], Ext[_MAX_EXT+1] ; strupr ( argv[0] ) ; _fullpath ( HomePath, argv[0], sizeof(HomePath) ) ; _splitpath ( HomePath, Drive, Dir, Fname, Ext ) ; if ( Dir[strlen(Dir)-1] == '\\' ) Dir[strlen(Dir)-1] = 0 ; strcpy ( HomePath, Drive ) ; strcat ( HomePath, Dir ) ; _chdrive ( Drive[0] - 'A' + 1 ) ; _chdir ( "\\" ) ; _chdir ( Dir ) ; /************************************************************************** * Set the C RunTime Library error message file handle. * **************************************************************************/ #ifdef __DEBUG_ALLOC__ Log ( "Escriba::main: Program started." ) ; _set_crt_msg_handle ( fileno(Logfile) ) ; #else #ifdef DEBUG Log ( "Escriba::main: Program started." ) ; #endif // DEBUG #endif // __DEBUG_ALLOC__ /************************************************************************** * Determine if another instance of this program is present. * * If so, pass the command-line information to it. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: Checking for another instance already loaded." ) ; #endif // DEBUG PublicMemory Memory ( MEMORY_NAME, sizeof(SHARED_MEMORY), TRUE ) ; if ( NOT Memory.QueryCreated() ) { // Get the main instance's window handle. Wait up to 20 seconds if necessary. HWND MainWindow = ((SHARED_MEMORY*)Memory.QueryMemory())->MainWindow ; clock_t LastClock = clock ( ) ; while ( MainWindow == 0 ) { if ( ( ( clock() - LastClock ) / CLOCKS_PER_SEC ) > 20 ) { Log ( "ERROR: Unable to get previous instance window handle." ) ; return ( 1 ) ; } /* endif */ DosSleep ( 100 ) ; MainWindow = ((SHARED_MEMORY*)Memory.QueryMemory())->MainWindow ; } /* endwhile */ // If any command-line parameters were given . . . if ( argc > 1 ) { // Build a command-line string. char Parms [512] = { 0 } ; int ParmLength = 0 ; while ( --argc ) { strcpy ( Parms+ParmLength, *(++argv) ) ; ParmLength += strlen(*argv) + 1 ; } /* endwhile */ Parms[++ParmLength] = 0 ; // Get the original process's ID. PID Process ; TID Thread ; if ( !WinQueryWindowProcess ( MainWindow, &Process, &Thread ) ) { char Message [512] ; Log ( "ERROR: Unable to query window process. %s", InterpretWinError(0,Message) ) ; return ( 1 ) ; } /* endif */ // Allocate shared memory to hold the current path. PVOID Memory1 ; APIRET Status = DosAllocSharedMem ( &Memory1, 0, strlen(InitialPath)+1, fALLOC | OBJ_GIVEABLE | OBJ_GETTABLE) ; if ( Status ) { Log ( "ERROR: Unable to allocate shared memory. Status %d.", Status ) ; return ( 1 ) ; } /* endif */ strcpy ( PCHAR(Memory1), InitialPath ) ; // Allocate shared memory to hold the command-line. PVOID Memory2 ; Status = DosAllocSharedMem ( &Memory2, 0, ParmLength, fALLOC | OBJ_GIVEABLE | OBJ_GETTABLE) ; if ( Status ) { Log ( "ERROR: Unable to allocate shared memory. Status %d.", Status ) ; return ( 1 ) ; } /* endif */ memcpy ( Memory2, Parms, ParmLength ) ; // Make both shared memory blocks available to the original process. Status = DosGiveSharedMem ( Memory1, Process, PAG_READ | PAG_WRITE ) ; DosFreeMem ( Memory1 ) ; if ( Status ) { Log ( "ERROR: Unable to give shared memory. Status %d.", Status ) ; return ( 1 ) ; } /* endif */ Status = DosGiveSharedMem ( Memory2, Process, PAG_READ | PAG_WRITE ) ; DosFreeMem ( Memory2 ) ; if ( Status ) { Log ( "ERROR: Unable to give shared memory. Status %d.", Status ) ; return ( 1 ) ; } /* endif */ // Pass the information to the original process. Sys_PostMessage ( MainWindow, WM_LOAD_FILE, MPFROMP(Memory1), MPFROMP(Memory2) ) ; } /* endif */ // Bring the previous instance to the fore. Sys_SetActiveWindow ( MainWindow ) ; // We're outta here . . . return ( 0 ) ; } /* endif */ /************************************************************************** * If the ISPELL environment variable isn't set, set it to the current * * directory, before we change it. This assumes that the current * * directory is also the directory to which Escriba (and ISPELL) was * * installed. This is true with the basic installation. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: Setting ISPELL environment variable." ) ; #endif // DEBUG { char *p = getenv ( "ISPELL" ) ; if ( p == 0 ) { static char SetString [_MAX_PATH+10] ; sprintf ( SetString, "ISPELL=%s", HomePath ) ; _putenv ( SetString ) ; } /* endif */ } /************************************************************************** * Get application language module. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: Loading default language." ) ; #endif // DEBUG char DefaultLanguage [80] = { 0 } ; { /* startblock */ Profile IniFile ( PSZ(PROGRAM_NAME), 0, HomePath ) ; if ( IniFile.QueryHandle() ) IniFile.GetString ( "Language", DefaultLanguage, sizeof(DefaultLanguage) ) ; else strcpy ( DefaultLanguage, "English" ) ; } /* endblock */ Library = Language_Create ( PROGRAM_NAME, REVISION, IDS_TITLE1, DefaultLanguage ) ; if ( Library == 0 ) { Process Proc ( PROGRAM_NAME, HWND_DESKTOP, 0 ) ; Debug ( HWND_DESKTOP, "ERROR: Unable to find language module for %s, %s, %s.", PROGRAM_NAME, REVISION, DefaultLanguage ) ; return ( 1 ) ; } /* endif */ LibraryHandle = Library->QueryHandle() ; /************************************************************************** * Get the program title. * **************************************************************************/ ResourceString Title ( Library->QueryHandle(), IDS_TITLE ) ; /************************************************************************** * Determine the default codepage. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: Determining codepage to use." ) ; #endif // DEBUG PUSHORT pCodePage = Library->QueryCodepages() ; while ( *pCodePage ) { if ( !DosSetProcessCp ( *pCodePage ) ) break ; pCodePage ++ ; } /* endwhile */ if ( *pCodePage == 0 ) { ResourceString Format ( Library->QueryHandle(), IDS_WARNING_BADCODEPAGE ) ; CHAR Message [200] ; sprintf ( Message, PCHAR(Format), *Library->QueryCodepages() ) ; Log ( "%s", Message ) ; MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message), PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ; return ( 1 ) ; } /* endif */ /************************************************************************** * Initialize the process with an extra-large message queue. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: Connecting to PM." ) ; #endif // DEBUG Process Proc ( PCHAR(Title), HWND_DESKTOP, Library->QueryHandle(), 100, *pCodePage ) ; if ( Proc.QueryAnchor() == 0 ) return ( 1 ) ; /************************************************************************** * Register the custom control classes. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: Registering custom control classes." ) ; #endif // DEBUG RegisterControls ( Proc.QueryAnchor() ) ; /************************************************************************** * Open up debug timer. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: Opening debug timer." ) ; #endif // DEBUG OpenTimer ( ) ; /************************************************************************** * Open the registration library, if it is present. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: About to open registration file." ) ; #endif // DEBUG char *RegistrationName = PROGRAM_NAME"R" ; Module *pRegistration = new Module ( RegistrationName, FALSE ) ; if ( pRegistration->QueryHandle() == 0 ) RegistrationName = "PLUMAR" ; delete pRegistration, pRegistration = 0 ; Module Registration = Module ( RegistrationName, FALSE ) ; /************************************************************************** * Load any extenders (except spell-check). * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: About to load extenders." ) ; #endif // DEBUG AddonList.Build ( DefaultLanguage ) ; /************************************************************************** * Get the country information. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: About to get country information." ) ; #endif // DEBUG GetCountryInfo ( 0, 0 ) ; /************************************************************************** * Set any language-specific globals. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: About to set language-specific globals." ) ; #endif // DEBUG ResourceString AllGraphicFiles ( LibraryHandle, IDS_ALL_GRAPHICS ) ; GraphicTypeList[0] = PSZ ( AllGraphicFiles ) ; /************************************************************************** * Check for command-line options and remove them from the argument list. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: About to parse the command line." ) ; #endif // DEBUG ResourceString ResetCommand ( Library->QueryHandle(), IDS_PARMS_RESET ) ; BOOL Reset = FALSE ; // ResourceString PrintCommand ( Library->QueryHandle(), IDS_PARMS_PRINT ) ; // BOOL Print = FALSE ; ResourceString TrapCommand ( Library->QueryHandle(), IDS_PARMS_TRAP ) ; BOOL Trap = FALSE ; int i = 1 ; char **p = argv + 1 ; while ( i < argc ) { if ( **p == '-' ) { if ( !stricmp ( (*p)+1, PCHAR(ResetCommand) ) ) { Reset = TRUE ; // } else if ( !stricmp ( (*p)+1, PCHAR(PrintCommand) ) ) { // Print = TRUE ; } else if ( !stricmp ( (*p)+1, PCHAR(TrapCommand) ) ) { Trap = TRUE ; } else { Debug ( HWND_DESKTOP, "ERROR: Invalid command-line parameter '%s'.", (*p)+1 ) ; return ( 1 ) ; } /* endif */ for ( int j=i+1; j<argc; j++ ) { argv[j-1] = argv[j] ; } /* endfor */ argv[j] = 0 ; argc -- ; continue ; } /* endif */ i ++ ; p ++ ; } /* endwhile */ /************************************************************************** * Create the help instance. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: About to create the help instance." ) ; #endif // DEBUG _splitpath ( Library->QueryName(), Drive, Dir, Fname, Ext ) ; char HelpFileName [CCHMAXPATH] ; sprintf ( HelpFileName, "%s.hlp", Fname ) ; ResourceString HelpTitle ( Library->QueryHandle(), IDS_HELPTITLE ) ; Help = new HelpWindow ( Proc.QueryAnchor(), 0, ID_MAIN, PSZ(HelpFileName), PSZ(HelpTitle) ) ; if ( Help->QueryHandle() == 0 ) { ERRORID Error = Sys_GetLastError ( Proc.QueryAnchor() ) ; ResourceString Format ( Library->QueryHandle(), IDS_ERROR_CREATEHELP ) ; CHAR Message [200] ; sprintf ( Message, PCHAR(Format), Error ) ; Log ( "%s", Message ) ; MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message), PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ; } /* endif */ /************************************************************************** * Open/create the profile file. Reset if requested. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: About to open profile file." ) ; #endif // DEBUG Profile2 IniFile ( PSZ(PROGRAM_NAME), Proc.QueryAnchor(), Library->QueryHandle(), IDD_PROFILE_PATH, Help, Reset ) ; if ( IniFile.QueryHandle() == 0 ) { ResourceString Message ( Library->QueryHandle(), IDS_ERROR_PRFOPENPROFILE ) ; Log ( "%s", PSZ(Message) ) ; MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message), PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ; CloseTimer() ; return ( 2 ) ; } /* endif */ /************************************************************************** * Get profile data. Try the OS2.INI first, then try for private INI. * * If obtained from OS2.INI, erase it afterwards and resave it. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: About to get profile data." ) ; #endif // DEBUG INIDATA IniData ( Registration.QueryHandle() ) ; IniFile.GetIniData ( IniData ) ; if ( IniData.Language [0] == 0 ) strcpy ( IniData.Language, DefaultLanguage ) ; /************************************************************************** * Activate the spell checker, if it is present. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: About to open the default dictionary." ) ; #endif // DEBUG char SpellerPath [ CCHMAXPATH ] = { 0 } ; if ( getenv ( "ISPELL" ) ) { strcpy ( SpellerPath, getenv ( "ISPELL" ) ) ; strcat ( SpellerPath, "\\" ) ; } /* endif */ strcat ( SpellerPath, "ISPELLER.DLL" ) ; Dictionary *Speller = new Dictionary ( SpellerPath, DefaultLanguage ) ; if ( Speller->QueryLibrary() == 0 ) { #ifdef DEBUG Log ( "Escriba::main: Could not find spellchecker. Will try again through LIBPATH." ) ; #endif // DEBUG delete Speller, Speller = 0 ; Speller = new Dictionary ( "ISPELLER", DefaultLanguage ) ; } /* endif */ if ( Speller->Available() ) { #ifdef DEBUG Log ( "Escriba::main: Adding dictionary object to extension list." ) ; #endif // DEBUG AddonList.Add ( Speller ) ; } else { #ifdef DEBUG Log ( "Escriba::main: Dictionary object could not be fully created." ) ; #endif // DEBUG delete Speller, Speller = 0 ; } /* endif */ /************************************************************************** * Create the frame window. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: About to create the frame window." ) ; #endif // DEBUG FRAMECDATA FrameControlData ; FrameControlData.cb = sizeof(FrameControlData) ; FrameControlData.flCreateFlags = FCF_TITLEBAR | FCF_MENU | FCF_ICON | FCF_NOBYTEALIGN | FCF_ACCELTABLE | FCF_SYSMENU | ( Trap ? 0 : FCF_SIZEBORDER | FCF_MINMAX ) ; FrameControlData.hmodResources = USHORT ( Library->QueryHandle() ) ; FrameControlData.idResources = ID_MAIN ; Window Frame ( HWND_DESKTOP, WC_FRAME, PSZ(Title), IniData.Animate ? WS_ANIMATE : 0, 0, 0, 0, 0, HWND_DESKTOP, HWND_TOP, ID_MAIN, &FrameControlData, NULL ) ; if ( Frame.QueryHandle() == 0 ) { ERRORID Error = Sys_GetLastError ( Proc.QueryAnchor() ) ; ResourceString Format ( Library->QueryHandle(), IDS_ERROR_CREATEFRAME ) ; CHAR Message [200] ; sprintf ( Message, PCHAR(Format), Error ) ; Log ( "%s", Message ) ; MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message), PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ; CloseTimer() ; return ( 3 ) ; } /* endif */ /************************************************************************** * Associate the help instance with the frame window. * **************************************************************************/ Help->Associate ( Frame.QueryHandle() ) ; /************************************************************************** * Register the client window class. * **************************************************************************/ if ( !WinRegisterClass ( Proc.QueryAnchor(), PSZ(CLASS_NAME), MessageProcessor, CS_MOVENOTIFY, sizeof(PVOID) ) ) { ERRORID Error = Sys_GetLastError ( Proc.QueryAnchor() ) ; ResourceString Format ( Library->QueryHandle(), IDS_ERROR_WINREGISTERCLASS ) ; CHAR Message [200] ; sprintf ( Message, PCHAR(Format), CLASS_NAME, Error ) ; Log ( "%s", Message ) ; MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message), PSZ(Title), IDD_ERROR_WINREGISTERCLASS, MB_ENTER | MB_ICONEXCLAMATION | MB_HELP, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ; CloseTimer() ; return ( 4 ) ; } /* endif */ /************************************************************************** * Build the presentation parameters for the main window. * **************************************************************************/ COLOR BackColor = IniData.fMainColors[0] ? IniData.MainColors[0] : WinQuerySysColor ( HWND_DESKTOP, SYSCLR_APPWORKSPACE, 0 ) ; ULONG Ids[] = { PP_BACKGROUNDCOLOR } ; ULONG ByteCounts[] = { sizeof(BackColor) } ; PUCHAR Params[] = { PUCHAR(&BackColor) } ; PPRESPARAMS PresParams = BuildPresParams ( sizeof(Ids)/sizeof(Ids[0]), Ids, ByteCounts, Params ) ; /************************************************************************** * Create client window. If this fails, destroy frame and return. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: About to create the client window." ) ; #endif // DEBUG PARMS Parms ; Parms.Filler = 0 ; Parms.Library = Library ; Parms.Registration = & Registration ; Parms.IniFile = & IniFile ; Parms.IniData = & IniData ; Parms.Speller = Speller ; Parms.InitialPath = InitialPath ; Parms.argc = argc ; Parms.argv = argv ; Parms.Trap = Trap ; Window Client ( Frame.QueryHandle(), PSZ(CLASS_NAME), PSZ(""), WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, 0, 0, Frame.QueryHandle(), HWND_BOTTOM, FID_CLIENT, &Parms, PresParams ) ; free ( PresParams ) ; if ( Client.QueryHandle() == 0 ) { ERRORID Error = Sys_GetLastError ( Proc.QueryAnchor() ) ; ResourceString Format ( Library->QueryHandle(), IDS_ERROR_CREATECLIENT ) ; CHAR Message [200] ; sprintf ( Message, PCHAR(Format), Error ) ; Log ( "%s", Message ) ; MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message), PSZ(Title), IDD_ERROR_CREATECLIENT, MB_ENTER | MB_ICONEXCLAMATION | MB_HELP, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ; CloseTimer ( ) ; return ( 5 ) ; } /* endif */ ((SHARED_MEMORY*)Memory.QueryMemory())->MainWindow = Client.QueryHandle() ; /************************************************************************** * Wait for and process messages to the window's queue. Terminate * * when the WM_QUIT message is received. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: About to enter the main message loop." ) ; #endif // DEBUG Sys_ProcessMessages ( Proc.QueryAnchor() ) ; /************************************************************************** * Discard all that had been requested of the system. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: About to close the HR Timer." ) ; #endif // DEBUG CloseTimer ( ) ; /************************************************************************** * Invoke nearly all the destructors. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: Invoking most destructors." ) ; #endif // DEBUG } /* Invoke all destructors except the global ones. */ /************************************************************************** * Invoke the remaining destructors. * **************************************************************************/ #ifdef DEBUG Log ( "Escriba::main: Clearing the addon list." ) ; #endif // DEBUG AddonList.Clear ( ) ; #ifdef DEBUG Log ( "Escriba::main: Clearing the file type list." ) ; #endif // DEBUG ClearFileTypeList ( ) ; #ifdef DEBUG Log ( "Escriba::main: Clearing the graphic type list." ) ; #endif // DEBUG ClearGraphicTypeList ( ) ; #ifdef DEBUG Log ( "Escriba::main: Destroying the help instance." ) ; #endif // DEBUG if ( Help ) delete Help ; #ifdef DEBUG Log ( "Escriba::main: Destroying the language library instance." ) ; #endif // DEBUG if ( Library ) delete Library ; /************************************************************************** * Check to see if any memory remains allocated. * **************************************************************************/ #ifdef __DEBUG_ALLOC__ Log ( "Escriba::main: Checking the heap." ) ; _dump_allocated ( 64 ) ; Log ( "Escriba::main: Program ended." ) ; fclose ( Logfile ) ; #else #ifdef DEBUG Log ( "Escriba::main: Program ended." ) ; #endif // DEBUG #endif // __DEBUG_ALLOC__ /************************************************************************** * Discard the exception filter. * **************************************************************************/ UNREGISTER_EXCEPTION_HANDLER(0); /************************************************************************** * Terminate the process. * **************************************************************************/ return ( 0 ) ; }
ULONG QueueWrite( PUCHAR name, ULONG argc, PRXSTRING args, PSZ queue, PRXSTRING result) { HQUEUE handle; PQueue q; PCH dataString; ULONG length; PVOID data; ULONG request; ULONG priority; APIRET rc; ULONG cc; if (argc < 2 || argc > 4) return QUEUE_BADPARAM; if (!RxStringToUnsigned(args + 0, &handle)) return QUEUE_BADPARAM; q = (PQueue)handle; if (!RxStringIsValid(args + 1)) return QUEUE_BADPARAM; dataString = args[1].strptr; length = args[1].strlength; if (argc > 2 && RxStringIsPresent(args + 2)) { if (!RxStringToUnsigned(args + 2, &request)) return QUEUE_BADPARAM; } else request = 0; if (argc > 3 && RxStringIsPresent(args + 3)) { if (!RxStringToUnsigned(args + 3, &priority)) return QUEUE_BADPARAM; } else priority = 0; if (q->server == q->client) { data = malloc(length); if (data == NULL) return QUEUE_NOMEM; memcpy(data, dataString, length); rc = NO_ERROR; } else { rc = DosAllocSharedMem( &data, NULL, length, PAG_COMMIT | PAG_WRITE | PAG_READ | OBJ_GIVEABLE); if (rc != NO_ERROR) return QUEUE_NOMEM; memcpy(data, dataString, length); rc = DosGiveSharedMem(data, q->server, PAG_READ | PAG_WRITE); } if (rc == NO_ERROR) { rc = DosWriteQueue(q->handle, request, length, data, priority); if (rc == ERROR_SYS_INTERNAL) rc = NO_ERROR; } if (q->server != q->client) DosFreeMem(data); else if (rc != NO_ERROR) free(data); cc = UnsignedToRxResult(rc, result); return cc; }
int main (int argc, char *argv[]) { HQUEUE hq_server, hq_client; ULONG rc, len; PID owner_pid; PVOID data; REQUESTDATA request; BYTE priority; char buffer[1024], name[512], *p; long client_pid; if (argc == 1) { if (spawnl (P_NOWAIT, argv[0], argv[0], "-r", NULL) < 0) { perror ("spawn"); return (1); } for (;;) { if (fgets (buffer, sizeof (buffer), stdin) == 0) return (0); p = buffer; while (*p != 0 && !(*p >= '0' && *p <= '9')) ++p; client_pid = strtol (p, NULL, 10); (void)sprintf (name, "/queues/emacs/clients/%ld", client_pid); rc = DosOpenQueue (&owner_pid, &hq_client, name); if (rc == 0) { len = strlen (buffer) + 1; rc = DosAllocSharedMem (&data, 0, len, PAG_COMMIT | OBJ_GIVEABLE | PAG_READ | PAG_WRITE); ERROR ("DosAllocSharedMem"); rc = DosGiveSharedMem (data, client_pid, PAG_READ); ERROR ("DosGiveSharedMem"); (void)memcpy (data, buffer, len); rc = DosWriteQueue (hq_client, 0, len, data, 0); ERROR ("DosWriteQueue"); rc = DosFreeMem (data); ERROR ("DosFreeMem"); rc = DosCloseQueue (hq_client); ERROR ("DosCloseQueue"); } } } else if (argc == 2 && strcmp (argv[1], "-r") == 0) { rc = DosCreateQueue (&hq_server, QUE_FIFO | QUE_CONVERT_ADDRESS, "/queues/emacs/server"); ERROR ("DosCreateQueue"); for (;;) { rc = DosReadQueue (hq_server, &request, &len, &data, 0, DCWW_WAIT, &priority, 0); ERROR ("DosReadQueue"); (void)printf ("Client: %d ", (int)request.pid); (void)fputs (data, stdout); (void)fflush (stdout); rc = DosFreeMem (data); ERROR ("DosFreeMem"); } } else { (void)fprintf (stderr, "Usage: %s\n", argv[0]); return (1); } }