static uiMenuItem *newItem(uiMenu *m, int type, const char *name) { uiMenuItem *item; if (menusFinalized) userbug("You can not create a new menu item after menus have been finalized."); if (m->len >= m->cap) { m->cap += grow; m->items = (uiMenuItem **) uiRealloc(m->items, m->cap * sizeof (uiMenuItem *), "uiMenuitem *[]"); } item = uiNew(uiMenuItem); m->items[m->len] = item; m->len++; item->type = type; switch (item->type) { case typeQuit: item->name = toUTF16("Quit"); break; case typePreferences: item->name = toUTF16("Preferences..."); break; case typeAbout: item->name = toUTF16("About"); break; case typeSeparator: break; default: item->name = toUTF16(name); break; } if (item->type != typeSeparator) { item->id = curID; curID++; } if (item->type == typeQuit) { // can't call uiMenuItemOnClicked() here item->onClicked = onQuitClicked; item->onClickedData = NULL; } else uiMenuItemOnClicked(item, defaultOnClicked, NULL); return item; }
static void msgbox(HWND parent, const char *title, const char *description, TASKDIALOG_COMMON_BUTTON_FLAGS buttons, PCWSTR icon) { WCHAR *wtitle, *wdescription; HRESULT hr; wtitle = toUTF16(title); wdescription = toUTF16(description); hr = TaskDialog(parent, NULL, NULL, wtitle, wdescription, buttons, icon, NULL); if (hr != S_OK) logHRESULT(L"error showing task dialog", hr); uiFree(wdescription); uiFree(wtitle); }
static const char *initerr(const char *message, const WCHAR *label, DWORD value) { WCHAR *sysmsg; BOOL hassysmsg; WCHAR *beforele; WCHAR *afterle; int n; WCHAR *wmessage; WCHAR *wstr; const char *str; if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, value, 0, (LPWSTR) (&sysmsg), 0, NULL) != 0) { hassysmsg = TRUE; beforele = L" ("; afterle = L")"; } else { hassysmsg = FALSE; sysmsg = L""; beforele = L""; afterle = L""; } wmessage = toUTF16(message); n = _scwprintf(initErrorFormat, initErrorArgs); wstr = (WCHAR *) uiAlloc((n + 1) * sizeof (WCHAR), "WCHAR[]"); snwprintf(wstr, n + 1, initErrorFormat, initErrorArgs); str = toUTF8(wstr); uiFree(wstr); if (hassysmsg) if (LocalFree(sysmsg) != NULL) logLastError("error freeing system message in loadLastError()"); uiFree(wmessage); return str; }
// the returned pointer is actually to the second character // if the first character is - then free, otherwise don't static const char *initerr(const char *message, const WCHAR *label, DWORD value) { WCHAR *sysmsg; BOOL hassysmsg; WCHAR *wmessage; WCHAR *wout; char *out; hassysmsg = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, value, 0, (LPWSTR) (&sysmsg), 0, NULL) != 0; if (!hassysmsg) sysmsg = L""; wmessage = toUTF16(message + 1); wout = debugstrf(L"-error initializing libui: %s; code %I32d (0x%08I32X) %s", wmessage, value, value, sysmsg); uiFree(wmessage); if (hassysmsg) LocalFree(sysmsg); // ignore error if (wout == NULL) // debugstrf() failed; return message raw return message + 1; out = toUTF8(wout); uiFree(wout); return out + 1; }
void uiRadioButtonsAppend(uiRadioButtons *r, const char *text) { HWND hwnd; WCHAR *wtext; DWORD groupTabStop; // the first radio button gets both WS_GROUP and WS_TABSTOP // successive radio buttons get *neither* groupTabStop = 0; if (r->hwnds->size() == 0) groupTabStop = WS_GROUP | WS_TABSTOP; wtext = toUTF16(text); hwnd = uiWindowsEnsureCreateControlHWND(0, L"button", wtext, BS_RADIOBUTTON | groupTabStop, hInstance, NULL, TRUE); uiFree(wtext); uiWindowsEnsureSetParentHWND(hwnd, r->hwnd); uiWindowsRegisterWM_COMMANDHandler(hwnd, onWM_COMMAND, uiControl(r)); r->hwnds->push_back(hwnd); radiobuttonsArrangeChildren(r); uiWindowsControlMinimumSizeChanged(uiWindowsControl(r)); }
void uiWindowsSetWindowText(HWND hwnd, const char *text) { WCHAR *wtext; wtext = toUTF16(text); setWindowText(hwnd, wtext); uiFree(wtext); }
static void msgbox(const char *title, const char *description, TASKDIALOG_COMMON_BUTTON_FLAGS buttons, PCWSTR icon) { WCHAR *wtitle, *wdescription; HWND dialogHelper; HRESULT hr; wtitle = toUTF16(title); wdescription = toUTF16(description); dialogHelper = beginDialogHelper(); hr = TaskDialog(dialogHelper, NULL, NULL, wtitle, wdescription, buttons, icon, NULL); if (hr != S_OK) logHRESULT("error showing task dialog in msgbox()", hr); endDialogHelper(dialogHelper); uiFree(wdescription); uiFree(wtitle); }
void uiWindowsUtilSetText(HWND hwnd, const char *text) { WCHAR *wtext; wtext = toUTF16(text); if (SetWindowTextW(hwnd, wtext) == 0) logLastError("error setting control text in uiWindowsControlSetText()"); uiFree(wtext); }
static HRESULT drawTextPart(HRESULT hr, struct drawState *s) { COLORREF prevText; int prevMode; RECT r; uiTableValue *value; WCHAR *wstr; if (hr != S_OK) return hr; if (!s->m->hasText) return S_OK; // don't draw the text underneath an edit control if (s->t->edit != NULL && s->t->editedItem == s->iItem && s->t->editedSubitem == s->iSubItem) return S_OK; prevText = SetTextColor(s->dc, s->textColor); if (prevText == CLR_INVALID) { logLastError(L"SetTextColor()"); return E_FAIL; } prevMode = SetBkMode(s->dc, TRANSPARENT); if (prevMode == 0) { logLastError(L"SetBkMode()"); return E_FAIL; } value = uiprivTableModelCellValue(s->model, s->iItem, s->p->textModelColumn); wstr = toUTF16(uiTableValueString(value)); uiFreeTableValue(value); // These flags are a menagerie of flags from various sources: // guessing, the Windows 2000 source leak, various custom // draw examples on the web, etc. // TODO find the real correct flags if (DrawTextW(s->dc, wstr, -1, &(s->m->realTextRect), DT_LEFT | DT_VCENTER | DT_END_ELLIPSIS | DT_SINGLELINE | DT_NOPREFIX | DT_EDITCONTROL) == 0) { uiprivFree(wstr); logLastError(L"DrawTextW()"); return E_FAIL; } uiprivFree(wstr); // TODO decide once and for all what to compare to here and with SelectObject() if (SetBkMode(s->dc, prevMode) != TRANSPARENT) { logLastError(L"SetBkMode() prev"); return E_FAIL; } if (SetTextColor(s->dc, prevText) != s->textColor) { logLastError(L"SetTextColor() prev"); return E_FAIL; } return S_OK; }
void uiEditableComboboxAppend(uiEditableCombobox *c, const char *text) { WCHAR *wtext; LRESULT res; wtext = toUTF16(text); res = SendMessageW(c->hwnd, CB_ADDSTRING, 0, (LPARAM) wtext); if (res == (LRESULT) CB_ERR) logLastError(L"error appending item to uiEditableCombobox"); else if (res == (LRESULT) CB_ERRSPACE) logLastError(L"memory exhausted appending item to uiEditableCombobox"); uiprivFree(wtext); }
// TOOD crlf stuff void uiMultilineEntryAppend(uiMultilineEntry *e, const char *text) { LRESULT n; WCHAR *wtext; // TODO does doing this raise EN_CHANGED? // TODO preserve selection? caret? what if caret used to be at end? // TODO scroll to bottom? n = SendMessageW(e->hwnd, WM_GETTEXTLENGTH, 0, 0); SendMessageW(e->hwnd, EM_SETSEL, n, n); wtext = toUTF16(text); SendMessageW(e->hwnd, EM_REPLACESEL, FALSE, (LPARAM) wtext); uiFree(wtext); }
void HistoryLogFunc(HANDLE hContact, std::string message) { if(gbHistoryLog) { if(hContact == INVALID_HANDLE_VALUE) return; std::string msg = message; msg.append("\n"); msg.append("Protocol: ").append(GetContactProto(hContact)).append(" Contact: "); msg.append(toUTF8((TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_TCHAR))).append(" ID: "); msg.append(toUTF8(GetContactUid(hContact,toUTF16(GetContactProto(hContact))))); HistoryLog(NULL, (char*)msg.c_str(), EVENTTYPE_MESSAGE, DBEF_READ); } }
static HRESULT openEditControl(uiTable *t, int iItem, int iSubItem, uiprivTableColumnParams *p) { uiTableValue *value; WCHAR *wstr; HRESULT hr; // the real list view accepts changes to the existing item when editing a new item hr = uiprivTableFinishEditingText(t); if (hr != S_OK) return hr; // the real list view creates the edit control with the string value = uiprivTableModelCellValue(t->model, iItem, p->textModelColumn); wstr = toUTF16(uiTableValueString(value)); uiFreeTableValue(value); // TODO copy WS_EX_RTLREADING t->edit = CreateWindowExW(0, L"EDIT", wstr, // these styles are what the normal listview edit uses WS_CHILD | WS_CLIPSIBLINGS | WS_BORDER | ES_AUTOHSCROLL, // as is this size 0, 0, 16384, 16384, // and this control ID t->hwnd, (HMENU) 1, hInstance, NULL); if (t->edit == NULL) { logLastError(L"CreateWindowExW()"); uiprivFree(wstr); return E_FAIL; } SendMessageW(t->edit, WM_SETFONT, (WPARAM) hMessageFont, (LPARAM) TRUE); // TODO check errors SetWindowSubclass(t->edit, editSubProc, 0, (DWORD_PTR) t); hr = resizeEdit(t, wstr, iItem, iSubItem); if (hr != S_OK) // TODO proper cleanup return hr; // TODO check errors on these two, if any SetFocus(t->edit); ShowWindow(t->edit, SW_SHOW); SendMessageW(t->edit, EM_SETSEL, 0, (LPARAM) (-1)); uiprivFree(wstr); t->editedItem = iItem; t->editedSubitem = iSubItem; return S_OK; }
uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar) { uiWindow *w; WCHAR *wtitle; BOOL hasMenubarBOOL; uiWindowsNewControl(uiWindow, w); hasMenubarBOOL = FALSE; if (hasMenubar) hasMenubarBOOL = TRUE; w->hasMenubar = hasMenubarBOOL; #define style WS_OVERLAPPEDWINDOW #define exstyle 0 wtitle = toUTF16(title); w->hwnd = CreateWindowExW(exstyle, windowClass, wtitle, style, CW_USEDEFAULT, CW_USEDEFAULT, // use the raw width and height for now // this will get CW_USEDEFAULT (hopefully) predicting well // even if it doesn't, we're adjusting it later width, height, NULL, NULL, hInstance, w); if (w->hwnd == NULL) logLastError(L"error creating window"); uiFree(wtitle); if (hasMenubar) { w->menubar = makeMenubar(); if (SetMenu(w->hwnd, w->menubar) == 0) logLastError(L"error giving menu to window"); } // and use the proper size setClientSize(w, width, height, hasMenubarBOOL, style, exstyle); uiWindowOnClosing(w, defaultOnClosing, NULL); windows[w] = true; return w; }
void uiMultilineEntryAppend(uiMultilineEntry *e, const char *text) { LRESULT n; char *crlf; WCHAR *wtext; // doing this raises an EN_CHANGED e->inhibitChanged = TRUE; // TODO preserve selection? caret? what if caret used to be at end? // TODO scroll to bottom? n = SendMessageW(e->hwnd, WM_GETTEXTLENGTH, 0, 0); SendMessageW(e->hwnd, EM_SETSEL, n, n); crlf = LFtoCRLF(text); wtext = toUTF16(crlf); uiFree(crlf); SendMessageW(e->hwnd, EM_REPLACESEL, FALSE, (LPARAM) wtext); uiFree(wtext); e->inhibitChanged = FALSE; }
uiGroup *uiNewGroup(const char *text) { uiGroup *g; WCHAR *wtext; uiWindowsNewControl(uiGroup, g); wtext = toUTF16(text); g->hwnd = uiWindowsEnsureCreateControlHWND(WS_EX_CONTROLPARENT, L"button", wtext, BS_GROUPBOX, hInstance, NULL, TRUE); uiFree(wtext); if (SetWindowSubclass(g->hwnd, groupSubProc, 0, (DWORD_PTR) g) == FALSE) logLastError(L"error subclassing groupbox to handle parent messages"); return g; }
uiMenu *uiNewMenu(const char *name) { uiMenu *m; if (menusFinalized) userbug("You can not create a new menu after menus have been finalized."); if (len >= cap) { cap += grow; menus = (uiMenu **) uiRealloc(menus, cap * sizeof (uiMenu *), "uiMenu *[]"); } m = uiNew(uiMenu); menus[len] = m; len++; m->name = toUTF16(name); return m; }
uiCheckbox *uiNewCheckbox(const char *text) { uiCheckbox *c; WCHAR *wtext; uiWindowsNewControl(uiCheckbox, c); wtext = toUTF16(text); c->hwnd = uiWindowsEnsureCreateControlHWND(0, L"button", wtext, BS_CHECKBOX | WS_TABSTOP, hInstance, NULL, TRUE); uiFree(wtext); uiWindowsRegisterWM_COMMANDHandler(c->hwnd, onWM_COMMAND, uiControl(c)); uiCheckboxOnToggled(c, defaultOnToggled, NULL); return c; }
void uiFormAppend(uiForm *f, const char *label, uiControl *c, int stretchy) { struct formChild fc; WCHAR *wlabel; fc.c = c; wlabel = toUTF16(label); fc.label = uiWindowsEnsureCreateControlHWND(0, L"STATIC", wlabel, SS_LEFT | SS_NOPREFIX, hInstance, NULL, TRUE); uiFree(wlabel); uiWindowsEnsureSetParentHWND(fc.label, f->hwnd); fc.stretchy = stretchy; uiControlSetParent(fc.c, uiControl(f)); uiWindowsControlSetParentHWND(uiWindowsControl(fc.c), f->hwnd); f->controls->push_back(fc); formArrangeChildren(f); uiWindowsControlMinimumSizeChanged(uiWindowsControl(f)); }
MIRANDA_HOOK_EVENT(ME_DB_EVENT_FILTER_ADD, w, l) { MCONTACT hContact = (MCONTACT)w; if (!l) //fix potential DEP crash return 0; DBEVENTINFO * dbei = (DBEVENTINFO*)l; // if event is in protocol that is not despammed if (!ProtoInList(dbei->szModule)) { // ...let the event go its way return 0; } //do not check excluded contact if (db_get_b(hContact, pluginName, "Answered", 0)) return 0; if (db_get_b(hContact, pluginName, "Excluded", 0)) { if (!db_get_b(hContact, "CList", "NotOnList", 0)) db_unset(hContact, pluginName, "Excluded"); return 0; } //we want block not only messages, i seen many types other eventtype flood if (dbei->flags & DBEF_READ) // ...let the event go its way return 0; //mark contact which we trying to contact for exclude from check if ((dbei->flags & DBEF_SENT) && db_get_b(hContact, "CList", "NotOnList", 0) && (!gbMaxQuestCount || db_get_dw(hContact, pluginName, "QuestionCount", 0) < gbMaxQuestCount) && gbExclude) { db_set_b(hContact, pluginName, "Excluded", 1); return 0; } // if message is from known or marked Answered contact if (!db_get_b(hContact, "CList", "NotOnList", 0)) // ...let the event go its way return 0; // if message is corrupted or empty it cannot be an answer. if (!dbei->cbBlob || !dbei->pBlob) // reject processing of the event return 1; tstring message; if (dbei->flags & DBEF_UTF) { wchar_t* msg_u; char* msg_a = mir_strdup((char*)dbei->pBlob); mir_utf8decode(msg_a, &msg_u); message = msg_u; } else message = mir_a2u((char*)(dbei->pBlob)); // if message contains right answer... boost::algorithm::erase_all(message, "\r"); boost::algorithm::erase_all(message, "\n"); bool bSendMsg = true; if (gbInvisDisable) { if (CallProtoService(dbei->szModule, PS_GETSTATUS, 0, 0) == ID_STATUS_INVISIBLE) bSendMsg = false; else if (db_get_w(hContact, dbei->szModule, "ApparentMode", 0) == ID_STATUS_OFFLINE) bSendMsg = false; //is it useful ? } bool answered = false; if (gbMathExpression) { if (boost::algorithm::all(message, boost::is_digit())) { int num = _ttoi(message.c_str()); int math_answer = db_get_dw(hContact, pluginName, "MathAnswer", 0); if (num && math_answer) answered = (num == math_answer); } } else if (!gbRegexMatch) answered = gbCaseInsensitive ? (!Stricmp(message.c_str(), (variables_parse(gbAnswer, hContact).c_str()))) : (!mir_tstrcmp(message.c_str(), (variables_parse(gbAnswer, hContact).c_str()))); else { if (gbCaseInsensitive) { std::string check(toUTF8(variables_parse(gbAnswer, hContact))), msg(toUTF8(message)); boost::algorithm::to_upper(check); boost::algorithm::to_upper(msg); boost::regex expr(check); answered = boost::regex_search(msg.begin(), msg.end(), expr); } else { std::string check(toUTF8(variables_parse(gbAnswer, hContact))), msg(toUTF8(message)); boost::regex expr(check); answered = boost::regex_search(msg.begin(), msg.end(), expr); } } if (answered) { // unhide contact db_unset(hContact, "CList", "Hidden"); db_unset(hContact, pluginName, "MathAnswer"); // mark contact as Answered db_set_b(hContact, pluginName, "Answered", 1); //add contact permanently if (gbAddPermanent) //do not use this ) db_unset(hContact, "CList", "NotOnList"); // send congratulation if (bSendMsg) { tstring prot = DBGetContactSettingStringPAN(NULL, dbei->szModule, "AM_BaseProto", _T("")); // for notICQ protocols or disable auto auth. reqwest if ((Stricmp(_T("ICQ"), prot.c_str())) || (!gbAutoReqAuth)) { char * buf = mir_utf8encodeW(variables_parse(gbCongratulation, hContact).c_str()); CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)buf); mir_free(buf); } // Note: For ANSI can be not work if (!Stricmp(_T("ICQ"), prot.c_str())) { // grand auth. if (gbAutoAuth) CallProtoService(dbei->szModule, "/GrantAuth", w, 0); // add contact to server list and local group if (gbAutoAddToServerList) { db_set_ws(hContact, "CList", "Group", gbAutoAuthGroup.c_str()); CallProtoService(dbei->szModule, "/AddServerContact", w, 0); db_unset(hContact, "CList", "NotOnList"); }; // auto auth. reqwest with send congratulation if (gbAutoReqAuth) CallContactService(hContact, PSS_AUTHREQUEST, 0, (LPARAM)variables_parse(gbCongratulation, hContact).c_str()); } } return 0; } // URL contains check bSendMsg = (bSendMsg && gbIgnoreURL) ? (!IsUrlContains((TCHAR *)message.c_str())) : bSendMsg; // if message message does not contain infintite talk protection prefix // and question count for this contact is less then maximum if (bSendMsg) { if ((!gbInfTalkProtection || tstring::npos == message.find(_T("StopSpam automatic message:\r\n"))) && (!gbMaxQuestCount || db_get_dw(hContact, pluginName, "QuestionCount", 0) < gbMaxQuestCount)) { // send question tstring q; if (gbInfTalkProtection) q += _T("StopSpam automatic message:\r\n"); if (gbMathExpression) { //parse math expression in question tstring tmp_question = gbQuestion; std::list<int> args; std::list<TCHAR> actions; tstring::size_type p1 = gbQuestion.find(_T("X")), p2 = 0; const tstring expr_chars = _T("X+-/*"), expr_acts = _T("+-/*"); while (p1 < gbQuestion.length() && p1 != tstring::npos && expr_chars.find(gbQuestion[p1]) != tstring::npos) { std::string arg; p2 = p1; for (p1 = gbQuestion.find(_T("X"), p1); (p1 < gbQuestion.length()) && (gbQuestion[p1] == L'X'); ++p1) arg += get_random_num(1); tmp_question.replace(p2, arg.size(), toUTF16(arg)); args.push_back(atoi(arg.c_str())); if ((p1 < gbQuestion.length()) && (p1 != tstring::npos) && (expr_acts.find(gbQuestion[p1]) != tstring::npos)) actions.push_back(gbQuestion[p1]); ++p1; } int math_answer = 0; math_answer = args.front(); args.pop_front(); while (!args.empty()) { if (!actions.empty()) { switch (actions.front()) { case _T('+'): { math_answer += args.front(); args.pop_front(); } break; case _T('-'): { math_answer -= args.front(); args.pop_front(); } break; case _T('/'): { math_answer /= args.front(); args.pop_front(); } break; case _T('*'): { math_answer *= args.front(); args.pop_front(); } break; } actions.pop_front(); } else break; } db_set_dw(hContact, pluginName, "MathAnswer", math_answer); q += variables_parse(tmp_question, hContact); } else q += variables_parse(gbQuestion, hContact); CallContactService(hContact, PSS_MESSAGE, 0, ptrA(mir_utf8encodeW(q.c_str()))); // increment question count DWORD questCount = db_get_dw(hContact, pluginName, "QuestionCount", 0); db_set_dw(hContact, pluginName, "QuestionCount", questCount + 1); } else { if (gbIgnoreContacts) db_set_dw(hContact, "Ignore", "Mask1", 0x0000007F); } } if (gbHideContacts) db_set_b(hContact, "CList", "Hidden", 1); if (gbSpecialGroup) db_set_ws(hContact, "CList", "Group", gbSpammersGroup.c_str()); db_set_b(hContact, "CList", "NotOnList", 1); // save first message from contact if (db_get_dw(hContact, pluginName, "QuestionCount", 0) < 2) { dbei->flags |= DBEF_READ; db_event_add(hContact, dbei); }; // reject processing of the event LogSpamToFile(hContact, message); return 1; }
static HRESULT drawButtonPart(HRESULT hr, struct drawState *s) { uiTableValue *value; WCHAR *wstr; bool enabled; HTHEME theme; RECT r; TEXTMETRICW tm; if (hr != S_OK) return hr; if (s->p->buttonModelColumn == -1) return S_OK; value = uiprivTableModelCellValue(s->model, s->iItem, s->p->buttonModelColumn); wstr = toUTF16(uiTableValueString(value)); uiFreeTableValue(value); enabled = uiprivTableModelCellEditable(s->model, s->iItem, s->p->buttonClickableModelColumn); theme = OpenThemeData(s->t->hwnd, L"button"); if (GetTextMetricsW(s->dc, &tm) == 0) { logLastError(L"GetTextMetricsW()"); hr = E_FAIL; goto fail; } r = s->m->subitemBounds; if (theme != NULL) { int state; state = PBS_NORMAL; if (!enabled) state = PBS_DISABLED; hr = DrawThemeBackground(theme, s->dc, BP_PUSHBUTTON, state, &r, NULL); if (hr != S_OK) { logHRESULT(L"DrawThemeBackground()", hr); goto fail; } // TODO DT_EDITCONTROL? // TODO DT_PATH_ELLIPSIS DT_WORD_ELLIPSIS instead of DT_END_ELLIPSIS? a middle-ellipsis option would be ideal here // TODO is there a theme property we can get instead of hardcoding these flags? if not, make these flags a macro hr = DrawThemeText(theme, s->dc, BP_PUSHBUTTON, state, wstr, -1, DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS | DT_SINGLELINE | DT_NOPREFIX, 0, &r); if (hr != S_OK) { logHRESULT(L"DrawThemeText()", hr); goto fail; } } else { UINT state; HBRUSH color, prevColor; int prevBkMode; // TODO check errors // TODO explain why we're not doing this in the themed case (it has to do with extra transparent pixels) InflateRect(&r, -1, -1); state = DFCS_BUTTONPUSH; if (!enabled) state |= DFCS_INACTIVE; if (DrawFrameControl(s->dc, &r, DFC_BUTTON, state) == 0) { logLastError(L"DrawFrameControl()"); hr = E_FAIL; goto fail; } color = GetSysColorBrush(COLOR_BTNTEXT); // TODO check errors for these two prevColor = (HBRUSH) SelectObject(s->dc, color); prevBkMode = SetBkMode(s->dc, TRANSPARENT); // TODO DT_EDITCONTROL? // TODO DT_PATH_ELLIPSIS DT_WORD_ELLIPSIS instead of DT_END_ELLIPSIS? a middle-ellipsis option would be ideal here if (DrawTextW(s->dc, wstr, -1, &r, DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS | DT_SINGLELINE | DT_NOPREFIX) == 0) { logLastError(L"DrawTextW()"); hr = E_FAIL; goto fail; } // TODO check errors for these two SetBkMode(s->dc, prevBkMode); SelectObject(s->dc, prevColor); } hr = S_OK; fail: // TODO check errors if (theme != NULL) CloseThemeData(theme); uiprivFree(wstr); return hr; }
std::string toUTF8(std::string str) { return toUTF8(toUTF16(str)); }
void UnicodeConverter::toUTF16(const char* utf8String, std::wstring& utf16String) { toUTF16(utf8String, (int) std::strlen(utf8String), utf16String); }