Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.220.154.41] |
|
Сообщ.
#1
,
|
|
|
Пишу самодельный эл.управления типа RichTextBox для вывода результатов программы. RichTextBox не устраивает, потому что нужны разделения на страницы и миниатюры страниц как в pdf- или djvu- просмотрщиках.
Появилась задача вставить картинки, кроме текста. Делаю на чистом WinAPI без MFC и др. Само рисование не вызывает вопросов. Проблема в следующем, чтобы выделить и скопировать, а потом вставить текст с картинками в Word, нужно перевести эти текст и картинки в формат RTF. Интересует перевод именно рисунков в RTF. По теме найдено 1) из Delphi Russian Knowledge Base 3, благодоря проделанной работе Vit-a Скрытый текст function BitmapToRTF(pict: TBitmap): string; var bi, bb, rtf: string; bis, bbs: Cardinal; achar: ShortString; hexpict: string; I: Integer; begin GetDIBSizes(pict.Handle, bis, bbs); SetLength(bi, bis); SetLength(bb, bbs); GetDIB(pict.Handle, pict.Palette, PChar(bi)^, PChar(bb)^); rtf := '{\rtf1 {\pict\dibitmap0 '; SetLength(hexpict, (Length(bb) + Length(bi)) * 2); I := 2; for bis := 1 to Length(bi) do begin achar := IntToHex(Integer(bi[bis]), 2); hexpict[I - 1] := achar[1]; hexpict[I] := achar[2]; Inc(I, 2); end; for bbs := 1 to Length(bb) do begin achar := IntToHex(Integer(bb[bbs]), 2); hexpict[I - 1] := achar[1]; hexpict[I] := achar[2]; Inc(I, 2); end; rtf := rtf + hexpict + ' }}'; Result := rtf; end; 2) Нашел по адресу microsoft.public.pocketpc.developer.narkive.com Скрытый текст PBITMAPINFO pbmi = NULL; WORD cClrBits = 1; int nColors = 2; RGBQUAD Colors2[] = { {0x00, 0x00, 0x00, 0x00}, {0xFF, 0xFF, 0xFF, 0x00} }; int nBytesPerLine = ((nWidth * cClrBits + 31)&(~31)) / 8; DWORD dwBitmapInfoSize = sizeof(BITMAPINFOHEADER) + nColors * sizeof (RGBQUAD); DWORD dwFileHeaderSize = dwBitmapInfoSize + sizeof(BITMAPFILEHEADER); HBITMAP hBmp; LPVOID ppvBits; BYTE *lpBits, *lpBuf = new BYTE[dwBitmapInfoSize + 1]; BITMAPINFO* lpbi = (BITMAPINFO*) lpBuf; BITMAPFILEHEADER bmpfhdr; BITMAPINFOHEADER& bih = lpbi->bmiHeader; // Initialize the fields in the BITMAPINFO structure. memset(&bih, 0, sizeof(BITMAPINFOHEADER)); bih.biSize = sizeof(BITMAPINFOHEADER); bih.biWidth = nWidth; bih.biHeight = nHeight; bih.biPlanes = 1; bih.biBitCount = 1; bih.biCompression = BI_RGB; bih.biSizeImage = 0; RGBQUAD* pColors = &Colors2[0]; memcpy(&lpbi->bmiColors[0], &pColors[0], sizeof(RGBQUAD)); memcpy(&lpbi->bmiColors[1], &pColors[1], sizeof(RGBQUAD)); bmpfhdr.bfType = 0x4d42; //'BM' file type bmpfhdr.bfSize = dwFileHeaderSize + (nBytesPerLine * nHeight); bmpfhdr.bfReserved1 = 0; bmpfhdr.bfReserved2 = 0; bmpfhdr.bfOffBits = dwFileHeaderSize; // Then create our DIBSection using the structure manually created from above... HBITMAP hPictureBMP = CreateDIBSection(pictureDC, lpbi, DIB_RGB_COLORS, &ppvBits, NULL, 0); lpBits = (BYTE*)ppvBits; HDC hMemDC = CreateCompatibleDC(pictureDC); hBmp = (HBITMAP) SelectObject(hMemDC, hPictureBMP); BitBlt(hMemDC,0,0,nWidth,nHeight,pictureDC,0,0,SRCCOPY); SelectObject(hMemDC, hBmp); DeleteObject(hPictureBMP); DWORD dwNumBytes; if (ppvBits) { char szBuffer[MAX_BUFFER]; // pichgoal = 1440 / DPI = 1440 / 96 = 15 int rtfHeaderSize = sprintf(szBuffer,"{\\pict\\dibitmap0\ \wbmbitspixel%u\\wbmplanes%u\\wbmwidthbytes%u\\picw%u\\pich%u\\picwgoal %u\\pichgoal%u\\picscalex100\\picscaley100 ", bih.biBitCount, bih.biPlanes, nBytesPerLine, nWidth, nHeight, nWidth*16, nHeight*16); { int offset; for (offset=0; offset < (int)dwBitmapInfoSize; offset++) sprintf(szBuffer+rtfHeaderSize+offset*2,"%02X",lpBuf[offset]); for (offset=0; offset<nBytesPerLine * nHeight; ++offset) sprintf(szBuffer+rtfHeaderSize+(dwBitmapInfoSize+offset) *2,"%02X",lpBits[offset]); } szBuffer[rtfHeaderSize + (dwBitmapInfoSize + nBytesPerLine * nHeight) * 2] = '}'; szBuffer[rtfHeaderSize + (dwBitmapInfoSize + nBytesPerLine * nHeight) * 2 + 1] = 0; // Insert bitmap into document (there is enough rooom!!) memmove(documentSignature + strlen(szBuffer), documentSignature, strlen(documentSignature) + 1); memcpy (documentSignature, szBuffer, strlen(szBuffer)); } delete[] lpBuf; DeleteObject(hBmp); DeleteDC(hMemDC); Этот код взял за основу, переделываю под свою задачу. void ReportPicturesToRTF() { int i; int w, h, ncolors, nbytesperline, rtfheadersize; char buffer[256]; HDC picturedc, hmemdc; HBITMAP hbmp, hpicturebmp; PBITMAPINFO pbmi; LPVOID ppvbits; BITMAPFILEHEADER bmpfhdr; WORD clrbits; DWORD dwbitmapinfosize, dwfileheadersize; BYTE *lpbits, *lpbuf; BITMAPINFO *lpbi; RGBQUAD* pcolors; RGBQUAD colors2[] = { {0x00, 0x00, 0x00, 0x00}, {0xFF, 0xFF, 0xFF, 0x00} }; picturedc = GetDC(e::reporthwnd[3]); // <--- здесь я беру окно со свои рисунком pbmi = NULL; clrbits = 1; ncolors = 2; w = 100; h = 20; nbytesperline = ((w * clrbits + 31) & (~31)) / 8; dwbitmapinfosize = sizeof(BITMAPINFOHEADER) + ncolors * sizeof(RGBQUAD); dwfileheadersize = dwbitmapinfosize + sizeof(BITMAPFILEHEADER); lpbuf = new BYTE[dwbitmapinfosize + 1]; lpbi = (BITMAPINFO*) lpbuf; BITMAPINFOHEADER& bih = lpbi->bmiHeader; memset(&bih, 0, sizeof(BITMAPINFOHEADER)); bih.biSize = sizeof(BITMAPINFOHEADER); bih.biWidth = w; bih.biHeight = h; bih.biPlanes = 1; bih.biBitCount = 1; bih.biCompression = BI_RGB; bih.biSizeImage = 0; pcolors = &colors2[0]; memcpy(&lpbi->bmiColors[0], &pcolors[0], sizeof(RGBQUAD)); memcpy(&lpbi->bmiColors[1], &pcolors[1], sizeof(RGBQUAD)); bmpfhdr.bfType = 0x4d42; bmpfhdr.bfSize = dwfileheadersize + (nbytesperline * h); bmpfhdr.bfReserved1 = 0; bmpfhdr.bfReserved2 = 0; bmpfhdr.bfOffBits = dwfileheadersize; hpicturebmp = CreateDIBSection(picturedc, lpbi, DIB_RGB_COLORS, &ppvbits, NULL, 0); lpbits = (BYTE*)ppvbits; hmemdc = CreateCompatibleDC(picturedc); hbmp = (HBITMAP) SelectObject(hmemdc, hpicturebmp); BitBlt(hmemdc, 0, 0, w, h, picturedc, 0, 0, SRCCOPY); SelectObject(hmemdc, hbmp); if (ppvbits) { rtfheadersize = sprintf(buffer,"{\\pict\\dibitmap0\\wbmbitspixel%u\\wbmplanes%u\\wbmwidthbytes%u\\picw%u\\pich%u\\picwgoal%u\\pichgoal%u\\picscalex100\\picscaley100 ", bih.biBitCount,bih.biPlanes, nbytesperline, w, h, w*16, h*16); { for (i=0; i<((int)dwbitmapinfosize); i++) { sprintf(buffer + rtfheadersize+i * 2, "%02X", lpbuf[i]); } for (i=0; i<(nbytesperline*h); ++i) { sprintf(buffer + rtfheadersize + (dwbitmapinfosize + i) * 2, "%02X", lpbits[i]); } } buffer[rtfheadersize + (dwbitmapinfosize + nbytesperline * h) * 2] = '}'; buffer[rtfheadersize + (dwbitmapinfosize + nbytesperline * h) * 2 + 1] = 0; // Insert bitmap into document (there is enough rooom!!) //memmove(documentSignature + strlen(buffer), documentSignature, strlen(documentSignature) + 1); //memcpy (documentSignature, buffer, strlen(buffer)); } delete[] lpbuf; DeleteObject(hpicturebmp); DeleteObject(hbmp); DeleteDC(hmemdc); } Вопросы: 1. Здесь, как я понял, для 2-х цветных (черно-белых) BMP. А как быть с большим количеством цветности ? Хотелось бы как минимум 256. 2. Есть ли уже готовые решения для такой задачи ? |
Сообщ.
#2
,
|
|
|
Сообщ.
#3
,
|
|
|
Цитата B.V. @ Не подобное ли ты ищешь? Не похоже, Там судя по названиям OLE технология используется. И нигде в HEX-значения перевода нет А мне нужно 1) мой hDC перегнать в HBITMAP 2) из HBITMAP выудить всю эту информацию (заголовки, размеры, цвета) 3) с учетом этой информации записать в СТРОКУ область данных рисунка HEX-значения 4) Потом эту СТРОКУ можно будет скопировать в буфер обмена. Застрял на изучении формата BMP (такая муть!) Сейчас сочиняю на Си функцию из VCL которая там имеет название GetDIBSizes()... PS думал за день справлюсь - ошибался )) |
Сообщ.
#4
,
|
|
|
B.V.Спасибо за наводку на сайт, www.codeproject.com
Я про него как-то забыл )) надо там внимательнее поискать. |