1
0

embeddedEditor.cpp 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240
  1. #include "main.h"
  2. #include "./embeddedEditor.h"
  3. #include <vector>
  4. #define EMBEDDEDEDITOR_FRAME_LEFT 1
  5. #define EMBEDDEDEDITOR_FRAME_TOP 1
  6. #define EMBEDDEDEDITOR_FRAME_RIGHT 1
  7. #define EMBEDDEDEDITOR_FRAME_BOTTOM 1
  8. #define EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_LEFT 1
  9. #define EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_TOP 1
  10. #define EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_RIGHT 1
  11. #define EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_BOTTOM 1
  12. #define EMBEDDEDEDITOR_FRAME_INNER_SPACE_LEFT 0
  13. #define EMBEDDEDEDITOR_FRAME_INNER_SPACE_TOP 0
  14. #define EMBEDDEDEDITOR_FRAME_INNER_SPACE_RIGHT 0
  15. #define EMBEDDEDEDITOR_FRAME_INNER_SPACE_BOTTOM 0
  16. #define EMBEDDEDEDITOR_MARGIN_LEFT 4
  17. #define EMBEDDEDEDITOR_MARGIN_TOP 1
  18. #define EMBEDDEDEDITOR_MARGIN_RIGHT 4
  19. #define EMBEDDEDEDITOR_MARGIN_BOTTOM 1
  20. #define EMBEDDEDEDITOR_BORDER_LEFT (EMBEDDEDEDITOR_FRAME_LEFT + \
  21. EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_LEFT + \
  22. EMBEDDEDEDITOR_FRAME_INNER_SPACE_LEFT)
  23. #define EMBEDDEDEDITOR_BORDER_TOP (EMBEDDEDEDITOR_FRAME_TOP + \
  24. EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_TOP + \
  25. EMBEDDEDEDITOR_FRAME_INNER_SPACE_TOP)
  26. #define EMBEDDEDEDITOR_BORDER_RIGHT (EMBEDDEDEDITOR_FRAME_RIGHT + \
  27. EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_RIGHT + \
  28. EMBEDDEDEDITOR_FRAME_INNER_SPACE_RIGHT)
  29. #define EMBEDDEDEDITOR_BORDER_BOTTOM (EMBEDDEDEDITOR_FRAME_BOTTOM + \
  30. EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_BOTTOM + \
  31. EMBEDDEDEDITOR_FRAME_INNER_SPACE_BOTTOM)
  32. typedef struct EmbeddedEditor
  33. {
  34. WNDPROC originalProc;
  35. COLORREF textColor;
  36. COLORREF backColor;
  37. COLORREF borderColor;
  38. HBRUSH backBrush;
  39. HBRUSH borderBrush;
  40. EmbeddedEditorFinishCb callback;
  41. void *user;
  42. POINT anchorPoint;
  43. SIZE maximumSize;
  44. wchar_t *buffer;
  45. size_t bufferSize;
  46. long spacing;
  47. long lineHeight;
  48. } EmbeddedEditor;
  49. typedef std::vector<HWND> WindowList;
  50. typedef struct EmbeddedEditorParent
  51. {
  52. WNDPROC originalProc;
  53. WindowList editorList;
  54. } EmbeddedEditorParent;
  55. typedef struct EmbeddedEditorThread
  56. {
  57. HHOOK hook;
  58. HWND window;
  59. } EmbeddedEditorThread;
  60. static size_t editorTls = ((size_t)-1);
  61. static ATOM EMBEDDEDEDITOR_PROP = 0;
  62. #define EMBEDDEDEDITOR(_hwnd) ((EmbeddedEditor*)GetPropW((_hwnd), MAKEINTATOM(EMBEDDEDEDITOR_PROP)))
  63. #define EMBEDDEDEDITOR_RET_VOID(_self, _hwnd) { (_self) = EMBEDDEDEDITOR((_hwnd)); if (NULL == (_self)) return; }
  64. #define EMBEDDEDEDITOR_RET_VAL(_self, _hwnd, _error) { (_self) = EMBEDDEDEDITOR((_hwnd)); if (NULL == (_self)) return (_error); }
  65. #define EMBEDDEDEDITOR_PARENT(_hwnd) ((EmbeddedEditorParent*)GetPropW((_hwnd), MAKEINTATOM(EMBEDDEDEDITOR_PROP)))
  66. static LRESULT WINAPI
  67. EmbeddedEditor_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  68. static LRESULT WINAPI
  69. EmbeddedEditorParent_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  70. static LRESULT CALLBACK
  71. EmbeddidEditorThread_MouseProc(int code, unsigned int messageId, MOUSEHOOKSTRUCT *mouse);
  72. static BOOL
  73. EmbeddidEditorThread_BeginMouseMonitor(HWND editorWindow)
  74. {
  75. EmbeddedEditorThread *threadData;
  76. if (NULL == WASABI_API_APP ||
  77. NULL == editorWindow)
  78. {
  79. return FALSE;
  80. }
  81. if ((size_t)-1 == editorTls)
  82. {
  83. editorTls = WASABI_API_APP->AllocateThreadStorage();
  84. if ((size_t)-1 == editorTls)
  85. return FALSE;
  86. threadData = NULL;
  87. }
  88. else
  89. {
  90. threadData = (EmbeddedEditorThread*)WASABI_API_APP->GetThreadStorage(editorTls);
  91. WASABI_API_APP->SetThreadStorage(editorTls, NULL);
  92. }
  93. if (NULL != threadData)
  94. {
  95. if (NULL != threadData->window)
  96. DestroyWindow(threadData->window);
  97. }
  98. else
  99. {
  100. threadData = (EmbeddedEditorThread*)malloc(sizeof(EmbeddedEditorThread));
  101. if (NULL == threadData)
  102. return FALSE;
  103. threadData->hook = SetWindowsHookEx(WH_MOUSE, (HOOKPROC)EmbeddidEditorThread_MouseProc, NULL, GetCurrentThreadId());
  104. if (NULL == threadData->hook)
  105. {
  106. free(threadData);
  107. return FALSE;
  108. }
  109. }
  110. threadData->window = editorWindow;
  111. WASABI_API_APP->SetThreadStorage(editorTls, threadData);
  112. return TRUE;
  113. }
  114. static void
  115. EmbeddidEditorThread_EndMouseMonitor(HWND editorWindow)
  116. {
  117. EmbeddedEditorThread *threadData;
  118. if (NULL == WASABI_API_APP ||
  119. (size_t)-1 == editorTls ||
  120. NULL == editorWindow)
  121. {
  122. return;
  123. }
  124. threadData = (EmbeddedEditorThread*)WASABI_API_APP->GetThreadStorage(editorTls);
  125. WASABI_API_APP->SetThreadStorage(editorTls, NULL);
  126. if (NULL != threadData)
  127. {
  128. if (NULL != threadData->hook)
  129. UnhookWindowsHookEx(threadData->hook);
  130. free(threadData);
  131. }
  132. }
  133. static BOOL
  134. EmbeddedEditorParent_AddChild(HWND hwnd, HWND child)
  135. {
  136. EmbeddedEditorParent *self;
  137. if (NULL == hwnd || NULL == child)
  138. return FALSE;
  139. self = EMBEDDEDEDITOR_PARENT(hwnd);
  140. if (NULL == self)
  141. {
  142. self = new EmbeddedEditorParent();
  143. if (NULL == self)
  144. return FALSE;
  145. self->originalProc = (WNDPROC)(LONG_PTR)SetWindowLongPtr(hwnd, GWLP_WNDPROC,
  146. (LONGX86)(LONG_PTR)EmbeddedEditorParent_WindowProc);
  147. if (NULL != self->originalProc &&
  148. FALSE == SetProp(hwnd, MAKEINTATOM(EMBEDDEDEDITOR_PROP), self))
  149. {
  150. SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)self->originalProc);
  151. delete self;
  152. return FALSE;
  153. }
  154. }
  155. else
  156. {
  157. size_t index;
  158. index = self->editorList.size();
  159. while(index--)
  160. {
  161. if (self->editorList[index] == child)
  162. return FALSE;
  163. }
  164. }
  165. self->editorList.push_back(child);
  166. return TRUE;
  167. }
  168. static BOOL
  169. EmbeddedEditorParent_RemoveChild(HWND hwnd, HWND child)
  170. {
  171. size_t index;
  172. EmbeddedEditorParent *self;
  173. if (NULL == hwnd || NULL == child)
  174. return FALSE;
  175. self = EMBEDDEDEDITOR_PARENT(hwnd);
  176. if (NULL == self)
  177. return FALSE;
  178. index = self->editorList.size();
  179. while(index--)
  180. {
  181. if (self->editorList[index] == child)
  182. break;
  183. }
  184. if (((size_t)-1) == index)
  185. return FALSE;
  186. self->editorList.erase(self->editorList.begin() + index);
  187. if (0 == self->editorList.size())
  188. {
  189. RemoveProp(hwnd, MAKEINTATOM(EMBEDDEDEDITOR_PROP));
  190. if (NULL != self->originalProc)
  191. SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)self->originalProc);
  192. delete self;
  193. }
  194. return TRUE;
  195. }
  196. BOOL
  197. EmbeddedEditor_Attach(HWND hwnd, EmbeddedEditorFinishCb callback, void *user)
  198. {
  199. HWND parent;
  200. EmbeddedEditor *self;
  201. if (NULL == hwnd)
  202. return FALSE;
  203. if (0 == EMBEDDEDEDITOR_PROP)
  204. {
  205. EMBEDDEDEDITOR_PROP = GlobalAddAtom(TEXT("EmdeddedEditorProp"));
  206. if (0 == EMBEDDEDEDITOR_PROP)
  207. return FALSE;
  208. }
  209. self = (EmbeddedEditor*)malloc(sizeof(EmbeddedEditor));
  210. if (NULL == self)
  211. return FALSE;
  212. memset(self, 0, sizeof(EmbeddedEditor));
  213. self->originalProc = (WNDPROC)(LONG_PTR)SetWindowLongPtr(hwnd, GWLP_WNDPROC,
  214. (LONGX86)(LONG_PTR)EmbeddedEditor_WindowProc);
  215. if (NULL != self->originalProc &&
  216. FALSE == SetProp(hwnd, MAKEINTATOM(EMBEDDEDEDITOR_PROP), self))
  217. {
  218. SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)self->originalProc);
  219. free(self);
  220. return FALSE;
  221. }
  222. self->callback = callback;
  223. self->user = user;
  224. self->backColor = RGB(0, 0, 255); //GetSysColor(COLOR_WINDOW);
  225. self->backBrush = NULL;
  226. self->textColor = RGB(255, 255, 0); //GetSysColor(COLOR_WINDOWTEXT);
  227. self->borderColor = RGB(255, 0, 0); //GetSysColor(COLOR_WINDOWFRAME);
  228. self->borderBrush = NULL;
  229. self->spacing = -1;
  230. self->lineHeight = -1;
  231. parent = GetAncestor(hwnd, GA_PARENT);
  232. if(NULL != parent)
  233. EmbeddedEditorParent_AddChild(parent, hwnd);
  234. EmbeddidEditorThread_BeginMouseMonitor(hwnd);
  235. RECT rect, formatRect;
  236. GetWindowRect(hwnd, &rect);
  237. SetRect(&formatRect, 0, 0, RECTWIDTH(rect) - 6, RECTHEIGHT(rect) - 6);
  238. SendMessage(hwnd, EM_SETRECTNP, 0, (LPARAM)&formatRect);
  239. SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
  240. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
  241. return TRUE;
  242. }
  243. BOOL
  244. EmbeddedEditor_AdjustWindowRectEx(RECT *rect, unsigned long styleEx, unsigned long style)
  245. {
  246. if (NULL == rect)
  247. return FALSE;
  248. if (0 != ((WS_EX_STATICEDGE | WS_EX_CLIENTEDGE) & styleEx) ||
  249. 0 != (WS_BORDER & style))
  250. {
  251. rect->left -= (EMBEDDEDEDITOR_BORDER_LEFT + EMBEDDEDEDITOR_MARGIN_LEFT);
  252. rect->top -= (EMBEDDEDEDITOR_BORDER_TOP + EMBEDDEDEDITOR_MARGIN_TOP);
  253. rect->right += (EMBEDDEDEDITOR_BORDER_RIGHT + EMBEDDEDEDITOR_MARGIN_RIGHT);
  254. rect->bottom += (EMBEDDEDEDITOR_BORDER_BOTTOM + EMBEDDEDEDITOR_MARGIN_BOTTOM);
  255. }
  256. return TRUE;
  257. }
  258. static HBRUSH
  259. EmbeddedEditor_GetBackBrush(EmbeddedEditor *self)
  260. {
  261. if (NULL == self->backBrush)
  262. self->backBrush = CreateSolidBrush(self->backColor);
  263. return self->backBrush;
  264. }
  265. static HBRUSH
  266. EmbeddedEditor_GetBorderBrush(EmbeddedEditor *self)
  267. {
  268. if (NULL == self->borderBrush)
  269. self->borderBrush = CreateSolidBrush(self->borderColor);
  270. return self->borderBrush;
  271. }
  272. static BOOL
  273. EmbdeddedEditor_GetBorderEnabled(HWND hwnd)
  274. {
  275. unsigned long style;
  276. style = GetWindowStyleEx(hwnd);
  277. if (0 != ((WS_EX_STATICEDGE | WS_EX_CLIENTEDGE) & style))
  278. return TRUE;
  279. style = GetWindowStyle(hwnd);
  280. if (0 != (WS_BORDER & style))
  281. return TRUE;
  282. return FALSE;
  283. }
  284. static BOOL
  285. EmbdeddedEditor_DrawBorder(EmbeddedEditor *self, HWND hwnd, HDC hdc)
  286. {
  287. RECT windowRect, clientRect;
  288. HRGN borderRgn;
  289. POINT polygons[16] = {0};
  290. const int polygonsPointCount[] = {4, 4, 4, 4};
  291. if (FALSE == GetWindowRect(hwnd, &windowRect) ||
  292. FALSE == GetClientRect(hwnd, &clientRect))
  293. {
  294. return FALSE;
  295. }
  296. MapWindowPoints(hwnd, HWND_DESKTOP, (POINT*)&clientRect, 2);
  297. OffsetRect(&clientRect, -windowRect.left, -windowRect.top);
  298. OffsetRect(&windowRect, -windowRect.left, -windowRect.top);
  299. MakeRectPolygon(&polygons[0], windowRect.left, windowRect.top, windowRect.right, clientRect.top);
  300. MakeRectPolygon(&polygons[4], clientRect.right, clientRect.top, windowRect.right, clientRect.bottom);
  301. MakeRectPolygon(&polygons[8], windowRect.left, clientRect.bottom, windowRect.right, windowRect.bottom);
  302. MakeRectPolygon(&polygons[12], windowRect.left, clientRect.top, clientRect.left, clientRect.bottom);
  303. borderRgn = CreatePolyPolygonRgn(polygons,
  304. polygonsPointCount,
  305. ARRAYSIZE(polygonsPointCount),
  306. WINDING);
  307. if (NULL != borderRgn)
  308. {
  309. MakeRectPolygon(&polygons[0],
  310. windowRect.left + EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_LEFT,
  311. windowRect.top + EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_TOP,
  312. windowRect.right - EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_RIGHT,
  313. windowRect.top + (EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_TOP + EMBEDDEDEDITOR_FRAME_TOP));
  314. MakeRectPolygon(&polygons[4],
  315. windowRect.right - (EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_RIGHT + EMBEDDEDEDITOR_FRAME_RIGHT),
  316. windowRect.top + (EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_TOP + EMBEDDEDEDITOR_FRAME_TOP),
  317. windowRect.right - EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_RIGHT,
  318. windowRect.bottom - (EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_BOTTOM + EMBEDDEDEDITOR_FRAME_BOTTOM));
  319. MakeRectPolygon(&polygons[8],
  320. windowRect.left + EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_LEFT,
  321. windowRect.bottom - (EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_BOTTOM + EMBEDDEDEDITOR_FRAME_BOTTOM),
  322. windowRect.right - EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_RIGHT,
  323. windowRect.bottom - EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_BOTTOM);
  324. MakeRectPolygon(&polygons[12],
  325. windowRect.left + EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_LEFT,
  326. windowRect.top + (EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_TOP + EMBEDDEDEDITOR_FRAME_TOP),
  327. windowRect.left + (EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_LEFT + EMBEDDEDEDITOR_FRAME_LEFT),
  328. windowRect.bottom - (EMBEDDEDEDITOR_FRAME_OUTTER_SPACE_BOTTOM + EMBEDDEDEDITOR_FRAME_BOTTOM));
  329. HRGN frameRgn = CreatePolyPolygonRgn(polygons,
  330. polygonsPointCount,
  331. ARRAYSIZE(polygonsPointCount),
  332. WINDING);
  333. if (NULL != frameRgn)
  334. {
  335. int combineResult = CombineRgn(frameRgn, borderRgn, frameRgn, RGN_AND);
  336. if (NULLREGION != combineResult && ERROR != combineResult)
  337. {
  338. FillRgn(hdc, frameRgn, EmbeddedEditor_GetBorderBrush(self));
  339. combineResult = CombineRgn(borderRgn, borderRgn, frameRgn, RGN_DIFF);
  340. }
  341. else
  342. combineResult = COMPLEXREGION;
  343. if (NULLREGION != combineResult && ERROR != combineResult)
  344. FillRgn(hdc, borderRgn, EmbeddedEditor_GetBackBrush(self));
  345. DeleteObject(frameRgn);
  346. }
  347. DeleteObject(borderRgn);
  348. }
  349. return TRUE;
  350. }
  351. static BOOL
  352. EmbeddedEditor_InvokeCallback(EmbeddedEditor *self, HWND hwnd, BOOL cancelMode, BOOL removeCallback)
  353. {
  354. wchar_t *text;
  355. unsigned int length;
  356. EmbeddedEditorFinishCb callback;
  357. if (NULL == self || NULL == self->callback)
  358. return FALSE;
  359. length = (unsigned int)SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0L);
  360. text = String_Malloc(++length);
  361. if (NULL == text)
  362. return FALSE;
  363. SendMessage(hwnd, WM_GETTEXT, (WPARAM)length, (LPARAM)text);
  364. callback = self->callback;
  365. if (FALSE != removeCallback)
  366. self->callback = NULL;
  367. callback(hwnd, cancelMode, text, self->user);
  368. return TRUE;
  369. }
  370. static const wchar_t *
  371. EmbeddedEditor_GetWindowText(EmbeddedEditor *self, HWND hwnd, size_t *lengthOut)
  372. {
  373. size_t length;
  374. length = (size_t)SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0L);
  375. if (length >= self->bufferSize)
  376. {
  377. size_t size;
  378. size = (((length + 1)/128) + 1) * 128;
  379. String_Free(self->buffer);
  380. self->buffer = String_Malloc(size);
  381. if (NULL == self->buffer)
  382. return FALSE;
  383. self->bufferSize = size;
  384. }
  385. if (0 != length)
  386. length = SendMessage(hwnd, WM_GETTEXT, (WPARAM)self->bufferSize, (LPARAM)self->buffer);
  387. else
  388. self->buffer[0] = L'\0';
  389. if (NULL != lengthOut)
  390. *lengthOut = length;
  391. return self->buffer;
  392. }
  393. static BOOL
  394. EmbeddedEditor_Resize(EmbeddedEditor *self, HWND hwnd, BOOL redraw)
  395. {
  396. size_t textLength;
  397. const wchar_t *text;
  398. HDC hdc;
  399. SIZE maximumSize;
  400. BOOL borderEnabled;
  401. HWND parentWindow;
  402. RECT rect, parentRect, marginRect;
  403. SIZE parentSize;
  404. BOOL result;
  405. unsigned int windowStyle;
  406. HFONT font, prevFont;
  407. parentWindow = GetAncestor(hwnd, GA_PARENT);
  408. if (NULL == parentWindow ||
  409. FALSE == GetClientRect(parentWindow, &parentRect))
  410. {
  411. return FALSE;
  412. }
  413. parentSize.cx = RECTWIDTH(parentRect);
  414. parentSize.cy = RECTHEIGHT(parentRect);
  415. windowStyle = GetWindowStyle(hwnd);
  416. borderEnabled = EmbdeddedEditor_GetBorderEnabled(hwnd);
  417. text = EmbeddedEditor_GetWindowText(self, hwnd, &textLength);
  418. if (NULL == text)
  419. return FALSE;
  420. hdc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS);
  421. if (NULL == hdc)
  422. return FALSE;
  423. result = FALSE;
  424. font = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0L);
  425. prevFont = SelectFont(hdc, font);
  426. if (-1 == self->spacing ||
  427. -1 == self->lineHeight)
  428. {
  429. TEXTMETRIC textMetrics;
  430. if (FALSE != GetTextMetrics(hdc, &textMetrics))
  431. {
  432. self->spacing = textMetrics.tmAveCharWidth;
  433. self->lineHeight = textMetrics.tmHeight;
  434. }
  435. }
  436. if (0 == (ES_MULTILINE & windowStyle))
  437. {
  438. unsigned long margins;
  439. margins = (unsigned long)SendMessage(hwnd, EM_GETMARGINS, 0, 0L);
  440. SetRect(&marginRect, (short)LOWORD(margins), 0, (short)HIWORD(margins), 0);
  441. }
  442. else
  443. {
  444. RECT clientRect;
  445. if (FALSE == GetClientRect(hwnd, &clientRect))
  446. SetRectEmpty(&clientRect);
  447. if (clientRect.right < clientRect.left)
  448. clientRect.right = clientRect.left;
  449. if (clientRect.bottom < (clientRect.top + self->lineHeight))
  450. clientRect.bottom = clientRect.top + self->lineHeight;
  451. SendMessage(hwnd, EM_GETRECT, 0, (LPARAM)&marginRect);
  452. marginRect.left = (marginRect.left > clientRect.left) ?
  453. (marginRect.left - clientRect.left) : 1;
  454. marginRect.top = (marginRect.top > clientRect.top) ?
  455. (marginRect.top - clientRect.top) : 1;
  456. marginRect.right = (marginRect.right < clientRect.right) ?
  457. (clientRect.right - marginRect.right) : 1;
  458. marginRect.bottom = (marginRect.bottom < clientRect.bottom) ?
  459. (clientRect.bottom - marginRect.bottom) : 1;
  460. if (SendMessage(hwnd, EM_GETLINECOUNT, 0, 0L) > 1)
  461. {
  462. if (marginRect.bottom >= (self->lineHeight - 1))
  463. marginRect.bottom -= (self->lineHeight - 2);
  464. }
  465. SetRect(&marginRect, EMBEDDEDEDITOR_MARGIN_LEFT, EMBEDDEDEDITOR_MARGIN_TOP,
  466. EMBEDDEDEDITOR_MARGIN_RIGHT, EMBEDDEDEDITOR_MARGIN_BOTTOM);
  467. }
  468. maximumSize.cx = (self->maximumSize.cx > 0) ? MIN(parentSize.cx, self->maximumSize.cx) : parentSize.cx;
  469. maximumSize.cx -= (marginRect.left + marginRect.right);
  470. if (FALSE != borderEnabled)
  471. maximumSize.cx -= (EMBEDDEDEDITOR_BORDER_LEFT + EMBEDDEDEDITOR_BORDER_RIGHT);
  472. if (maximumSize.cx < 0)
  473. maximumSize.cx = 0;
  474. maximumSize.cy = (self->maximumSize.cy > 0) ? MIN(parentSize.cy, self->maximumSize.cy) : parentSize.cy;
  475. maximumSize.cy -= (marginRect.top + marginRect.bottom);
  476. if (FALSE != borderEnabled)
  477. maximumSize.cy -= (EMBEDDEDEDITOR_BORDER_TOP + EMBEDDEDEDITOR_BORDER_BOTTOM);
  478. if (maximumSize.cy < 0)
  479. maximumSize.cy = 0;
  480. if (0 == textLength)
  481. {
  482. SetRectEmpty(&rect);
  483. result = TRUE;
  484. }
  485. else
  486. {
  487. SetRect(&rect, 0, 0, maximumSize.cx, maximumSize.cy);
  488. result = DrawText(hdc, text, (int)textLength, &rect,
  489. DT_CALCRECT | DT_LEFT | DT_TOP | DT_WORDBREAK |
  490. DT_EDITCONTROL | DT_NOPREFIX);
  491. }
  492. SelectFont(hdc, prevFont);
  493. ReleaseDC(hwnd, hdc);
  494. if (FALSE != result)
  495. {
  496. unsigned int flags;
  497. rect.right += 2 * self->spacing;
  498. if (RECTHEIGHT(rect) < self->lineHeight)
  499. rect.bottom = rect.top + self->lineHeight;
  500. else if (RECTHEIGHT(rect) > self->lineHeight)
  501. rect.right = rect.left + maximumSize.cx;
  502. rect.right += (marginRect.left + marginRect.right);
  503. rect.bottom += (marginRect.top + marginRect.bottom);
  504. if (FALSE != borderEnabled)
  505. {
  506. rect.right += (EMBEDDEDEDITOR_BORDER_LEFT + EMBEDDEDEDITOR_BORDER_RIGHT);
  507. rect.bottom += (EMBEDDEDEDITOR_BORDER_TOP + EMBEDDEDEDITOR_BORDER_BOTTOM);
  508. }
  509. flags = SWP_NOACTIVATE | SWP_NOZORDER;
  510. if (FALSE == redraw)
  511. flags |= SWP_NOREDRAW;
  512. OffsetRect(&rect, self->anchorPoint.x, self->anchorPoint.y);
  513. long offsetX = 0, offsetY = 0;
  514. if (0 != (ES_CENTER & windowStyle))
  515. {
  516. if (self->maximumSize.cx > 0)
  517. {
  518. offsetX += (self->maximumSize.cx - RECTWIDTH(rect))/2;
  519. }
  520. }
  521. if (rect.right > parentSize.cx)
  522. offsetX -= (rect.right - parentSize.cx);
  523. if (rect.bottom > parentSize.cy)
  524. offsetY -= (rect.bottom - parentSize.cy);
  525. OffsetRect(&rect, offsetX, offsetY);
  526. result = SetWindowPos(hwnd, NULL, rect.left, rect.top, RECTWIDTH(rect), RECTHEIGHT(rect), flags);
  527. }
  528. return result;
  529. }
  530. static void
  531. EmbdeddedEditor_OnDestroy(EmbeddedEditor *self, HWND hwnd)
  532. {
  533. HWND parent;
  534. if (NULL != self &&
  535. NULL != self->callback)
  536. {
  537. EmbeddedEditor_InvokeCallback(self, hwnd, TRUE, TRUE);
  538. }
  539. RemoveProp(hwnd, MAKEINTATOM(EMBEDDEDEDITOR_PROP));
  540. if (NULL == self)
  541. return;
  542. if (NULL != self->originalProc)
  543. {
  544. SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)self->originalProc);
  545. CallWindowProc(self->originalProc, hwnd, WM_DESTROY, 0, 0L);
  546. }
  547. if(NULL != self->backBrush)
  548. DeleteObject(self->backBrush);
  549. if (NULL != self->borderBrush)
  550. DeleteObject(self->borderBrush);
  551. String_Free(self->buffer);
  552. free(self);
  553. parent = GetAncestor(hwnd, GA_PARENT);
  554. if(NULL != parent)
  555. EmbeddedEditorParent_RemoveChild(parent, hwnd);
  556. EmbeddidEditorThread_EndMouseMonitor(hwnd);
  557. }
  558. static BOOL
  559. EmbdeddedEditor_OnNcCalcSize(EmbeddedEditor *self, HWND hwnd, BOOL calcValidRects,
  560. NCCALCSIZE_PARAMS *params, LRESULT *result)
  561. {
  562. if (FALSE != EmbdeddedEditor_GetBorderEnabled(hwnd))
  563. {
  564. if (FALSE != calcValidRects)
  565. {
  566. SetRect(&params->rgrc[0],
  567. params->lppos->x + EMBEDDEDEDITOR_BORDER_LEFT,
  568. params->lppos->y + EMBEDDEDEDITOR_BORDER_TOP,
  569. params->lppos->x + params->lppos->cx - EMBEDDEDEDITOR_BORDER_RIGHT,
  570. params->lppos->y + params->lppos->cy - EMBEDDEDEDITOR_BORDER_BOTTOM);
  571. *result = WVR_ALIGNTOP | WVR_ALIGNLEFT;
  572. }
  573. else
  574. {
  575. if (FALSE != GetWindowRect(hwnd, &params->rgrc[0]))
  576. {
  577. params->rgrc[0].left += EMBEDDEDEDITOR_BORDER_LEFT;
  578. params->rgrc[0].top += EMBEDDEDEDITOR_BORDER_TOP;
  579. params->rgrc[0].right -= EMBEDDEDEDITOR_BORDER_RIGHT;
  580. params->rgrc[0].bottom -= EMBEDDEDEDITOR_BORDER_BOTTOM;
  581. }
  582. }
  583. }
  584. return TRUE;
  585. }
  586. static BOOL
  587. EmbdeddedEditor_OnNcPaint(EmbeddedEditor *self, HWND hwnd, HRGN updateRegion)
  588. {
  589. BOOL result;
  590. if (FALSE != EmbdeddedEditor_GetBorderEnabled(hwnd))
  591. {
  592. HDC hdc;
  593. unsigned int flags;
  594. flags = DCX_PARENTCLIP | DCX_CACHE | DCX_WINDOW | DCX_CLIPSIBLINGS |
  595. DCX_INTERSECTUPDATE | DCX_VALIDATE;
  596. hdc = GetDCEx(hwnd, ((HRGN)NULLREGION != updateRegion) ? updateRegion : NULL, flags);
  597. if (NULL != hdc)
  598. {
  599. result = EmbdeddedEditor_DrawBorder(self, hwnd, hdc);
  600. ReleaseDC(hwnd, hdc);
  601. }
  602. else
  603. result = FALSE;
  604. }
  605. else
  606. result = TRUE;
  607. return result;
  608. }
  609. static BOOL
  610. EmbeddedEditor_OnSetCursor(EmbeddedEditor *self, HWND hwnd, HWND cursorWindow, int hitTest, int mouseMessage, LRESULT *result)
  611. {
  612. HCURSOR cursor;
  613. if (cursorWindow != hwnd ||
  614. HTCLIENT != hitTest)
  615. {
  616. return FALSE;
  617. }
  618. cursor = LoadCursor(NULL, IDC_IBEAM);
  619. if (NULL == cursor)
  620. return FALSE;
  621. SetCursor(cursor);
  622. *result = TRUE;
  623. return TRUE;
  624. }
  625. static BOOL
  626. EmbeddedEditor_OnGetDlgCode(EmbeddedEditor *self, HWND hwnd, unsigned int vKey, MSG *message, LRESULT *result)
  627. {
  628. if (NULL != message)
  629. {
  630. switch(vKey)
  631. {
  632. case VK_TAB:
  633. case VK_ESCAPE:
  634. EmbeddedEditor_InvokeCallback(self, hwnd, TRUE, TRUE);
  635. DestroyWindow(hwnd);
  636. *result = DLGC_WANTMESSAGE;
  637. return TRUE;
  638. case VK_RETURN:
  639. EmbeddedEditor_InvokeCallback(self, hwnd, FALSE, TRUE);
  640. DestroyWindow(hwnd);
  641. *result = DLGC_WANTMESSAGE;
  642. return TRUE;
  643. }
  644. }
  645. if (NULL != self->originalProc)
  646. *result = CallWindowProc(self->originalProc, hwnd, WM_GETDLGCODE, (WPARAM)vKey, (LPARAM)message);
  647. else
  648. *result = 0;
  649. if (NULL == message)
  650. *result |= DLGC_WANTMESSAGE;
  651. return TRUE;
  652. }
  653. static BOOL
  654. EmbeddedEditor_OnKillFocus(EmbeddedEditor *self, HWND hwnd, HWND focusedWindow)
  655. {
  656. EmbeddedEditor_InvokeCallback(self, hwnd, FALSE, TRUE);
  657. DestroyWindow(hwnd);
  658. return TRUE;
  659. }
  660. static BOOL
  661. EmbeddedEditor_OnMouseWheel(EmbeddedEditor *self, HWND hwnd, int virtualKeys, int distance, long pointer_s)
  662. {
  663. HWND parentWindow;
  664. parentWindow = GetAncestor(hwnd, GA_PARENT);
  665. EmbeddedEditor_InvokeCallback(self, hwnd, TRUE, TRUE);
  666. DestroyWindow(hwnd);
  667. if (NULL != parentWindow)
  668. {
  669. SendMessage(parentWindow, WM_MOUSEWHEEL,
  670. MAKEWPARAM(virtualKeys, distance), (LPARAM)pointer_s);
  671. }
  672. return TRUE;
  673. }
  674. static void
  675. EmbeddedEditor_OnCommand(EmbeddedEditor *self, HWND hwnd, int eventId)
  676. {
  677. switch(eventId)
  678. {
  679. case EN_UPDATE:
  680. EmbeddedEditor_Resize(self, hwnd, TRUE);
  681. break;
  682. }
  683. }
  684. static BOOL
  685. EmbeddedEditor_OnSetFont(EmbeddedEditor *self, HWND hwnd, HFONT font, BOOL redraw)
  686. {
  687. if (NULL != self->originalProc)
  688. CallWindowProc(self->originalProc, hwnd, WM_SETFONT, (WPARAM)font, MAKELPARAM(redraw, 0));
  689. self->spacing = -1;
  690. self->lineHeight = -1;
  691. EmbeddedEditor_Resize(self, hwnd, redraw);
  692. return TRUE;
  693. }
  694. static BOOL
  695. EmbeddedEditor_OnWindowPosChanged(EmbeddedEditor *self, HWND hwnd, WINDOWPOS *pwp)
  696. {
  697. if (SWP_NOSIZE != ((SWP_NOSIZE | SWP_FRAMECHANGED) & pwp->flags))
  698. {
  699. RECT formatRect;
  700. if (FALSE != GetClientRect(hwnd, &formatRect))
  701. {
  702. formatRect.left += EMBEDDEDEDITOR_MARGIN_LEFT;
  703. formatRect.top += EMBEDDEDEDITOR_MARGIN_TOP;
  704. formatRect.right -= EMBEDDEDEDITOR_MARGIN_RIGHT;
  705. formatRect.bottom -= EMBEDDEDEDITOR_MARGIN_BOTTOM;
  706. if (formatRect.right < formatRect.left)
  707. formatRect.right = formatRect.left;
  708. if (formatRect.bottom < formatRect.top)
  709. formatRect.bottom = formatRect.top;
  710. SendMessage(hwnd, EM_SETRECTNP, 0, (LPARAM)&formatRect);
  711. }
  712. }
  713. if (NULL != self->originalProc)
  714. CallWindowProc(self->originalProc, hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)pwp);
  715. return TRUE;
  716. }
  717. static void
  718. EmbeddedEditor_OnSetTextColor(EmbeddedEditor *self, HWND hwnd, COLORREF color, LRESULT *result)
  719. {
  720. *result = (LRESULT)self->textColor;
  721. if (self->textColor != color)
  722. self->textColor = color;
  723. }
  724. static void
  725. EmbeddedEditor_OnGetTextColor(EmbeddedEditor *self, HWND hwnd, LRESULT *result)
  726. {
  727. *result = (LRESULT)self->textColor;
  728. }
  729. static void
  730. EmbeddedEditor_OnSetBackColor(EmbeddedEditor *self, HWND hwnd, COLORREF color, LRESULT *result)
  731. {
  732. *result = (LRESULT)self->backColor;
  733. if (self->backColor != color)
  734. {
  735. self->backColor = color;
  736. if (NULL != self->backBrush)
  737. {
  738. DeleteObject(self->backBrush);
  739. self->backBrush = NULL;
  740. }
  741. }
  742. }
  743. static void
  744. EmbeddedEditor_OnGetBackColor(EmbeddedEditor *self, HWND hwnd, LRESULT *result)
  745. {
  746. *result = (LRESULT)self->backColor;
  747. }
  748. static void
  749. EmbeddedEditor_OnSetBorderColor(EmbeddedEditor *self, HWND hwnd, COLORREF color, LRESULT *result)
  750. {
  751. *result = (LRESULT)self->borderColor;
  752. if (self->borderColor != color)
  753. {
  754. self->borderColor = color;
  755. if (NULL != self->borderBrush)
  756. {
  757. DeleteObject(self->borderBrush);
  758. self->borderBrush = NULL;
  759. }
  760. }
  761. }
  762. static void
  763. EmbeddedEditor_OnGetBorderColor(EmbeddedEditor *self, HWND hwnd, LRESULT *result)
  764. {
  765. *result = (LRESULT)self->borderColor;
  766. }
  767. static void
  768. EmbeddedEditor_OnSetUserData(EmbeddedEditor *self, HWND hwnd, void *user, LRESULT *result)
  769. {
  770. *result = (LRESULT)self->user;
  771. self->user = user;
  772. }
  773. static void
  774. EmbeddedEditor_OnGetUserData(EmbeddedEditor *self, HWND hwnd, LRESULT *result)
  775. {
  776. *result = (LRESULT)self->user;
  777. }
  778. static void
  779. EmbeddedEditor_OnSetAnchorPoint(EmbeddedEditor *self, HWND hwnd, long x, long y, LRESULT *result)
  780. {
  781. self->anchorPoint.x = x;
  782. self->anchorPoint.y = y;
  783. *result = TRUE;
  784. }
  785. static void
  786. EmbeddedEditor_OnGetAnchorPoint(EmbeddedEditor *self, HWND hwnd, long *x, long *y, LRESULT *result)
  787. {
  788. if (NULL != x)
  789. *x = self->anchorPoint.x;
  790. if (NULL != y)
  791. *y = self->anchorPoint.y;
  792. *result = TRUE;
  793. }
  794. static void
  795. EmbeddedEditor_OnSetMaxSize(EmbeddedEditor *self, HWND hwnd, long width, long height, LRESULT *result)
  796. {
  797. self->maximumSize.cx = width;
  798. self->maximumSize.cy = height;
  799. *result = TRUE;
  800. }
  801. static void
  802. EmbeddedEditor_OnGetMaxSize(EmbeddedEditor *self, HWND hwnd, long *width, long *height, LRESULT *result)
  803. {
  804. if (NULL != width)
  805. *width = self->maximumSize.cx;
  806. if (NULL != height)
  807. *height = self->maximumSize.cy;
  808. *result = TRUE;
  809. }
  810. static void
  811. EmbeddedEditor_OnEndEditing(EmbeddedEditor *self, HWND hwnd, BOOL cancel)
  812. {
  813. EmbeddedEditor_InvokeCallback(self, hwnd, cancel, TRUE);
  814. DestroyWindow(hwnd);
  815. }
  816. static BOOL
  817. EmbeddedEditor_MessageProc(EmbeddedEditor *self, HWND hwnd, UINT uMsg,
  818. WPARAM wParam, LPARAM lParam, LRESULT *result)
  819. {
  820. switch(uMsg)
  821. {
  822. case WM_DESTROY:
  823. EmbdeddedEditor_OnDestroy(self, hwnd);
  824. return TRUE;
  825. case WM_NCCALCSIZE:
  826. return EmbdeddedEditor_OnNcCalcSize(self, hwnd, (BOOL)wParam, (NCCALCSIZE_PARAMS*)lParam, result);
  827. case WM_NCPAINT:
  828. return EmbdeddedEditor_OnNcPaint(self, hwnd, (HRGN)wParam);
  829. case WM_SETCURSOR:
  830. return EmbeddedEditor_OnSetCursor(self, hwnd, (HWND)wParam,
  831. LOWORD(lParam), HIWORD(lParam), result);
  832. case WM_GETDLGCODE:
  833. return EmbeddedEditor_OnGetDlgCode(self, hwnd, (unsigned int)wParam, (MSG*)lParam, result);
  834. case WM_KILLFOCUS:
  835. EmbeddedEditor_OnKillFocus(self, hwnd, (HWND)wParam);
  836. return 0;
  837. case WM_MOUSEWHEEL:
  838. return EmbeddedEditor_OnMouseWheel(self, hwnd, LOWORD(wParam), (short)HIWORD(wParam), (LONG)lParam);
  839. case WM_SETFONT:
  840. return EmbeddedEditor_OnSetFont(self, hwnd, (HFONT)wParam, (BOOL)LOWORD(lParam));
  841. case WM_WINDOWPOSCHANGED:
  842. return EmbeddedEditor_OnWindowPosChanged(self, hwnd, (WINDOWPOS*)lParam);
  843. case EMBEDDEDEDITOR_WM_SET_TEXT_COLOR: EmbeddedEditor_OnSetTextColor(self, hwnd, (COLORREF)lParam, result); return TRUE;
  844. case EMBEDDEDEDITOR_WM_GET_TEXT_COLOR: EmbeddedEditor_OnGetTextColor(self, hwnd, result); return TRUE;
  845. case EMBEDDEDEDITOR_WM_SET_BACK_COLOR: EmbeddedEditor_OnSetBackColor(self, hwnd, (COLORREF)lParam, result); return TRUE;
  846. case EMBEDDEDEDITOR_WM_GET_BACK_COLOR: EmbeddedEditor_OnGetBackColor(self, hwnd, result); return TRUE;
  847. case EMBEDDEDEDITOR_WM_SET_BORDER_COLOR: EmbeddedEditor_OnSetBorderColor(self, hwnd, (COLORREF)lParam, result); return TRUE;
  848. case EMBEDDEDEDITOR_WM_GET_BORDER_COLOR: EmbeddedEditor_OnGetBorderColor(self, hwnd, result); return TRUE;
  849. case EMBEDDEDEDITOR_WM_SET_USER_DATA: EmbeddedEditor_OnSetUserData(self, hwnd, (void*)lParam, result); return TRUE;
  850. case EMBEDDEDEDITOR_WM_GET_USER_DATA: EmbeddedEditor_OnGetUserData(self, hwnd, result); return TRUE;
  851. case EMBEDDEDEDITOR_WM_SET_ANCHOR_POINT: EmbeddedEditor_OnSetAnchorPoint(self, hwnd, (long)wParam, (long)lParam, result); return TRUE;
  852. case EMBEDDEDEDITOR_WM_GET_ANCHOR_POINT: EmbeddedEditor_OnGetAnchorPoint(self, hwnd, (long*)wParam, (long*)lParam, result); return TRUE;
  853. case EMBEDDEDEDITOR_WM_SET_MAX_SIZE: EmbeddedEditor_OnSetMaxSize(self, hwnd, (long)wParam, (long)lParam, result); return TRUE;
  854. case EMBEDDEDEDITOR_WM_GET_MAX_SIZE: EmbeddedEditor_OnGetMaxSize(self, hwnd, (long*)wParam, (long*)lParam, result); return TRUE;
  855. case EMBEDDEDEDITOR_WM_END_EDITING: EmbeddedEditor_OnEndEditing(self, hwnd, (BOOL)wParam); return TRUE;
  856. }
  857. return FALSE;
  858. }
  859. static LRESULT WINAPI
  860. EmbeddedEditor_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  861. {
  862. EmbeddedEditor *self;
  863. LRESULT result;
  864. self = EMBEDDEDEDITOR(hwnd);
  865. if (NULL == self ||
  866. NULL == self->originalProc)
  867. {
  868. return DefWindowProc(hwnd, uMsg, wParam, lParam);
  869. }
  870. result = 0;
  871. if (FALSE != EmbeddedEditor_MessageProc(self, hwnd, uMsg, wParam, lParam, &result))
  872. {
  873. return result;
  874. }
  875. return CallWindowProc(self->originalProc, hwnd, uMsg, wParam, lParam);
  876. }
  877. static void
  878. EmbdeddedEditorParent_OnDestroy(EmbeddedEditorParent *self, HWND hwnd)
  879. {
  880. RemoveProp(hwnd, MAKEINTATOM(EMBEDDEDEDITOR_PROP));
  881. if (NULL == self)
  882. return;
  883. if (NULL != self->originalProc)
  884. {
  885. SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)self->originalProc);
  886. CallWindowProc(self->originalProc, hwnd, WM_DESTROY, 0, 0L);
  887. }
  888. delete self;
  889. }
  890. static BOOL
  891. EmbdeddedEditorParent_OnGetEditColors(EmbeddedEditorParent *self, HWND hwnd, HDC hdc, HWND control, LRESULT *result)
  892. {
  893. size_t index;
  894. index = self->editorList.size();
  895. while(index--)
  896. {
  897. if (control == self->editorList[index])
  898. {
  899. EmbeddedEditor *editor = EMBEDDEDEDITOR(control);
  900. if (NULL != editor)
  901. {
  902. SetTextColor(hdc, editor->textColor);
  903. SetBkColor(hdc, editor->backColor);
  904. *result = (LRESULT)EmbeddedEditor_GetBackBrush(editor);
  905. return TRUE;
  906. }
  907. }
  908. }
  909. return FALSE;
  910. }
  911. static void
  912. EmbdeddedEditorParent_OnCommand(EmbeddedEditorParent *self, HWND hwnd, int commandId, int eventId, HWND control)
  913. {
  914. size_t index;
  915. if (NULL == control)
  916. return;
  917. index = self->editorList.size();
  918. while(index--)
  919. {
  920. if (control == self->editorList[index])
  921. {
  922. EmbeddedEditor *editor = EMBEDDEDEDITOR(control);
  923. if (NULL != editor)
  924. {
  925. EmbeddedEditor_OnCommand(editor, control, eventId);
  926. }
  927. }
  928. }
  929. }
  930. static BOOL
  931. EmbeddedEditorParent_MessageProc(EmbeddedEditorParent *self, HWND hwnd, UINT uMsg,
  932. WPARAM wParam, LPARAM lParam, LRESULT *result)
  933. {
  934. switch(uMsg)
  935. {
  936. case WM_DESTROY:
  937. EmbdeddedEditorParent_OnDestroy(self, hwnd);
  938. return TRUE;
  939. case WM_CTLCOLOREDIT:
  940. return EmbdeddedEditorParent_OnGetEditColors(self, hwnd, (HDC)wParam, (HWND)lParam, result);
  941. case WM_COMMAND:
  942. EmbdeddedEditorParent_OnCommand(self, hwnd, LOWORD(wParam), HIWORD(wParam), (HWND)lParam);
  943. break;
  944. }
  945. return FALSE;
  946. }
  947. static LRESULT WINAPI
  948. EmbeddedEditorParent_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  949. {
  950. EmbeddedEditorParent *self;
  951. LRESULT result;
  952. self = EMBEDDEDEDITOR_PARENT(hwnd);
  953. if (NULL == self ||
  954. NULL == self->originalProc)
  955. {
  956. return DefWindowProc(hwnd, uMsg, wParam, lParam);
  957. }
  958. result = 0;
  959. if (FALSE != EmbeddedEditorParent_MessageProc(self, hwnd, uMsg, wParam, lParam, &result))
  960. {
  961. return result;
  962. }
  963. return CallWindowProc(self->originalProc, hwnd, uMsg, wParam, lParam);
  964. }
  965. static LRESULT CALLBACK
  966. EmbeddidEditorThread_MouseProc(int code, unsigned int messageId, MOUSEHOOKSTRUCT *mouse)
  967. {
  968. if ((size_t)-1 != editorTls)
  969. {
  970. EmbeddedEditorThread *threadData;
  971. threadData = (EmbeddedEditorThread*)WASABI_API_APP->GetThreadStorage(editorTls);
  972. if (NULL != threadData)
  973. {
  974. LRESULT result;
  975. if (NULL != threadData->hook)
  976. result = CallNextHookEx(threadData->hook, code, (WPARAM)messageId, (LPARAM)mouse);
  977. else
  978. result = 0;
  979. if (code >= 0)
  980. {
  981. if ((messageId >= WM_LBUTTONDOWN && messageId <= 0x20E && mouse->hwnd != threadData->window) ||
  982. (messageId >= WM_NCLBUTTONDOWN && messageId <= 0x00AD))
  983. {
  984. HWND editorWindow;
  985. editorWindow = threadData->window;
  986. if (NULL != editorWindow)
  987. PostMessage(editorWindow, EMBEDDEDEDITOR_WM_END_EDITING, FALSE, 0L);
  988. }
  989. }
  990. return result;
  991. }
  992. }
  993. return 0;
  994. }