/****************************************************************************** * * * RichEdit example program. Demonstrates some basics of a RichEdit control. * * Allows you to change the text color on the fly, save and load RTF data * * using stream callbacks. * * * ******************************************************************************/ #define WIN32_LEAN_AND_MEAN #include "windows.h" #include "commdlg.h" #include "richedit.h" // === Function Prototypes ==================================================== BOOL WINAPI MainDlgProc( HWND, UINT, WPARAM, LPARAM ); BOOL SaveEditAsStream( HWND ); DWORD CALLBACK RTFSaveStreamCallback( DWORD, LPBYTE, LONG, LONG * ); BOOL LoadEditAsStream( HWND ); DWORD CALLBACK RTFLoadStreamCallback( DWORD, LPBYTE, LONG, LONG * ); BOOL GetNewTextColor( HWND ); // === Global Variables ======================================================= HINSTANCE hInst; // Program instance handle HANDLE hRichEdit; // RICHED32.DLL handle DWORD dwTextColor; // Current text color // === Program Entry Points =================================================== int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmd, int nShow ) { hInst = hInstance; // Save program instance in global hRichEdit = LoadLibrary( "RICHED32.DLL" ); // Load Rich Edit control if( ! hRichEdit ) { // If Rich Edit DLL load fails, exit MessageBox( NULL, "Unable to load the Rich Edit control!", "RETest", MB_OK | MB_ICONEXCLAMATION ); return( FALSE ); } // Call main dialog box DialogBox( hInst, MAKEINTRESOURCE( 10000 ), NULL, MainDlgProc ); FreeLibrary( hRichEdit ); // Release Rich Edit DLL before leaving return( FALSE ); } // === Main Dialog Proc ======================================================= BOOL WINAPI MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_INITDIALOG: { CHARFORMAT cf; if( GetDlgItem( hDlg, 100 ) ) // Sanity Check { dwTextColor = 0x0000FF00; memset( &cf, 0, sizeof(CHARFORMAT) ); // Initialize structure cf.cbSize = sizeof(CHARFORMAT); // Initialize RichEdit cf.dwMask = CFM_COLOR | CFM_FACE | CFM_SIZE; // control structure cf.crTextColor = dwTextColor; cf.yHeight = 32; strcpy( cf.szFaceName, "Courier" ); // Set character formatting and background color SendDlgItemMessage( hDlg, 100, EM_SETCHARFORMAT, 4, (LPARAM)&cf ); SendDlgItemMessage( hDlg, 100, EM_SETBKGNDCOLOR, FALSE, 0 ); } return( TRUE ); // End of dialog initialization code } case WM_COMMAND: if( wParam == 101 ) // "Color" button pressed { GetNewTextColor( hDlg ); // Get new color for text SetFocus( GetDlgItem( hDlg, 100 ) ); // Back to edit control break; } if( wParam == 102 ) // "Save" button pressed { SaveEditAsStream( hDlg ); // Save rich edit contents to file SetFocus( GetDlgItem( hDlg, 100 ) ); // Back to edit control break; } if( wParam == 103 ) // "Load" button pressed { LoadEditAsStream( hDlg ); // Load RTF file into richedit SetFocus( GetDlgItem( hDlg, 100 ) ); // Back to edit control break; } if( wParam == IDCANCEL ) // Close dialog if Esc pressed { EndDialog( hDlg, TRUE ); return( TRUE ); } break; } return( FALSE ); } // End of MainDlgProc // === Read RTF Data as a Rich Edit stream ==================================== BOOL SaveEditAsStream( HWND hDlg ) { EDITSTREAM es; LONG lOut; OPENFILENAME ofn; HANDLE hFile; char szFilename[ 256 ]; memset( &ofn, 0, sizeof(OPENFILENAME) ); // Initialize structure strcpy( szFilename, "*.rtf" ); // Initialize filename field ofn.lStructSize = sizeof(OPENFILENAME); // Fill in OPENFILENAME struct ofn.hwndOwner = hDlg; ofn.lpstrFilter = "RTF File\0*.rtf\0All Files\0*.*\0\0"; ofn.lpstrFile = szFilename; ofn.nMaxFile = 256; ofn.lpstrTitle = "Save RTF File"; ofn.Flags = OFN_OVERWRITEPROMPT; if( ! GetSaveFileName( &ofn ) ) // Get a filename or quit return( FALSE ); // Create the specified file hFile = CreateFile( szFilename, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if( hFile == INVALID_HANDLE_VALUE ) return( FALSE ); // Quit if file creation fails es.dwCookie = (DWORD)hFile; // Pass file handle to callback es.dwError = 0; // so the callback can do the file write es.pfnCallback = (EDITSTREAMCALLBACK)RTFSaveStreamCallback; // Start the callback proc lOut = SendDlgItemMessage( hDlg, 100, EM_STREAMOUT, SF_RTF, (LPARAM)&es ); CloseHandle( hFile ); // Close file handle and exit return( TRUE ); } // End of SaveEditAsStream // === RichEdit RTF Output Stream Handler ===================================== DWORD CALLBACK RTFSaveStreamCallback( DWORD dwCookie, LPBYTE lpBuffer, LONG lSize, LONG *plRead ) { if( ! lSize ) // Sanity check...exit if nothing passed return( 1 ); *plRead = 0; // Initialize "amount read" variable for WriteFile() // dwCookie is the file handle WriteFile( (HANDLE)dwCookie, lpBuffer, lSize, plRead, NULL ); return( 0 ); // Continue, if needed } // === Load RTF File into Rich Edit Control =================================== BOOL LoadEditAsStream( HWND hDlg ) { EDITSTREAM es; LONG lOut; OPENFILENAME ofn; HANDLE hFile; char szFilename[ 256 ]; memset( &ofn, 0, sizeof(OPENFILENAME) ); // Initialize OPENFILENAME struct strcpy( szFilename, "*.rtf" ); // Initialize filename field ofn.lStructSize = sizeof(OPENFILENAME); // Fill in structure ofn.hwndOwner = hDlg; ofn.lpstrFilter = "RTF File\0*.rtf\0All Files\0*.*\0\0"; ofn.lpstrFile = szFilename; ofn.nMaxFile = 256; ofn.lpstrTitle = "Open RTF File"; ofn.Flags = OFN_FILEMUSTEXIST; if( ! GetOpenFileName( &ofn ) ) // Get file name or exit return( FALSE ); // Attempt to open specified file hFile = CreateFile( szFilename, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if( hFile == INVALID_HANDLE_VALUE ) return( FALSE ); // Exit if open fails es.dwCookie = (DWORD)hFile; // Pass file handle to callback es.dwError = 0; es.pfnCallback = (EDITSTREAMCALLBACK)RTFLoadStreamCallback; // Start the callback proc lOut = SendDlgItemMessage( hDlg, 100, EM_STREAMIN, SF_RTF, (LPARAM)&es ); CloseHandle( hFile ); // Close file handle before leaving return( TRUE ); } // === RichEdit RTF Input Stream Handler ====================================== DWORD CALLBACK RTFLoadStreamCallback( DWORD dwCookie, LPBYTE lpBuffer, LONG lSize, LONG *plRead ) { if( ! lSize ) // Sanity check...exit if nothing passed return( 1 ); *plRead = 0; // Initialize amount read variable // dwCookie is the file handle ReadFile( (HANDLE)dwCookie, lpBuffer, lSize, plRead, NULL ); return( 0 ); } // === Specify New Text Color ================================================= BOOL GetNewTextColor( HWND hDlg ) { CHOOSECOLOR cc; CHARFORMAT cf; DWORD dwColors[ 16 ]; memset( &cc, 0, sizeof(CHOOSECOLOR) ); cc.lStructSize = sizeof(CHOOSECOLOR); cc.hwndOwner = hDlg; cc.lpCustColors = dwColors; cc.Flags = CC_RGBINIT; cc.rgbResult = dwTextColor; if( ! ChooseColor( &cc ) ) return( FALSE ); dwTextColor = cc.rgbResult; memset( &cf, 0, sizeof(CHARFORMAT) ); cf.cbSize = sizeof(CHARFORMAT); cf.dwMask = CFM_COLOR; cf.crTextColor = dwTextColor; SendDlgItemMessage( hDlg, 100, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf ); return( TRUE ); } // ============================================================================ .