1 Attachment(s)
[RESOLVED] Help me fix bug in my edit control
Dear all,
I write an edit control for myself. When i press keys arrow (vbkeyleft, vbkeyright) then my control still forward focus to another control in my form, but the standard edit control in VB6 doesn't. Please view my attached source code and help me fix this bug. Thanks for reading.
Best regard!.
*** Warning: The code attached to this message might be dangerous for your system if executed, run at your own risk - JeffB, CodeGuru Moderator ***
Re: Help me fix bug in my edit control
Hm. Maybe I'm doing something wrong...
When I run your TestProject, leftarrow and rightarrow keys don't pass the focus on to other controls, but perform cursor movements as supposed to.
Maybe I misunderstood you. Please describe the problem closer.
Re: Help me fix bug in my edit control
Hey, please explain what you do in your code.
You seem to patch VB6 and kernal 32 with some hex code!!!???
I stupidly ran your sample and now my system seems to behave strange!
Please report if these patches you apply could have destroyed my VB6 installation or even altered my system in any way. I depend on it, you know?
Re: Help me fix bug in my edit control
Hope you didn't run the exe. It could have been anything.
the vb program was probably subclassing gone bad. reboot and hope for the best.
Re: Help me fix bug in my edit control
Quote:
Originally Posted by WoF
Hey, please explain what you do in your code.
You seem to patch VB6 and kernal 32 with some hex code!!!???
I stupidly ran your sample and now my system seems to behave strange!
Please report if these patches you apply could have destroyed my VB6 installation or even altered my system in any way. I depend on it, you know?
Sorry for the problem on your system. But some hex code i use to subclass my usercontrol and catch some events from user and it still run normally at my system (and some system i tested).
I have to force to use hex code because the usercontrol must not use CallWindowProc API.
Now, i detail this error to you:
First, when you run (F5), if you click on my edit control, the cursor still movement normally. But if you press the TAB key to move the forcus to another control and when the focus return my edit control, leftarrow and rightarrow keys is invalid.
Thanks for your response!.
Re: Help me fix bug in my edit control
First off, after a start like that, do something. I downloaded and looked at your code, but didn't run it.
It seemed to be a text editor that did something with unicode.
You are subclassing things.
Explain what you are trying to do. What does the program do?
How do you use it? What for?
Re: Help me fix bug in my edit control
I looked at this code. I don't see any malicious code, but since it use subclassing and some strange hex patch-code with GlobalAlloc and MoveMemory, it can cause all sort of bads things to your computer, so be carefull with it ;)
JeffB
Re: Help me fix bug in my edit control
If you look at the Function Subclass_Start(...) there are some patches done, possibly to user32.dll, VB6(.exe?).
I want to know what kind of code is it you patch there. Unfortunately I'm not familiar with the PC assembler language, but maybe someone else is.
Or you, Mr. Chimdangsung, explain why you need these patches and what they do.
Is there any chance, they alter the system file user32.dll and VB6.exe on disk??? After doublechecking with 2 other computers I found my user32.dll a little longer... so I changed it back using a Knoppix CD to boot.
Anyway this kind of hex-patching looks dubious to me and I won't run it again until I know exactly what it does.
Re: Help me fix bug in my edit control
To WoF:
Code:
Const FUNC_CWP As String = "CallWindowProcA"
Const FUNC_EBM As String = "EbMode"
Const FUNC_SWL As String = "SetWindowLongA"
Const MOD_USER As String = "user32"
Const MOD_VBA5 As String = "vba5"
Const MOD_VBA6 As String = "vba6"
It seems with:
Code:
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
and this is an address of CallWindowProc function when run the usercontrol:
Code:
sHex = "5589E583C4F85731C08945FC8945F8EB0EE80000000083F802742185C07424E830000000837DF800750AE838000000E84D00" & _
"00005F8B45FCC9C21000E826000000EBF168000000006AFCFF7508E800000000EBE031D24ABF00000000B900000000E82D00" & _
"0000C3FF7514FF7510FF750CFF75086800000000E8000000008945FCC331D2BF00000000B900000000E801000000C3E33209" & _
"C978078B450CF2AF75278D4514508D4510508D450C508D4508508D45FC508D45F85052B800000000508B00FF90A4070000C3"
It doesn't change anything of user32.dll or VB6.exe and i don't known what happen on your system?!.
I found this code from some usercontrols on planetsourecode and it maybe the seem with SSubTimer.dll at vbaccelerator is used to subclassing for the usercontrol.
To dglienna:
Quote:
It seemed to be a text editor that did something with unicode.
You are subclassing things.
Explain what you are trying to do. What does the program do?
How do you use it? What for?
It 's an edit control with unicode supported. I uses it to replace the standard Textbox control in vb6 that not support unicode for my language (Vietnamese). It is written finally and had only one bug that i concerned above.
I thinks the cause of bug is: the usercontrol preview all key when i return forcus to my control by tab key. But i can not fix it. Please help me!.
Re: Help me fix bug in my edit control
Quote:
Originally Posted by WoF
If you look at the Function Subclass_Start(...) there are some patches done, possibly to user32.dll, VB6(.exe?).
I want to know what kind of code is it you patch there. Unfortunately I'm not familiar with the PC assembler language, but maybe someone else is.
Or you, Mr. Chimdangsung, explain why you need these patches and what they do.
Is there any chance, they alter the system file user32.dll and VB6.exe on disk??? After doublechecking with 2 other computers I found my user32.dll a little longer... so I changed it back using a Knoppix CD to boot.
Anyway this kind of hex-patching looks dubious to me and I won't run it again until I know exactly what it does.
In my eyes its a bit deeper. even when you dont run the code as it is a usercontrol, even when you try to open the editor so you see the control an the form the usercontrol is running in designmode. Are you sure that it isn't patching in this time ? As I told to WoF I was warned by him and didn't run the exe,only had looked to the code and once opened the control in designmode. I had problems with my laptop afterwards. I could no longer open workplace by doubleclicking it and needed to rightclick to all files to open or programs to run. After booting again two times it now works again without troubles and hopefully stays that way. Are you sure that this code doesn't alter some dlls in a way they maybe work without troubles in languages like Vietnamese but are dangerouse to european ( german ) localised dlls ? Patching is always dangerous. Why is this patch really needed ? The explanation you give us, isn't really satisfying me. Can you post the link to the source where you got the code, as you say its planetsource, maybe in this link there is a full explanation of whats going on ? And where did you get the patch itself that one in vbaccelerator seems me to be different
Re: Help me fix bug in my edit control
Well, I looked at the form in design mode, but didn't run it. Nothing got changed, as it would have been picked up immediately. My laptop is fine.
Re: Help me fix bug in my edit control
Quote:
Can you post the link to the source where you got the code, as you say its planetsource, maybe in this link there is a full explanation of whats going on ?
It 's here:
http://www.planet-source-code.com/vb...64286&lngWId=1
Re: Help me fix bug in my edit control
Quote:
Originally Posted by chimdangsung
Thx. My Laptop was fine after reboot. But as I know, things like subclassing in VB or hooking easily can lead to a crashe of VB IDE, even when the code is fine.
Re: Help me fix bug in my edit control
Is this code embedding native code? Yes.
Is it required for subclassing a control? NO! SetWindowLong is used to replace the window procedure of its own control... and any global VB function can be passed instead for subclassing:
Code:
.nAddrOrig = SetWindowLong(.hwnd, GWL_WNDPROC, .nAddrSub)
Is it buggy? Might as well be, since I wouldn't replace a window procedure with the address of a buffer allocated with GlobalAlloc BEFORE actually copying the native code at that address!!! What if the window procedure is called in the meantime, as in a multithreaded environment might...
Code:
.nAddrSub = GlobalAlloc(GMEM_FIXED, CODE_LEN)
.nAddrOrig = SetWindowLong(.hwnd, GWL_WNDPROC, .nAddrSub)
Call RtlMoveMemory(ByVal .nAddrSub, aBuf(1), CODE_LEN)
Is this code patching anything? Lets see...
First, lets break down the hex string representing native code into asm instruction representation:
Code:
"55" & " 89E5" & "83C4F8" & "57" & "31C0" & "8945FC" & "8945F8" & "EB0E" & "E800000000" & _
"83F802" & "7421" & "85C0" & "7424" & "E830000000" & _
"837DF800" & "750A" & "E838000000" & _
"E84D000000" & _
"5F" & "8B45FC" & "C9" & "C21000" & _
_
"E826000000" & _
"EBF1" & "6800000000" & _
"6AFC" & "FF7508" & "E800000000" & _
"EBE0" & "31D2" & "4A" & "BF00000000" & _
"B900000000" & _
"E82D000000" & _
"C3" & _
_
"FF7514" & "FF7510" & "FF750C" & "FF7508" & "6800000000" & _
"E800000000" & _
"8945FC" & "C3" & _
_
"31D2" & "BF00000000" & _
"B900000000" & _
"E801000000" & _
"C3" & _
_
"E332" & "09C9" & "7807" & "8B450C" & "F2AF" & "7527" & "8D4514" & "50" & "8D4510" & "50" & "8D450C" & "50" & "8D4508" & "50" & _
"8D45FC" & "50" & "8D45F8" & "50" & "52" & "B800000000" & _
"50" & "8B00" & "FF90A4070000" & _
"C3"
How does the assembly look like:
Code:
0014BA89 push ebp
0014BA8A mov ebp,esp
0014BA8C add esp,0F8h
0014BA8F push edi
0014BA90 xor eax,eax
0014BA92 mov dword ptr [ebp-4],eax
0014BA95 mov dword ptr [ebp-8],eax
0014BA98 jmp 0014BAA8
0014BA9A call 0014BA9F
0014BA9F cmp eax,2
0014BAA2 je 0014BAC5
0014BAA4 test eax,eax
0014BAA6 je 0014BACC
0014BAA8 call 0014BADD
0014BAAD cmp dword ptr [ebp-8],0
0014BAB1 jne 0014BABD
0014BAB3 call 0014BAF0
0014BAB8 call 0014BB0A
0014BABD pop edi
0014BABE mov eax,dword ptr [ebp-4]
0014BAC1 leave
0014BAC2 ret 10h
0014BAC5 call 0014BAF0
0014BACA jmp 0014BABD
0014BACC push 0
0014BAD1 push 0FCh
0014BAD3 push dword ptr [ebp+8]
0014BAD6 call 0014BADB
0014BADB jmp 0014BABD
0014BADD xor edx,edx
0014BADF dec edx
0014BAE0 mov edi,0
0014BAE5 mov ecx,0
0014BAEA call 0014BB1C
0014BAEF ret
0014BAF0 push dword ptr [ebp+14h]
0014BAF3 push dword ptr [ebp+10h]
0014BAF6 push dword ptr [ebp+0Ch]
0014BAF9 push dword ptr [ebp+8]
0014BAFC push 0
0014BB01 call 0014BB06
0014BB06 mov dword ptr [ebp-4],eax
0014BB09 ret
0014BB0A xor edx,edx
0014BB0C mov edi,0
0014BB11 mov ecx,0
0014BB16 call 0014BB1C
0014BB1B ret
0014BB1C jecxz 0014BB50
0014BB1E or ecx,ecx
0014BB20 js 0014BB29
0014BB22 mov eax,dword ptr [ebp+0Ch]
0014BB25 repne scas dword ptr [edi]
0014BB27 jne 0014BB50
0014BB29 lea eax,[ebp+14h]
0014BB2C push eax
0014BB2D lea eax,[ebp+10h]
0014BB30 push eax
0014BB31 lea eax,[ebp+0Ch]
0014BB34 push eax
0014BB35 lea eax,[ebp+8]
0014BB38 push eax
0014BB39 lea eax,[ebp-4]
0014BB3C push eax
0014BB3D lea eax,[ebp-8]
0014BB40 push eax
0014BB41 push edx
0014BB42 mov eax,0
0014BB47 push eax
0014BB48 mov eax,dword ptr [eax]
0014BB4A call dword ptr [eax+7A4h]
0014BB50 ret
Hmm, but that's NOT exactly how it looks like when is executed, because it is modified (patched) at runtime, multiple times. For better understanding, I've spent the time to check all replacements that occur within the native code before it gets executed, and the result is:
Code:
000 push ebp
001 mov ebp,esp
003 add esp,0F8h
006 push edi
007 xor eax,eax
009 mov dword ptr [ebp-4],eax
012 mov dword ptr [ebp-8],eax
015 jmp 0014BAA8 'unconditional jump to offset 31
017 call pEbMode 'PATCH_01: call to offset 22 ('pEbMode'=0)
022 cmp eax,2
025 je 0014BAC5
027 test eax,eax
029 je 0014BACC 'conditional jump to offset 67
031 call 0014BADD 'call to offset 84
036 cmp dword ptr [ebp-8],0
040 jne 0014BABD 'conditional jump to offset 52
042 call 0014BAF0 'call to offset 103
047 call 0014BB0A 'call to offset 129
052 pop edi
053 mov eax,dword ptr [ebp-4]
056 leave
057 ret 10h
060 call 0014BAF0 'call to offset 103
065 jmp 0014BABD 'unconditional jump to offset 52
067 push .nAddrOrig 'PATCH_02: push the address of original window procedure
072 push 0FCh
074 push dword ptr [ebp+8]
077 call pSWL 'PATCH_03: call the address of SetWindowLongA from user32.dll
082 jmp 0014BABD 'unconditional jump to offset 52
084 xor edx,edx
086 dec edx
087 mov edi,VarPtr(aMsgTbl(1))) 'PATCH_04: set the pointer to the message table
092 mov ecx,nMsgCnt 'PATCH_05: set the message count in the table
097 call 0014BB1C 'call to offset 147
102 ret
103 push dword ptr [ebp+14h]
106 push dword ptr [ebp+10h]
109 push dword ptr [ebp+0Ch]
112 push dword ptr [ebp+8]
115 push .nAddrOrig 'PATCH_06: push the address of original window procedure
120 call pCWP 'PATCH_07: call the address of CallWindowProcA from user32.dll
125 mov dword ptr [ebp-4],eax
128 ret
129 xor edx,edx
131 mov edi,0 'PATCH_08: set the pointer to the message table
136 mov ecx,0 'PATCH_09: set the message count in the table
141 call 0014BB1C 'call to offset 147
146 ret
147 jecxz 0014BB50 'conditional jump to offset 199 (return)
149 or ecx,ecx
151 js 0014BB29 'conditional jump to offset 160
153 mov eax,dword ptr [ebp+0Ch]
156 repne scas dword ptr [edi]
158 jne 0014BB50 'conditional jump to offset 199 (return)
160 lea eax,[ebp+14h]
163 push eax
164 lea eax,[ebp+10h]
167 push eax
168 lea eax,[ebp+0Ch]
171 push eax
172 lea eax,[ebp+8]
175 push eax
176 lea eax,[ebp-4]
179 push eax
180 lea eax,[ebp-8]
183 push eax
184 push edx
185 mov eax,ObjPtr(Me) 'PATCH_0A: get the pointer to the UserControl object
190 push eax
191 mov eax,dword ptr [eax] 'get vftable of object
193 call dword ptr [eax+7A4h] 'call virtual method from vftable
199 ret
200
As you can see, this code is not modifying any files on your hdd, which I presume was meant by patching. If you'd like to read more about embedding native code, please see corresponding section in my new article.
I'm sorry chimdangsung, I didn't find a solution for your problem with the arrows handling. A friend of mine had a similar problem with events when using tab switching and arrow keys, but was caused by encapsulating a VB6 control within a .NET form. He did could not fix the problem, just found a workaround for the situation.
Best regards,
Re: Help me fix bug in my edit control
@chimdangsung: You have forgot to copy the following code from the original source:
Code:
'Get API function addresses
If Subclass_InIDE Then 'If we're running in the VB IDE
aBuf(16) = &H90 'Patch the code buffer to enable the IDE state code
aBuf(17) = &H90 'Patch the code buffer to enable the IDE state code
pEbMode = zAddrFunc(MOD_VBA6, FUNC_EBM) 'Get the address of EbMode in vba6.dll
If pEbMode = 0 Then 'Found?
pEbMode = zAddrFunc(MOD_VBA5, FUNC_EBM) 'VB5 perhaps
End If
End If
This might create problems because the code is calling a wrong address, thus modifying the stack by pushing a return address which isn't properly handled... not saying that the original author had reasons to call this function.
Regards,