#include "stdafx.h" #include "ScintillaEditCtrl.h" const TCHAR WC_SCINTILLA[] = _T("Scintilla"); const TCHAR CScintillaEditCtrl::SCINTILLADLLNAME[] = _T("scintilla.dll"); const CScintillaEditCtrl::HMARKER CScintillaEditCtrl::INVALIDHMARKER = -1; const char CScintillaEditCtrl::PIXMAP_FIRSTOPAQUEENTRY = '\"'+1; const char CScintillaEditCtrl::PIXMAP_TRANSPARENTENTRY = 32; const COLORREF CScintillaEditCtrl::CREF_NONE = 0x01000000; const COLORREF CScintillaEditCtrl::CREF_TOPLEFTPIXEL = 0x01000001; BOOL AfxInitScintilla(void) { // Load the DLL HMODULE hmod = LoadLibrary(CScintillaEditCtrl::SCINTILLADLLNAME); ASSERT(hmod != NULL); return (hmod != NULL); } ///////////////////////////////////////////////////////////////////////////// // CScintillaEditCtrl void CScintillaEditCtrl::ConvertPaletteToPixmap(CString& strPalette, CPalette* pPalette) { strPalette.Format("\"%c c None\",\n", PIXMAP_TRANSPARENTENTRY); for (int i = 0; i< pPalette->GetEntryCount(); i++) { CString strTemp; PALETTEENTRY palentry; pPalette->GetPaletteEntries(i,1,&palentry); // Some pixmaps I've found, have 16 bits per channel, so the format // mask for each channel should be %02x00 instead of just %02x, // but Scintilla doesn't support those (Irfanview does, though) strTemp.Format("\"%c c #%02x%02x%02x\",\n", PIXMAP_FIRSTOPAQUEENTRY+i, palentry.peRed, palentry.peGreen, palentry.peBlue ); strPalette += strTemp; } } void CScintillaEditCtrl::ConvertPixelsToPixmap(CString& strPixels, CSize& sizPixels, CDC& dcColor, CPalette* pPalette, const CDC& dcMask, COLORREF crefTransparent) { int nWidth = sizPixels.cx; int nHeight = sizPixels.cy; // Check if the transparent color has to come from the topleft pixel if (crefTransparent == CREF_TOPLEFTPIXEL) { ASSERT(dcMask.m_hDC == NULL); crefTransparent = dcColor.GetPixel(0,0); } // Image dump strPixels = ""; for (int y = 0; yGetNearestPaletteIndex(crefColor) + PIXMAP_FIRSTOPAQUEENTRY; } str.Format("%c",cColor); strPixels += str; } strPixels += "\",\n"; } // There's an extra "," at the end, but it doesn't really matter. } void CScintillaEditCtrl::ConvertToPixmap(CString& strPixmap, HBITMAP hbmColor, HBITMAP hbmMask, COLORREF crefTransparent) { ASSERT(hbmColor != NULL); CDC* pDC = GetDC(); // Ideally we would like to use DrawIcon on a memory HDC and // use GetPixel to obtain the values, but for some reason DrawIcon on HICONs // extracted from IMAGELISTs only renders the top left quarter of the icon // at x2 size. So instead, we attach the mask and the color HBITMAPs to memory HDCs // and calculate the masking ourselves. CBitmap bmpMask; CDC dcMask; CBitmap* pbmpOldMask; if (hbmMask != NULL) { // If the mask bitmap is valid, attach the bitmap to a memory DC bmpMask.Attach(hbmMask); dcMask.CreateCompatibleDC(pDC); pbmpOldMask = dcMask.SelectObject(&bmpMask); } CBitmap bmpColor; CBitmap* pbmpOldColor; CDC dcColor; // Attach the color bitmap to a memory DC bmpColor.Attach(hbmColor); dcColor.CreateCompatibleDC(pDC); pbmpOldColor = dcColor.SelectObject(&bmpColor); // Get the color bitmap palette CPalette* pPalette = dcColor.GetCurrentPalette(); // Get the color bitmap extents BITMAP bmpinfo; bmpColor.GetBitmap(&bmpinfo); // Header dump CString strHeader; strHeader.Format( "/* XPM */\n" "static char * icon [] = {\n" "\"%d %d %d %d\",\n", bmpinfo.bmWidth, bmpinfo.bmHeight, pPalette->GetEntryCount()+1, 1 ); // Get the palette text CString strPalette; ConvertPaletteToPixmap(strPalette, pPalette); // Get the pixel data text CString strPixels; ConvertPixelsToPixmap(strPixels, CSize(bmpinfo.bmWidth, bmpinfo.bmHeight), dcColor, pPalette, dcMask, crefTransparent); // Finish the pixmap strPixels += "}"; // Release resources if (hbmMask != NULL) { dcMask.SelectObject(pbmpOldMask); bmpMask.Detach(); } dcColor.SelectObject(pbmpOldColor); bmpColor.Detach(); ReleaseDC(pDC); strPixmap = strHeader + strPalette + strPixels; } IMPLEMENT_DYNCREATE(CScintillaEditCtrl, CWnd) BEGIN_MESSAGE_MAP(CScintillaEditCtrl, CWnd) //{{AFX_MSG_MAP(CScintillaEditCtrl) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CScintillaEditCtrl message handlers