This is a simple skeleton of a windows rich text editor as published by german computer magazine c't in 1996. It's also demonstrates how to implement resources.
The remarks are in german language.
Para Complementar el Post de kingboyD (Complement the kingboyD Contribution).
// To create an RichEdit Window.
HWND RTF_New( HWND hwnd, int tid, int x, int y, int w, int h)
{
return CreateWindow(RICHEDIT_CLASSA, "", ES_MULTILINE|WS_BORDER|WS_TABSTOP|WS_CHILD|WS_VISIBLE, x, y, w, h, hwnd, (HMENU)tid, (HINSTANCE) GetWindowLong( hwnd, GWL_HINSTANCE), 0);
}
// To Save RTF Content to an file.
DWORD CALLBACK RTF_SaveCallback(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, PLONG pcb)
{
HANDLE hFile = (HANDLE)dwCookie;
if (WriteFile(hFile, lpBuff, cb, (DWORD *)pcb, NULL)) return 0;
return -1;
}
BOOL RTF_Save(HWND hwnd, LPCTSTR pszFile)
{
BOOL fSuccess = FALSE;
HANDLE hFile = CreateFile(pszFile, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
EDITSTREAM es = { 0 };
es.pfnCallback = RTF_SaveCallback;
es.dwCookie = (DWORD_PTR)hFile;
if (SendMessage(hwnd, EM_STREAMOUT, SF_RTF, (LPARAM)&es) && es.dwError == 0) fSuccess = TRUE;
CloseHandle(hFile);
}
return fSuccess;
}
// To Read RTF Content from a File
DWORD CALLBACK RTF_ReadCallback(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, PLONG pcb)
{
HANDLE hFile = (HANDLE)dwCookie;
if (ReadFile(hFile, lpBuff, cb, (DWORD *)pcb, NULL)) {
return 0;
}
return -1;
}
BOOL RTF_Read(HWND hwnd, LPCTSTR pszFile)
{
BOOL fSuccess = FALSE;
HANDLE hFile = CreateFile(pszFile, GENERIC_READ,
FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
EDITSTREAM es = { 0 };
es.pfnCallback = RTF_ReadCallback;
es.dwCookie = (DWORD_PTR)hFile;
if (SendMessage(hwnd, EM_STREAMIN, SF_RTF, (LPARAM)&es) && es.dwError == 0) fSuccess = TRUE;
CloseHandle(hFile);
}
return fSuccess;
}
// PRINT RTF Content
// hPrinterDC must filled with PrintDlg( LPPRINTDLG ) with the PD_COLLATE | PD_RETURNDC Flags
void RTF_Print(HWND hwnd, HDC hPrinterDC, LPSTR szFileName, int lnmargin )
{ PRINTDLG pd;
FORMATRANGE fr;
if (hPrinterDC== NULL) return;
int nHorizRes = GetDeviceCaps(hPrinterDC, HORZRES),
nVertRes = GetDeviceCaps(hPrinterDC, VERTRES),
nLogPixelsX = GetDeviceCaps(hPrinterDC, LOGPIXELSX),
nLogPixelsY = GetDeviceCaps(hPrinterDC, LOGPIXELSY);
LONG lTextLength, lTextPrinted=0, ut = 0; // Amount of document printed.
int lnmg = lrint( lnmargin * (254.0 / 1440.0) );
DOCINFO di;
SetMapMode ( hPrinterDC, MM_TEXT );
ZeroMemory(&fr, sizeof(fr));
fr.hdc = fr.hdcTarget = hPrinterDC;
// Set up the page.
fr.rcPage.left = fr.rcPage.top = 0;
fr.rcPage.right = (nHorizRes/nLogPixelsX) * 1440;
fr.rcPage.bottom = (nVertRes/nLogPixelsY) * 1440;
// Set up 1" margins all around.
fr.rc.left = fr.rcPage.left + lnmg; // 1440 TWIPS = 1 inch.
fr.rc.top = fr.rcPage.top + lnmg;
fr.rc.right = fr.rcPage.right - lnmg;
fr.rc.bottom = fr.rcPage.bottom - lnmg;
// Default the range of text to print as the entire document.
// Set up the print job (standard printing stuff here).
ZeroMemory(&di, sizeof(di));
di.cbSize = sizeof(DOCINFO);
if (*szFileName) di.lpszDocName = szFileName;
else di.lpszDocName = "Lucindo"; //di.lpszOutput = NULL;
StartDoc(hPrinterDC, &di);
// Find out real size of document in characters.
SendMessage(hwnd, EM_SETSEL, 0, (LPARAM)-1);
// Get the selection into a CHARRANGE.
SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&fr.chrg);
while (fr.chrg.cpMin < fr.chrg.cpMax) {
StartPage(hPrinterDC) > 0;
int cpMin = SendMessage(hwnd, EM_FORMATRANGE, TRUE, (LPARAM)&fr);
if (cpMin <= fr.chrg.cpMin) break;
fr.chrg.cpMin = cpMin;
EndPage(hPrinterDC);
}
SendMessage(hwnd, EM_FORMATRANGE, FALSE, 0);
EndDoc (hPrinterDC);
}