From 59e53cb6cad99051eb3e46b919fd78ab7493061d Mon Sep 17 00:00:00 2001 From: mataes2007 Date: Wed, 23 Nov 2011 18:16:39 +0000 Subject: added Help plugin git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@201 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- Help/helpdlg.c | 700 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 700 insertions(+) create mode 100644 Help/helpdlg.c (limited to 'Help/helpdlg.c') diff --git a/Help/helpdlg.c b/Help/helpdlg.c new file mode 100644 index 0000000..8fa78bd --- /dev/null +++ b/Help/helpdlg.c @@ -0,0 +1,700 @@ +/* +Miranda IM Help Plugin +Copyright (C) 2002 Richard Hughes, 2005-2007 H. Herkenrath + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (Help-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include +#include +#define _WIN32_WINNT 0x0500 +#define __RPCASYNC_H__ /* header shows warnings in VS6 */ +#include +#include + +#define MIRANDA_VER 0x0600 +#include +#include +#include +#include +#include "help.h" + +#include +#pragma warning(disable:4201) /* nonstandard extension used : nameless struct/union */ +#include +#pragma warning(default:4201) /* nonstandard extension used : nameless struct/union */ +#include "resource.h" + +extern HINSTANCE hInst; +HWND hwndHelpDlg; + +static int HelpDialogResize(HWND hwndDlg,LPARAM lParam,UTILRESIZECONTROL *urc) +{ + UNREFERENCED_PARAMETER(hwndDlg); + UNREFERENCED_PARAMETER(lParam); + switch(urc->wId) { + case IDC_CTLTEXT: +#ifdef EDITOR + case IDC_DLGID: + case IDC_MODULE: +#endif + return RD_ANCHORX_WIDTH|RD_ANCHORY_TOP; + case IDC_TEXT: + return RD_ANCHORX_WIDTH|RD_ANCHORY_HEIGHT; + } + return RD_ANCHORX_LEFT|RD_ANCHORY_TOP; +} + +#ifndef EDITOR +BOOL CALLBACK ShadowDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + switch(msg) { + case WM_INITDIALOG: + { BOOL (WINAPI *pfnSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD); + *(FARPROC*)&pfnSetLayeredWindowAttributes=GetProcAddress(GetModuleHandleA("USER32"),"SetLayeredWindowAttributes"); + if(!pfnSetLayeredWindowAttributes) { + *(HANDLE*)lParam=NULL; // hwndShadowDlg reset + DestroyWindow(hwndDlg); + return FALSE; + } + EnableWindow(hwndDlg,FALSE); + SetWindowLong(hwndDlg,GWL_EXSTYLE,GetWindowLong(hwndDlg,GWL_EXSTYLE)|WS_EX_LAYERED); + pfnSetLayeredWindowAttributes(hwndDlg,RGB(0,0,0),96,LWA_ALPHA); + return FALSE; + } + case WM_CTLCOLORDLG: + return (BOOL)GetSysColorBrush(COLOR_WINDOWFRAME); + } + return FALSE; +} + +// in client coordinates +int GetCharRangeRect(HWND hwndEdit,LONG *cpMin,LONG cpMax,RECT *rcRange) +{ + LONG cpLineBreak; + { LONG nLine,nLinePrev; + if(*cpMin>cpMax) return 1; + nLine=SendMessage(hwndEdit,EM_EXLINEFROMCHAR,0,*cpMin); + for(cpLineBreak=*cpMin+1;cpLineBreak<=cpMax;cpLineBreak++) { + nLinePrev=nLine; + nLine=SendMessage(hwndEdit,EM_EXLINEFROMCHAR,0,cpLineBreak); + if(nLine!=nLinePrev) break; + } + cpMax=cpLineBreak-1; + } + { POINTL pt; + if(SendMessage(hwndEdit,EM_SETTYPOGRAPHYOPTIONS,0,0)) { // test for richedit v3.0 + SendMessage(hwndEdit,EM_POSFROMCHAR,(WPARAM)&pt,*cpMin); + rcRange->left=pt.x; rcRange->top=pt.y; + SendMessage(hwndEdit,EM_POSFROMCHAR,(WPARAM)&pt,cpMax); + rcRange->right=pt.x; rcRange->bottom=pt.y; + } + else { + DWORD pos; + pos=SendMessage(hwndEdit,EM_POSFROMCHAR,(WPARAM)*cpMin,0); + POINTSTOPOINT(pt,MAKEPOINTS(pos)); + rcRange->left=pt.x; rcRange->top=pt.y; + pos=SendMessage(hwndEdit,EM_POSFROMCHAR,(WPARAM)cpMax,0); + POINTSTOPOINT(pt,MAKEPOINTS(pos)); + rcRange->right=pt.x; rcRange->bottom=pt.y; + } + } + { FORMATRANGE fr; + ZeroMemory(&fr,sizeof(fr)); + fr.chrg.cpMin=*cpMin; + fr.chrg.cpMax=cpMax; + fr.hdc=fr.hdcTarget=GetDC(hwndEdit); + if(fr.hdc==NULL) return 1; + SendMessage(hwndEdit,EM_FORMATRANGE,0,(LPARAM)&fr); + PostMessage(hwndEdit,EM_FORMATRANGE,0,0); // clear memory + rcRange->bottom+=MulDiv(fr.rc.bottom,GetDeviceCaps(fr.hdc,LOGPIXELSY),1440); // twips to pixels + ReleaseDC(hwndEdit,fr.hdc); + } + *cpMin=cpLineBreak; + return 0; +} + +static HCURSOR hHandCursor; +static LRESULT CALLBACK HelpSubclassProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) +{ + switch(msg) { + case WM_KEYDOWN: + if(GetKeyState(VK_CONTROL)&0x8000 && wParam=='C') { + SendMessage(GetParent(hwnd),M_CLIPBOARDCOPY,0,0); + return 0; + } + break; + case WM_LBUTTONDBLCLK: + DestroyWindow(GetParent(hwnd)); + return 0; + case WM_CONTEXTMENU: + return DefWindowProc(hwnd,msg,wParam,lParam); // redirect to parent + case WM_SETCURSOR: // not available via EN_MSGFILTER + if(GetDlgCtrlID((HWND)wParam)==IDC_TEXT) { + POINT pt; + DWORD pos; + CHARRANGE rng; + pos=GetMessagePos(); + POINTSTOPOINT(pt,MAKEPOINTS(pos)); + ScreenToClient((HWND)wParam,&pt); + pos=SendMessage((HWND)wParam,EM_CHARFROMPOS,0,(WPARAM)&pt); + if(IsHyperlink(pos,&rng.cpMin,&rng.cpMax,NULL)) { + RECT rc; + while(!GetCharRangeRect((HWND)wParam,&rng.cpMin,rng.cpMax,&rc)) + if(PtInRect(&rc,pt)) { + SetCursor(hHandCursor); + return TRUE; + } + } + } + break; + } + return CallWindowProc((WNDPROC)GetWindowLong(hwnd,GWL_USERDATA),hwnd,msg,wParam,lParam); +} +#endif // !defined EDITOR + +BOOL CALLBACK HelpDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam) +{ + HWND hwndCtl=(HWND)GetWindowLong(hwndDlg,GWL_USERDATA); + static LCID locale; +#ifndef EDITOR + static HWND hwndShadowDlg; + static HWND hwndToolTip; +#endif + + switch(msg) { + case WM_INITDIALOG: + hwndHelpDlg=hwndDlg; +#ifdef EDITOR + TranslateDialogDefault(hwndDlg); + SetWindowLong(GetDlgItem(hwndDlg,IDC_DLGID),GWL_STYLE,GetWindowLong(GetDlgItem(hwndDlg,IDC_DLGID),GWL_STYLE)|SS_ENDELLIPSIS); + SendDlgItemMessage(hwndDlg,IDC_TEXT,EM_SETEVENTMASK,0,ENM_KEYEVENTS); + { RECT rcDlg,rcWork; + if(SystemParametersInfo(SPI_GETWORKAREA,0,&rcWork,FALSE) && GetWindowRect(hwndDlg,&rcDlg)) + SetWindowPos(hwndDlg,0,rcDlg.left,rcWork.bottom-rcDlg.bottom+rcDlg.top,0,0,SWP_NOZORDER|SWP_NOSIZE); + } +#else + { RECT rc,rcBuf; + SendDlgItemMessage(hwndDlg,IDC_CTLTEXT,EM_GETRECT,0,(LPARAM)&rcBuf); + SendDlgItemMessage(hwndDlg,IDC_TEXT,EM_GETRECT,0,(LPARAM)&rc); + rc.left=rcBuf.left; // sync richedit offset with edit + rc.right=rcBuf.right; + SendDlgItemMessage(hwndDlg,IDC_TEXT,EM_SETRECTNP,0,(LPARAM)&rc); + } + SetWindowLong(GetDlgItem(hwndDlg,IDC_CTLTEXT),GWL_USERDATA,SetWindowLong(GetDlgItem(hwndDlg,IDC_CTLTEXT),GWL_WNDPROC,(LONG)HelpSubclassProc)); + SetWindowLong(GetDlgItem(hwndDlg,IDC_CARETSUCKER),GWL_USERDATA,SetWindowLong(GetDlgItem(hwndDlg,IDC_CARETSUCKER),GWL_WNDPROC,(LONG)HelpSubclassProc)); + SendDlgItemMessage(hwndDlg,IDC_TEXT,EM_SETEVENTMASK,0,ENM_KEYEVENTS|ENM_MOUSEEVENTS|ENM_REQUESTRESIZE); + SendDlgItemMessage(hwndDlg,IDC_TEXT,EM_SETBKGNDCOLOR,0,GetSysColor(COLOR_INFOBK)); + SendDlgItemMessage(hwndDlg,IDC_TEXT,EM_SETEDITSTYLE,SES_EXTENDBACKCOLOR,SES_EXTENDBACKCOLOR); + SetWindowLong(GetDlgItem(hwndDlg,IDC_TEXT),GWL_USERDATA,SetWindowLong(GetDlgItem(hwndDlg,IDC_TEXT),GWL_WNDPROC,(LONG)HelpSubclassProc)); + hwndShadowDlg=CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_SHADOW),hwndDlg,ShadowDlgProc,(LPARAM)&hwndShadowDlg); + hwndToolTip=CreateWindowEx(WS_EX_TOPMOST,TOOLTIPS_CLASS,NULL,WS_POPUP|TTS_ALWAYSTIP|TTS_NOPREFIX,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,hwndDlg,NULL,hInst,NULL); + if(hwndToolTip!=NULL) { + SetWindowPos(hwndToolTip,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + SendMessage(hwndToolTip,TTM_SETTIPBKCOLOR,GetSysColor(COLOR_WINDOW),0); // yelleow on yellow looks silly + SendMessage(hwndToolTip,TTM_SETDELAYTIME,TTDT_AUTOMATIC,GetDoubleClickTime()*3); + } + hHandCursor=(HCURSOR)LoadImage(NULL,IDC_HAND,IMAGE_CURSOR,0,0,LR_DEFAULTSIZE|LR_SHARED); + if(hHandCursor==NULL) // use fallback out of miranda32.exe + hHandCursor=(HCURSOR)LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(214),IMAGE_CURSOR,0,0,LR_DEFAULTSIZE|LR_SHARED); +#endif + SendDlgItemMessage(hwndDlg,IDC_TEXT,EM_SETLANGOPTIONS,0,SendDlgItemMessage(hwndDlg,IDC_TEXT,EM_GETLANGOPTIONS,0,0)|IMF_UIFONTS); + SetWindowPos(hwndDlg,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + return TRUE; + case WM_SIZE: + { UTILRESIZEDIALOG urd; + ZeroMemory(&urd,sizeof(urd)); + urd.cbSize=sizeof(urd); + urd.hInstance=hInst; + urd.hwndDlg=hwndDlg; + urd.lpTemplate=MAKEINTRESOURCEA(IDD_HELP); + urd.pfnResizer=HelpDialogResize; + CallService(MS_UTILS_RESIZEDIALOG,0,(LPARAM)&urd); + InvalidateRect(hwndDlg,NULL,TRUE); +#ifdef EDITOR + break; +#endif + } +#ifndef EDITOR + case WM_MOVE: + if(IsWindow(hwndShadowDlg)) { + RECT rc; + HRGN hRgnShadow,hRgnDlg; + if(!GetWindowRect(hwndDlg,&rc)) break; + hRgnShadow=CreateRectRgnIndirect(&rc); + if(hRgnShadow==NULL) break; + OffsetRgn(hRgnShadow,5,5); + hRgnDlg=CreateRectRgnIndirect(&rc); + if(hRgnDlg==NULL) break; + if(CombineRgn(hRgnShadow,hRgnShadow,hRgnDlg,RGN_DIFF)==ERROR) { + DeleteObject(hRgnShadow); + DeleteObject(hRgnDlg); + break; + } + DeleteObject(hRgnDlg); + OffsetRgn(hRgnShadow,-rc.left-5,-rc.top-5); + SetWindowRgn(hwndShadowDlg,hRgnShadow,FALSE); // system gets ownership of hRgnShadow + SetWindowPos(hwndShadowDlg,HWND_TOPMOST,rc.left+5,rc.top+5,rc.right-rc.left,rc.bottom-rc.top,SWP_SHOWWINDOW); + SetWindowPos(hwndDlg,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); + } + break; + case WM_KEYDOWN: + if(GetKeyState(VK_CONTROL)&0x8000 && wParam=='C') { + SendMessage(hwndDlg,M_CLIPBOARDCOPY,0,0); + return TRUE; + } + break; + case WM_CONTEXTMENU: + { HMENU hMenu; + POINT pt; + POINTSTOPOINT(pt,MAKEPOINTS(lParam)); + hMenu=CreatePopupMenu(); + AppendMenu(hMenu,MF_STRING,WM_COPY,TranslateT("&Copy")); + if(TrackPopupMenuEx(hMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_HORPOSANIMATION|TPM_VERPOSANIMATION|TPM_RIGHTBUTTON|TPM_RETURNCMD|TPM_NONOTIFY,pt.x,pt.y,hwndDlg,NULL)) + SendMessage(hwndDlg,M_CLIPBOARDCOPY,0,0); + DestroyMenu(hMenu); + } + return 0; + case WM_LBUTTONDBLCLK: + DestroyWindow(hwndDlg); + return TRUE; + case M_CLIPBOARDCOPY: + { HWND hwnd=GetFocus(); + if(hwnd==GetDlgItem(hwndDlg,IDC_CTLTEXT) || hwnd==GetDlgItem(hwndDlg,IDC_TEXT)) { + CHARRANGE sel; + ZeroMemory(&sel,sizeof(sel)); + SendMessage(hwnd,EM_GETSEL,(WPARAM)&sel.cpMin,(LPARAM)&sel.cpMax); + if(sel.cpMin!=sel.cpMax) { + SendMessage(hwnd,WM_COPY,0,0); + return TRUE; + } + } + } + if(OpenClipboard(hwndDlg)) { + HGLOBAL hglb; + int cch,len; + EmptyClipboard(); + hglb=GlobalAlloc(GMEM_MOVEABLE,sizeof(LCID)); + if(hglb!=NULL) { + LCID *plocale=GlobalLock(hglb); + if(plocale!=NULL) { + *plocale=locale; + GlobalUnlock(hglb); + if(!SetClipboardData(CF_LOCALE,hglb)) GlobalFree(hglb); // shell takes ownership + } else GlobalFree(hglb); + } + cch=GetWindowTextLength(GetDlgItem(hwndDlg,IDC_CTLTEXT))+GetWindowTextLength(GetDlgItem(hwndDlg,IDC_TEXT))+3; + hglb=GlobalAlloc(GMEM_MOVEABLE,(cch+1)*sizeof(TCHAR)); + if(hglb!=NULL) { + TCHAR *pszText=GlobalLock(hglb); + if(pszText!=NULL) { + if(!GetWindowText(GetDlgItem(hwndDlg,IDC_CTLTEXT),pszText,cch-2)) pszText[0]=_T('\0'); + len=lstrlen(pszText); + if(GetWindowText(GetDlgItem(hwndDlg,IDC_TEXT),pszText+len+2,cch-2-len) && len) { + pszText[len]=_T('\r'); + pszText[len+1]=_T('\n'); + } + GlobalUnlock(hglb); +#if defined(_UNICODE) + if(!SetClipboardData(CF_UNICODETEXT,hglb)) GlobalFree(hglb); // shell takes ownership +#else + if(!SetClipboardData(CF_TEXT,hglb)) GlobalFree(hglb); // shell takes ownership +#endif + } else GlobalFree(hglb); + } + CloseClipboard(); + } + return TRUE; + case WM_CTLCOLORDLG: + case WM_CTLCOLORSTATIC: + SetTextColor((HDC)wParam,GetSysColor(COLOR_INFOTEXT)); + SetBkColor((HDC)wParam,GetSysColor(COLOR_INFOBK)); + return (BOOL)GetSysColorBrush(COLOR_INFOBK); + case WM_ACTIVATE: + if(LOWORD(wParam)!=WA_INACTIVE) break; + if(GetParent((HWND)lParam)==hwndDlg) break; + // fall through + case WM_SYSCOLORCHANGE: + case WM_ACTIVATEAPP: + PostMessage(hwndDlg,WM_CLOSE,0,0); // no DestroyWindow() here! would cause recursion + break; +#endif // !defined EDITOR + case M_CHANGEHELPCONTROL: + if(hwndCtl==(HWND)lParam) break; + SetWindowLong(hwndDlg,GWL_USERDATA,lParam); + hwndCtl=(HWND)lParam; + SetDlgItemText(hwndDlg,IDC_CTLTEXT,NULL); +#ifdef EDITOR + { TCHAR text[1024]; + char *szModule,*szDlgId; + + GetControlTitle(hwndCtl,text,SIZEOF(text)); + SetDlgItemText(hwndDlg,IDC_CTLTEXT,text); + mir_sntprintf(text,SIZEOF(text),TranslateT("Control ID: %d"),GetControlID(hwndCtl)); + SetDlgItemText(hwndDlg,IDC_CTLID,text); + + szDlgId=CreateDialogIdString(GetControlDialog(hwndCtl)); + mir_sntprintf(text,SIZEOF(text),TranslateT("Dialog ID: %hs"),(szDlgId!=NULL)?szDlgId:Translate("Unknown")); + mir_free(szDlgId); // does NULL check + SetDlgItemText(hwndDlg,IDC_DLGID,text); + + mir_sntprintf(text,SIZEOF(text),TranslateT("Type: %s"),TranslateTS(szControlTypeNames[GetControlType(hwndCtl)])); + SetDlgItemText(hwndDlg,IDC_CTLTYPE,text); + + szModule=GetControlModuleName(hwndCtl); + mir_sntprintf(text,SIZEOF(text),TranslateT("Module: %hs"),szModule?szModule:Translate("Unknown")); + mir_free(szModule); // does NULL check + SetDlgItemText(hwndDlg,IDC_MODULE,text); + } +#endif // defined EDITOR + SetDlgItemText(hwndDlg,IDC_TEXT,NULL); + SendMessage(hwndDlg,M_LOADHELP,0,0); +#ifdef EDITOR + ShowWindow(hwndDlg,SW_SHOWNORMAL); +#else + SendDlgItemMessage(hwndDlg,IDC_TEXT,EM_REQUESTRESIZE,0,0); + return FALSE; +#endif + return TRUE; + case M_HELPLOADFAILED: + if(hwndCtl!=(HWND)lParam) break; +#ifdef EDITOR + EnableWindow(GetDlgItem(hwndDlg,IDC_TEXT),TRUE); + { TCHAR text[2024]; + GetControlTitle(hwndCtl,text,SIZEOF(text)); + SetDlgItemText(hwndDlg,IDC_CTLTEXT,text); + } +#else + SetDlgItemText(hwndDlg,IDC_CTLTEXT,TranslateT("No Help Pack installed!")); +#endif + SetDlgItemText(hwndDlg,IDC_TEXT,NULL); + MessageBeep(MB_ICONERROR); + break; +#ifdef EDITOR + case M_SAVECOMPLETE: +#endif + case M_HELPLOADED: + if(hwndCtl!=(HWND)lParam) break; + case M_LOADHELP: + { TCHAR *szTitle; + char *szText; + char *szDlgId,*szModule; + UINT codepage; + BOOL isRTL; + int id,loading; +#ifdef EDITOR + EnableWindow(GetDlgItem(hwndDlg,IDC_TEXT),TRUE); +#endif + szDlgId=CreateDialogIdString(GetControlDialog(hwndCtl)); + szModule=GetControlModuleName(hwndCtl); + id=GetControlID(hwndCtl); +#ifndef EDITOR + // show id string instead of help text when 'ctrl' key pressed + if(msg==M_LOADHELP && GetAsyncKeyState(VK_CONTROL)&0x8000) { + char *buf; + HWND hwnd; + buf=CreateControlIdentifier(szDlgId?szDlgId:"unknown",szModule?szModule:"unknown",id,hwndCtl); + hwnd=GetDlgItem(hwndDlg,IDC_CTLTEXT); + SetWindowTextA(hwnd,buf); // accepts NULL + SetDlgItemText(hwndDlg,IDC_TEXT,NULL); + mir_free(buf); // does NULL check + mir_free(szDlgId); // does NULL check + mir_free(szModule); // does NULL check + break; + } +#endif + if(szDlgId==NULL || szModule==NULL) { + SetDlgItemText(hwndDlg,IDC_TEXT,NULL); +#ifndef EDITOR + SetDlgItemText(hwndDlg,IDC_CTLTEXT,TranslateT("No help available for this item.")); +#endif + mir_free(szDlgId); // does NULL check + mir_free(szModule); // does NULL check + break; + } + + loading=GetControlHelp(hwndCtl,szDlgId,szModule,id,&szTitle,&szText,NULL,&locale,&codepage,&isRTL,(msg==M_HELPLOADED)?GCHF_DONTLOAD:0); + if(!loading) { + if(szText) StreamInHtml(GetDlgItem(hwndDlg,IDC_TEXT),szText,codepage,RGB(255,0,0)); + else SetDlgItemText(hwndDlg,IDC_TEXT,NULL); + if(szTitle) { + TCHAR buf[128]; + RECT rc; + HFONT hFontPrev; + DWORD exStyle; + HWND hwndCtlText; + HDC hdc; + hwndCtlText=GetDlgItem(hwndDlg,IDC_CTLTEXT); + exStyle=GetWindowLong(GetDlgItem(hwndDlg,IDC_CTLTEXT),GWL_EXSTYLE); + hdc=GetDC(hwndCtlText); + { DWORD (WINAPI *pfnGetLayout)(HDC); // obey right-to-left languages + *(FARPROC*)&pfnGetLayout=GetProcAddress(GetModuleHandleA("GDI32"),"GetLayout"); + if(pfnGetLayout) isRTL=(isRTL && !pfnGetLayout(hdc)); + if(isRTL) exStyle|=WS_EX_RTLREADING|WS_EX_RIGHT; + else exStyle&=~(WS_EX_RTLREADING|WS_EX_RIGHT); + } + mir_sntprintf(buf,SIZEOF(buf)-4,_T("%s"),szTitle); + if(hdc!=NULL && hwndCtlText!=NULL) { + SendMessage(hwndCtlText,EM_GETRECT,0,(LPARAM)&rc); + hFontPrev=SelectObject(hdc,(HFONT)SendMessage(hwndCtlText,WM_GETFONT,0,0)); + // doesn't actually draw the string due to DT_CALCRECT + DrawTextEx(hdc,buf,-1,&rc,DT_MODIFYSTRING|DT_CALCRECT|DT_EDITCONTROL|DT_END_ELLIPSIS|DT_INTERNAL|(isRTL?(DT_RTLREADING|DT_RIGHT):DT_LEFT)|DT_NOPREFIX|DT_SINGLELINE,NULL); + SelectObject(hdc,hFontPrev); + ReleaseDC(hwndCtlText,hdc); + } + SetWindowLong(GetDlgItem(hwndDlg,IDC_CTLTEXT),GWL_EXSTYLE,exStyle); + SetWindowText(hwndCtlText,buf); + } else SetDlgItemText(hwndDlg,IDC_CTLTEXT,NULL); + } + else { + if(msg==M_HELPLOADED) { + SetDlgItemText(hwndDlg,IDC_TEXT,NULL); +#ifndef EDITOR + SetDlgItemText(hwndDlg,IDC_CTLTEXT,TranslateT("No help available for this item.")); +#endif + } + else { +#ifdef EDITOR + EnableWindow(GetDlgItem(hwndDlg,IDC_TEXT),FALSE); + SetDlgItemText(hwndDlg,IDC_TEXT,TranslateT("Loading...")); +#else + SetDlgItemText(hwndDlg,IDC_CTLTEXT,TranslateT("Loading...")); + SetDlgItemText(hwndDlg,IDC_TEXT,NULL); +#endif + } + } + mir_free(szDlgId); + mir_free(szModule); + break; + } + case WM_NOTIFY: + switch(((NMHDR*)lParam)->idFrom) { + case IDC_TEXT: + switch(((NMHDR*)lParam)->code) { +#ifdef EDITOR + case EN_MSGFILTER: + switch(((MSGFILTER*)lParam)->msg) { + case WM_CHAR: + switch(((MSGFILTER*)lParam)->wParam) { + case 'B'-'A'+1: + case 'I'-'A'+1: + case 'U'-'A'+1: + case 'H'-'A'+1: + case 'L'-'A'+1: + case 'S'-'A'+1: + case 'G'-'A'+1: + SetWindowLong(hwndDlg,DWL_MSGRESULT,TRUE); + return TRUE; + } + break; + case WM_KEYDOWN: + { CHARFORMAT cf; + int changes=0; + + ZeroMemory(&cf,sizeof(cf)); + if(!(GetKeyState(VK_CONTROL)&0x8000)) break; + cf.cbSize=sizeof(cf); + SendDlgItemMessage(hwndDlg,IDC_TEXT,EM_GETCHARFORMAT,TRUE,(LPARAM)&cf); + switch(((MSGFILTER*)lParam)->wParam) { + case 'B': + cf.dwEffects^=CFE_BOLD; + cf.dwMask=CFM_BOLD; + changes=1; + break; + case 'I': + cf.dwEffects^=CFE_ITALIC; + cf.dwMask=CFM_ITALIC; + changes=1; + break; + case 'U': + cf.dwEffects^=CFE_UNDERLINE; + cf.dwMask=CFM_UNDERLINE; + changes=1; + break; + case 'L': + { CHOOSECOLOR cc; + COLORREF custCol[16]; + ZeroMemory(&custCol,sizeof(custCol)); + ZeroMemory(&cc,sizeof(cc)); + cc.lStructSize=sizeof(cc); + cc.hwndOwner=hwndDlg; + cc.lpCustColors=custCol; + cc.rgbResult=cf.crTextColor; + cc.Flags=CC_ANYCOLOR|CC_FULLOPEN|CC_RGBINIT; + if(!ChooseColor(&cc)) break; + cf.crTextColor=0; + cf.dwEffects=0; + if(cc.rgbResult) cf.crTextColor=cc.rgbResult; + else cf.dwEffects=CFE_AUTOCOLOR; + cf.dwMask=CFM_COLOR; + changes=1; + break; + } + case 'H': + cf.dwEffects^=CFE_STRIKEOUT; + cf.dwMask=CFM_STRIKEOUT; + changes=1; + break; + case VK_OEM_PLUS: + cf.yHeight=((GetKeyState(VK_SHIFT)&0x8000)?TEXTSIZE_BIG:TEXTSIZE_NORMAL)*10; + cf.dwMask=CFM_SIZE; + changes=1; + break; + case VK_OEM_MINUS: + cf.yHeight=TEXTSIZE_SMALL*10; + cf.dwMask=CFM_SIZE; + changes=1; + break; + case 'S': + { TCHAR szTitle[1024]; + char *szText,*szDlgId,*szModule; + if(!GetDlgItemText(hwndDlg,IDC_CTLTEXT,szTitle,SIZEOF(szTitle))) break; + szDlgId=CreateDialogIdString(GetControlDialog(hwndCtl)); + if(szDlgId==NULL) break; + szText=StreamOutHtml(GetDlgItem(hwndDlg,IDC_TEXT)); + szModule=GetControlModuleName(hwndCtl); + if(szModule==NULL) { + mir_free(szDlgId); + break; + } + SetControlHelp(szDlgId,szModule,GetControlID(hwndCtl),szTitle,szText,GetControlType(hwndCtl)); + mir_free(szText); + mir_free(szDlgId); + mir_free(szModule); + SaveDialogCache(); + SetWindowLong(hwndDlg,DWL_MSGRESULT,TRUE); + return TRUE; + } + case 'G': + SendMessage(hwndDlg,M_LOADHELP,0,0); + SetWindowLong(hwndDlg,DWL_MSGRESULT,TRUE); + return TRUE; + } + if(changes) { + SendDlgItemMessage(hwndDlg,IDC_TEXT,EM_SETCHARFORMAT,SCF_WORD|SCF_SELECTION,(LPARAM)&cf); + SetWindowLong(hwndDlg,DWL_MSGRESULT,TRUE); + return TRUE; + } + break; + } + } + break; +#else // defined EDITOR + case EN_MSGFILTER: + { MSGFILTER *msgf=(MSGFILTER*)lParam; + switch(msgf->msg) { + case WM_LBUTTONUP: + { POINT pt; + DWORD pos; + CHARRANGE sel; + char *pszLink; + HWND hwndEdit=msgf->nmhdr.hwndFrom; + + ZeroMemory(&sel,sizeof(sel)); + SendMessage(msgf->nmhdr.hwndFrom,EM_EXGETSEL,0,(LPARAM)&sel); + if(sel.cpMin!=sel.cpMax) break; + POINTSTOPOINT(pt,MAKEPOINTS(msgf->lParam)); + pos=SendMessage(hwndEdit,EM_CHARFROMPOS,0,(WPARAM)&pt); + if(IsHyperlink(pos,NULL,NULL,&pszLink)) { + CallService(MS_UTILS_OPENURL,1,(LPARAM)pszLink); // pszLink is MBCS string in CP_ACP + SetWindowLong(hwndDlg,DWL_MSGRESULT,TRUE); + return TRUE; + } + } + break; + case WM_MOUSEMOVE: // register hyperlink tooltips when current + if(hwndToolTip!=NULL) { + POINTL pt; + DWORD pos; + CHARRANGE rng; + char *pszLink; + + POINTSTOPOINT(pt,MAKEPOINTS(msgf->lParam)); + pos=SendMessage(msgf->nmhdr.hwndFrom,EM_CHARFROMPOS,0,(WPARAM)&pt); + if(IsHyperlink(pos,&rng.cpMin,&rng.cpMax,&pszLink)) { // pszLink is MBCS in CP_ACP + TTTOOLINFOA ti; + ZeroMemory(&ti,sizeof(ti)); + ti.cbSize=sizeof(ti); + ti.hwnd=msgf->nmhdr.hwndFrom; + ti.uId=(UINT)rng.cpMin; + if(!SendMessage(hwndToolTip,TTM_GETTOOLINFOA,0,(LPARAM)&ti)) { + LONG cpRectMin; + ti.uFlags=TTF_SUBCLASS; + ti.lpszText=pszLink; + cpRectMin=rng.cpMin; + while(!GetCharRangeRect(ti.hwnd,&rng.cpMin,rng.cpMax,&ti.rect)) { + ti.uId=(UINT)cpRectMin; + SendMessage(hwndToolTip,TTM_ADDTOOLA,0,(LPARAM)&ti); + cpRectMin=rng.cpMin; + } + } + } + } + break; + } + } + break; + case EN_REQUESTRESIZE: + { RECT rcDlg,rcEdit,rcCtl,rcNew; + REQRESIZE *rr=(REQRESIZE*)lParam; + POINT ptScreenBottomRight; + + if(!GetWindowRect(hwndDlg,&rcDlg)) break; + if(!GetWindowRect(hwndCtl,&rcCtl)) break; + if(!GetWindowRect(GetDlgItem(hwndDlg,IDC_TEXT),&rcEdit)) break; + rcNew.left=rcCtl.left+30; + rcNew.top=rcCtl.bottom+10; + rcNew.right=rcNew.left+(rr->rc.right-rr->rc.left)+(rcDlg.right-rcDlg.left)-(rcEdit.right-rcEdit.left)+(GetWindowLong(GetDlgItem(hwndDlg,IDC_TEXT),GWL_STYLE)&WS_VSCROLL?GetSystemMetrics(SM_CXVSCROLL):0); + if(GetWindowTextLength(GetDlgItem(hwndDlg,IDC_TEXT))) + rcNew.bottom=rcNew.top+min(GetSystemMetrics(SM_CYSCREEN)/5,(rr->rc.bottom-rr->rc.top)+(rcDlg.bottom-rcDlg.top)-(rcEdit.bottom-rcEdit.top)); + else + rcNew.bottom=rcNew.top+min(GetSystemMetrics(SM_CYSCREEN)/5,(rcDlg.bottom-rcDlg.top)-(rcEdit.bottom-rcEdit.top)); + if(GetSystemMetrics(SM_CXVIRTUALSCREEN)) { + ptScreenBottomRight.x=GetSystemMetrics(SM_CXVIRTUALSCREEN)+GetSystemMetrics(SM_XVIRTUALSCREEN); + ptScreenBottomRight.y=GetSystemMetrics(SM_CYVIRTUALSCREEN)+GetSystemMetrics(SM_YVIRTUALSCREEN); + } + else { + ptScreenBottomRight.x=GetSystemMetrics(SM_CXSCREEN); + ptScreenBottomRight.y=GetSystemMetrics(SM_CYSCREEN); + } + if(rcNew.right>=ptScreenBottomRight.x) OffsetRect(&rcNew,ptScreenBottomRight.x-rcNew.right,0); + if(rcNew.bottom>=ptScreenBottomRight.y) OffsetRect(&rcNew,0,ptScreenBottomRight.y-rcNew.bottom); + SetWindowPos(hwndDlg,0,rcNew.left,rcNew.top,rcNew.right-rcNew.left,rcNew.bottom-rcNew.top,SWP_NOZORDER); + ShowWindow(hwndDlg,SW_SHOWNORMAL); + break; + } +#endif // defined EDITOR + } + } + break; + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDCANCEL: // WM_CLOSE + DestroyWindow(hwndDlg); + return TRUE; + } + break; + case WM_DESTROY: +#ifndef EDITOR + FreeHyperlinkData(); + if(IsWindow(hwndShadowDlg)) DestroyWindow(hwndShadowDlg); + if(hwndToolTip!=NULL) DestroyWindow(hwndToolTip); +#endif + hwndHelpDlg=NULL; + break; + } + return FALSE; +} -- cgit v1.2.3