/* * IupScintilla component * * Description : A source code editing component, * derived from Scintilla (http://www.scintilla.org/) */ #include #include #include #include #include "Scintilla.h" #include "SciLexer.h" #include #include "iup.h" #include "iup_scintilla.h" #include "iupcbs.h" #include "iup_key.h" #include "iup_class.h" #include "iup_object.h" #include "iup_attrib.h" #include "iup_str.h" #include "iup_drv.h" #include "iup_drvfont.h" #include "iup_register.h" #include "iup_layout.h" #include "iup_assert.h" #include "iupwin_drv.h" #include "iupwin_str.h" #include "iupsci.h" #define WM_IUPCARET WM_APP+1 /* Custom IUP message */ void iupdrvScintillaRefreshCaret(Ihandle* ih) { PostMessage(ih->handle, WM_IUPCARET, 0, 0L); } int iupdrvScintillaGetBorder(void) { int border_size = 2 * 3; return border_size; } void iupdrvScintillaOpen(void) { Scintilla_RegisterClasses(IupGetGlobal("HINSTANCE")); } sptr_t IupScintillaSendMessage(Ihandle* ih, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return SendMessage(ih->handle, iMessage, wParam, lParam); } static int winScintillaWmNotify(Ihandle* ih, NMHDR* msg_info, int *result) { SCNotification *pMsg = (SCNotification*)msg_info; iupScintillaNotify(ih, pMsg); (void)result; return 0; /* result not used */ } static int winScintillaMsgProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result) { if (msg==WM_KEYDOWN) /* process K_ANY before text callbacks */ { int ret = iupwinBaseMsgProc(ih, msg, wp, lp, result); if (ret) { if (iupObjectCheck(ih)) iupAttribSet(ih, "_IUPWIN_IGNORE_CHAR", "1"); *result = 0; return 1; } else { if (iupObjectCheck(ih)) iupAttribSet(ih, "_IUPWIN_IGNORE_CHAR", NULL); } } switch (msg) { case WM_CHAR: { /* even aborting WM_KEYDOWN, a WM_CHAR will be sent, so ignore it also */ /* if a dialog was shown, the loop will be processed, so ignore out of focus WM_CHAR messages */ if (GetFocus() != ih->handle || iupAttribGet(ih, "_IUPWIN_IGNORE_CHAR")) { iupAttribSet(ih, "_IUPWIN_IGNORE_CHAR", NULL); *result = 0; return 1; } break; } case WM_KEYDOWN: { PostMessage(ih->handle, WM_IUPCARET, 0, 0L); return 0; /* already processed at the beginning of this function */ } case WM_KEYUP: { PostMessage(ih->handle, WM_IUPCARET, 0, 0L); break; } case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK: case WM_LBUTTONDOWN: case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: { iupwinFlagButtonDown(ih, msg); if (iupwinButtonDown(ih, msg, wp, lp)==-1) { *result = 0; return 1; } PostMessage(ih->handle, WM_IUPCARET, 0, 0L); break; } case WM_MBUTTONUP: case WM_RBUTTONUP: case WM_LBUTTONUP: { if (!iupwinFlagButtonUp(ih, msg)) { *result = 0; return 1; } if (iupwinButtonUp(ih, msg, wp, lp)==-1) { *result = 0; return 1; } PostMessage(ih->handle, WM_IUPCARET, 0, 0L); break; } case WM_IUPCARET: { iupScintillaCallCaretCb(ih); break; } case WM_MOUSEMOVE: { iupwinMouseMove(ih, msg, wp, lp); break; } } return iupwinBaseMsgProc(ih, msg, wp, lp, result); } int iupdrvScintillaPrintAttrib(Ihandle* ih, const char* value) { PRINTDLG pdlg; DOCINFO di; int startPos = 0, endPos = 0; HDC hdc; struct Sci_RangeToFormat frPrint; int margin_left, margin_top, margin_right, margin_bottom, margin_units, page_width, page_height; int p, printPage; double dpi; LONG lengthDoc, lengthDocMax, lengthPrinted; ZeroMemory(&pdlg, sizeof(PRINTDLG)); pdlg.lStructSize = sizeof(PRINTDLG); pdlg.hwndOwner = IupGetDialog(ih)->handle; pdlg.hInstance = (HINSTANCE)IupGetGlobal("HINSTANCE"); pdlg.Flags = PD_USEDEVMODECOPIES | PD_ALLPAGES | PD_RETURNDC; pdlg.nCopies = 1; pdlg.nFromPage = 1; pdlg.nToPage = 1; pdlg.nMinPage = 1; pdlg.nMaxPage = 0xffffU; /* We do not know how many pages in the */ /* document until the printer is selected and the paper size is known. */ /* See if a range has been selected */ IupGetIntInt(ih, "SELECTIONPOS", &startPos, &endPos); if (startPos == endPos) pdlg.Flags |= PD_NOSELECTION; else pdlg.Flags |= PD_SELECTION; if (!iupAttribGetBoolean(ih, "PRINTDIALOG")) { /* Don't display dialog box, just use the default printer and options */ pdlg.Flags |= PD_RETURNDEFAULT; } if (!PrintDlg(&pdlg)) { if (pdlg.hDevMode) GlobalFree(pdlg.hDevMode); if (pdlg.hDevNames) GlobalFree(pdlg.hDevNames); return 0; } hdc = pdlg.hDC; page_width = GetDeviceCaps(hdc, HORZRES); /* physically printable pixels */ page_height = GetDeviceCaps(hdc, VERTRES); dpi = (double)GetDeviceCaps(hdc, LOGPIXELSY); di.cbSize = sizeof(DOCINFO); di.lpszDocName = iupwinStrToSystem(value); di.lpszOutput = 0; di.lpszDatatype = 0; di.fwType = 0; if (StartDoc(hdc, &di) < 0) { DeleteDC(hdc); /* Use DeleteDC for printer */ if (pdlg.hDevMode) GlobalFree(pdlg.hDevMode); if (pdlg.hDevNames) GlobalFree(pdlg.hDevNames); return 0; } lengthDoc = (LONG)IupScintillaSendMessage(ih, SCI_GETLENGTH, 0, 0); lengthDocMax = lengthDoc; lengthPrinted = 0; /* Requested to print selection */ if (pdlg.Flags & PD_SELECTION) { if (startPos > endPos) { lengthPrinted = endPos; lengthDoc = startPos; } else { lengthPrinted = startPos; lengthDoc = endPos; } if (lengthPrinted < 0) lengthPrinted = 0; if (lengthDoc > lengthDocMax) lengthDoc = lengthDocMax; } margin_units = iupSciGetPrintMarginUnits(ih); margin_left = iupSciGetPrintMargin(ih, "PRINTMARGINLEFT", margin_units, dpi); margin_top = iupSciGetPrintMargin(ih, "PRINTMARGINTOP", margin_units, dpi); margin_right = iupSciGetPrintMargin(ih, "PRINTMARGINRIGHT", margin_units, dpi); margin_bottom = iupSciGetPrintMargin(ih, "PRINTMARGINBOTTOM", margin_units, dpi); frPrint.hdc = hdc; frPrint.hdcTarget = hdc; frPrint.rc.left = margin_left; frPrint.rc.top = margin_top; frPrint.rc.right = page_width - margin_right; frPrint.rc.bottom = page_height - margin_bottom; frPrint.rcPage.left = 0; frPrint.rcPage.top = 0; frPrint.rcPage.right = page_width; frPrint.rcPage.bottom = page_height; /* Print each page */ p = 1; /* starts at 1 to match page selection */ while (lengthPrinted < lengthDoc) { printPage = (!(pdlg.Flags & PD_PAGENUMS) || ((p >= pdlg.nFromPage) && (p <= pdlg.nToPage))); if (printPage) StartPage(hdc); frPrint.chrg.cpMin = lengthPrinted; frPrint.chrg.cpMax = lengthDoc; lengthPrinted = (LONG)IupScintillaSendMessage(ih, SCI_FORMATRANGE, printPage, (sptr_t)&frPrint); p++; if (printPage) EndPage(hdc); if ((pdlg.Flags & PD_PAGENUMS) && (p > pdlg.nToPage)) break; } IupScintillaSendMessage(ih, SCI_FORMATRANGE, FALSE, 0); EndDoc(hdc); DeleteDC(hdc); /* Use DeleteDC for printer */ if (pdlg.hDevMode) GlobalFree(pdlg.hDevMode); if (pdlg.hDevNames) GlobalFree(pdlg.hDevNames); return 0; } /*****************************************************************************/ int idrvScintillaMap(Ihandle* ih) { DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS; DWORD dwExStyle = 0; if (!ih->parent) return IUP_ERROR; if (iupAttribGetBoolean(ih, "CANFOCUS")) dwStyle |= WS_TABSTOP; if (iupAttribGetBoolean(ih, "BORDER")) dwExStyle |= WS_EX_CLIENTEDGE; if (!iupwinCreateWindow(ih, TEXT("Scintilla"), dwExStyle, dwStyle, NULL)) return IUP_ERROR; /* Process Scintilla Notifications */ IupSetCallback(ih, "_IUPWIN_NOTIFY_CB", (Icallback)winScintillaWmNotify); /* Process BUTTON_CB, MOTION_CB and CARET_CB */ IupSetCallback(ih, "_IUPWIN_CTRLMSGPROC_CB", (Icallback)winScintillaMsgProc); return IUP_NOERROR; } void iupdrvScintillaReleaseMethod(Iclass* ic) { (void)ic; Scintilla_ReleaseResources(); }