| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- #include "./editboxExtender.h"
- #include "./common.h"
- #include <commctrl.h>
- #define NAEF_USERFLAGSMASK 0x00FFFFFF
- #define NAEF_UNICODE 0x01000000
- typedef struct __EDITBOXEXTENDER
- {
- WNDPROC originalProc;
- UINT flags;
- DWORD dblclkTime;
- LPWSTR rollbackText;
- } EDITBOXEXTENDER;
- #define EDITBOXEXTENDER_PROP L"NullsoftEditboxExtender"
- #define GetEditbox(__hwnd) ((EDITBOXEXTENDER*)GetProp((__hwnd), EDITBOXEXTENDER_PROP))
- static LRESULT CALLBACK EditboxExtender_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL EditboxExtender_AttachWindow(HWND hEditbox)
- {
- if (!IsWindow(hEditbox))
- return FALSE;
- EDITBOXEXTENDER *editbox = (EDITBOXEXTENDER*)GetProp(hEditbox, EDITBOXEXTENDER_PROP);
- if (NULL != editbox) return TRUE;
-
- editbox = (EDITBOXEXTENDER*)calloc(1, sizeof(EDITBOXEXTENDER));
- if (NULL == editbox) return FALSE;
- if (IsWindowUnicode(hEditbox))
- editbox->flags |= NAEF_UNICODE;
- editbox->originalProc = (WNDPROC)(LONG_PTR)((0 != (NAEF_UNICODE & editbox->flags)) ?
- SetWindowLongPtrW(hEditbox, GWLP_WNDPROC, (LONGX86)(LONG_PTR)EditboxExtender_WindowProc) :
- SetWindowLongPtrA(hEditbox, GWLP_WNDPROC, (LONGX86)(LONG_PTR)EditboxExtender_WindowProc));
- if (NULL == editbox->originalProc || !SetProp(hEditbox, EDITBOXEXTENDER_PROP, editbox))
- {
- if (NULL != editbox->originalProc)
- {
- if (0 != (NAEF_UNICODE & editbox->flags))
- SetWindowLongPtrW(hEditbox, GWLP_WNDPROC, (LONGX86)(LONG_PTR)editbox->originalProc);
- else
- SetWindowLongPtrA(hEditbox, GWLP_WNDPROC, (LONGX86)(LONG_PTR)editbox->originalProc);
- }
-
- free(editbox);
- return FALSE;
- }
- return TRUE;
- }
- static void EditboxExtender_Detach(HWND hwnd)
- {
- EDITBOXEXTENDER *editbox = GetEditbox(hwnd);
- RemoveProp(hwnd, EDITBOXEXTENDER_PROP);
- if (NULL == editbox)
- return;
- if (NULL != editbox->originalProc)
- {
- if (0 != (NAEF_UNICODE & editbox->flags))
- SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)editbox->originalProc);
- else
- SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)editbox->originalProc);
- }
- free(editbox);
- }
- static LRESULT EditboxExtender_CallOrigWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- EDITBOXEXTENDER *editbox = GetEditbox(hwnd);
- if (NULL == editbox || NULL == editbox->originalProc)
- {
- return (0 != (NAEF_UNICODE & editbox->flags)) ?
- DefWindowProcW(hwnd, uMsg, wParam, lParam) :
- DefWindowProcA(hwnd, uMsg, wParam, lParam);
- }
- return (0 != (NAEF_UNICODE & editbox->flags)) ?
- CallWindowProcW(editbox->originalProc, hwnd, uMsg, wParam, lParam) :
- CallWindowProcA(editbox->originalProc, hwnd, uMsg, wParam, lParam);
- }
- static void EditboxExtender_OnDestroy(HWND hwnd)
- {
- EDITBOXEXTENDER *editbox = GetEditbox(hwnd);
-
- WNDPROC originalProc = editbox->originalProc;
- BOOL fUnicode = (0 != (NAEF_UNICODE & editbox->flags));
- EditboxExtender_Detach(hwnd);
- if (NULL != originalProc)
- {
- if (FALSE != fUnicode)
- CallWindowProcW(originalProc, hwnd, WM_DESTROY, 0, 0L);
- else
- CallWindowProcA(originalProc, hwnd, WM_DESTROY, 0, 0L);
- }
- }
- static LRESULT EditboxExtender_OnGetDlgCode(HWND hwnd, INT vKey, MSG* pMsg)
- {
- LRESULT result = EditboxExtender_CallOrigWindowProc(hwnd, WM_GETDLGCODE, (WPARAM)vKey, (LPARAM)pMsg);
- return result;
- }
- static void EditboxExtender_OnLButtonDown(HWND hwnd, UINT vKey, POINTS pts)
- {
- EDITBOXEXTENDER *editbox = GetEditbox(hwnd);
- if (NULL != editbox)
- {
- DWORD clickTime = GetTickCount();
- if (clickTime >= editbox->dblclkTime && clickTime <= (editbox->dblclkTime + GetDoubleClickTime()))
- {
- SendMessage(hwnd, EM_SETSEL, 0, -1);
- return;
- }
- }
- EditboxExtender_CallOrigWindowProc(hwnd, WM_LBUTTONDOWN, (WPARAM)vKey, *((LPARAM*)&pts));
- }
- static void EditboxExtender_OnLButtonDblClk(HWND hwnd, UINT vKey, POINTS pts)
- {
- EDITBOXEXTENDER *editbox = GetEditbox(hwnd);
- if (NULL == editbox) return;
-
- DWORD clickTime = GetTickCount();
- if (clickTime >= editbox->dblclkTime && clickTime <= (editbox->dblclkTime + 2*GetDoubleClickTime()))
- {
- INT r = (INT)SendMessage(hwnd, EM_CHARFROMPOS, 0, *(LPARAM*)&pts);
- r = LOWORD(r);
- SendMessage(hwnd, EM_SETSEL, (WPARAM)r, (LPARAM)r);
- editbox->dblclkTime = 0;
- }
- else
- {
- editbox->dblclkTime = clickTime;
- }
- INT f, l;
- SendMessage(hwnd, EM_GETSEL, (WPARAM)&f, (LPARAM)&l);
- if (f != l) return;
-
-
- EditboxExtender_CallOrigWindowProc(hwnd, WM_LBUTTONDBLCLK, (WPARAM)vKey, *((LPARAM*)&pts));
- }
- static void EditboxExtender_OnChar(HWND hwnd, UINT vKey, UINT state)
- {
- if (0 == (0x8000 & GetAsyncKeyState(VK_CONTROL)) && 0 == (0x8000 & GetAsyncKeyState(VK_MENU)))
- {
- HWND hParent = GetAncestor(hwnd, GA_PARENT);
- if (NULL != hParent)
- {
- NMCHAR nmh;
- nmh.hdr.hwndFrom = hwnd;
- nmh.hdr.idFrom = (INT)(INT_PTR)GetWindowLongPtr(hwnd, GWLP_ID);
- nmh.hdr.code = NM_CHAR;
- nmh.ch = vKey;
- nmh.dwItemNext = 0;
- nmh.dwItemPrev = 0;
- if (FALSE != (BOOL)SendMessage(hParent, WM_NOTIFY, nmh.hdr.idFrom, (LPARAM)&nmh))
- return;
- }
- }
- EditboxExtender_CallOrigWindowProc(hwnd, WM_CHAR, (WPARAM)vKey, (LPARAM)state);
- }
- static void EditboxExtender_OnKeyDown(HWND hwnd, UINT vKey, UINT state)
- {
- HWND hParent = GetAncestor(hwnd, GA_PARENT);
- if (NULL != hParent)
- {
- NMKEY nmh;
- nmh.hdr.hwndFrom = hwnd;
- nmh.hdr.idFrom = (INT)(INT_PTR)GetWindowLongPtr(hwnd, GWLP_ID);
- nmh.hdr.code = NM_KEYDOWN;
- nmh.nVKey = vKey;
- nmh.uFlags = HIWORD(state);
- if (FALSE != (BOOL)SendMessage(hParent, WM_NOTIFY, nmh.hdr.idFrom, (LPARAM)&nmh))
- return;
- }
- EditboxExtender_CallOrigWindowProc(hwnd, WM_KEYDOWN, (WPARAM)vKey, (LPARAM)state);
- }
- static void EditboxExtender_PasteText(HWND hwnd, LPCWSTR pszClipboard)
- {
- HWND hParent = GetAncestor(hwnd, GA_PARENT);
- if (NULL != hParent)
- {
- EENMPASTE nmh;
- nmh.hdr.hwndFrom = hwnd;
- nmh.hdr.idFrom = (INT)(INT_PTR)GetWindowLongPtr(hwnd, GWLP_ID);
- nmh.hdr.code = EENM_PASTE;
- nmh.text = pszClipboard;
- if (FALSE != (BOOL)SendMessage(hParent, WM_NOTIFY, nmh.hdr.idFrom, (LPARAM)&nmh))
- return;
- }
- SendMessage(hwnd, EM_REPLACESEL, (WPARAM)TRUE, (LPARAM)pszClipboard);
- }
- static void EditboxExtender_OnPaste(HWND hwnd)
- {
- IDataObject *pObject;
- HRESULT hr = OleGetClipboard(&pObject);
- if (SUCCEEDED(hr))
- {
- FORMATETC fmt = {CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
- STGMEDIUM stgm;
- hr = pObject->GetData(&fmt, &stgm);
- if(S_OK == hr)
- {
- LPCWSTR pClipboard = (LPCWSTR)GlobalLock(stgm.hGlobal);
- EditboxExtender_PasteText(hwnd, pClipboard);
-
- GlobalUnlock(stgm.hGlobal);
- ReleaseStgMedium(&stgm);
- }
- else
- {
- fmt.cfFormat = CF_TEXT;
- hr = pObject->GetData(&fmt, &stgm);
- if(S_OK == hr)
- {
- LPCSTR pClipboardAnsi = (LPCSTR)GlobalLock(stgm.hGlobal);
- LPWSTR pClipboard;
- if (FAILED(LoginBox_MultiByteToWideChar(CP_ACP, 0, pClipboardAnsi, -1, &pClipboard)))
- pClipboard = NULL;
- EditboxExtender_PasteText(hwnd, pClipboard);
-
- LoginBox_FreeString(pClipboard);
- GlobalUnlock(stgm.hGlobal);
- ReleaseStgMedium(&stgm);
- }
- }
- pObject->Release();
- }
- }
- static LRESULT CALLBACK EditboxExtender_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch(uMsg)
- {
- case WM_DESTROY: EditboxExtender_OnDestroy(hwnd); return 0;
- case WM_GETDLGCODE: return EditboxExtender_OnGetDlgCode(hwnd, (INT)wParam, (MSG*)lParam);
- case WM_LBUTTONDOWN: EditboxExtender_OnLButtonDown(hwnd, (UINT)wParam, MAKEPOINTS(lParam)); return 0;
- case WM_LBUTTONDBLCLK: EditboxExtender_OnLButtonDblClk(hwnd, (UINT)wParam, MAKEPOINTS(lParam)); return 0;
- case WM_CHAR: EditboxExtender_OnChar(hwnd, (UINT)wParam, (UINT)lParam); return 0;
- case WM_KEYDOWN: EditboxExtender_OnKeyDown(hwnd, (UINT)wParam, (UINT)lParam); return 0;
- case WM_PASTE: EditboxExtender_OnPaste(hwnd); return 1;
- }
-
- return EditboxExtender_CallOrigWindowProc(hwnd, uMsg, wParam, lParam);
- }
|