LCF-AT Posted June 12, 2021 Posted June 12, 2021 Hi guys, short question.I'am using a tool called "Everything" from voidtools to find files on my HDD etc.I see that this tool is using a simple edit control where you can enter text.If I now wanna get selected the whole edit control then I just need to click once on the outline of that edit control and I got all selected in edit control.Thats pretty cool and now I wanna know how to manage that = what kind of "Edit Control Notification Messages" I have to catch? https://docs.microsoft.com/en-us/windows/win32/controls/bumper-edit-control-reference-notifications Don't find any who does it.Do you know how?Below a example image... ....AND.... ...so if I see it right then I do click inside of the edit control = must be belong to it right?Just wanna know what EN_X I have to check out to notify that click on the outline of the edit control.Otherwise it would be a click on the main dialog background or?Maybe you know it and can tell us. Thank you. greetz
Kurapica Posted June 13, 2021 Posted June 13, 2021 https://docs.microsoft.com/en-us/windows/win32/controls/em-setsel 1
CodeExplorer Posted June 13, 2021 Posted June 13, 2021 (edited) https://stackoverflow.com/questions/8725541/em-setsel-swaps-parameters Edited June 13, 2021 by CodeExplorer 1
LCF-AT Posted June 13, 2021 Author Posted June 13, 2021 Hi guys, seems you didn't understand what I was talking about.I'am not looking for a EM_SETSEL = sendmessage, I'am looking for EN_ X notify message to catch if I press with the mouse on the outline of the edit control itself = not in edit control itself / text area. I need to catch the left mouse click on the edit outline (not in text field) and right after that I can send a EM message to select all inside but how to catch that mouse click?Just look at my images, right there where you can see the mousepointer I did click. greetz
LCF-AT Posted June 13, 2021 Author Posted June 13, 2021 PS: I did check the controls with WinSpy and it seems that the edit control & combobox (not to see on my image) are inside of a ToolBar.Somehow this must be the reason.Not sure how to put a edit control and others into a toolbar yet. greetz
Kurapica Posted June 13, 2021 Posted June 13, 2021 you are entering a world of pain, sub-classing to catch the right message and etc ... 1
fearless Posted June 13, 2021 Posted June 13, 2021 Could use EN_SETFOCUS and EN_UPDATE and/or EN_CHANGE. For setfocus once a user clicks in the edit box the EN_SETFOCUS should trigger via the WM_COMMAND and you can then call the EM_SETSEL to select the whole edit contents. 2
LCF-AT Posted June 13, 2021 Author Posted June 13, 2021 Hi, EN_SETFOCUS = triggers if I press inside of edit control = keyboard focus EN_UPDATE = triggers if I did enter anything in edit control EN_CAHNGE = triggers if I enter anything / paste etc All not what I'am looking for.I want to have that one mouseclick on outline = selecting entire edit control.Below a example animation to see what I mean. greetz
LCF-AT Posted June 14, 2021 Author Posted June 14, 2021 Hi again, ok, so if that is not possible to do (as you can see on the animation above) then I would trying the other thing.....catching EN_SETFOCUS and select all in edit control if the edit control gets the focus.Problem here seems that its not working when using the mouse itself and to click on the edit control = nothing gets selected.Just when using the tab key to switch from control to control it gets selected.So how to get all selected if I click inside of the edit control for the first time to set the focus? greetz
NOP Posted June 18, 2021 Posted June 18, 2021 I use Delphi and have done similar using the click event... procedure TtestFrm.EditBox1Click(Sender: TObject); begin EditBox1.SelectAll; end; procedure TtestFrm.EditBox2Click(Sender: TObject); begin EditBox2.SelectAll; end; Test.rar 1
LCF-AT Posted June 18, 2021 Author Posted June 18, 2021 Hi, and what does it mean for me?Whats click event?I dont have something to enable in WinASM etc.Otherwise this method is also bad because you can't do any good selection if you need it.The best method is really that method the Everything tool does use by selecting all by clicking on outline of edit control.Would really like know how to make that happen.Maybe anyone of you coders could check that out how it works.Just look at the animation I did post above.It works pretty nice and look beautiful. Just a must have feature in my opinion.Just don't know how to make it. greetz
Extreme Coders Posted June 19, 2021 Posted June 19, 2021 Here's something similar: Selects the entire text if its' clicked at any position after the text ends Spoiler Relevant code from Pelles C.: The main idea is to attach a window procedure to the edit control using SetWindowLongPtr. Within there handle WM_LBUTTONDOWN messages and check if the click is within the existing text or outside it. The code is not perfect but it works Spoiler LONG_PTR previousEditProc; static INT_PTR CALLBACK EditProc(HWND hwndEdit, UINT uMsg, WPARAM wParam, LPARAM lParam) { POINT clickPt; LRESULT res; LRESULT closestChar; int textLength; res = CallWindowProc((WNDPROC)previousEditProc, hwndEdit, uMsg, wParam, lParam); switch (uMsg) { case WM_LBUTTONDOWN: clickPt.x = GET_X_LPARAM(lParam); clickPt.y = GET_Y_LPARAM(lParam); closestChar = SendMessage(hwndEdit, EM_CHARFROMPOS, 0, MAKEWPARAM(clickPt.x, clickPt.y)); textLength = GetWindowTextLength(hwndEdit); if (closestChar == textLength) { SendMessage(hwndEdit, EM_SETSEL, 0, -1); } } return res; } static INT_PTR CALLBACK MainDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { HWND hwndEdit; switch (uMsg) { case WM_INITDIALOG: hwndEdit = GetDlgItem(hwndDlg, ID_EDIT); previousEditProc = SetWindowLongPtr(hwndEdit, GWLP_WNDPROC, (LONG_PTR)EditProc); return TRUE; case WM_SIZE: return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: EndDialog(hwndDlg, TRUE); return TRUE; } break; case WM_CLOSE: EndDialog(hwndDlg, 0); return TRUE; } return FALSE; } 3
LCF-AT Posted June 21, 2021 Author Posted June 21, 2021 Hi, thank you for that example. Its a better method and also working for me so far.Only disadvantage is that I can not paste anymore anything after the whole content in edit control because all gets selected (if I just use the mouse). Otherwise I would still really like to know how the guys of the Everything tool did it.They made it really great with that outline click / select all etc.So if anyone does find it out then just tell us.That would be perfect. PS: Sorry for my late answer but somehow the forum didn't show all new posts on my unread content page. Strange. greetz
Progman Posted June 23, 2021 Posted June 23, 2021 This requires subclassing and lower down messages. If you have a tool that does this, easy to disassemble and see how they did it. Probably WM_LBUTTONDOWN and some coordinate checks. Thanks to windows not giving the source to controls, calculating boundaries is practically impossible for all Windows versions or all settings such as accessibility, global display settings, DPI, etc 2
LCF-AT Posted June 23, 2021 Author Posted June 23, 2021 Hi, so WM_LBUTTONDOWN gets triggered on click on the outline. WM_LBUTTONDOWN equ 201h 0019F870 004853E5 /CALL to GetClientRect from Everythi.004853DF 0019F874 001E064A |hWnd = 001E064A (class='EVERYTHING_TOOLBAR',parent=000604FA) 0019F878 0019F88C \pRect = 0019F88C 0019F868 00485439 /CALL to SendMessageW from Everythi.00485433 0019F86C 000A0664 |hWnd = A0664 0019F870 000000B1 |Message = EM_SETSEL 0019F874 00000000 |Start = 0 0019F878 FFFFFFFF \End = FFFFFFFF (-1.) 0019F874 00485443 /CALL to SetFocus from Everythi.0048543D 0019F878 000A0664 \hWnd = 000A0664 (class='Edit',parent=001E064A) 0019F868 00484C49 RETURN to Everythi.00484C49 from ntdll.NtdllDefWindowProc_W Just dont check what the Everything_toolbar class does. $ ==> 0019F338 <cbSize> 00000030 $+4 0019F33C <style> 0000000B $+8 0019F340 <lpfnWndProc> 00484B10 Everythi.00484B10 $+C 0019F344 <cbClsExtra> 00000000 $+10 0019F348 <cbWndExtra> 00000000 $+14 0019F34C <hInstance> 00400000 Everythi.00400000 $+18 0019F350 <hIcon> 00000000 $+1C 0019F354 <hCursor> 00010003 $+20 0019F358 <hbrBackground> 00000010 $+24 0019F35C <lpszMenuName> 00000000 $+28 0019F360 <lpszClassName> 0019F374 UNICODE "EVERYTHING_TOOLBAR" $+2C 0019F364 <hIconSm> 00000000 The toolbar is right behind or same as edit control / background + few pixel more.Not sure how to do that.Somehow it must be done simple but how. |----------------| <--- toolbar class |----------------| <---- edit control |________________| <---- edit control |----------------| <--- toolbar class 0019F104 00470BCC /CALL to CreateWindowExW from Everythi.00470BC6 0019F108 00000000 |ExtStyle = 0 0019F10C 0019F35C |Class = "EVERYTHING_TOOLBAR" 0019F110 0019F148 |WindowName = "" 0019F114 56000000 |Style = WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_VISIBLE 0019F118 00000000 |X = 0 0019F11C 00000000 |Y = 0 0019F120 00000000 |Width = 0 0019F124 00000000 |Height = 0 0019F128 001A076A |hParent = 001A076A (class='EVERYTHING') 0019F12C 00002716 |hMenu = 00002716 0019F130 00400000 |hInst = 00400000 0019F134 00000000 \lParam = NULL greetz
LCF-AT Posted June 23, 2021 Author Posted June 23, 2021 Hi again, ok I think I got it working now. But looks bad of course.Somehow I must paint the extra class with same white color like edit control has inside + the outline / edge around the class to fake / show a border like in Edit control if you use clientedge. invoke RtlZeroMemory,addr wc,sizeof wc mov wc.cbSize, sizeof WNDCLASSEX mov wc.style, 0 mov wc.lpfnWndProc, offset WndProc_2 push hInstance pop wc.hInstance Invoke LoadCursor, NULL, IDC_ARROW mov wc.hCursor, eax mov wc.hbrBackground,COLOR_BTNTEXT mov wc.lpszClassName, chr$("MyApp_Toolbar") Invoke RegisterClassEx, addr wc mov edi, eax invoke CreateWindowEx,0,chr$("MyApp_Toolbar"),0,WS_CHILD or WS_VISIBLE or WS_CLIPSIBLINGS or WS_CLIPCHILDREN,0,0,352,20,hWin,0,hInstance,0 WndProc_2 proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM .if uMsg == WM_NCCREATE mov eax, TRUE ret .elseif uMsg == WM_CREATE mov eax, 0 ret .elseif uMsg == WM_NCDESTROY mov eax, 0 ret .elseif uMsg == WM_LBUTTONDOWN invoke SendMessage,EditHandle,EM_SETSEL,0,-1h invoke SetFocus,EditHandle .endif Invoke DefWindowProc, hWin, uMsg, wParam, lParam Ret WndProc_2 endp Edit_OutlineClassClick.7z greetz
LCF-AT Posted June 24, 2021 Author Posted June 24, 2021 Hi again, short question.How can I get the actually position state of a control element to place another element on the same position?Just have problems with the calc operation... GetClientRect = height and width GetWindowRect SetWindowPos / MoveWindow ...just wanna get same coordinates of control A and set control B on same coordinates.Just dont remember the calc process for that so maybe you can tell me again. greetz
LCF-AT Posted June 25, 2021 Author Posted June 25, 2021 Hi guys, just wanna ask again today so I still didnt find it out. I made a simple image so just have a look on it... ...so I know I can use GetClientRect function to get the Widht & Height of the button control in this example but how to get the position / location in the dialog where the button control is set?My simple goal is it just to get the Width & Height & position X / Y and set another control on the same location like another button (Hide button control A and showing button control B ).I just dont remember anymore.Something with GetWindowRect & calc xy etc.Could you maybe tell me quickly how it was again?Thank you. greetz
aIjundi Posted June 25, 2021 Posted June 25, 2021 You could use GetWindowRect to get the coordinates relative to the screen, then use ScreenToClient to get them relative to the window. 2
LCF-AT Posted June 25, 2021 Author Posted June 25, 2021 Hi, I need a example code. invoke GetWindowRect,hWin,addr rc invoke GetClientRect,hWin,addr rc2 mov eax, rc.left add eax, rc2.left mov left, eax mov eax, rc.top add eax, rc2.top mov top, eax invoke GetWindowRect,edi,addr rc3 invoke GetClientRect,edi,addr rc4 ; exit mov eax, rc3.left sub eax, left mov ecx, rc3.top sub ecx, top mov eax, left mov ecx, top mov p.x, eax mov p.y, ecx invoke ScreenToClient,hWin,addr p invoke MoveWindow,esi,eax, ecx, rc4.right, rc4.bottom, 1 I dont get it work for 100% correctly yet. Data of Dialog.... ...data of Exit button... ....now I need to calc out that X: 131 and Y:55 values to use them with MoveWindow on the Test button to set it on same place like the exit button.How to do it right?Is there some formula I can remember?Some rule etc?I always forgot that. greetz
LCF-AT Posted June 25, 2021 Author Posted June 25, 2021 Edit: I think I got it now... invoke GetWindowRect,edi,addr rc invoke GetClientRect,edi,addr rc2 mov eax, rc.left mov ecx, rc.top mov p.x, eax mov p.y, ecx invoke ScreenToClient,hWin,addr p invoke MoveWindow,esi,p.x, p.y, rc2.right, rc2.bottom, 1 ....just using that ScreenToClient function.Anyhow I dont check that function and ClientToScreen too. greetz 1
LCF-AT Posted June 25, 2021 Author Posted June 25, 2021 Ok it seems I got it now working as I wanted so just have a look.... ....hmmmm, so wonder pretty. 3
Progman Posted June 26, 2021 Posted June 26, 2021 Windows XP source code leak will give you more accuracy for all scenarios. It is worth a read of the edit control source to see optimal methods. As far as I remember they do not have to deal with screen coordinates and conversions because the control data is accessed directly. But that data structure is platform dependent and noone is targeting XP anymore. Nonetheless some complications of accessibility and others can be seen there. Just because it looks good in your one specific case does not mean it works well everywhere. And no developer in their right mind has time to do such testing. I never understood why they dont open source the basic UI elements. Either you use the limited functionality, you resort to hacks, or you use some owner draw or custom drawing. But customizing is bound to break some details whether it be keyboard only mode or whatever. It's such an approximation because they do not give us any high quality option in between. Ideally when you want to custom draw the edit control, the source of the base WM_PAINT handler should appear for work to begin. Certainly it would make life harder for Microsoft to do this and still deal with forward and backward compatibility, and non reliance on internal control data structures. But we would have much better custom implementations that saved hours of developer time. 1
LCF-AT Posted June 26, 2021 Author Posted June 26, 2021 Hi again, so in my example case I do not change or mod the edit control itself so I kept all untouched so far.I'am just using WM_PAINT to make the draw around the edit control + a frame so that it sill looks like a original edit control. Its just like a picture frame I made. So I have another little question.How can I get the used color of a control (edit control in this case)?So I mean if I just create a edit control then the background is has white color but if I use WM_CTLCOLOREDIT to change color of edit background etc then I need to find out the actually background color of it.How to do that?I tried to play around with GetPixel function but dosent work. Example: I know where the control / edit is set (rect/position) and right from there I need to get a color pixel from.You know what I mean right?So how to do that?Just need to know the used background color of the specific edit control so that I can create a frame in same color. greetz
Progman Posted June 27, 2021 Posted June 27, 2021 GetSysColor https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsyscolor Again the XP source is very useful for every question you will ask. GetPixel is an ugly hack 2
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now