UIRichEdit.cpp 73 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804
  1. #include "StdAfx.h"
  2. #include "UIRichEdit.h"
  3. #ifdef _USEIMM
  4. #include <imm.h>
  5. #pragma comment(lib, "imm32.lib")
  6. #endif
  7. // These constants are for backward compatibility. They are the
  8. // sizes used for initialization and reset in RichEdit 1.0
  9. namespace DuiLib {
  10. #define ID_RICH_UNDO 101
  11. #define ID_RICH_CUT 102
  12. #define ID_RICH_COPY 103
  13. #define ID_RICH_PASTE 104
  14. #define ID_RICH_CLEAR 105
  15. #define ID_RICH_SELECTALL 106
  16. #define ID_RICH_REDO 107
  17. const LONG cInitTextMax = (32 * 1024) - 1;
  18. EXTERN_C const IID IID_ITextServices = { // 8d33f740-cf58-11ce-a89d-00aa006cadc5
  19. 0x8d33f740,
  20. 0xcf58,
  21. 0x11ce,
  22. {0xa8, 0x9d, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5}
  23. };
  24. EXTERN_C const IID IID_ITextHost = { /* c5bdd8d0-d26e-11ce-a89e-00aa006cadc5 */
  25. 0xc5bdd8d0,
  26. 0xd26e,
  27. 0x11ce,
  28. {0xa8, 0x9e, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5}
  29. };
  30. #ifndef LY_PER_INCH
  31. #define LY_PER_INCH 1440
  32. #endif
  33. #ifndef HIMETRIC_PER_INCH
  34. #define HIMETRIC_PER_INCH 2540
  35. #endif
  36. #include <textserv.h>
  37. class CTxtWinHost : public ITextHost
  38. {
  39. public:
  40. CTxtWinHost();
  41. BOOL Init(CRichEditUI *re , const CREATESTRUCT *pcs);
  42. virtual ~CTxtWinHost();
  43. ITextServices* GetTextServices(void) { return pserv; }
  44. void SetClientRect(RECT *prc);
  45. RECT* GetClientRect() { return &rcClient; }
  46. BOOL IsWordWrap(void) { return fWordWrap; }
  47. void SetWordWrap(BOOL fWordWrap);
  48. BOOL IsReadOnly();
  49. void SetReadOnly(BOOL fReadOnly);
  50. void SetFont(HFONT hFont);
  51. void SetColor(DWORD dwColor);
  52. SIZEL* GetExtent();
  53. void SetExtent(SIZEL *psizelExtent);
  54. void LimitText(LONG nChars);
  55. BOOL IsCaptured();
  56. BOOL IsShowCaret();
  57. void NeedFreshCaret();
  58. INT GetCaretWidth();
  59. INT GetCaretHeight();
  60. BOOL GetAllowBeep();
  61. void SetAllowBeep(BOOL fAllowBeep);
  62. WORD GetDefaultAlign();
  63. void SetDefaultAlign(WORD wNewAlign);
  64. BOOL GetRichTextFlag();
  65. void SetRichTextFlag(BOOL fNew);
  66. LONG GetDefaultLeftIndent();
  67. void SetDefaultLeftIndent(LONG lNewIndent);
  68. BOOL SetSaveSelection(BOOL fSaveSelection);
  69. HRESULT OnTxInPlaceDeactivate();
  70. HRESULT OnTxInPlaceActivate(LPCRECT prcClient);
  71. BOOL GetActiveState(void) { return fInplaceActive; }
  72. BOOL DoSetCursor(RECT *prc, POINT *pt);
  73. void SetTransparent(BOOL fTransparent);
  74. void GetControlRect(LPRECT prc);
  75. LONG SetAccelPos(LONG laccelpos);
  76. WCHAR SetPasswordChar(WCHAR chPasswordChar);
  77. void SetDisabled(BOOL fOn);
  78. LONG SetSelBarWidth(LONG lSelBarWidth);
  79. BOOL GetTimerState();
  80. void SetCharFormat(CHARFORMAT2W &c);
  81. void SetParaFormat(PARAFORMAT2 &p);
  82. // -----------------------------
  83. // IUnknown interface
  84. // -----------------------------
  85. virtual HRESULT _stdcall QueryInterface(REFIID riid, void **ppvObject);
  86. virtual ULONG _stdcall AddRef(void);
  87. virtual ULONG _stdcall Release(void);
  88. // -----------------------------
  89. // ITextHost interface
  90. // -----------------------------
  91. virtual HDC TxGetDC();
  92. virtual INT TxReleaseDC(HDC hdc);
  93. virtual BOOL TxShowScrollBar(INT fnBar, BOOL fShow);
  94. virtual BOOL TxEnableScrollBar (INT fuSBFlags, INT fuArrowflags);
  95. virtual BOOL TxSetScrollRange(INT fnBar, LONG nMinPos, INT nMaxPos, BOOL fRedraw);
  96. virtual BOOL TxSetScrollPos (INT fnBar, INT nPos, BOOL fRedraw);
  97. virtual void TxInvalidateRect(LPCRECT prc, BOOL fMode);
  98. virtual void TxViewChange(BOOL fUpdate);
  99. virtual BOOL TxCreateCaret(HBITMAP hbmp, INT xWidth, INT yHeight);
  100. virtual BOOL TxShowCaret(BOOL fShow);
  101. virtual BOOL TxSetCaretPos(INT x, INT y);
  102. virtual BOOL TxSetTimer(UINT idTimer, UINT uTimeout);
  103. virtual void TxKillTimer(UINT idTimer);
  104. virtual void TxScrollWindowEx (INT dx, INT dy, LPCRECT lprcScroll, LPCRECT lprcClip, HRGN hrgnUpdate, LPRECT lprcUpdate, UINT fuScroll);
  105. virtual void TxSetCapture(BOOL fCapture);
  106. virtual void TxSetFocus();
  107. virtual void TxSetCursor(HCURSOR hcur, BOOL fText);
  108. virtual BOOL TxScreenToClient (LPPOINT lppt);
  109. virtual BOOL TxClientToScreen (LPPOINT lppt);
  110. virtual HRESULT TxActivate( LONG * plOldState );
  111. virtual HRESULT TxDeactivate( LONG lNewState );
  112. virtual HRESULT TxGetClientRect(LPRECT prc);
  113. virtual HRESULT TxGetViewInset(LPRECT prc);
  114. virtual HRESULT TxGetCharFormat(const CHARFORMATW **ppCF );
  115. virtual HRESULT TxGetParaFormat(const PARAFORMAT **ppPF);
  116. virtual COLORREF TxGetSysColor(int nIndex);
  117. virtual HRESULT TxGetBackStyle(TXTBACKSTYLE *pstyle);
  118. virtual HRESULT TxGetMaxLength(DWORD *plength);
  119. virtual HRESULT TxGetScrollBars(DWORD *pdwScrollBar);
  120. virtual HRESULT TxGetPasswordChar(TCHAR *pch);
  121. virtual HRESULT TxGetAcceleratorPos(LONG *pcp);
  122. virtual HRESULT TxGetExtent(LPSIZEL lpExtent);
  123. virtual HRESULT OnTxCharFormatChange (const CHARFORMATW * pcf);
  124. virtual HRESULT OnTxParaFormatChange (const PARAFORMAT * ppf);
  125. virtual HRESULT TxGetPropertyBits(DWORD dwMask, DWORD *pdwBits);
  126. virtual HRESULT TxNotify(DWORD iNotify, void *pv);
  127. virtual HIMC TxImmGetContext(void);
  128. virtual void TxImmReleaseContext(HIMC himc);
  129. virtual HRESULT TxGetSelectionBarWidth (LONG *lSelBarWidth);
  130. private:
  131. CRichEditUI *m_re;
  132. ULONG cRefs; // Reference Count
  133. ITextServices *pserv; // pointer to Text Services object
  134. // Properties
  135. DWORD dwStyle; // style bits
  136. unsigned fEnableAutoWordSel :1; // enable Word style auto word selection?
  137. unsigned fWordWrap :1; // Whether control should word wrap
  138. unsigned fAllowBeep :1; // Whether beep is allowed
  139. unsigned fRich :1; // Whether control is rich text
  140. unsigned fSaveSelection :1; // Whether to save the selection when inactive
  141. unsigned fInplaceActive :1; // Whether control is inplace active
  142. unsigned fTransparent :1; // Whether control is transparent
  143. unsigned fTimer :1; // A timer is set
  144. unsigned fCaptured :1;
  145. unsigned fShowCaret :1;
  146. unsigned fNeedFreshCaret :1; // 修正改变大小后点击其他位置原来光标不能消除的问题
  147. INT iCaretWidth;
  148. INT iCaretHeight;
  149. INT iCaretLastWidth;
  150. INT iCaretLastHeight;
  151. LONG lSelBarWidth; // Width of the selection bar
  152. LONG cchTextMost; // maximum text size
  153. DWORD dwEventMask; // DoEvent mask to pass on to parent window
  154. LONG icf;
  155. LONG ipf;
  156. RECT rcClient; // Client Rect for this control
  157. SIZEL sizelExtent; // Extent array
  158. CHARFORMAT2W cf; // Default character format
  159. PARAFORMAT2 pf; // Default paragraph format
  160. LONG laccelpos; // Accelerator position
  161. WCHAR chPasswordChar; // Password character
  162. };
  163. // Convert Pixels on the X axis to Himetric
  164. LONG DXtoHimetricX(LONG dx, LONG xPerInch)
  165. {
  166. return (LONG) MulDiv(dx, HIMETRIC_PER_INCH, xPerInch);
  167. }
  168. // Convert Pixels on the Y axis to Himetric
  169. LONG DYtoHimetricY(LONG dy, LONG yPerInch)
  170. {
  171. return (LONG) MulDiv(dy, HIMETRIC_PER_INCH, yPerInch);
  172. }
  173. HRESULT InitDefaultCharFormat(CRichEditUI* re, CHARFORMAT2W* pcf, HFONT hfont)
  174. {
  175. memset(pcf, 0, sizeof(CHARFORMAT2W));
  176. if(hfont == NULL) {
  177. hfont = re->GetManager()->GetFont(re->GetFont());
  178. }
  179. LOGFONT lf;
  180. ::GetObject(hfont, sizeof(LOGFONT), &lf);
  181. DWORD dwColor = re->GetTextColor();
  182. if(re->GetManager()->IsLayered()) {
  183. CRenderEngine::CheckAlphaColor(dwColor);
  184. }
  185. pcf->cbSize = sizeof(CHARFORMAT2W);
  186. pcf->crTextColor = RGB(GetBValue(dwColor), GetGValue(dwColor), GetRValue(dwColor));
  187. LONG yPixPerInch = GetDeviceCaps(re->GetManager()->GetPaintDC(), LOGPIXELSY);
  188. pcf->yHeight = -lf.lfHeight * LY_PER_INCH / yPixPerInch;
  189. pcf->yOffset = 0;
  190. pcf->dwEffects = 0;
  191. pcf->dwMask = CFM_SIZE | CFM_OFFSET | CFM_FACE | CFM_CHARSET | CFM_COLOR | CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE;
  192. if(lf.lfWeight >= FW_BOLD)
  193. pcf->dwEffects |= CFE_BOLD;
  194. if(lf.lfItalic)
  195. pcf->dwEffects |= CFE_ITALIC;
  196. if(lf.lfUnderline)
  197. pcf->dwEffects |= CFE_UNDERLINE;
  198. pcf->bCharSet = lf.lfCharSet;
  199. pcf->bPitchAndFamily = lf.lfPitchAndFamily;
  200. #ifdef _UNICODE
  201. _tcscpy(pcf->szFaceName, lf.lfFaceName);
  202. #else
  203. //need to thunk pcf->szFaceName to a standard char string.in this case it's easy because our thunk is also our copy
  204. MultiByteToWideChar(CP_ACP, 0, lf.lfFaceName, LF_FACESIZE, pcf->szFaceName, LF_FACESIZE) ;
  205. #endif
  206. return S_OK;
  207. }
  208. HRESULT InitDefaultParaFormat(CRichEditUI* re, PARAFORMAT2* ppf)
  209. {
  210. memset(ppf, 0, sizeof(PARAFORMAT2));
  211. ppf->cbSize = sizeof(PARAFORMAT2);
  212. ppf->dwMask = PFM_ALL;
  213. ppf->wAlignment = PFA_LEFT;
  214. ppf->cTabCount = 1;
  215. ppf->rgxTabs[0] = lDefaultTab;
  216. return S_OK;
  217. }
  218. HRESULT CreateHost(CRichEditUI *re, const CREATESTRUCT *pcs, CTxtWinHost **pptec)
  219. {
  220. HRESULT hr = E_FAIL;
  221. CTxtWinHost *phost = new CTxtWinHost();
  222. if(phost) {
  223. if (phost->Init(re, pcs)) {
  224. *pptec = phost;
  225. hr = S_OK;
  226. }
  227. }
  228. if (FAILED(hr)) {
  229. delete phost;
  230. }
  231. return TRUE;
  232. }
  233. CTxtWinHost::CTxtWinHost() : m_re(NULL)
  234. {
  235. ::ZeroMemory(&cRefs, sizeof(CTxtWinHost) - offsetof(CTxtWinHost, cRefs));
  236. cchTextMost = cInitTextMax;
  237. laccelpos = -1;
  238. }
  239. CTxtWinHost::~CTxtWinHost()
  240. {
  241. pserv->OnTxInPlaceDeactivate();
  242. pserv->Release();
  243. }
  244. ////////////////////// Create/Init/Destruct Commands ///////////////////////
  245. BOOL CTxtWinHost::Init(CRichEditUI *re, const CREATESTRUCT *pcs)
  246. {
  247. IUnknown *pUnk = NULL;
  248. HRESULT hr;
  249. m_re = re;
  250. // Initialize Reference count
  251. cRefs = 1;
  252. // Create and cache CHARFORMAT for this control
  253. if(FAILED(InitDefaultCharFormat(re, &cf, NULL)))
  254. goto err;
  255. // Create and cache PARAFORMAT for this control
  256. if(FAILED(InitDefaultParaFormat(re, &pf)))
  257. goto err;
  258. // edit controls created without a window are multiline by default
  259. // so that paragraph formats can be
  260. dwStyle = ES_MULTILINE;
  261. // edit controls are rich by default
  262. fRich = re->IsRich();
  263. cchTextMost = re->GetLimitText();
  264. if (pcs )
  265. {
  266. dwStyle = pcs->style;
  267. if ( !(dwStyle & (ES_AUTOHSCROLL | WS_HSCROLL)) )
  268. {
  269. fWordWrap = TRUE;
  270. }
  271. }
  272. if( !(dwStyle & ES_LEFT) )
  273. {
  274. if(dwStyle & ES_CENTER)
  275. pf.wAlignment = PFA_CENTER;
  276. else if(dwStyle & ES_RIGHT)
  277. pf.wAlignment = PFA_RIGHT;
  278. }
  279. fInplaceActive = TRUE;
  280. PCreateTextServices TextServicesProc = NULL;
  281. #ifdef _UNICODE
  282. HMODULE hmod = LoadLibrary(_T("Msftedit.dll"));
  283. #else
  284. HMODULE hmod = LoadLibrary(_T("Riched20.dll"));
  285. #endif
  286. if (hmod) {
  287. TextServicesProc = (PCreateTextServices)GetProcAddress(hmod,"CreateTextServices");
  288. }
  289. if (TextServicesProc != NULL) {
  290. HRESULT hr = TextServicesProc(NULL, this, &pUnk);
  291. }
  292. hr = pUnk->QueryInterface(IID_ITextServices,(void **)&pserv);
  293. // Whether the previous call succeeded or failed we are done
  294. // with the private interface.
  295. pUnk->Release();
  296. if(FAILED(hr))
  297. {
  298. goto err;
  299. }
  300. // Set window text
  301. if(pcs && pcs->lpszName)
  302. {
  303. #ifdef _UNICODE
  304. if(FAILED(pserv->TxSetText((TCHAR *)pcs->lpszName)))
  305. goto err;
  306. #else
  307. size_t iLen = _tcslen(pcs->lpszName);
  308. LPWSTR lpText = new WCHAR[iLen + 1];
  309. ::ZeroMemory(lpText, (iLen + 1) * sizeof(WCHAR));
  310. ::MultiByteToWideChar(CP_ACP, 0, pcs->lpszName, -1, (LPWSTR)lpText, iLen) ;
  311. if(FAILED(pserv->TxSetText((LPWSTR)lpText))) {
  312. delete[] lpText;
  313. goto err;
  314. }
  315. delete[] lpText;
  316. #endif
  317. }
  318. return TRUE;
  319. err:
  320. return FALSE;
  321. }
  322. ///////////////////////////////// IUnknown ////////////////////////////////
  323. HRESULT CTxtWinHost::QueryInterface(REFIID riid, void **ppvObject)
  324. {
  325. HRESULT hr = E_NOINTERFACE;
  326. *ppvObject = NULL;
  327. if (IsEqualIID(riid, IID_IUnknown)
  328. || IsEqualIID(riid, IID_ITextHost))
  329. {
  330. AddRef();
  331. *ppvObject = (ITextHost *) this;
  332. hr = S_OK;
  333. }
  334. return hr;
  335. }
  336. ULONG CTxtWinHost::AddRef(void)
  337. {
  338. return ++cRefs;
  339. }
  340. ULONG CTxtWinHost::Release(void)
  341. {
  342. ULONG c_Refs = --cRefs;
  343. if (c_Refs == 0)
  344. {
  345. delete this;
  346. }
  347. return c_Refs;
  348. }
  349. ///////////////////////////////// Far East Support //////////////////////////////////////
  350. HIMC CTxtWinHost::TxImmGetContext(void)
  351. {
  352. return NULL;
  353. }
  354. void CTxtWinHost::TxImmReleaseContext(HIMC himc)
  355. {
  356. //::ImmReleaseContext( hwnd, himc );
  357. }
  358. //////////////////////////// ITextHost Interface ////////////////////////////
  359. HDC CTxtWinHost::TxGetDC()
  360. {
  361. return m_re->GetManager()->GetPaintDC();
  362. }
  363. int CTxtWinHost::TxReleaseDC(HDC hdc)
  364. {
  365. return 1;
  366. }
  367. BOOL CTxtWinHost::TxShowScrollBar(INT fnBar, BOOL fShow)
  368. {
  369. CScrollBarUI* pVerticalScrollBar = m_re->GetVerticalScrollBar();
  370. CScrollBarUI* pHorizontalScrollBar = m_re->GetHorizontalScrollBar();
  371. if( fnBar == SB_VERT && pVerticalScrollBar ) {
  372. pVerticalScrollBar->SetVisible(fShow == TRUE);
  373. }
  374. else if( fnBar == SB_HORZ && pHorizontalScrollBar ) {
  375. pHorizontalScrollBar->SetVisible(fShow == TRUE);
  376. }
  377. else if( fnBar == SB_BOTH ) {
  378. if( pVerticalScrollBar ) pVerticalScrollBar->SetVisible(fShow == TRUE);
  379. if( pHorizontalScrollBar ) pHorizontalScrollBar->SetVisible(fShow == TRUE);
  380. }
  381. return TRUE;
  382. }
  383. BOOL CTxtWinHost::TxEnableScrollBar (INT fuSBFlags, INT fuArrowflags)
  384. {
  385. if( fuSBFlags == SB_VERT ) {
  386. m_re->EnableScrollBar(true, m_re->GetHorizontalScrollBar() != NULL);
  387. m_re->GetVerticalScrollBar()->SetVisible(fuArrowflags != ESB_DISABLE_BOTH);
  388. }
  389. else if( fuSBFlags == SB_HORZ ) {
  390. m_re->EnableScrollBar(m_re->GetVerticalScrollBar() != NULL, true);
  391. m_re->GetHorizontalScrollBar()->SetVisible(fuArrowflags != ESB_DISABLE_BOTH);
  392. }
  393. else if( fuSBFlags == SB_BOTH ) {
  394. m_re->EnableScrollBar(true, true);
  395. m_re->GetVerticalScrollBar()->SetVisible(fuArrowflags != ESB_DISABLE_BOTH);
  396. m_re->GetHorizontalScrollBar()->SetVisible(fuArrowflags != ESB_DISABLE_BOTH);
  397. }
  398. return TRUE;
  399. }
  400. BOOL CTxtWinHost::TxSetScrollRange(INT fnBar, LONG nMinPos, INT nMaxPos, BOOL fRedraw)
  401. {
  402. CScrollBarUI* pVerticalScrollBar = m_re->GetVerticalScrollBar();
  403. CScrollBarUI* pHorizontalScrollBar = m_re->GetHorizontalScrollBar();
  404. if( fnBar == SB_VERT && pVerticalScrollBar ) {
  405. if( nMaxPos - nMinPos - rcClient.bottom + rcClient.top <= 0 ) {
  406. pVerticalScrollBar->SetVisible(false);
  407. }
  408. else {
  409. pVerticalScrollBar->SetVisible(true);
  410. pVerticalScrollBar->SetScrollRange(nMaxPos - nMinPos - rcClient.bottom + rcClient.top);
  411. }
  412. }
  413. else if( fnBar == SB_HORZ && pHorizontalScrollBar ) {
  414. if( nMaxPos - nMinPos - rcClient.right + rcClient.left <= 0 ) {
  415. pHorizontalScrollBar->SetVisible(false);
  416. }
  417. else {
  418. pHorizontalScrollBar->SetVisible(true);
  419. pHorizontalScrollBar->SetScrollRange(nMaxPos - nMinPos - rcClient.right + rcClient.left);
  420. }
  421. }
  422. return TRUE;
  423. }
  424. BOOL CTxtWinHost::TxSetScrollPos (INT fnBar, INT nPos, BOOL fRedraw)
  425. {
  426. CScrollBarUI* pVerticalScrollBar = m_re->GetVerticalScrollBar();
  427. CScrollBarUI* pHorizontalScrollBar = m_re->GetHorizontalScrollBar();
  428. if( fnBar == SB_VERT && pVerticalScrollBar ) {
  429. pVerticalScrollBar->SetScrollPos(nPos);
  430. }
  431. else if( fnBar == SB_HORZ && pHorizontalScrollBar ) {
  432. pHorizontalScrollBar->SetScrollPos(nPos);
  433. }
  434. return TRUE;
  435. }
  436. void CTxtWinHost::TxInvalidateRect(LPCRECT prc, BOOL fMode)
  437. {
  438. if( prc == NULL ) {
  439. m_re->GetManager()->Invalidate(rcClient);
  440. return;
  441. }
  442. RECT rc = *prc;
  443. m_re->GetManager()->Invalidate(rc);
  444. }
  445. void CTxtWinHost::TxViewChange(BOOL fUpdate)
  446. {
  447. if( m_re->OnTxViewChanged() ) m_re->Invalidate();
  448. }
  449. BOOL CTxtWinHost::TxCreateCaret(HBITMAP hbmp, INT xWidth, INT yHeight)
  450. {
  451. iCaretWidth = xWidth;
  452. iCaretHeight = yHeight;
  453. return ::CreateCaret(m_re->GetManager()->GetPaintWindow(), hbmp, xWidth, yHeight);
  454. }
  455. BOOL CTxtWinHost::TxShowCaret(BOOL fShow)
  456. {
  457. fShowCaret = fShow;
  458. if(fShow)
  459. return ::ShowCaret(m_re->GetManager()->GetPaintWindow());
  460. else
  461. return ::HideCaret(m_re->GetManager()->GetPaintWindow());
  462. }
  463. BOOL CTxtWinHost::TxSetCaretPos(INT x, INT y)
  464. {
  465. POINT ptCaret = { 0 };
  466. ::GetCaretPos(&ptCaret);
  467. RECT rcCaret = { ptCaret.x, ptCaret.y, ptCaret.x + iCaretLastWidth, ptCaret.y + iCaretLastHeight };
  468. if( m_re->GetManager()->IsLayered() ) m_re->GetManager()->Invalidate(rcCaret);
  469. else if( fNeedFreshCaret == TRUE ) {
  470. m_re->GetManager()->Invalidate(rcCaret);
  471. fNeedFreshCaret = FALSE;
  472. }
  473. rcCaret.left = x;
  474. rcCaret.top = y;
  475. rcCaret.right = x + iCaretWidth;
  476. rcCaret.bottom = y + iCaretHeight;
  477. if( m_re->GetManager()->IsLayered() ) m_re->GetManager()->Invalidate(rcCaret);
  478. iCaretLastWidth = iCaretWidth;
  479. iCaretLastHeight = iCaretHeight;
  480. return ::SetCaretPos(x, y);
  481. }
  482. BOOL CTxtWinHost::TxSetTimer(UINT idTimer, UINT uTimeout)
  483. {
  484. fTimer = TRUE;
  485. return m_re->GetManager()->SetTimer(m_re, idTimer, uTimeout) == TRUE;
  486. }
  487. void CTxtWinHost::TxKillTimer(UINT idTimer)
  488. {
  489. m_re->GetManager()->KillTimer(m_re, idTimer);
  490. fTimer = FALSE;
  491. }
  492. void CTxtWinHost::TxScrollWindowEx (INT dx, INT dy, LPCRECT lprcScroll, LPCRECT lprcClip, HRGN hrgnUpdate, LPRECT lprcUpdate, UINT fuScroll)
  493. {
  494. return;
  495. }
  496. void CTxtWinHost::TxSetCapture(BOOL fCapture)
  497. {
  498. if (fCapture) m_re->GetManager()->SetCapture();
  499. else m_re->GetManager()->ReleaseCapture();
  500. fCaptured = fCapture;
  501. }
  502. void CTxtWinHost::TxSetFocus()
  503. {
  504. m_re->SetFocus();
  505. }
  506. void CTxtWinHost::TxSetCursor(HCURSOR hcur, BOOL fText)
  507. {
  508. ::SetCursor(hcur);
  509. }
  510. BOOL CTxtWinHost::TxScreenToClient(LPPOINT lppt)
  511. {
  512. return ::ScreenToClient(m_re->GetManager()->GetPaintWindow(), lppt);
  513. }
  514. BOOL CTxtWinHost::TxClientToScreen(LPPOINT lppt)
  515. {
  516. return ::ClientToScreen(m_re->GetManager()->GetPaintWindow(), lppt);
  517. }
  518. HRESULT CTxtWinHost::TxActivate(LONG *plOldState)
  519. {
  520. return S_OK;
  521. }
  522. HRESULT CTxtWinHost::TxDeactivate(LONG lNewState)
  523. {
  524. return S_OK;
  525. }
  526. HRESULT CTxtWinHost::TxGetClientRect(LPRECT prc)
  527. {
  528. *prc = rcClient;
  529. GetControlRect(prc);
  530. return NOERROR;
  531. }
  532. HRESULT CTxtWinHost::TxGetViewInset(LPRECT prc)
  533. {
  534. prc->left = prc->right = prc->top = prc->bottom = 0;
  535. return NOERROR;
  536. }
  537. HRESULT CTxtWinHost::TxGetCharFormat(const CHARFORMATW **ppCF)
  538. {
  539. *ppCF = &cf;
  540. return NOERROR;
  541. }
  542. HRESULT CTxtWinHost::TxGetParaFormat(const PARAFORMAT **ppPF)
  543. {
  544. *ppPF = &pf;
  545. return NOERROR;
  546. }
  547. COLORREF CTxtWinHost::TxGetSysColor(int nIndex)
  548. {
  549. return ::GetSysColor(nIndex);
  550. }
  551. HRESULT CTxtWinHost::TxGetBackStyle(TXTBACKSTYLE *pstyle)
  552. {
  553. *pstyle = !fTransparent ? TXTBACK_OPAQUE : TXTBACK_TRANSPARENT;
  554. return NOERROR;
  555. }
  556. HRESULT CTxtWinHost::TxGetMaxLength(DWORD *pLength)
  557. {
  558. *pLength = cchTextMost;
  559. return NOERROR;
  560. }
  561. HRESULT CTxtWinHost::TxGetScrollBars(DWORD *pdwScrollBar)
  562. {
  563. *pdwScrollBar = dwStyle & (WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL |
  564. ES_AUTOHSCROLL | ES_DISABLENOSCROLL);
  565. return NOERROR;
  566. }
  567. HRESULT CTxtWinHost::TxGetPasswordChar(TCHAR *pch)
  568. {
  569. #ifdef _UNICODE
  570. *pch = chPasswordChar;
  571. #else
  572. ::WideCharToMultiByte(CP_ACP, 0, &chPasswordChar, 1, pch, 1, NULL, NULL) ;
  573. #endif
  574. return NOERROR;
  575. }
  576. HRESULT CTxtWinHost::TxGetAcceleratorPos(LONG *pcp)
  577. {
  578. *pcp = laccelpos;
  579. return S_OK;
  580. }
  581. HRESULT CTxtWinHost::OnTxCharFormatChange(const CHARFORMATW *pcf)
  582. {
  583. return S_OK;
  584. }
  585. HRESULT CTxtWinHost::OnTxParaFormatChange(const PARAFORMAT *ppf)
  586. {
  587. return S_OK;
  588. }
  589. HRESULT CTxtWinHost::TxGetPropertyBits(DWORD dwMask, DWORD *pdwBits)
  590. {
  591. DWORD dwProperties = 0;
  592. if (fRich)
  593. {
  594. dwProperties = TXTBIT_RICHTEXT;
  595. }
  596. if (dwStyle & ES_MULTILINE)
  597. {
  598. dwProperties |= TXTBIT_MULTILINE;
  599. }
  600. if (dwStyle & ES_READONLY)
  601. {
  602. dwProperties |= TXTBIT_READONLY;
  603. }
  604. if (dwStyle & ES_PASSWORD)
  605. {
  606. dwProperties |= TXTBIT_USEPASSWORD;
  607. }
  608. if (!(dwStyle & ES_NOHIDESEL))
  609. {
  610. dwProperties |= TXTBIT_HIDESELECTION;
  611. }
  612. if (fEnableAutoWordSel)
  613. {
  614. dwProperties |= TXTBIT_AUTOWORDSEL;
  615. }
  616. if (fWordWrap)
  617. {
  618. dwProperties |= TXTBIT_WORDWRAP;
  619. }
  620. if (fAllowBeep)
  621. {
  622. dwProperties |= TXTBIT_ALLOWBEEP;
  623. }
  624. if (fSaveSelection)
  625. {
  626. dwProperties |= TXTBIT_SAVESELECTION;
  627. }
  628. *pdwBits = dwProperties & dwMask;
  629. return NOERROR;
  630. }
  631. HRESULT CTxtWinHost::TxNotify(DWORD iNotify, void *pv)
  632. {
  633. if( iNotify == EN_REQUESTRESIZE ) {
  634. RECT rc;
  635. REQRESIZE *preqsz = (REQRESIZE *)pv;
  636. GetControlRect(&rc);
  637. rc.bottom = rc.top + preqsz->rc.bottom;
  638. rc.right = rc.left + preqsz->rc.right;
  639. SetClientRect(&rc);
  640. return S_OK;
  641. }
  642. m_re->OnTxNotify(iNotify, pv);
  643. return S_OK;
  644. }
  645. HRESULT CTxtWinHost::TxGetExtent(LPSIZEL lpExtent)
  646. {
  647. *lpExtent = sizelExtent;
  648. return S_OK;
  649. }
  650. HRESULT CTxtWinHost::TxGetSelectionBarWidth (LONG *plSelBarWidth)
  651. {
  652. *plSelBarWidth = lSelBarWidth;
  653. return S_OK;
  654. }
  655. void CTxtWinHost::SetWordWrap(BOOL _fWordWrap)
  656. {
  657. fWordWrap = _fWordWrap;
  658. pserv->OnTxPropertyBitsChange(TXTBIT_WORDWRAP, fWordWrap ? TXTBIT_WORDWRAP : 0);
  659. }
  660. BOOL CTxtWinHost::IsReadOnly()
  661. {
  662. return (dwStyle & ES_READONLY) != 0;
  663. }
  664. void CTxtWinHost::SetReadOnly(BOOL fReadOnly)
  665. {
  666. if (fReadOnly)
  667. {
  668. dwStyle |= ES_READONLY;
  669. }
  670. else
  671. {
  672. dwStyle &= ~ES_READONLY;
  673. }
  674. pserv->OnTxPropertyBitsChange(TXTBIT_READONLY,
  675. fReadOnly ? TXTBIT_READONLY : 0);
  676. }
  677. void CTxtWinHost::SetFont(HFONT hFont)
  678. {
  679. if( hFont == NULL ) return;
  680. LOGFONT lf;
  681. ::GetObject(hFont, sizeof(LOGFONT), &lf);
  682. LONG yPixPerInch = ::GetDeviceCaps(m_re->GetManager()->GetPaintDC(), LOGPIXELSY);
  683. cf.yHeight = -lf.lfHeight * LY_PER_INCH / yPixPerInch;
  684. if(lf.lfWeight >= FW_BOLD) cf.dwEffects |= CFE_BOLD;
  685. else cf.dwEffects &= ~CFE_BOLD;
  686. if(lf.lfItalic) cf.dwEffects |= CFE_ITALIC;
  687. else cf.dwEffects &= ~CFE_ITALIC;
  688. if(lf.lfUnderline) cf.dwEffects |= CFE_UNDERLINE;
  689. else cf.dwEffects &= ~CFE_UNDERLINE;
  690. cf.bCharSet = lf.lfCharSet;
  691. cf.bPitchAndFamily = lf.lfPitchAndFamily;
  692. #ifdef _UNICODE
  693. _tcscpy(cf.szFaceName, lf.lfFaceName);
  694. #else
  695. //need to thunk pcf->szFaceName to a standard char string.in this case it's easy because our thunk is also our copy
  696. MultiByteToWideChar(CP_ACP, 0, lf.lfFaceName, LF_FACESIZE, cf.szFaceName, LF_FACESIZE) ;
  697. #endif
  698. pserv->OnTxPropertyBitsChange(TXTBIT_CHARFORMATCHANGE,
  699. TXTBIT_CHARFORMATCHANGE);
  700. }
  701. void CTxtWinHost::SetColor(DWORD dwColor)
  702. {
  703. cf.crTextColor = RGB(GetBValue(dwColor), GetGValue(dwColor), GetRValue(dwColor));
  704. pserv->OnTxPropertyBitsChange(TXTBIT_CHARFORMATCHANGE,
  705. TXTBIT_CHARFORMATCHANGE);
  706. }
  707. SIZEL* CTxtWinHost::GetExtent()
  708. {
  709. return &sizelExtent;
  710. }
  711. void CTxtWinHost::SetExtent(SIZEL *psizelExtent)
  712. {
  713. sizelExtent = *psizelExtent;
  714. pserv->OnTxPropertyBitsChange(TXTBIT_EXTENTCHANGE, TXTBIT_EXTENTCHANGE);
  715. }
  716. void CTxtWinHost::LimitText(LONG nChars)
  717. {
  718. cchTextMost = nChars;
  719. if( cchTextMost <= 0 ) cchTextMost = cInitTextMax;
  720. pserv->OnTxPropertyBitsChange(TXTBIT_MAXLENGTHCHANGE, TXTBIT_MAXLENGTHCHANGE);
  721. }
  722. BOOL CTxtWinHost::IsCaptured()
  723. {
  724. return fCaptured;
  725. }
  726. BOOL CTxtWinHost::IsShowCaret()
  727. {
  728. return fShowCaret;
  729. }
  730. void CTxtWinHost::NeedFreshCaret()
  731. {
  732. fNeedFreshCaret = TRUE;
  733. }
  734. INT CTxtWinHost::GetCaretWidth()
  735. {
  736. return iCaretWidth;
  737. }
  738. INT CTxtWinHost::GetCaretHeight()
  739. {
  740. return iCaretHeight;
  741. }
  742. BOOL CTxtWinHost::GetAllowBeep()
  743. {
  744. return fAllowBeep;
  745. }
  746. void CTxtWinHost::SetAllowBeep(BOOL fAllowBeep)
  747. {
  748. fAllowBeep = fAllowBeep;
  749. pserv->OnTxPropertyBitsChange(TXTBIT_ALLOWBEEP,
  750. fAllowBeep ? TXTBIT_ALLOWBEEP : 0);
  751. }
  752. WORD CTxtWinHost::GetDefaultAlign()
  753. {
  754. return pf.wAlignment;
  755. }
  756. void CTxtWinHost::SetDefaultAlign(WORD wNewAlign)
  757. {
  758. pf.wAlignment = wNewAlign;
  759. // Notify control of property change
  760. pserv->OnTxPropertyBitsChange(TXTBIT_PARAFORMATCHANGE, 0);
  761. }
  762. BOOL CTxtWinHost::GetRichTextFlag()
  763. {
  764. return fRich;
  765. }
  766. void CTxtWinHost::SetRichTextFlag(BOOL fNew)
  767. {
  768. fRich = fNew;
  769. pserv->OnTxPropertyBitsChange(TXTBIT_RICHTEXT,
  770. fNew ? TXTBIT_RICHTEXT : 0);
  771. }
  772. LONG CTxtWinHost::GetDefaultLeftIndent()
  773. {
  774. return pf.dxOffset;
  775. }
  776. void CTxtWinHost::SetDefaultLeftIndent(LONG lNewIndent)
  777. {
  778. pf.dxOffset = lNewIndent;
  779. pserv->OnTxPropertyBitsChange(TXTBIT_PARAFORMATCHANGE, 0);
  780. }
  781. void CTxtWinHost::SetClientRect(RECT *prc)
  782. {
  783. rcClient = *prc;
  784. LONG xPerInch = ::GetDeviceCaps(m_re->GetManager()->GetPaintDC(), LOGPIXELSX);
  785. LONG yPerInch = ::GetDeviceCaps(m_re->GetManager()->GetPaintDC(), LOGPIXELSY);
  786. sizelExtent.cx = DXtoHimetricX(rcClient.right - rcClient.left, xPerInch);
  787. sizelExtent.cy = DYtoHimetricY(rcClient.bottom - rcClient.top, yPerInch);
  788. pserv->OnTxPropertyBitsChange(TXTBIT_VIEWINSETCHANGE, TXTBIT_VIEWINSETCHANGE);
  789. }
  790. BOOL CTxtWinHost::SetSaveSelection(BOOL f_SaveSelection)
  791. {
  792. BOOL fResult = f_SaveSelection;
  793. fSaveSelection = f_SaveSelection;
  794. // notify text services of property change
  795. pserv->OnTxPropertyBitsChange(TXTBIT_SAVESELECTION,
  796. fSaveSelection ? TXTBIT_SAVESELECTION : 0);
  797. return fResult;
  798. }
  799. HRESULT CTxtWinHost::OnTxInPlaceDeactivate()
  800. {
  801. HRESULT hr = pserv->OnTxInPlaceDeactivate();
  802. if (SUCCEEDED(hr))
  803. {
  804. fInplaceActive = FALSE;
  805. }
  806. return hr;
  807. }
  808. HRESULT CTxtWinHost::OnTxInPlaceActivate(LPCRECT prcClient)
  809. {
  810. fInplaceActive = TRUE;
  811. HRESULT hr = pserv->OnTxInPlaceActivate(prcClient);
  812. if (FAILED(hr))
  813. {
  814. fInplaceActive = FALSE;
  815. }
  816. return hr;
  817. }
  818. BOOL CTxtWinHost::DoSetCursor(RECT *prc, POINT *pt)
  819. {
  820. RECT rc = prc ? *prc : rcClient;
  821. // Is this in our rectangle?
  822. if (PtInRect(&rc, *pt))
  823. {
  824. RECT *prcClient = (!fInplaceActive || prc) ? &rc : NULL;
  825. pserv->OnTxSetCursor(DVASPECT_CONTENT, -1, NULL, NULL, m_re->GetManager()->GetPaintDC(),
  826. NULL, prcClient, pt->x, pt->y);
  827. return TRUE;
  828. }
  829. return FALSE;
  830. }
  831. void CTxtWinHost::GetControlRect(LPRECT prc)
  832. {
  833. prc->top = rcClient.top;
  834. prc->bottom = rcClient.bottom;
  835. prc->left = rcClient.left;
  836. prc->right = rcClient.right;
  837. }
  838. void CTxtWinHost::SetTransparent(BOOL f_Transparent)
  839. {
  840. fTransparent = f_Transparent;
  841. // notify text services of property change
  842. pserv->OnTxPropertyBitsChange(TXTBIT_BACKSTYLECHANGE, 0);
  843. }
  844. LONG CTxtWinHost::SetAccelPos(LONG l_accelpos)
  845. {
  846. LONG laccelposOld = l_accelpos;
  847. laccelpos = l_accelpos;
  848. // notify text services of property change
  849. pserv->OnTxPropertyBitsChange(TXTBIT_SHOWACCELERATOR, 0);
  850. return laccelposOld;
  851. }
  852. WCHAR CTxtWinHost::SetPasswordChar(WCHAR ch_PasswordChar)
  853. {
  854. WCHAR chOldPasswordChar = chPasswordChar;
  855. chPasswordChar = ch_PasswordChar;
  856. // notify text services of property change
  857. pserv->OnTxPropertyBitsChange(TXTBIT_USEPASSWORD,
  858. (chPasswordChar != 0) ? TXTBIT_USEPASSWORD : 0);
  859. return chOldPasswordChar;
  860. }
  861. void CTxtWinHost::SetDisabled(BOOL fOn)
  862. {
  863. cf.dwMask |= CFM_COLOR | CFM_DISABLED;
  864. cf.dwEffects |= CFE_AUTOCOLOR | CFE_DISABLED;
  865. if( !fOn )
  866. {
  867. cf.dwEffects &= ~CFE_DISABLED;
  868. }
  869. pserv->OnTxPropertyBitsChange(TXTBIT_CHARFORMATCHANGE,
  870. TXTBIT_CHARFORMATCHANGE);
  871. }
  872. LONG CTxtWinHost::SetSelBarWidth(LONG l_SelBarWidth)
  873. {
  874. LONG lOldSelBarWidth = lSelBarWidth;
  875. lSelBarWidth = l_SelBarWidth;
  876. if (lSelBarWidth)
  877. {
  878. dwStyle |= ES_SELECTIONBAR;
  879. }
  880. else
  881. {
  882. dwStyle &= (~ES_SELECTIONBAR);
  883. }
  884. pserv->OnTxPropertyBitsChange(TXTBIT_SELBARCHANGE, TXTBIT_SELBARCHANGE);
  885. return lOldSelBarWidth;
  886. }
  887. BOOL CTxtWinHost::GetTimerState()
  888. {
  889. return fTimer;
  890. }
  891. void CTxtWinHost::SetCharFormat(CHARFORMAT2W &c)
  892. {
  893. cf = c;
  894. }
  895. void CTxtWinHost::SetParaFormat(PARAFORMAT2 &p)
  896. {
  897. pf = p;
  898. }
  899. /////////////////////////////////////////////////////////////////////////////////////
  900. //
  901. //
  902. IMPLEMENT_DUICONTROL(CRichEditUI)
  903. CRichEditUI::CRichEditUI() : m_pTwh(NULL), m_bVScrollBarFixing(false), m_bWantTab(true), m_bWantReturn(true),
  904. m_bWantCtrlReturn(true), m_bTransparent(true), m_bRich(true), m_bReadOnly(false), m_bWordWrap(false), m_dwTextColor(0), m_iFont(-1),
  905. m_iLimitText(cInitTextMax), m_lTwhStyle(ES_MULTILINE), m_bDrawCaret(true), m_bInited(false), m_chLeadByte(0),m_uButtonState(0),
  906. m_dwTipValueColor(0xFFBAC0C5), m_uTipValueAlign(DT_SINGLELINE | DT_LEFT)
  907. {
  908. #ifndef _UNICODE
  909. m_fAccumulateDBC =true;
  910. #else
  911. m_fAccumulateDBC= false;
  912. #endif
  913. ::ZeroMemory(&m_rcTextPadding, sizeof(m_rcTextPadding));
  914. }
  915. CRichEditUI::~CRichEditUI()
  916. {
  917. if( m_pTwh ) {
  918. m_pTwh->Release();
  919. m_pManager->RemoveMessageFilter(this);
  920. }
  921. }
  922. LPCTSTR CRichEditUI::GetClass() const
  923. {
  924. return _T("RichEditUI");
  925. }
  926. LPVOID CRichEditUI::GetInterface(LPCTSTR pstrName)
  927. {
  928. if( _tcscmp(pstrName, DUI_CTR_RICHEDIT) == 0 ) return static_cast<CRichEditUI*>(this);
  929. return CContainerUI::GetInterface(pstrName);
  930. }
  931. UINT CRichEditUI::GetControlFlags() const
  932. {
  933. if( !IsEnabled() ) return CControlUI::GetControlFlags();
  934. return UIFLAG_SETCURSOR | UIFLAG_TABSTOP;
  935. }
  936. void CRichEditUI::SetEnabled(bool bEnabled)
  937. {
  938. CContainerUI::SetEnabled(bEnabled);
  939. if(m_pTwh) {
  940. if(IsEnabled()) {
  941. m_pTwh->SetColor(GetTextColor());
  942. }
  943. else {
  944. m_pTwh->SetColor (m_pManager->GetDefaultDisabledColor());
  945. }
  946. }
  947. }
  948. bool CRichEditUI::IsMultiLine()
  949. {
  950. return (m_lTwhStyle & ES_MULTILINE) == ES_MULTILINE;
  951. }
  952. void CRichEditUI::SetMultiLine(bool bMultiLine)
  953. {
  954. if(!bMultiLine) m_lTwhStyle &= ~ES_MULTILINE;
  955. else m_lTwhStyle |= ES_MULTILINE;
  956. }
  957. bool CRichEditUI::IsWantTab()
  958. {
  959. return m_bWantTab;
  960. }
  961. void CRichEditUI::SetWantTab(bool bWantTab)
  962. {
  963. m_bWantTab = bWantTab;
  964. }
  965. bool CRichEditUI::IsWantReturn()
  966. {
  967. return m_bWantReturn;
  968. }
  969. void CRichEditUI::SetWantReturn(bool bWantReturn)
  970. {
  971. m_bWantReturn = bWantReturn;
  972. }
  973. bool CRichEditUI::IsWantCtrlReturn()
  974. {
  975. return m_bWantCtrlReturn;
  976. }
  977. void CRichEditUI::SetWantCtrlReturn(bool bWantCtrlReturn)
  978. {
  979. m_bWantCtrlReturn = bWantCtrlReturn;
  980. }
  981. bool CRichEditUI::IsTransparent()
  982. {
  983. return m_bTransparent;
  984. }
  985. void CRichEditUI::SetTransparent(bool bTransparent)
  986. {
  987. m_bTransparent = bTransparent;
  988. if( m_pTwh ) m_pTwh->SetTransparent(bTransparent);
  989. }
  990. bool CRichEditUI::IsRich()
  991. {
  992. return m_bRich;
  993. }
  994. void CRichEditUI::SetRich(bool bRich)
  995. {
  996. m_bRich = bRich;
  997. if( m_pTwh ) m_pTwh->SetRichTextFlag(bRich);
  998. }
  999. bool CRichEditUI::IsReadOnly()
  1000. {
  1001. return m_bReadOnly;
  1002. }
  1003. void CRichEditUI::SetReadOnly(bool bReadOnly)
  1004. {
  1005. m_bReadOnly = bReadOnly;
  1006. if( m_pTwh ) m_pTwh->SetReadOnly(bReadOnly);
  1007. }
  1008. bool CRichEditUI::IsWordWrap()
  1009. {
  1010. return m_bWordWrap;
  1011. }
  1012. void CRichEditUI::SetWordWrap(bool bWordWrap)
  1013. {
  1014. m_bWordWrap = bWordWrap;
  1015. if( m_pTwh ) m_pTwh->SetWordWrap(bWordWrap);
  1016. }
  1017. int CRichEditUI::GetFont()
  1018. {
  1019. return m_iFont;
  1020. }
  1021. void CRichEditUI::SetFont(int index)
  1022. {
  1023. m_iFont = index;
  1024. if( m_pTwh ) {
  1025. m_pTwh->SetFont(GetManager()->GetFont(m_iFont));
  1026. }
  1027. }
  1028. void CRichEditUI::SetFont(LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic)
  1029. {
  1030. if( m_pTwh ) {
  1031. LOGFONT lf = { 0 };
  1032. ::GetObject(::GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lf);
  1033. _tcsncpy(lf.lfFaceName, pStrFontName, LF_FACESIZE);
  1034. lf.lfCharSet = DEFAULT_CHARSET;
  1035. lf.lfHeight = -nSize;
  1036. if( bBold ) lf.lfWeight += FW_BOLD;
  1037. if( bUnderline ) lf.lfUnderline = TRUE;
  1038. if( bItalic ) lf.lfItalic = TRUE;
  1039. HFONT hFont = ::CreateFontIndirect(&lf);
  1040. if( hFont == NULL ) return;
  1041. m_pTwh->SetFont(hFont);
  1042. ::DeleteObject(hFont);
  1043. }
  1044. }
  1045. LONG CRichEditUI::GetWinStyle()
  1046. {
  1047. return m_lTwhStyle;
  1048. }
  1049. void CRichEditUI::SetWinStyle(LONG lStyle)
  1050. {
  1051. m_lTwhStyle = lStyle;
  1052. }
  1053. DWORD CRichEditUI::GetTextColor()
  1054. {
  1055. return m_dwTextColor;
  1056. }
  1057. void CRichEditUI::SetTextColor(DWORD dwTextColor)
  1058. {
  1059. m_dwTextColor = dwTextColor;
  1060. if( m_pTwh ) {
  1061. m_pTwh->SetColor(dwTextColor);
  1062. }
  1063. }
  1064. int CRichEditUI::GetLimitText()
  1065. {
  1066. return m_iLimitText;
  1067. }
  1068. void CRichEditUI::SetLimitText(int iChars)
  1069. {
  1070. m_iLimitText = iChars;
  1071. if( m_pTwh ) {
  1072. m_pTwh->LimitText(m_iLimitText);
  1073. }
  1074. }
  1075. long CRichEditUI::GetTextLength(DWORD dwFlags) const
  1076. {
  1077. GETTEXTLENGTHEX textLenEx;
  1078. textLenEx.flags = dwFlags;
  1079. #ifdef _UNICODE
  1080. textLenEx.codepage = 1200;
  1081. #else
  1082. textLenEx.codepage = CP_ACP;
  1083. #endif
  1084. LRESULT lResult;
  1085. TxSendMessage(EM_GETTEXTLENGTHEX, (WPARAM)&textLenEx, 0, &lResult);
  1086. return (long)lResult;
  1087. }
  1088. CDuiString CRichEditUI::GetText() const
  1089. {
  1090. long lLen = GetTextLength(GTL_DEFAULT);
  1091. LPTSTR lpText = NULL;
  1092. GETTEXTEX gt;
  1093. gt.flags = GT_DEFAULT;
  1094. #ifdef _UNICODE
  1095. gt.cb = sizeof(TCHAR) * (lLen + 1) ;
  1096. gt.codepage = 1200;
  1097. lpText = new TCHAR[lLen + 1];
  1098. ::ZeroMemory(lpText, (lLen + 1) * sizeof(TCHAR));
  1099. #else
  1100. gt.cb = sizeof(TCHAR) * lLen * 2 + 1;
  1101. gt.codepage = CP_ACP;
  1102. lpText = new TCHAR[lLen * 2 + 1];
  1103. ::ZeroMemory(lpText, (lLen * 2 + 1) * sizeof(TCHAR));
  1104. #endif
  1105. gt.lpDefaultChar = NULL;
  1106. gt.lpUsedDefChar = NULL;
  1107. TxSendMessage(EM_GETTEXTEX, (WPARAM)&gt, (LPARAM)lpText, 0);
  1108. CDuiString sText(lpText);
  1109. delete[] lpText;
  1110. return sText;
  1111. }
  1112. void CRichEditUI::SetText(LPCTSTR pstrText)
  1113. {
  1114. m_sText = pstrText;
  1115. if( !m_pTwh ) return;
  1116. SetSel(0, -1);
  1117. ReplaceSel(pstrText, FALSE);
  1118. }
  1119. bool CRichEditUI::IsModify() const
  1120. {
  1121. if( !m_pTwh ) return false;
  1122. LRESULT lResult;
  1123. TxSendMessage(EM_GETMODIFY, 0, 0, &lResult);
  1124. return (BOOL)lResult == TRUE;
  1125. }
  1126. void CRichEditUI::SetModify(bool bModified) const
  1127. {
  1128. TxSendMessage(EM_SETMODIFY, bModified, 0, 0);
  1129. }
  1130. void CRichEditUI::GetSel(CHARRANGE &cr) const
  1131. {
  1132. TxSendMessage(EM_EXGETSEL, 0, (LPARAM)&cr, 0);
  1133. }
  1134. void CRichEditUI::GetSel(long& nStartChar, long& nEndChar) const
  1135. {
  1136. CHARRANGE cr;
  1137. TxSendMessage(EM_EXGETSEL, 0, (LPARAM)&cr, 0);
  1138. nStartChar = cr.cpMin;
  1139. nEndChar = cr.cpMax;
  1140. }
  1141. int CRichEditUI::SetSel(CHARRANGE &cr)
  1142. {
  1143. LRESULT lResult;
  1144. TxSendMessage(EM_EXSETSEL, 0, (LPARAM)&cr, &lResult);
  1145. return (int)lResult;
  1146. }
  1147. int CRichEditUI::SetSel(long nStartChar, long nEndChar)
  1148. {
  1149. CHARRANGE cr;
  1150. cr.cpMin = nStartChar;
  1151. cr.cpMax = nEndChar;
  1152. LRESULT lResult;
  1153. TxSendMessage(EM_EXSETSEL, 0, (LPARAM)&cr, &lResult);
  1154. return (int)lResult;
  1155. }
  1156. void CRichEditUI::ReplaceSel(LPCTSTR lpszNewText, bool bCanUndo)
  1157. {
  1158. #ifdef _UNICODE
  1159. TxSendMessage(EM_REPLACESEL, (WPARAM) bCanUndo, (LPARAM)lpszNewText, 0);
  1160. #else
  1161. int iLen = _tcslen(lpszNewText);
  1162. LPWSTR lpText = new WCHAR[iLen + 1];
  1163. ::ZeroMemory(lpText, (iLen + 1) * sizeof(WCHAR));
  1164. ::MultiByteToWideChar(CP_ACP, 0, lpszNewText, -1, (LPWSTR)lpText, iLen) ;
  1165. TxSendMessage(EM_REPLACESEL, (WPARAM) bCanUndo, (LPARAM)lpText, 0);
  1166. delete[] lpText;
  1167. #endif
  1168. }
  1169. void CRichEditUI::ReplaceSelW(LPCWSTR lpszNewText, bool bCanUndo)
  1170. {
  1171. TxSendMessage(EM_REPLACESEL, (WPARAM) bCanUndo, (LPARAM)lpszNewText, 0);
  1172. }
  1173. CDuiString CRichEditUI::GetSelText() const
  1174. {
  1175. if( !m_pTwh ) return CDuiString();
  1176. CHARRANGE cr;
  1177. cr.cpMin = cr.cpMax = 0;
  1178. TxSendMessage(EM_EXGETSEL, 0, (LPARAM)&cr, 0);
  1179. LPWSTR lpText = NULL;
  1180. lpText = new WCHAR[cr.cpMax - cr.cpMin + 1];
  1181. ::ZeroMemory(lpText, (cr.cpMax - cr.cpMin + 1) * sizeof(WCHAR));
  1182. TxSendMessage(EM_GETSELTEXT, 0, (LPARAM)lpText, 0);
  1183. CDuiString sText;
  1184. sText = (LPCWSTR)lpText;
  1185. delete[] lpText;
  1186. return sText;
  1187. }
  1188. int CRichEditUI::SetSelAll()
  1189. {
  1190. return SetSel(0, -1);
  1191. }
  1192. int CRichEditUI::SetSelNone()
  1193. {
  1194. return SetSel(-1, 0);
  1195. }
  1196. bool CRichEditUI::GetZoom(int& nNum, int& nDen) const
  1197. {
  1198. LRESULT lResult;
  1199. TxSendMessage(EM_GETZOOM, (WPARAM)&nNum, (LPARAM)&nDen, &lResult);
  1200. return (BOOL)lResult == TRUE;
  1201. }
  1202. bool CRichEditUI::SetZoom(int nNum, int nDen)
  1203. {
  1204. if (nNum < 0 || nNum > 64) return false;
  1205. if (nDen < 0 || nDen > 64) return false;
  1206. LRESULT lResult;
  1207. TxSendMessage(EM_SETZOOM, nNum, nDen, &lResult);
  1208. return (BOOL)lResult == TRUE;
  1209. }
  1210. bool CRichEditUI::SetZoomOff()
  1211. {
  1212. LRESULT lResult;
  1213. TxSendMessage(EM_SETZOOM, 0, 0, &lResult);
  1214. return (BOOL)lResult == TRUE;
  1215. }
  1216. WORD CRichEditUI::GetSelectionType() const
  1217. {
  1218. LRESULT lResult;
  1219. TxSendMessage(EM_SELECTIONTYPE, 0, 0, &lResult);
  1220. return (WORD)lResult;
  1221. }
  1222. bool CRichEditUI::GetAutoURLDetect() const
  1223. {
  1224. LRESULT lResult;
  1225. TxSendMessage(EM_GETAUTOURLDETECT, 0, 0, &lResult);
  1226. return (BOOL)lResult == TRUE;
  1227. }
  1228. bool CRichEditUI::SetAutoURLDetect(bool bAutoDetect)
  1229. {
  1230. LRESULT lResult;
  1231. TxSendMessage(EM_AUTOURLDETECT, bAutoDetect, 0, &lResult);
  1232. return (BOOL)lResult == FALSE;
  1233. }
  1234. DWORD CRichEditUI::GetEventMask() const
  1235. {
  1236. LRESULT lResult;
  1237. TxSendMessage(EM_GETEVENTMASK, 0, 0, &lResult);
  1238. return (DWORD)lResult;
  1239. }
  1240. DWORD CRichEditUI::SetEventMask(DWORD dwEventMask)
  1241. {
  1242. LRESULT lResult;
  1243. TxSendMessage(EM_SETEVENTMASK, 0, dwEventMask, &lResult);
  1244. return (DWORD)lResult;
  1245. }
  1246. CDuiString CRichEditUI::GetTextRange(long nStartChar, long nEndChar) const
  1247. {
  1248. TEXTRANGEW tr = { 0 };
  1249. tr.chrg.cpMin = nStartChar;
  1250. tr.chrg.cpMax = nEndChar;
  1251. LPWSTR lpText = NULL;
  1252. lpText = new WCHAR[nEndChar - nStartChar + 1];
  1253. ::ZeroMemory(lpText, (nEndChar - nStartChar + 1) * sizeof(WCHAR));
  1254. tr.lpstrText = lpText;
  1255. TxSendMessage(EM_GETTEXTRANGE, 0, (LPARAM)&tr, 0);
  1256. CDuiString sText;
  1257. sText = (LPCWSTR)lpText;
  1258. delete[] lpText;
  1259. return sText;
  1260. }
  1261. void CRichEditUI::HideSelection(bool bHide, bool bChangeStyle)
  1262. {
  1263. TxSendMessage(EM_HIDESELECTION, bHide, bChangeStyle, 0);
  1264. }
  1265. void CRichEditUI::ScrollCaret()
  1266. {
  1267. TxSendMessage(EM_SCROLLCARET, 0, 0, 0);
  1268. }
  1269. int CRichEditUI::InsertText(long nInsertAfterChar, LPCTSTR lpstrText, bool bCanUndo)
  1270. {
  1271. int nRet = SetSel(nInsertAfterChar, nInsertAfterChar);
  1272. ReplaceSel(lpstrText, bCanUndo);
  1273. return nRet;
  1274. }
  1275. int CRichEditUI::AppendText(LPCTSTR lpstrText, bool bCanUndo)
  1276. {
  1277. int nRet = SetSel(-1, -1);
  1278. ReplaceSel(lpstrText, bCanUndo);
  1279. return nRet;
  1280. }
  1281. DWORD CRichEditUI::GetDefaultCharFormat(CHARFORMAT2 &cf) const
  1282. {
  1283. cf.cbSize = sizeof(CHARFORMAT2);
  1284. LRESULT lResult;
  1285. TxSendMessage(EM_GETCHARFORMAT, 0, (LPARAM)&cf, &lResult);
  1286. return (DWORD)lResult;
  1287. }
  1288. bool CRichEditUI::SetDefaultCharFormat(CHARFORMAT2 &cf)
  1289. {
  1290. if( !m_pTwh ) return false;
  1291. cf.cbSize = sizeof(CHARFORMAT2);
  1292. LRESULT lResult;
  1293. TxSendMessage(EM_SETCHARFORMAT, 0, (LPARAM)&cf, &lResult);
  1294. if( (BOOL)lResult == TRUE ) {
  1295. CHARFORMAT2W cfw;
  1296. cfw.cbSize = sizeof(CHARFORMAT2W);
  1297. TxSendMessage(EM_GETCHARFORMAT, 1, (LPARAM)&cfw, 0);
  1298. m_pTwh->SetCharFormat(cfw);
  1299. return true;
  1300. }
  1301. return false;
  1302. }
  1303. DWORD CRichEditUI::GetSelectionCharFormat(CHARFORMAT2 &cf) const
  1304. {
  1305. cf.cbSize = sizeof(CHARFORMAT2);
  1306. LRESULT lResult;
  1307. TxSendMessage(EM_GETCHARFORMAT, 1, (LPARAM)&cf, &lResult);
  1308. return (DWORD)lResult;
  1309. }
  1310. bool CRichEditUI::SetSelectionCharFormat(CHARFORMAT2 &cf)
  1311. {
  1312. if( !m_pTwh ) return false;
  1313. cf.cbSize = sizeof(CHARFORMAT2);
  1314. LRESULT lResult;
  1315. TxSendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf, &lResult);
  1316. return (BOOL)lResult == TRUE;
  1317. }
  1318. bool CRichEditUI::SetWordCharFormat(CHARFORMAT2 &cf)
  1319. {
  1320. if( !m_pTwh ) return false;
  1321. cf.cbSize = sizeof(CHARFORMAT2);
  1322. LRESULT lResult;
  1323. TxSendMessage(EM_SETCHARFORMAT, SCF_SELECTION|SCF_WORD, (LPARAM)&cf, &lResult);
  1324. return (BOOL)lResult == TRUE;
  1325. }
  1326. DWORD CRichEditUI::GetParaFormat(PARAFORMAT2 &pf) const
  1327. {
  1328. pf.cbSize = sizeof(PARAFORMAT2);
  1329. LRESULT lResult;
  1330. TxSendMessage(EM_GETPARAFORMAT, 0, (LPARAM)&pf, &lResult);
  1331. return (DWORD)lResult;
  1332. }
  1333. bool CRichEditUI::SetParaFormat(PARAFORMAT2 &pf)
  1334. {
  1335. if( !m_pTwh ) return false;
  1336. pf.cbSize = sizeof(PARAFORMAT2);
  1337. LRESULT lResult;
  1338. TxSendMessage(EM_SETPARAFORMAT, 0, (LPARAM)&pf, &lResult);
  1339. if( (BOOL)lResult == TRUE ) {
  1340. m_pTwh->SetParaFormat(pf);
  1341. return true;
  1342. }
  1343. return false;
  1344. }
  1345. bool CRichEditUI::CanUndo()
  1346. {
  1347. if( !m_pTwh ) return false;
  1348. LRESULT lResult;
  1349. TxSendMessage(EM_CANUNDO, 0, 0, &lResult);
  1350. return (BOOL)lResult == TRUE;
  1351. }
  1352. bool CRichEditUI::CanRedo()
  1353. {
  1354. if( !m_pTwh ) return false;
  1355. LRESULT lResult;
  1356. TxSendMessage(EM_CANREDO, 0, 0, &lResult);
  1357. return (BOOL)lResult == TRUE;
  1358. }
  1359. bool CRichEditUI::CanPaste()
  1360. {
  1361. if( !m_pTwh ) return false;
  1362. LRESULT lResult;
  1363. TxSendMessage(EM_CANPASTE, 0, 0, &lResult);
  1364. return (BOOL)lResult == TRUE;
  1365. }
  1366. bool CRichEditUI::Redo()
  1367. {
  1368. if( !m_pTwh ) return false;
  1369. LRESULT lResult;
  1370. TxSendMessage(EM_REDO, 0, 0, &lResult);
  1371. return (BOOL)lResult == TRUE;
  1372. }
  1373. bool CRichEditUI::Undo()
  1374. {
  1375. if( !m_pTwh ) return false;
  1376. LRESULT lResult;
  1377. TxSendMessage(EM_UNDO, 0, 0, &lResult);
  1378. return (BOOL)lResult == TRUE;
  1379. }
  1380. void CRichEditUI::Clear()
  1381. {
  1382. TxSendMessage(WM_CLEAR, 0, 0, 0);
  1383. }
  1384. void CRichEditUI::Copy()
  1385. {
  1386. TxSendMessage(WM_COPY, 0, 0, 0);
  1387. }
  1388. void CRichEditUI::Cut()
  1389. {
  1390. TxSendMessage(WM_CUT, 0, 0, 0);
  1391. }
  1392. void CRichEditUI::Paste()
  1393. {
  1394. TxSendMessage(WM_PASTE, 0, 0, 0);
  1395. }
  1396. int CRichEditUI::GetLineCount() const
  1397. {
  1398. if( !m_pTwh ) return 0;
  1399. LRESULT lResult;
  1400. TxSendMessage(EM_GETLINECOUNT, 0, 0, &lResult);
  1401. return (int)lResult;
  1402. }
  1403. CDuiString CRichEditUI::GetLine(int nIndex, int nMaxLength) const
  1404. {
  1405. LPWSTR lpText = NULL;
  1406. lpText = new WCHAR[nMaxLength + 1];
  1407. ::ZeroMemory(lpText, (nMaxLength + 1) * sizeof(WCHAR));
  1408. *(LPWORD)lpText = (WORD)nMaxLength;
  1409. TxSendMessage(EM_GETLINE, nIndex, (LPARAM)lpText, 0);
  1410. CDuiString sText;
  1411. sText = (LPCWSTR)lpText;
  1412. delete[] lpText;
  1413. return sText;
  1414. }
  1415. int CRichEditUI::LineIndex(int nLine) const
  1416. {
  1417. LRESULT lResult;
  1418. TxSendMessage(EM_LINEINDEX, nLine, 0, &lResult);
  1419. return (int)lResult;
  1420. }
  1421. int CRichEditUI::LineLength(int nLine) const
  1422. {
  1423. LRESULT lResult;
  1424. TxSendMessage(EM_LINELENGTH, nLine, 0, &lResult);
  1425. return (int)lResult;
  1426. }
  1427. bool CRichEditUI::LineScroll(int nLines, int nChars)
  1428. {
  1429. LRESULT lResult;
  1430. TxSendMessage(EM_LINESCROLL, nChars, nLines, &lResult);
  1431. return (BOOL)lResult == TRUE;
  1432. }
  1433. CDuiPoint CRichEditUI::GetCharPos(long lChar) const
  1434. {
  1435. CDuiPoint pt;
  1436. TxSendMessage(EM_POSFROMCHAR, (WPARAM)&pt, (LPARAM)lChar, 0);
  1437. return pt;
  1438. }
  1439. long CRichEditUI::LineFromChar(long nIndex) const
  1440. {
  1441. if( !m_pTwh ) return 0L;
  1442. LRESULT lResult;
  1443. TxSendMessage(EM_EXLINEFROMCHAR, 0, nIndex, &lResult);
  1444. return (long)lResult;
  1445. }
  1446. CDuiPoint CRichEditUI::PosFromChar(UINT nChar) const
  1447. {
  1448. POINTL pt;
  1449. TxSendMessage(EM_POSFROMCHAR, (WPARAM)&pt, nChar, 0);
  1450. return CDuiPoint(pt.x, pt.y);
  1451. }
  1452. int CRichEditUI::CharFromPos(CDuiPoint pt) const
  1453. {
  1454. POINTL ptl = {pt.x, pt.y};
  1455. if( !m_pTwh ) return 0;
  1456. LRESULT lResult;
  1457. TxSendMessage(EM_CHARFROMPOS, 0, (LPARAM)&ptl, &lResult);
  1458. return (int)lResult;
  1459. }
  1460. void CRichEditUI::EmptyUndoBuffer()
  1461. {
  1462. TxSendMessage(EM_EMPTYUNDOBUFFER, 0, 0, 0);
  1463. }
  1464. UINT CRichEditUI::SetUndoLimit(UINT nLimit)
  1465. {
  1466. if( !m_pTwh ) return 0;
  1467. LRESULT lResult;
  1468. TxSendMessage(EM_SETUNDOLIMIT, (WPARAM) nLimit, 0, &lResult);
  1469. return (UINT)lResult;
  1470. }
  1471. long CRichEditUI::StreamIn(int nFormat, EDITSTREAM &es)
  1472. {
  1473. if( !m_pTwh ) return 0L;
  1474. LRESULT lResult;
  1475. TxSendMessage(EM_STREAMIN, nFormat, (LPARAM)&es, &lResult);
  1476. return (long)lResult;
  1477. }
  1478. long CRichEditUI::StreamOut(int nFormat, EDITSTREAM &es)
  1479. {
  1480. if( !m_pTwh ) return 0L;
  1481. LRESULT lResult;
  1482. TxSendMessage(EM_STREAMOUT, nFormat, (LPARAM)&es, &lResult);
  1483. return (long)lResult;
  1484. }
  1485. void CRichEditUI::SetAccumulateDBCMode( bool bDBCMode )
  1486. {
  1487. m_fAccumulateDBC = bDBCMode;
  1488. }
  1489. bool CRichEditUI::IsAccumulateDBCMode()
  1490. {
  1491. return m_fAccumulateDBC;
  1492. }
  1493. void CRichEditUI::DoInit()
  1494. {
  1495. if(m_bInited)
  1496. return ;
  1497. CREATESTRUCT cs;
  1498. cs.style = m_lTwhStyle;
  1499. cs.x = 0;
  1500. cs.y = 0;
  1501. cs.cy = 0;
  1502. cs.cx = 0;
  1503. cs.lpszName = m_sText.GetData();
  1504. CreateHost(this, &cs, &m_pTwh);
  1505. if( m_pTwh ) {
  1506. if( m_bTransparent ) m_pTwh->SetTransparent(TRUE);
  1507. LRESULT lResult;
  1508. m_pTwh->GetTextServices()->TxSendMessage(EM_SETLANGOPTIONS, 0, 0, &lResult);
  1509. m_pTwh->GetTextServices()->TxSendMessage(EM_SETEVENTMASK, 0, ENM_DROPFILES|ENM_LINK|ENM_CHANGE, &lResult);
  1510. m_pTwh->OnTxInPlaceActivate(NULL);
  1511. m_pManager->AddMessageFilter(this);
  1512. m_pManager->SetTimer(this, DEFAULT_TIMERID, ::GetCaretBlinkTime());
  1513. if (!m_bEnabled) {
  1514. m_pTwh->SetColor(m_pManager->GetDefaultDisabledColor());
  1515. }
  1516. }
  1517. m_bInited= true;
  1518. }
  1519. HRESULT CRichEditUI::TxSendMessage(UINT msg, WPARAM wparam, LPARAM lparam, LRESULT *plresult) const
  1520. {
  1521. if( m_pTwh ) {
  1522. if( msg == WM_KEYDOWN && wparam == VK_RETURN ) {
  1523. if( !m_bWantReturn || (::GetKeyState(VK_CONTROL) < 0 && !m_bWantCtrlReturn) ) {
  1524. if( m_pManager != NULL ) m_pManager->SendNotify((CControlUI*)this, DUI_MSGTYPE_RETURN);
  1525. return S_OK;
  1526. }
  1527. }
  1528. return m_pTwh->GetTextServices()->TxSendMessage(msg, wparam, lparam, plresult);
  1529. }
  1530. return S_FALSE;
  1531. }
  1532. IDropTarget* CRichEditUI::GetTxDropTarget()
  1533. {
  1534. IDropTarget *pdt = NULL;
  1535. if( m_pTwh->GetTextServices()->TxGetDropTarget(&pdt) == NOERROR ) return pdt;
  1536. return NULL;
  1537. }
  1538. bool CRichEditUI::OnTxViewChanged()
  1539. {
  1540. return true;
  1541. }
  1542. bool CRichEditUI::SetDropAcceptFile(bool bAccept)
  1543. {
  1544. LRESULT lResult;
  1545. TxSendMessage(EM_SETEVENTMASK, 0,ENM_DROPFILES|ENM_LINK, // ENM_CHANGE| ENM_CORRECTTEXT | ENM_DRAGDROPDONE | ENM_DROPFILES | ENM_IMECHANGE | ENM_LINK | ENM_OBJECTPOSITIONS | ENM_PROTECTED | ENM_REQUESTRESIZE | ENM_SCROLL | ENM_SELCHANGE | ENM_UPDATE,
  1546. &lResult);
  1547. return (BOOL)lResult == FALSE;
  1548. }
  1549. void CRichEditUI::OnTxNotify(DWORD iNotify, void *pv)
  1550. {
  1551. switch(iNotify)
  1552. {
  1553. case EN_CHANGE:
  1554. {
  1555. GetManager()->SendNotify(this, DUI_MSGTYPE_TEXTCHANGED);
  1556. break;
  1557. }
  1558. case EN_DROPFILES:
  1559. case EN_MSGFILTER:
  1560. case EN_OLEOPFAILED:
  1561. case EN_PROTECTED:
  1562. case EN_SAVECLIPBOARD:
  1563. case EN_SELCHANGE:
  1564. case EN_STOPNOUNDO:
  1565. case EN_LINK:
  1566. case EN_OBJECTPOSITIONS:
  1567. case EN_DRAGDROPDONE:
  1568. {
  1569. if(pv) // Fill out NMHDR portion of pv
  1570. {
  1571. LONG nId = GetWindowLong(this->GetManager()->GetPaintWindow(), GWL_ID);
  1572. NMHDR *phdr = (NMHDR *)pv;
  1573. phdr->hwndFrom = this->GetManager()->GetPaintWindow();
  1574. phdr->idFrom = nId;
  1575. phdr->code = iNotify;
  1576. if(SendMessage(this->GetManager()->GetPaintWindow(), WM_NOTIFY, (WPARAM) nId, (LPARAM) pv))
  1577. {
  1578. //hr = S_FALSE;
  1579. }
  1580. }
  1581. }
  1582. break;
  1583. }
  1584. }
  1585. CDuiSize CRichEditUI::GetNaturalSize(LONG width, LONG height)
  1586. {
  1587. if (width < 0)
  1588. {
  1589. width = 0;
  1590. }
  1591. if (height < 0)
  1592. {
  1593. height = 0;
  1594. }
  1595. CDuiSize sz(0, 0);
  1596. LONG lWidth = width;
  1597. LONG lHeight = height;
  1598. SIZEL szExtent = { -1, -1 };
  1599. if (m_pTwh)
  1600. {
  1601. m_pTwh->GetTextServices()->TxGetNaturalSize(
  1602. DVASPECT_CONTENT,
  1603. m_pManager->GetPaintDC(),
  1604. NULL,
  1605. NULL,
  1606. TXTNS_FITTOCONTENT,
  1607. &szExtent,
  1608. &lWidth,
  1609. &lHeight);
  1610. }
  1611. sz.cx = (int)lWidth;
  1612. sz.cy = (int)lHeight;
  1613. return sz;
  1614. }
  1615. // 多行非rich格式的richedit有一个滚动条bug,在最后一行是空行时,LineDown和SetScrollPos无法滚动到最后
  1616. // 引入iPos就是为了修正这个bug
  1617. void CRichEditUI::SetScrollPos(SIZE szPos, bool bMsg)
  1618. {
  1619. int cx = 0;
  1620. int cy = 0;
  1621. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {
  1622. int iLastScrollPos = m_pVerticalScrollBar->GetScrollPos();
  1623. m_pVerticalScrollBar->SetScrollPos(szPos.cy);
  1624. cy = m_pVerticalScrollBar->GetScrollPos() - iLastScrollPos;
  1625. }
  1626. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {
  1627. int iLastScrollPos = m_pHorizontalScrollBar->GetScrollPos();
  1628. m_pHorizontalScrollBar->SetScrollPos(szPos.cx);
  1629. cx = m_pHorizontalScrollBar->GetScrollPos() - iLastScrollPos;
  1630. }
  1631. if( cy != 0 ) {
  1632. int iPos = 0;
  1633. if( m_pTwh && !m_bRich && m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() )
  1634. iPos = m_pVerticalScrollBar->GetScrollPos();
  1635. WPARAM wParam = MAKEWPARAM(SB_THUMBPOSITION, m_pVerticalScrollBar->GetScrollPos());
  1636. TxSendMessage(WM_VSCROLL, wParam, 0L, 0);
  1637. if( m_pTwh && !m_bRich && m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {
  1638. if( cy > 0 && m_pVerticalScrollBar->GetScrollPos() <= iPos )
  1639. m_pVerticalScrollBar->SetScrollPos(iPos);
  1640. }
  1641. }
  1642. if( cx != 0 ) {
  1643. WPARAM wParam = MAKEWPARAM(SB_THUMBPOSITION, m_pHorizontalScrollBar->GetScrollPos());
  1644. TxSendMessage(WM_HSCROLL, wParam, 0L, 0);
  1645. }
  1646. }
  1647. void CRichEditUI::LineUp()
  1648. {
  1649. TxSendMessage(WM_VSCROLL, SB_LINEUP, 0L, 0);
  1650. }
  1651. void CRichEditUI::LineDown()
  1652. {
  1653. int iPos = 0;
  1654. if( m_pTwh && !m_bRich && m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() )
  1655. iPos = m_pVerticalScrollBar->GetScrollPos();
  1656. TxSendMessage(WM_VSCROLL, SB_LINEDOWN, 0L, 0);
  1657. if( m_pTwh && !m_bRich && m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {
  1658. if( m_pVerticalScrollBar->GetScrollPos() <= iPos )
  1659. m_pVerticalScrollBar->SetScrollPos(m_pVerticalScrollBar->GetScrollRange());
  1660. }
  1661. }
  1662. void CRichEditUI::PageUp()
  1663. {
  1664. TxSendMessage(WM_VSCROLL, SB_PAGEUP, 0L, 0);
  1665. }
  1666. void CRichEditUI::PageDown()
  1667. {
  1668. TxSendMessage(WM_VSCROLL, SB_PAGEDOWN, 0L, 0);
  1669. }
  1670. void CRichEditUI::HomeUp()
  1671. {
  1672. TxSendMessage(WM_VSCROLL, SB_TOP, 0L, 0);
  1673. }
  1674. void CRichEditUI::EndDown()
  1675. {
  1676. TxSendMessage(WM_VSCROLL, SB_BOTTOM, 0L, 0);
  1677. }
  1678. void CRichEditUI::LineLeft()
  1679. {
  1680. TxSendMessage(WM_HSCROLL, SB_LINELEFT, 0L, 0);
  1681. }
  1682. void CRichEditUI::LineRight()
  1683. {
  1684. TxSendMessage(WM_HSCROLL, SB_LINERIGHT, 0L, 0);
  1685. }
  1686. void CRichEditUI::PageLeft()
  1687. {
  1688. TxSendMessage(WM_HSCROLL, SB_PAGELEFT, 0L, 0);
  1689. }
  1690. void CRichEditUI::PageRight()
  1691. {
  1692. TxSendMessage(WM_HSCROLL, SB_PAGERIGHT, 0L, 0);
  1693. }
  1694. void CRichEditUI::HomeLeft()
  1695. {
  1696. TxSendMessage(WM_HSCROLL, SB_LEFT, 0L, 0);
  1697. }
  1698. void CRichEditUI::EndRight()
  1699. {
  1700. TxSendMessage(WM_HSCROLL, SB_RIGHT, 0L, 0);
  1701. }
  1702. void CRichEditUI::DoEvent(TEventUI& event)
  1703. {
  1704. if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
  1705. if( m_pParent != NULL ) m_pParent->DoEvent(event);
  1706. else CControlUI::DoEvent(event);
  1707. return;
  1708. }
  1709. if( event.Type == UIEVENT_SETCURSOR && IsEnabled() )
  1710. {
  1711. if( m_pTwh && m_pTwh->DoSetCursor(NULL, &event.ptMouse) ) {
  1712. return;
  1713. }
  1714. }
  1715. else if( event.Type == UIEVENT_WINDOWSIZE ) {
  1716. if( m_pTwh ) m_pTwh->NeedFreshCaret();
  1717. }
  1718. else if( event.Type == UIEVENT_SETFOCUS ) {
  1719. if( m_pTwh ) {
  1720. m_pTwh->OnTxInPlaceActivate(NULL);
  1721. m_pTwh->GetTextServices()->TxSendMessage(WM_SETFOCUS, 0, 0, 0);
  1722. }
  1723. m_bFocused = true;
  1724. Invalidate();
  1725. return;
  1726. }
  1727. if( event.Type == UIEVENT_KILLFOCUS ) {
  1728. if( m_pTwh ) {
  1729. m_pTwh->OnTxInPlaceActivate(NULL);
  1730. m_pTwh->GetTextServices()->TxSendMessage(WM_KILLFOCUS, 0, 0, 0);
  1731. }
  1732. m_bFocused = false;
  1733. Invalidate();
  1734. return;
  1735. }
  1736. else if( event.Type == UIEVENT_TIMER ) {
  1737. if( event.wParam == DEFAULT_TIMERID ) {
  1738. if(m_pManager->IsLayered() && IsFocused() && m_pTwh && m_pTwh->IsShowCaret()) {
  1739. if (::GetFocus() != m_pManager->GetPaintWindow()) return;
  1740. m_bDrawCaret = !m_bDrawCaret;
  1741. POINT ptCaret;
  1742. ::GetCaretPos(&ptCaret);
  1743. RECT rcCaret = { ptCaret.x, ptCaret.y, ptCaret.x + m_pTwh->GetCaretWidth(), ptCaret.y + m_pTwh->GetCaretHeight() };
  1744. RECT rcTemp = rcCaret;
  1745. if( !::IntersectRect(&rcCaret, &rcTemp, &m_rcItem) ) return;
  1746. CControlUI* pParent = this;
  1747. RECT rcParent;
  1748. while( pParent = pParent->GetParent() ) {
  1749. rcTemp = rcCaret;
  1750. rcParent = pParent->GetPos();
  1751. if( !::IntersectRect(&rcCaret, &rcTemp, &rcParent) ) {
  1752. return;
  1753. }
  1754. }
  1755. m_pManager->Invalidate(rcCaret);
  1756. }
  1757. else if(IsFocused() && m_pTwh) {
  1758. if (::GetFocus() != m_pManager->GetPaintWindow()) return;
  1759. if(m_pTwh->IsShowCaret()) m_pTwh->TxShowCaret(FALSE);
  1760. else m_pTwh->TxShowCaret(TRUE);
  1761. }
  1762. return;
  1763. }
  1764. else if( m_pTwh ) {
  1765. m_pTwh->GetTextServices()->TxSendMessage(WM_TIMER, event.wParam, event.lParam, 0);
  1766. }
  1767. return;
  1768. }
  1769. if( event.Type == UIEVENT_SCROLLWHEEL ) {
  1770. if( (event.wKeyState & MK_CONTROL) != 0 ) {
  1771. return;
  1772. }
  1773. }
  1774. if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK )
  1775. {
  1776. return;
  1777. }
  1778. if( event.Type == UIEVENT_MOUSEMOVE )
  1779. {
  1780. return;
  1781. }
  1782. if( event.Type == UIEVENT_BUTTONUP )
  1783. {
  1784. return;
  1785. }
  1786. if( event.Type > UIEVENT__KEYBEGIN && event.Type < UIEVENT__KEYEND )
  1787. {
  1788. return;
  1789. }
  1790. CContainerUI::DoEvent(event);
  1791. }
  1792. SIZE CRichEditUI::EstimateSize(SIZE szAvailable)
  1793. {
  1794. return CContainerUI::EstimateSize(szAvailable);
  1795. }
  1796. void CRichEditUI::SetPos(RECT rc, bool bNeedInvalidate)
  1797. {
  1798. CControlUI::SetPos(rc, bNeedInvalidate);
  1799. rc = m_rcItem;
  1800. RECT rcInset = GetInset();
  1801. rc.left += rcInset.left;
  1802. rc.top += rcInset.top;
  1803. rc.right -= rcInset.right;
  1804. rc.bottom -= rcInset.bottom;
  1805. RECT rcScrollView = rc;
  1806. bool bVScrollBarVisiable = false;
  1807. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {
  1808. bVScrollBarVisiable = true;
  1809. rc.top -= m_pVerticalScrollBar->GetScrollPos();
  1810. rc.bottom -= m_pVerticalScrollBar->GetScrollPos();
  1811. rc.bottom += m_pVerticalScrollBar->GetScrollRange();
  1812. rc.right -= m_pVerticalScrollBar->GetFixedWidth();
  1813. rcScrollView.right -= m_pVerticalScrollBar->GetFixedWidth();
  1814. }
  1815. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {
  1816. rc.left -= m_pHorizontalScrollBar->GetScrollPos();
  1817. rc.right -= m_pHorizontalScrollBar->GetScrollPos();
  1818. rc.right += m_pHorizontalScrollBar->GetScrollRange();
  1819. rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  1820. rcScrollView.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  1821. }
  1822. if( m_pTwh != NULL ) {
  1823. RECT rcTextPadding = GetTextPadding();
  1824. RECT rcScrollTextView = rcScrollView;
  1825. rcScrollTextView.left += rcTextPadding.left;
  1826. rcScrollTextView.right -= rcTextPadding.right;
  1827. rcScrollTextView.top += rcTextPadding.top;
  1828. rcScrollTextView.bottom -= rcTextPadding.bottom;
  1829. RECT rcText = rc;
  1830. rcText.left += rcTextPadding.left;
  1831. rcText.right -= rcTextPadding.right;
  1832. rcText.top += rcTextPadding.top;
  1833. rcText.bottom -= rcTextPadding.bottom;
  1834. m_pTwh->SetClientRect(&rcScrollTextView);
  1835. if( bVScrollBarVisiable && (!m_pVerticalScrollBar->IsVisible() || m_bVScrollBarFixing) ) {
  1836. LONG lWidth = rcText.right - rcText.left + m_pVerticalScrollBar->GetFixedWidth();
  1837. LONG lHeight = 0;
  1838. SIZEL szExtent = { -1, -1 };
  1839. m_pTwh->GetTextServices()->TxGetNaturalSize(
  1840. DVASPECT_CONTENT,
  1841. GetManager()->GetPaintDC(),
  1842. NULL,
  1843. NULL,
  1844. TXTNS_FITTOCONTENT,
  1845. &szExtent,
  1846. &lWidth,
  1847. &lHeight);
  1848. if( lHeight > rcText.bottom - rcText.top ) {
  1849. m_pVerticalScrollBar->SetVisible(true);
  1850. m_pVerticalScrollBar->SetScrollPos(0);
  1851. m_bVScrollBarFixing = true;
  1852. }
  1853. else {
  1854. if( m_bVScrollBarFixing ) {
  1855. m_pVerticalScrollBar->SetVisible(false);
  1856. m_bVScrollBarFixing = false;
  1857. }
  1858. }
  1859. }
  1860. }
  1861. if( m_pVerticalScrollBar != NULL && m_pVerticalScrollBar->IsVisible() ) {
  1862. RECT rcScrollBarPos = { rcScrollView.right, rcScrollView.top,
  1863. rcScrollView.right + m_pVerticalScrollBar->GetFixedWidth(), rcScrollView.bottom};
  1864. m_pVerticalScrollBar->SetPos(rcScrollBarPos, false);
  1865. }
  1866. if( m_pHorizontalScrollBar != NULL && m_pHorizontalScrollBar->IsVisible() ) {
  1867. RECT rcScrollBarPos = { rcScrollView.left, rcScrollView.bottom, rcScrollView.right,
  1868. rcScrollView.bottom + m_pHorizontalScrollBar->GetFixedHeight()};
  1869. m_pHorizontalScrollBar->SetPos(rcScrollBarPos, false);
  1870. }
  1871. for( int it = 0; it < m_items.GetSize(); it++ ) {
  1872. CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
  1873. if( !pControl->IsVisible() ) continue;
  1874. if( pControl->IsFloat() ) {
  1875. SetFloatPos(it);
  1876. }
  1877. else {
  1878. SIZE sz = { rc.right - rc.left, rc.bottom - rc.top };
  1879. if( sz.cx < pControl->GetMinWidth() ) sz.cx = pControl->GetMinWidth();
  1880. if( sz.cx > pControl->GetMaxWidth() ) sz.cx = pControl->GetMaxWidth();
  1881. if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight();
  1882. if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight();
  1883. RECT rcCtrl = { rc.left, rc.top, rc.left + sz.cx, rc.top + sz.cy };
  1884. pControl->SetPos(rcCtrl, false);
  1885. }
  1886. }
  1887. }
  1888. void CRichEditUI::Move(SIZE szOffset, bool bNeedInvalidate)
  1889. {
  1890. CContainerUI::Move(szOffset, bNeedInvalidate);
  1891. if( m_pTwh != NULL ) {
  1892. RECT rc = m_rcItem;
  1893. RECT rcInset = GetInset();
  1894. rc.left += rcInset.left;
  1895. rc.top += rcInset.top;
  1896. rc.right -= rcInset.right;
  1897. rc.bottom -= rcInset.bottom;
  1898. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth();
  1899. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  1900. m_pTwh->SetClientRect(&rc);
  1901. }
  1902. }
  1903. bool CRichEditUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl)
  1904. {
  1905. RECT rcTemp = { 0 };
  1906. if( !::IntersectRect(&rcTemp, &rcPaint, &m_rcItem) ) return true;
  1907. CRenderClip clip;
  1908. CRenderClip::GenerateClip(hDC, rcTemp, clip);
  1909. CControlUI::DoPaint(hDC, rcPaint, pStopControl);
  1910. if( m_pTwh ) {
  1911. RECT rc;
  1912. m_pTwh->GetControlRect(&rc);
  1913. // Remember wparam is actually the hdc and lparam is the update
  1914. // rect because this message has been preprocessed by the window.
  1915. m_pTwh->GetTextServices()->TxDraw(
  1916. DVASPECT_CONTENT, // Draw Aspect
  1917. /*-1*/0, // Lindex
  1918. NULL, // Info for drawing optimazation
  1919. NULL, // target device information
  1920. hDC, // Draw device HDC
  1921. NULL, // Target device HDC
  1922. (RECTL*)&rc, // Bounding client rectangle
  1923. NULL, // Clipping rectangle for metafiles
  1924. (RECT*)&rcPaint, // Update rectangle
  1925. NULL, // Call back function
  1926. NULL, // Call back parameter
  1927. 0); // What view of the object
  1928. if( m_bVScrollBarFixing ) {
  1929. LONG lWidth = rc.right - rc.left + m_pVerticalScrollBar->GetFixedWidth();
  1930. LONG lHeight = 0;
  1931. SIZEL szExtent = { -1, -1 };
  1932. m_pTwh->GetTextServices()->TxGetNaturalSize(
  1933. DVASPECT_CONTENT,
  1934. GetManager()->GetPaintDC(),
  1935. NULL,
  1936. NULL,
  1937. TXTNS_FITTOCONTENT,
  1938. &szExtent,
  1939. &lWidth,
  1940. &lHeight);
  1941. if( lHeight <= rc.bottom - rc.top ) {
  1942. NeedUpdate();
  1943. }
  1944. }
  1945. }
  1946. if( m_items.GetSize() > 0 ) {
  1947. RECT rc = m_rcItem;
  1948. RECT rcInset = GetInset();
  1949. rc.left += rcInset.left;
  1950. rc.top += rcInset.top;
  1951. rc.right -= rcInset.right;
  1952. rc.bottom -= rcInset.bottom;
  1953. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth();
  1954. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  1955. if( !::IntersectRect(&rcTemp, &rcPaint, &rc) ) {
  1956. for( int it = 0; it < m_items.GetSize(); it++ ) {
  1957. CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
  1958. if( pControl == pStopControl ) return false;
  1959. if( !pControl->IsVisible() ) continue;
  1960. if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue;
  1961. if( pControl->IsFloat() ) {
  1962. if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue;
  1963. if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
  1964. }
  1965. }
  1966. }
  1967. else {
  1968. CRenderClip childClip;
  1969. CRenderClip::GenerateClip(hDC, rcTemp, childClip);
  1970. for( int it = 0; it < m_items.GetSize(); it++ ) {
  1971. CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
  1972. if( pControl == pStopControl ) return false;
  1973. if( !pControl->IsVisible() ) continue;
  1974. if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue;
  1975. if( pControl->IsFloat() ) {
  1976. if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue;
  1977. CRenderClip::UseOldClipBegin(hDC, childClip);
  1978. if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
  1979. CRenderClip::UseOldClipEnd(hDC, childClip);
  1980. }
  1981. else {
  1982. if( !::IntersectRect(&rcTemp, &rc, &pControl->GetPos()) ) continue;
  1983. if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
  1984. }
  1985. }
  1986. }
  1987. }
  1988. if(m_pManager->IsLayered() && IsFocused() && m_pTwh && m_pTwh->IsShowCaret()) {
  1989. if(m_bDrawCaret) {
  1990. POINT ptCaret;
  1991. ::GetCaretPos(&ptCaret);
  1992. if( ::PtInRect(&m_rcItem, ptCaret) ) {
  1993. RECT rcCaret = { ptCaret.x, ptCaret.y, ptCaret.x, ptCaret.y + m_pTwh->GetCaretHeight() };
  1994. DWORD dwTextColor = GetTextColor();
  1995. CRenderEngine::DrawLine(hDC, rcCaret, m_pTwh->GetCaretWidth(), dwTextColor);
  1996. }
  1997. }
  1998. }
  1999. if( m_pVerticalScrollBar != NULL ) {
  2000. if( m_pVerticalScrollBar == pStopControl ) return false;
  2001. if (m_pVerticalScrollBar->IsVisible()) {
  2002. if( ::IntersectRect(&rcTemp, &rcPaint, &m_pVerticalScrollBar->GetPos()) ) {
  2003. if( !m_pVerticalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false;
  2004. }
  2005. }
  2006. }
  2007. if( m_pHorizontalScrollBar != NULL ) {
  2008. if( m_pHorizontalScrollBar == pStopControl ) return false;
  2009. if (m_pHorizontalScrollBar->IsVisible()) {
  2010. if( ::IntersectRect(&rcTemp, &rcPaint, &m_pHorizontalScrollBar->GetPos()) ) {
  2011. if( !m_pHorizontalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false;
  2012. }
  2013. }
  2014. }
  2015. // 绘制提示文字
  2016. CDuiString sDrawText = GetText();
  2017. if(sDrawText.IsEmpty() && !m_bFocused) {
  2018. DWORD dwTextColor = GetTipValueColor();
  2019. CDuiString sTipValue = GetTipValue();
  2020. RECT rc = m_rcItem;
  2021. RECT rcTextPadding = GetTextPadding();
  2022. rc.left += rcTextPadding.left;
  2023. rc.right -= rcTextPadding.right;
  2024. rc.top += rcTextPadding.top;
  2025. rc.bottom -= rcTextPadding.bottom;
  2026. UINT uTextAlign = GetTipValueAlign();
  2027. if(IsMultiLine()) uTextAlign |= DT_TOP;
  2028. else uTextAlign |= DT_VCENTER;
  2029. CRenderEngine::DrawText(hDC, m_pManager, rc, sTipValue, dwTextColor, m_iFont, uTextAlign);
  2030. }
  2031. return true;
  2032. }
  2033. LPCTSTR CRichEditUI::GetNormalImage()
  2034. {
  2035. return m_sNormalImage;
  2036. }
  2037. void CRichEditUI::SetNormalImage(LPCTSTR pStrImage)
  2038. {
  2039. m_sNormalImage = pStrImage;
  2040. Invalidate();
  2041. }
  2042. LPCTSTR CRichEditUI::GetHotImage()
  2043. {
  2044. return m_sHotImage;
  2045. }
  2046. void CRichEditUI::SetHotImage(LPCTSTR pStrImage)
  2047. {
  2048. m_sHotImage = pStrImage;
  2049. Invalidate();
  2050. }
  2051. LPCTSTR CRichEditUI::GetFocusedImage()
  2052. {
  2053. return m_sFocusedImage;
  2054. }
  2055. void CRichEditUI::SetFocusedImage(LPCTSTR pStrImage)
  2056. {
  2057. m_sFocusedImage = pStrImage;
  2058. Invalidate();
  2059. }
  2060. LPCTSTR CRichEditUI::GetDisabledImage()
  2061. {
  2062. return m_sDisabledImage;
  2063. }
  2064. void CRichEditUI::SetDisabledImage(LPCTSTR pStrImage)
  2065. {
  2066. m_sDisabledImage = pStrImage;
  2067. Invalidate();
  2068. }
  2069. RECT CRichEditUI::GetTextPadding() const
  2070. {
  2071. RECT rcTextPadding = m_rcTextPadding;
  2072. if(m_pManager) m_pManager->GetDPIObj()->Scale(&rcTextPadding);
  2073. return rcTextPadding;
  2074. }
  2075. void CRichEditUI::SetTextPadding(RECT rc)
  2076. {
  2077. m_rcTextPadding = rc;
  2078. Invalidate();
  2079. }
  2080. void CRichEditUI::SetTipValue( LPCTSTR pStrTipValue )
  2081. {
  2082. m_sTipValue = pStrTipValue;
  2083. Invalidate();
  2084. }
  2085. LPCTSTR CRichEditUI::GetTipValue()
  2086. {
  2087. return m_sTipValue.GetData();
  2088. }
  2089. void CRichEditUI::SetTipValueColor( LPCTSTR pStrColor )
  2090. {
  2091. if( *pStrColor == _T('#')) pStrColor = ::CharNext(pStrColor);
  2092. LPTSTR pstr = NULL;
  2093. DWORD clrColor = _tcstoul(pStrColor, &pstr, 16);
  2094. m_dwTipValueColor = clrColor;
  2095. Invalidate();
  2096. }
  2097. DWORD CRichEditUI::GetTipValueColor()
  2098. {
  2099. return m_dwTipValueColor;
  2100. }
  2101. void CRichEditUI::SetTipValueAlign(UINT uAlign)
  2102. {
  2103. m_uTipValueAlign = uAlign;
  2104. if(GetText().IsEmpty()) Invalidate();
  2105. }
  2106. UINT CRichEditUI::GetTipValueAlign()
  2107. {
  2108. return m_uTipValueAlign;
  2109. }
  2110. void CRichEditUI::PaintStatusImage(HDC hDC)
  2111. {
  2112. if( IsFocused() ) m_uButtonState |= UISTATE_FOCUSED;
  2113. else m_uButtonState &= ~ UISTATE_FOCUSED;
  2114. if( !IsEnabled() ) m_uButtonState |= UISTATE_DISABLED;
  2115. else m_uButtonState &= ~ UISTATE_DISABLED;
  2116. if( (m_uButtonState & UISTATE_DISABLED) != 0 ) {
  2117. if( !m_sDisabledImage.IsEmpty() ) {
  2118. if( !DrawImage(hDC, (LPCTSTR)m_sDisabledImage) ) {}
  2119. else return;
  2120. }
  2121. }
  2122. else if( (m_uButtonState & UISTATE_FOCUSED) != 0 ) {
  2123. if( !m_sFocusedImage.IsEmpty() ) {
  2124. if( !DrawImage(hDC, (LPCTSTR)m_sFocusedImage) ) {}
  2125. else return;
  2126. }
  2127. }
  2128. else if( (m_uButtonState & UISTATE_HOT ) != 0 ) {
  2129. if( !m_sHotImage.IsEmpty() ) {
  2130. if( !DrawImage(hDC, (LPCTSTR)m_sHotImage) ) {}
  2131. else return;
  2132. }
  2133. }
  2134. if( !m_sNormalImage.IsEmpty() ) {
  2135. if( !DrawImage(hDC, (LPCTSTR)m_sNormalImage) ) {}
  2136. else return;
  2137. }
  2138. }
  2139. void CRichEditUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
  2140. {
  2141. if( _tcscmp(pstrName, _T("vscrollbar")) == 0 ) {
  2142. if( _tcscmp(pstrValue, _T("true")) == 0 ) m_lTwhStyle |= ES_DISABLENOSCROLL | WS_VSCROLL;
  2143. }
  2144. if( _tcscmp(pstrName, _T("autovscroll")) == 0 ) {
  2145. if( _tcscmp(pstrValue, _T("true")) == 0 ) m_lTwhStyle |= ES_AUTOVSCROLL;
  2146. }
  2147. else if( _tcscmp(pstrName, _T("hscrollbar")) == 0 ) {
  2148. if( _tcscmp(pstrValue, _T("true")) == 0 ) m_lTwhStyle |= ES_DISABLENOSCROLL | WS_HSCROLL;
  2149. }
  2150. if( _tcscmp(pstrName, _T("autohscroll")) == 0 ) {
  2151. if( _tcscmp(pstrValue, _T("true")) == 0 ) m_lTwhStyle |= ES_AUTOHSCROLL;
  2152. }
  2153. else if( _tcsicmp(pstrName, _T("multiline")) == 0 ) {
  2154. SetMultiLine(_tcscmp(pstrValue, _T("true")) == 0);
  2155. }
  2156. else if( _tcscmp(pstrName, _T("wanttab")) == 0 ) {
  2157. SetWantTab(_tcscmp(pstrValue, _T("true")) == 0);
  2158. }
  2159. else if( _tcscmp(pstrName, _T("wantreturn")) == 0 ) {
  2160. SetWantReturn(_tcscmp(pstrValue, _T("true")) == 0);
  2161. }
  2162. else if( _tcscmp(pstrName, _T("wantctrlreturn")) == 0 ) {
  2163. SetWantCtrlReturn(_tcscmp(pstrValue, _T("true")) == 0);
  2164. }
  2165. else if( _tcscmp(pstrName, _T("transparent")) == 0 ) {
  2166. SetTransparent(_tcscmp(pstrValue, _T("true")) == 0);
  2167. }
  2168. else if( _tcscmp(pstrName, _T("rich")) == 0 ) {
  2169. SetRich(_tcscmp(pstrValue, _T("true")) == 0);
  2170. }
  2171. else if( _tcscmp(pstrName, _T("readonly")) == 0 ) {
  2172. if( _tcscmp(pstrValue, _T("true")) == 0 ) { m_lTwhStyle |= ES_READONLY; m_bReadOnly = true; }
  2173. }
  2174. else if( _tcscmp(pstrName, _T("password")) == 0 ) {
  2175. if( _tcscmp(pstrValue, _T("true")) == 0 ) m_lTwhStyle |= ES_PASSWORD;
  2176. }
  2177. else if( _tcscmp(pstrName, _T("align")) == 0 ) {
  2178. if( _tcsstr(pstrValue, _T("left")) != NULL ) {
  2179. m_lTwhStyle &= ~(ES_CENTER | ES_RIGHT);
  2180. m_lTwhStyle |= ES_LEFT;
  2181. }
  2182. if( _tcsstr(pstrValue, _T("center")) != NULL ) {
  2183. m_lTwhStyle &= ~(ES_LEFT | ES_RIGHT);
  2184. m_lTwhStyle |= ES_CENTER;
  2185. }
  2186. if( _tcsstr(pstrValue, _T("right")) != NULL ) {
  2187. m_lTwhStyle &= ~(ES_LEFT | ES_CENTER);
  2188. m_lTwhStyle |= ES_RIGHT;
  2189. }
  2190. }
  2191. else if( _tcscmp(pstrName, _T("font")) == 0 ) SetFont(_ttoi(pstrValue));
  2192. else if( _tcscmp(pstrName, _T("textcolor")) == 0 ) {
  2193. while( *pstrValue > _T('\0') && *pstrValue <= _T(' ') ) pstrValue = ::CharNext(pstrValue);
  2194. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  2195. LPTSTR pstr = NULL;
  2196. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  2197. SetTextColor(clrColor);
  2198. }
  2199. else if( _tcsicmp(pstrName, _T("maxchar")) == 0 ) SetLimitText(_ttoi(pstrValue));
  2200. else if( _tcsicmp(pstrName, _T("normalimage")) == 0 ) SetNormalImage(pstrValue);
  2201. else if( _tcsicmp(pstrName, _T("hotimage")) == 0 ) SetHotImage(pstrValue);
  2202. else if( _tcsicmp(pstrName, _T("focusedimage")) == 0 ) SetFocusedImage(pstrValue);
  2203. else if( _tcsicmp(pstrName, _T("disabledimage")) == 0 ) SetDisabledImage(pstrValue);
  2204. else if( _tcsicmp(pstrName, _T("textpadding")) == 0 ) {
  2205. RECT rcTextPadding = { 0 };
  2206. LPTSTR pstr = NULL;
  2207. rcTextPadding.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr);
  2208. rcTextPadding.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  2209. rcTextPadding.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  2210. rcTextPadding.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  2211. SetTextPadding(rcTextPadding);
  2212. }
  2213. else if( _tcsicmp(pstrName, _T("tipvalue")) == 0 ) SetTipValue(pstrValue);
  2214. else if( _tcsicmp(pstrName, _T("tipvaluecolor")) == 0 ) SetTipValueColor(pstrValue);
  2215. else if( _tcsicmp(pstrName, _T("tipvaluealign")) == 0 ) {
  2216. if( _tcsstr(pstrValue, _T("left")) != NULL ) {
  2217. m_uTipValueAlign = DT_SINGLELINE | DT_LEFT;
  2218. }
  2219. if( _tcsstr(pstrValue, _T("center")) != NULL ) {
  2220. m_uTipValueAlign = DT_SINGLELINE | DT_CENTER;
  2221. }
  2222. if( _tcsstr(pstrValue, _T("right")) != NULL ) {
  2223. m_uTipValueAlign = DT_SINGLELINE | DT_RIGHT;
  2224. }
  2225. }
  2226. else CContainerUI::SetAttribute(pstrName, pstrValue);
  2227. }
  2228. LRESULT CRichEditUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled)
  2229. {
  2230. if( !IsVisible() || !IsEnabled() ) return 0;
  2231. if( !IsMouseEnabled() && uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST ) return 0;
  2232. if( uMsg == WM_MOUSEWHEEL && (LOWORD(wParam) & MK_CONTROL) == 0 ) return 0;
  2233. if (uMsg == WM_IME_COMPOSITION) {
  2234. // 解决微软输入法位置异常的问题
  2235. HIMC hIMC = ImmGetContext(GetManager()->GetPaintWindow());
  2236. if (hIMC) {
  2237. POINT point;
  2238. GetCaretPos(&point);
  2239. COMPOSITIONFORM Composition;
  2240. Composition.dwStyle = CFS_POINT;
  2241. Composition.ptCurrentPos.x = point.x;
  2242. Composition.ptCurrentPos.y = point.y;
  2243. ImmSetCompositionWindow(hIMC, &Composition);
  2244. ImmReleaseContext(GetManager()->GetPaintWindow(),hIMC);
  2245. }
  2246. return 0;
  2247. }
  2248. bool bWasHandled = true;
  2249. if( (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST) || uMsg == WM_SETCURSOR ) {
  2250. if( !m_pTwh->IsCaptured() ) {
  2251. switch (uMsg) {
  2252. case WM_LBUTTONDOWN:
  2253. case WM_LBUTTONUP:
  2254. case WM_LBUTTONDBLCLK:
  2255. case WM_RBUTTONDOWN:
  2256. case WM_RBUTTONUP:
  2257. case WM_MOUSEMOVE:
  2258. {
  2259. POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
  2260. CControlUI* pHover = GetManager()->FindControl(pt);
  2261. if(pHover != this) {
  2262. bWasHandled = false;
  2263. return 0;
  2264. }
  2265. }
  2266. break;
  2267. }
  2268. }
  2269. // Mouse message only go when captured or inside rect
  2270. DWORD dwHitResult = m_pTwh->IsCaptured() ? HITRESULT_HIT : HITRESULT_OUTSIDE;
  2271. if( dwHitResult == HITRESULT_OUTSIDE ) {
  2272. RECT rc;
  2273. m_pTwh->GetControlRect(&rc);
  2274. POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
  2275. if( uMsg == WM_SETCURSOR ) {
  2276. ::GetCursorPos(&pt);
  2277. ::ScreenToClient(GetManager()->GetPaintWindow(), &pt);
  2278. }
  2279. else if( uMsg == WM_MOUSEWHEEL ) ::ScreenToClient(GetManager()->GetPaintWindow(), &pt);
  2280. if( ::PtInRect(&rc, pt) && !GetManager()->IsCaptured() ) dwHitResult = HITRESULT_HIT;
  2281. }
  2282. if( dwHitResult != HITRESULT_HIT ) return 0;
  2283. if( uMsg == WM_SETCURSOR ) bWasHandled = false;
  2284. else if( uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK || uMsg == WM_RBUTTONDOWN ) {
  2285. if (!GetManager()->IsNoActivate()) ::SetFocus(GetManager()->GetPaintWindow());
  2286. SetFocus();
  2287. }
  2288. }
  2289. #ifdef _UNICODE
  2290. else if( uMsg >= WM_KEYFIRST && uMsg <= WM_KEYLAST ) {
  2291. #else
  2292. else if( (uMsg >= WM_KEYFIRST && uMsg <= WM_KEYLAST) || uMsg == WM_CHAR || uMsg == WM_IME_CHAR ) {
  2293. #endif
  2294. if( !IsFocused() ) return 0;
  2295. }
  2296. #ifdef _USEIMM
  2297. else if( uMsg == WM_IME_STARTCOMPOSITION ) {
  2298. if( IsFocused() ) {
  2299. POINT ptCaret;
  2300. ::GetCaretPos(&ptCaret);
  2301. HIMC hMic = ::ImmGetContext(GetManager()->GetPaintWindow());
  2302. COMPOSITIONFORM cpf;
  2303. cpf.dwStyle = CFS_FORCE_POSITION;
  2304. cpf.ptCurrentPos.x = ptCaret.x + m_pTwh->GetCaretWidth();
  2305. cpf.ptCurrentPos.y = ptCaret.y;
  2306. ::ImmSetCompositionWindow(hMic, &cpf);
  2307. HFONT hFont = GetManager()->GetFont(m_iFont);
  2308. LOGFONT lf;
  2309. ::GetObject(hFont, sizeof(LOGFONT), &lf);
  2310. ::ImmSetCompositionFont(hMic, &lf);
  2311. ::ImmReleaseContext(GetManager()->GetPaintWindow(), hMic);
  2312. }
  2313. bWasHandled = false;
  2314. return 0;
  2315. }
  2316. #endif
  2317. else if( uMsg == WM_CONTEXTMENU ) {
  2318. // RichEdit是否支持右键菜单,使用menu属性来控制
  2319. if(!IsContextMenuUsed()) {
  2320. bWasHandled = false;
  2321. return 0;
  2322. }
  2323. POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
  2324. ::ScreenToClient(GetManager()->GetPaintWindow(), &pt);
  2325. CControlUI* pHover = GetManager()->FindControl(pt);
  2326. if(pHover != this) {
  2327. bWasHandled = false;
  2328. return 0;
  2329. }
  2330. //创建一个弹出式菜单
  2331. HMENU hPopMenu = CreatePopupMenu();
  2332. AppendMenu(hPopMenu, 0, ID_RICH_UNDO, _T("撤销(&U)"));
  2333. AppendMenu(hPopMenu, 0, ID_RICH_REDO, _T("重做(&R)"));
  2334. AppendMenu(hPopMenu, MF_SEPARATOR, 0, _T(""));
  2335. AppendMenu(hPopMenu, 0, ID_RICH_CUT, _T("剪切(&X)"));
  2336. AppendMenu(hPopMenu, 0, ID_RICH_COPY, _T("复制(&C)"));
  2337. AppendMenu(hPopMenu, 0, ID_RICH_PASTE, _T("粘帖(&V)"));
  2338. AppendMenu(hPopMenu, 0, ID_RICH_CLEAR, _T("清空(&L)"));
  2339. AppendMenu(hPopMenu, MF_SEPARATOR, 0, _T(""));
  2340. AppendMenu(hPopMenu, 0, ID_RICH_SELECTALL, _T("全选(&A)"));
  2341. //初始化菜单项
  2342. UINT uUndo = (CanUndo() ? 0 : MF_GRAYED);
  2343. EnableMenuItem(hPopMenu, ID_RICH_UNDO, MF_BYCOMMAND | uUndo);
  2344. UINT uRedo = (CanRedo() ? 0 : MF_GRAYED);
  2345. EnableMenuItem(hPopMenu, ID_RICH_REDO, MF_BYCOMMAND | uRedo);
  2346. UINT uSel = ((GetSelectionType() != SEL_EMPTY) ? 0 : MF_GRAYED);
  2347. UINT uReadonly = IsReadOnly() ? MF_GRAYED : 0;
  2348. EnableMenuItem(hPopMenu, ID_RICH_CUT, MF_BYCOMMAND | uSel | uReadonly);
  2349. EnableMenuItem(hPopMenu, ID_RICH_COPY, MF_BYCOMMAND | uSel);
  2350. EnableMenuItem(hPopMenu, ID_RICH_CLEAR, MF_BYCOMMAND | uSel | uReadonly);
  2351. EnableMenuItem(hPopMenu, ID_RICH_PASTE, MF_BYCOMMAND | uReadonly);
  2352. ::ClientToScreen(GetManager()->GetPaintWindow(), &pt);
  2353. TrackPopupMenu(hPopMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, GetManager()->GetPaintWindow(), NULL);
  2354. DestroyMenu(hPopMenu);
  2355. }
  2356. else if( uMsg == WM_COMMAND ) {
  2357. bHandled = FALSE;
  2358. if( !IsFocused() ) return 0;
  2359. UINT uCmd = (UINT)wParam;
  2360. switch(uCmd) {
  2361. case ID_RICH_UNDO:
  2362. {
  2363. Undo();
  2364. break;
  2365. }
  2366. case ID_RICH_REDO:
  2367. {
  2368. Redo();
  2369. break;
  2370. }
  2371. case ID_RICH_CUT:
  2372. {
  2373. Cut();
  2374. break;
  2375. }
  2376. case ID_RICH_COPY:
  2377. {
  2378. Copy();
  2379. break;
  2380. }
  2381. case ID_RICH_PASTE:
  2382. {
  2383. Paste();
  2384. break;
  2385. }
  2386. case ID_RICH_CLEAR:
  2387. {
  2388. Clear();
  2389. break;
  2390. }
  2391. case ID_RICH_SELECTALL:
  2392. {
  2393. SetSelAll();
  2394. break;
  2395. }
  2396. default:break;
  2397. }
  2398. }
  2399. else
  2400. {
  2401. switch( uMsg ) {
  2402. case WM_HELP:
  2403. bWasHandled = false;
  2404. break;
  2405. default:
  2406. return 0;
  2407. }
  2408. }
  2409. if(WM_CHAR == uMsg)
  2410. {
  2411. #ifndef _UNICODE
  2412. // check if we are waiting for 2 consecutive WM_CHAR messages
  2413. if ( IsAccumulateDBCMode() )
  2414. {
  2415. if ( (GetKeyState(VK_KANA) & 0x1) )
  2416. {
  2417. // turn off accumulate mode
  2418. SetAccumulateDBCMode ( false );
  2419. m_chLeadByte = 0;
  2420. }
  2421. else
  2422. {
  2423. if ( !m_chLeadByte )
  2424. {
  2425. // This is the first WM_CHAR message,
  2426. // accumulate it if this is a LeadByte. Otherwise, fall thru to
  2427. // regular WM_CHAR processing.
  2428. if ( IsDBCSLeadByte ( (WORD)wParam ) )
  2429. {
  2430. // save the Lead Byte and don't process this message
  2431. m_chLeadByte = (WORD)wParam << 8 ;
  2432. //TCHAR a = (WORD)wParam << 8 ;
  2433. return 0;
  2434. }
  2435. }
  2436. else
  2437. {
  2438. // This is the second WM_CHAR message,
  2439. // combine the current byte with previous byte.
  2440. // This DBC will be handled as WM_IME_CHAR.
  2441. wParam |= m_chLeadByte;
  2442. uMsg = WM_IME_CHAR;
  2443. // setup to accumulate more WM_CHAR
  2444. m_chLeadByte = 0;
  2445. }
  2446. }
  2447. }
  2448. #endif
  2449. }
  2450. LRESULT lResult = 0;
  2451. HRESULT Hr = TxSendMessage(uMsg, wParam, lParam, &lResult);
  2452. if( Hr == S_OK ) bHandled = bWasHandled;
  2453. else if( (uMsg >= WM_KEYFIRST && uMsg <= WM_KEYLAST) || uMsg == WM_CHAR || uMsg == WM_IME_CHAR )
  2454. bHandled = bWasHandled;
  2455. else if( uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST ) {
  2456. if( m_pTwh->IsCaptured() ) bHandled = bWasHandled;
  2457. }
  2458. return lResult;
  2459. }
  2460. } // namespace DuiLib