UIRichEdit.cpp 74 KB

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