Hi all,
i am playing with windows, and now i want to create a POPUP window but
i want a CLOSE button on it.
Whats the style value ?
I am using this:
invoke CreateWindowEx, WS_EX_LEFT or WS_EX_NOPARENTNOTIFY,
offset _ClassChild, offset _MsgExecMsg,
WS_POPUP or WS_CAPTION,
100, 80, 280, 80, ; X,Y + Wid,Hei pixel
_hWnd, 0h, _hInstance, 0
EDIT: i found the solution for this problem:
WS_POPUP or WS_CAPTION or WS_SYSMENU,
Thank you
Thanks
Rui
Hi,
I created a popup window (inside the main window) but it is moveable
(we can move it taking it with the mouse but it crashes if we move it
to outside the screen).
How to create it in a fixed position in such a way that we cannot move it ?
Is it possible? Is there a style ? Other means ?
I attached PopUp5.zip (asm & exe) and you can see the problem:
PopUp -> Open PopUp1 -> move it
Thanks for any help
Rui
[attachment deleted by admin]
Rui,
If you want another window attached in an imovable way to a main window, you normally set the CHILD style for it using the main window as it parent. Note the you cannot have BOTH the WS_CHILD and WS_POPUP set for the same window.
Quote from: hutch-- on August 28, 2008, 12:22:11 PM
If you want another window attached in an imovable way to a main window, you normally set the CHILD style for it using the main window as it parent.
Hi Hutch,
Thank you
Ok i created the same prog. as PopUp5 ( Child6.zip ) but now i set
invoke CreateWindowEx, WS_EX_LEFT, ; Extended Style
offset _ClassChild, ; Class name
offset _MsgExecMsg, ; Title
WS_CHILD or WS_CAPTION or WS_VISIBLE, ; Style
80, 120, 280, 80, ; X,Y,W,H
_hWnd, 0, _hInstance, 0
It doesnt Print the messages !!!
And
It moves AND if i move the window
the program crashes, too !!!
Could you see my code to see if i am doing something wrong, please
Quote from: hutch-- on August 28, 2008, 12:22:11 PM
Note the you cannot have BOTH the WS_CHILD and WS_POPUP set for the same window.
Ok i know that
Thanks
Rui
[attachment deleted by admin]
Rui, for testing your code it is essential that you post all necessary components, preferably in one zip file. Sound5.wav is missing.
Quote from: jj2007 on August 28, 2008, 01:32:30 PM
Rui, for testing your code it is essential that you post all necessary components
Hi jj,
The EXE should run without sound efect. It is used when we close the Child window
In any way here is Child6 and rsrc without sound. Sound is not the problem
You can see the file Child6.ASM and run Child6.EXE. Doesnt run ?
Thank you
Rui
[attachment deleted by admin]
My eyes !
Rui, you should read iczelion's tutorials to see how to properly construct message processing loops. You'll keep stumbling to new problems if you continue on this source base.
Quote from: BlackVortex on August 28, 2008, 05:43:11 PM
... to see how to properly construct message processing loops.
Hi BlackVortex,
Thank you for your reply.
But could you say something more exactly, if you dont mind
Thanks
Rui
Check here :
http://win32assembly.online.fr/tutorials.html
I'm sure you will want to write your proggy from start !
P.S.: There are sources and examples for all those tutorials of course
Quote from: RuiLoureiro on August 28, 2008, 02:05:31 PM
The EXE should run without sound efect. It is used when we close the Child window
In any way here is Child6 and rsrc without sound. Sound is not the problem
You can see the file Child6.ASM and run Child6.EXE. Doesnt run ?
Your error is here:
mov eax, dword ptr [esi + ebx * 4]
;
_nOpenExecMsg: mov _pMsgPas, eax
Check the value of _pMsgPas... if it is 16 =10h, you'd better not use it.
P.S.: When files required by rsrc.rc are missing, eg. sound.wav, the whole project will not assemble.
EDIT: P.P.S.: The advice of BlackVortex is a good one...!
@ jj2007
Well, you could probably use an empty file with the correct name.
Quote from: BlackVortex on August 28, 2008, 05:57:10 PM
Check here :
http://win32assembly.online.fr/tutorials.html
I'm sure you will want to write your proggy from start !
P.S.: There are sources and examples for all those tutorials of course
BlackVortex,
We know, but the problem is with the example i posted.
Thanks
Rui
Quote from: jj2007 on August 28, 2008, 05:57:35 PM
Your error is here:
mov eax, dword ptr [esi + ebx * 4]
;
_nOpenExecMsg: mov _pMsgPas, eax
Hi jj,
The problem is not where you say
; replace this jmp _nOpenExecMsg
@@: dec ebx
mov eax, dword ptr [esi + ebx * 4]
;
_nOpenExecMsg: mov _pMsgPas, eax
; by this jmp _nOpenExecMsg
@@: dec ebx
shl ebx, 2 ; its the same
;**********************************************
.if ebx == 0
debWnd "EBX = 0", _hWnd
.elseif ebx == 4
debWnd "EBX = 4", _hWnd
.else
debWnd "EBX = outro valor", _hWnd
.endif
;**********************************************
mov eax, dword ptr [esi + ebx]
;
_nOpenExecMsg: mov _pMsgPas, eax
************************************************************
In the example, there are only 3 cases:
1. invoke OpenExecMsg, 1 => EBX= 1 -> dec ebx ... => ebx= 0
2. invoke OpenExecMsg, 2 => EBX= 2 -> dec ebx = 1 -> shl ebx, 2 => ebx=4
3 .invoke OpenExecMsg, 0 => mov eax, dword ptr [esi - 8]
Thank you
Rui
Quote from: RuiLoureiro on August 28, 2008, 06:51:15 PM
The problem is not where you say
I've let it crash in OllyDbg, and it crashed precisely because it reads from the address in eax passed here:
invoke PasMsgPr, hWnd, _pMsgPas
You use a debugger, I suppose?
Hi jj2007,
1st: Thank you for your reply
2nd: No, I never tried
3rd: It seems the problem is not there.
The problem seems to be another thing
EDITED 1: jj, i used PEEK «Useful little debugging tool "peek.dll"». It is elsewhere
in this Workshop. The value in _pMsgPas is correct, the same we get
at the starting point. It seems to be inside PasMsgPr.
Remove THIS and it WORKS:
;************************************************
;mov eax, pPas
;movzx edx, byte ptr [eax - 1]
;invoke GetTextExtentPoint32, hDC, eax, edx, addr _WidthStr
;mov edx, 280 ;CHILD_W
;sub edx, _WidthStr
;shr edx, 1
;mov _WidthStr, edx
EDITED 2:: The problem is exactly with _WidthStr. It was defined as DD
and it should be 2 DD.
I made some corrections and now you can see the file Child10
***********************************************************
Hi BlackVortex,
I am trying to be clear ( sorry, i hadnt time yesterday )
You said:
«Rui, you should read iczelion's tutorials to see how to properly
construct message processing loops.»
It seems you have reason. But ...
1st: If i understood your question the problem is about this:
«FROM Windows User Interface -> ... Designing a Window Procedure
The following example shows the structure of a typical window procedure.
...
Notice that each case returns a specific value for each message.
For messages that it does not process, the window procedure calls the DefWindowProc function.
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
// Initialize the window.
return 0;
case WM_PAINT:
// Paint the window's client area.
return 0;
case WM_SIZE:
// Set the size and position of the window.
return 0;
case WM_DESTROY:
// Clean up window-specific data objects.
return 0;
//
// Process other messages.
//
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
»
comment:
[ note1: return 0 means mov eax, 0
ret
and
return DefWindowProc(hwnd, uMsg, wParam, lParam)
means
invoke DefWindowProc, hwnd, uMsg, wParam, lParam
ret ; return the value DefWindowProc returns
]
OR
«iczelion's tutorials
...
IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax ; <=> mov eax, 0
ret
WndProc endp
Here comes the crucial part.
...
Your code must check the Windows message to see if it's a message it's interested in.
If it is, do anything you want to do in response to that message
and then return with zero in eax.
If it's not, you MUST call DefWindowProc, passing all parameters you received
to it for default processing.. »
So, IF we process the message THEN
mov eax, 0
ret
IF we dont process THEN
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
question A: Is there something wrong ?
One doubt: what does OS consider "we process the message" ?
It seems "when we pass EAX=0 and we dont call DefWindowProc"
2nd: Now, comes the practical example part:
In the files PopUp6.asm & PopUp7.asm
we can see this: ( WndProc is the WinMain message processor )
WndProc proc hWnd:DWORD, iMsg:DWORD, wParam:DWORD, lParam:DWORD
mov eax, iMsg
mov edx, wParam
;
cmp eax, WM_SIZE
jne _WM_COMMAND
;
; Client region
; ----------------
invoke GetClientRect, hWnd, addr _ClientLeftX
mov eax, 0 ; OK processed
ret
;jmp _eWndProc ; removed
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
_WM_COMMAND: cmp eax, WM_COMMAND
jne _WM_CLOSE
;
;=============== menu commands =======================
cmp edx, IDM_Open1
jne @F
; ******************
; Open PopUp window
; ******************
invoke OpenExecMsg, 1
; **********************************
; Why to pass it to DefWindowProc ? And Why not ?
; **********************************
mov eax, 0 ; OK processed
ret
;jmp _eWndProc ; removed
@@: cmp edx, IDM_Open2
jne @F
; ******************
; Open PopUp window
; ******************
invoke OpenExecMsg, 2
mov eax, 0 ; OK processed
ret
;jmp _eWndProc ; removed
@@: cmp edx, IDM_Open3
jne @F
; ******************
; Open PopUp window
; ******************
invoke OpenExecMsg, 5
mov eax, 0 ; OK processed
ret
;jmp _eWndProc ; removed
@@: cmp edx, IDM_Close1
jne @F
; ******************
; Close PopUp window
; ******************
call CloseExecMsg
mov eax, 0 ; OK processed
ret
;jmp _eWndProc ; removed
;...................................
@@: cmp edx, IDM_End
jne _eWndProc
;
invoke SendMessage, hWnd, WM_SYSCOMMAND, SC_CLOSE, NULL
mov eax, 0 ; OK processed
ret
;jmp _eWndProc ; removed
;
;============= end menu commands =====================
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
_WM_CLOSE: cmp eax, WM_CLOSE
je @F
cmp eax, WM_DESTROY
jne _eWndProc
;
@@: invoke PostQuitMessage, NULL
mov eax, 0 ; OK processed
ret
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
;
; Pass to OS to be processed
; **************************
_eWndProc: invoke DefWindowProc, hWnd, iMsg, wParam, lParam
ret
WndProc endp
question B: Now, is there something wrong ?
I will appreciate any well intended comments
EDITED: i updated the files PopUp5 and Child6
Thank you
Rui
[attachment deleted by admin]
Hello Rui, glad to see you are still programming in assembler. :U
If you have never tried OllyDbg, please give it a try. It is very helpful for finding bugs.
Using OllyDbg is very easy.
1. Download v1.10 from http://www.ollydbg.de/odbg110.zip and install it.
2. Next, open it and press F3 to load your executable file. At this point probably very few windows will be visible, so you might want to open addititional ones from the Window menu.
3. The highlighted line should be the entrypoint of your file. Press F8 repeatedly to watch as code is executed.
4. Set a breakpoint on a line by highlighting the desired line and pressing F2. Part of the line turns red to indicate it is a breakpoint. Now you can press F9 to run the code, and it will stop when execution reaches the breakpoint.
5. If an exception error occurs, the bottom statusbar displays which error occured and at what address. In some rare cases, it is possible to continue debugging by pressing shift+F7/F8/F9.
6. To restart debugging the application, press Control-F2.
That's it. There is much more OllyDbg is capable of, but these simple steps are really eye-opening. It really helps to understand how things are working.
Good luck, and have fun! :bg
BlackVortex,
About this you wrote to jj2007
«@ jj2007
Well, you could probably use an empty file with the correct name.»
i think you could probably give a job to jj2007: you order and he works to you.
And set the new rules of the forum.
To me, when someboby wants to help, see something that looks like incorrect
or have reasons to say something about it and "kick to corner" saying go and read etc. etc.
hummmmm its not a help, its another thing ! Why ? Simple because he have the source and he
can point the case, he can say exactly what is the problem he wants to point out.
About a question that somebody posts elsewhere (he doesnt give the source), Paul wrote:
«That is like saying, "Do you see that crowd of people over there?
One of them just robbed me, please arrest that person."»
About this you wrote
«I'm sure you will want to write your proggy from start !».
i think you didnt read all stuff from start and you dont know that i never
begin from start. Sure. Why to suppose ?
About this: «There are sources and examples for all those tutorials of course»
iam not sure that you know that there are many people in this world. Tonnes of them,
like tonnes of examples, like tonnes of tutorials, and so on. Why do you want to do
one more ? Your own case ?
Hello Mark,
glad to see you also ! :U
yes, still programming in assembler (for windows) and learning.
As you say debugger «really helps to understand how things are working»
I used it so many years in TASM for DOS, but now i use another method
for finding bugs.
But i go to try OllyDbg to learn.
Thank yoy Mark
Rui
@ Rui
I think you misunderstood my intentions, probably because english isn't your main language. I just downloaded your source to try to see if I could help, but it is so chaotic and difficult to read that I got disappointed. Just wanted you to reconsider remaking your program from start (based on the perfect examples) to make it truly better and not just fix one little problem and then stumble to the next etc.
And my suggestion to jj wasn't an "order" of course, I just thought that he should try using an empty .wav file to allow the source to assemble, since he said he couldn't do that and was asking you for the file.
EDIT: And why are you quoting me and underlining simple words with no special meaning ? :'(
BlackVortex,
1st: Perhaps i misunderstood your intentions
( english isn't my main language ). I suppose its yours, no ?
2nd: About your suggestion to jj, i think there is no need to remember
that he could compile .wav file simple putting // to remove
the statement. It is not to one that understand windows programming.
To remove in the .asm file we use ; as we know.
Correct suggestion: put // ... in rsrc.rc file (my opinion).
3rd: «...but it is so chaotic and difficult to read that I got disappointed»
Here i am we you. I give you a credit. Its normal. It happens with me
too although each one reacts as each one. But its normal. I dont like
to see many code files i see but ... doesnt matter and i read and
in many cases i understand.
4th: About your EDIT question, i suppose you are referring "correct name"
What is "correct name" ? I dont know ! I didnt understand. May be
for this reason.
5th: Sorry if i misunderstood your intentions. But think about this:
i post a lot of words asking for help. I got a reply something
like this: put your source code. Now, i put the source code
and i get a reply: go to see ... in the "next corner".
Rui
>> 2nd: About your suggestion to jj, i think there is no need to remember
>> that he could compile .wav file simple putting // to remove
>> the statement. It is not to one that understand windows programming.
>> To remove in the .asm file we use ; as we know.
>> Correct suggestion: put // ... in rsrc.rc file (my opinion).
But aren't there references to that file ? And doesn't the proggy try to play the .wav ? Just commenting it out in the resource file isn't enough. Better to just use an empty .wav or just some random .wav file :lol
Oh, and when I say "correct name" I just mean the exact name that's needed for the compilation.
Quote from: BlackVortex on August 30, 2008, 06:44:35 PM
Better to just use an empty .wav or just some random .wav file
I could have tried to use an empty file, but
1st there is always a chance that code crashes in mysterious ways because it does not find the expected files
2nd (and Rui seems to agree) one can increase chances to get qualified help by simply including all necessary files, instead of letting others dig deeply in various rc and inc files. On the other hand, if I get a zip with a dozen project files, I give up immediately. I like to have everything in a single file, so that I can find the error in one instance of the editor. Same as your frustration when seeing non-conventional messaging loops etc ;-)
But really, this should not turn into an ideological debate. Rui has a little problem, and he needs help to find it. Giving him Olly was a big step.
«Just commenting it out in the resource file isn't enough.»
Why not ? Thats the way to do this;
// TDWave7 WAVE sound7.wav
The reference is this in .asm file but it is a string
_WaveName7 db 'TDWave7', 0
and this
invoke PlaySound, addr _WaveName7, _hInstance, 40005h
so PlaySound doesnt find TDWave7 and doesnt play.
But you can comment both too.
Rui
Good Grief, I just read all that, will someone just phukking shoot me!
I cannot figure out if we are arguing about the problem or arguing about arguing about the problem.
-- Paul
Or maybe even arguing 3 about the problem ::)
The missing wav file is a small problem that is easy to identify and rectify, IMO not worthy of even a comment, much less an extended discussion. Some of Rui's source files have been a little difficult to read, but the only problem I can see with child10.asm is that it contains a mixture of tabs and spaces in a few places.
Well i am sorry
Hello Paul ! Thank you. ( I know you from my first post in this forum, Paul )
I am glad to see you here. I appreciate your particular "style"
(like i appreciate some others, too). I like you :U
Paul, Lord Byron should say "the best way to give a perfect example is putting
someone to look for a perfect example".
what to say to you, MichealW if everyboby knows you. Ever correct, Ever
trying to help, ever with the best you can. With perfect examples
What to say ?
This :green2
Now, goto the Next step
How could i know what the problem that someone is seeing if he dont want to say
what the problem is ? What ? Where ?
To write, to Assemble & Link etc. i use Quick Editor. And i use tabs and spaces
in many places. And ;;;. I dont know what happen when we use another editor. No one
wants to say anything. I dont guess. If it appears to be "chaotic" i dont know,
i cannot guess.
Now comes the problem i have
........................................................
Meanwhile i found this example about message processing loops
WndProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
LOCAL var :DWORD
LOCAL caW :DWORD
LOCAL caH :DWORD
LOCAL Rct :RECT
LOCAL buffer1[260]:BYTE ; these are two spare buffers
LOCAL buffer2[260]:BYTE ; for text manipulation etc..
Switch uMsg
Case WM_CREATE
mov butn1, rv(PushButton,"Show",hWin,20,20,100,25,500)
mov butn2, rv(PushButton,"Hide",hWin,20,50,100,25,510)
mov hChild, 0
Case WM_COMMAND
switch wParam
case 500
.if hChild == 0
mov hChild, rv(childwin,hWin)
.endif
case 510
.if hChild != 0
invoke DestroyWindow, hChild
mov hChild, 0
.endif
endsw
Case WM_SYSCOLORCHANGE
Case WM_SIZE
Case WM_CLOSE
Case WM_DESTROY
invoke PostQuitMessage,NULL
return 0
Endsw
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
WndProc endp
childproc proc hWin:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
Switch uMsg
Case WM_COMMAND
Case WM_CREATE
Case WM_SYSCOLORCHANGE
Case WM_SIZE
Case WM_CLOSE
Endsw
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
childproc endp
Rui
Hi
The 1st problem i posted was just about how to create a popup window with
WS_SYSMENU style (SYSMENU = close button - to me its not easy to follow
SYS != CLOSE, MENU != CLOSE).
But i did an error when i used copy-paste elsewhere
(copy a proc from a file paste into PopUp5).
And i got the error.
But the next problem was: How to create it in a fixed position in such a way
that we cannot move it ? THIS IS THE main PROBLEM. I read documentation and
i didnt see any way to do it.
And Hutch answer this:
«Rui,
If you want another window attached in an imovable way to a main window,
you normally set the CHILD style for it using the main window as it parent.»
Its clear: i need to change to WS_CHILD style.
I did the Child6 file, but it had the same error as PopUp5.
I posted child10 ( i didnt remove «include peek.inc & @peek» from child10.asm
please remove it if you want to assemble)
Hutch,
What to do to create the child window in a fixed position ?
Do i need to add a style ? Can you tell me, please ?
Anyone know ? Could you help me ?
Thank you
Rui
Quote from: RuiLoureiro on August 31, 2008, 03:39:57 PM
What to do to create the child window in a fixed position ?
You might not give it a caption. Or you intercept its WM_MOVE and WM_SIZE messages. Googling for subclass wm_move might help.
I'm still not sure that I understand what the goal is here, or how these "popup" windows will actually be used. For the code in the attachment I took a different approach that what I did in my first few attempts. Instead trying to use an application window or a dialog for the child windows, I created my own each with a static text control and a button, with all of the child windows sharing a window procedure separate from the main window procedure. The code is rough, and probably contains some substantial errors.
[attachment deleted by admin]
MichaelW,
It is to learn and it is to be used.
I liked the example. In your approach we can open 3 different popup windows.
I want only one. And i need 1 procedure to Open and 1 procedure to Close.
Open means: create, show and show the message number 134 (for example).
The Open procedure is to be used in many places. So, the easiest way to
call it is this: invoke OpenPopUp, 134 (for me). This is what i want to do.
In the file i posted, i used Open PopUp 1, Open PopUp 2, Open PopUp 3 but
it means send message 1, send message 2, etc. The parameters X, Y, W, H
where i want to show the window are constants. It is to be opened in only
one place.
In any case your example is good. It shows another way to create it
from a static text control with/without a button. They are in a fixed
position and we cannot move it with the mouse. The problem is the title bar.
I want to put a title.
As jj say, it seems i need to intercept messages. Why intercept ?
Many thanks to you
jj2007,
Thank you for your reply
«You might not give it a caption.»
The problem seems to be that: i want a title.
Intercept ? I am not understanding, sorry. Dont Know (!?)
I registered the class "WinChild". It is not a system class.
To process the messages i registered WndProcW procedure. So i can process
the WM_MOVE and WM_SIZE messages in WndProcW. The problem is: how ?
If i dont pass this messages to DefWindowProc, the window moves ( when we put
the mouse on the title bar and ...).
Thank you
one note: this is the warning i got when i downloaded that .wav file
«do not post on web site for download». As i dont like to break
the rules ... But i can post the link if necessary. No problems, jj
Rui
Quote from: RuiLoureiro on September 01, 2008, 04:11:23 PM
Intercept ? I am not understanding, sorry. Dont Know (!?)
When your child window receives a WM_MOVE or WM_SIZE message, you can tell Windows to simply ignore it:
CASE WM_SIZE
return 0
I hope this is correct, as I have no time to test it right now. You may have to subclass if the main message loop does not receive the child's message.
Here is a skeleton
; CASE WM_CREATE ; place this part in your WndProc
invoke CreateWindowEx, ...
invoke SetWindowLong, hChild, ; use just behind the line
GWL_WNDPROC, SubClassProc ; where you create your control
mov opEdit, eax ; the old pointer, see below
SubClassProc PROTO:DWORD,:DWORD,:DWORD,:DWORD ; move this line to proto section
°B3opEdit dd ? ; move this line to data? section
°B4SubClassProc proc hwnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
SWITCH uMsg
CASE WM_SIZE
return 0
CASE WM_MOVE
return 0
ENDSW
invoke CallWindowProc, opEdit, hwnd, uMsg, wParam, lParam
ret
SubClassProc endp
jj2007,
Thanks
«When your child window receives a WM_MOVE or WM_SIZE message,
you can tell Windows to simply ignore it:
CASE WM_SIZE
return 0 »
CASE WM_MOVE
return 0
This was exactly what i did ( in Chil10 ).
But as it didnt work i had doubts.
If i dont pass this messages to DefWindowProc, and process it
CASE WM_SIZE
return 0
CASE WM_MOVE
return 0 »
the window moves ( when we put the mouse on the title bar, take it with
left button and move ).
I dont know if subclassing works or not. My doubt is this: if i registered
WndProcW as a Child window procedure and that Child window is not a system
class window (it should not be processed by internal default procedures)
- it is not a control - why to create an intermediate procedure -
SubClassProc, for example - to process WM_MOVE & WM_SIZE if i can process
it directly in WndProcW ?
----------------------------------------------------------------------------------------------------------------
WndProcW proc hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
SWITCH uMsg
CASE WM_SIZE
return 0
CASE WM_MOVE
return 0
;..............................
CASE WM_PAINT
invoke PasMsgPr, hWnd, _pPasMsg
return 0
CASE WM_CLOSE
invoke DestroyWindow, hWnd
return 0
CASE WM_DESTROY
return 0
ENDSW
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
WndProcW endp
Rui
Quote from: RuiLoureiro on September 01, 2008, 06:25:16 PM
why to create an intermediate procedure -
SubClassProc, for example - to process WM_MOVE & WM_SIZE if i can process
it directly in WndProcW ?
Because those messages are for your main window, not for the children. Test it with a Debug window...
Subclassing is not that difficult, and an essential technique in Windows.
Rui,
I did not add a title bar to the popup window because to me a title bar implies a movable window. You could add another static control to the window and use it to display a title. You could control the color of the title by handling the WM_CTLCOLORSTATIC message in the popup window procedure. Because there would be more than one static control, you would need to check the control handle in lParam to ensure that you were setting the color of the correct control.
Also, you could make the CreatePopup procedure size the window and static controls to fit the message, similar to the way a Message Box sizes itself. To determine the on-screen size of the message string see GetTextExtentPoint32 (http://msdn.microsoft.com/en-us/library/ms534223(VS.85).aspx).
MichaelW,
If you didnt do an example with a title bar, hummm, i guess it doesnt seem to be
an easy task. May be jj can help me. Or you
Many thanks to you, MichaelW !
JJ2007,
I have some doubts, jj. Let me put it in this way:
1. About this question:
«why to create an intermediate procedure - SubClassProc, for example -
to process WM_MOVE & WM_SIZE if i can process it directly in WndProcW ?»
( WndProcW is the Child window procedure)
You gave this answer:
Because those messages are for your main window, not for the children.
Ok, it may be for the main window. Then
«why i need to create an intermediate procedure - SubClassMain, for example -
to process WM_MOVE & WM_SIZE if i can process it directly in WndProc ?».
( WndProc is the main window procedure that i registered. It is not
a system class procedure. )
2. The documentation about WM_MOVE & WM_SIZE says this:
** The WM_MOVE message is sent after a window has been moved;
** The WM_SIZE message is sent to a window after its size has changed;
If they are sent AFTER it has been moved/changed what can we do in
that time ? ISTBO that the child window is already in another position
when we receive that message.
If i process it in WndProc (in Child10), the window moves just as before.
3. About Subclassing:
«Subclassing is not that difficult, and an essential technique in Windows»
It seems that i understood it. When we have a system procedure X that process
messages in a way that we dont want, we give the address of another procedure Y
in such a way that the system calls the procedure Y first. In this way, in Y
we can process the messages that we dont want to pass to X. The messages that
we dont want to process in Y we pass to X. It is made with SetWindowsLong, etc.
Now, let me know where i am wrong.
Many thanks to you, JJ
ISTBO = It seems to be obvious
Rui
Rui,
Look at GetWindowPlacement and SetWindowPlacement. You would use tthe first API to mionitor and the second one to restore if the window is moved.
I ike you too.
--Paul
I modified my code to produce a single fixed-size, fixed-position popup window, with a title bar but without a close button. The popup window position is fixed within the client area of the main window, but since it is a child of the main window, it will move with the main window.
Edit: Provided a way to close the popup window.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
hInst dd 0
hWnd dd 0
hwndPop dd 0
_X dd 0
_Y dd 0
rc RECT <>
wcx WNDCLASSEX <>
msg MSG <>
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
CreatePopup proc hParent:DWORD, pszTitle:DWORD, pszMessage:DWORD
LOCAL hwnd:DWORD
LOCAL hdc:DWORD
LOCAL _x:DWORD, _y:DWORD
LOCAL sz:_SIZE
invoke GetDC, NULL
mov hdc, eax
mov edx, len(pszMessage)
invoke GetTextExtentPoint32, hdc, pszMessage, edx, ADDR sz
mov wcx.style, CS_BYTEALIGNWINDOW
mov wcx.lpfnWndProc, OFFSET PopupProc
mov wcx.cbClsExtra, NULL
mov wcx.cbWndExtra, NULL
m2m wcx.hInstance, hInst
mov wcx.hbrBackground, rv(GetStockObject, LTGRAY_BRUSH)
mov wcx.lpszMenuName, NULL
mov wcx.lpszClassName, chr$("popup_class")
mov wcx.hIcon, rv(LoadIcon, NULL, IDI_APPLICATION)
mov wcx.hCursor, rv(LoadCursor, NULL, IDC_ARROW)
mov wcx.hIconSm, 0
invoke RegisterClassEx, ADDR wcx
;------------------------------------------------
; This code sizes the window to fit the message.
;------------------------------------------------
invoke GetSystemMetrics, SM_CXFIXEDFRAME
add eax, eax
mov ecx, sz.x
add ecx, 20
add ecx, eax
mov _x, ecx
invoke GetSystemMetrics, SM_CYSIZE
push eax
invoke GetSystemMetrics, SM_CXFIXEDFRAME
add eax, eax
pop ecx
add eax, ecx
add eax, sz.y
add eax, 8
mov _y, eax
invoke CreateWindowEx, NULL,
chr$("popup_class"),
pszTitle,
WS_VISIBLE or WS_CHILD or \
WS_BORDER or WS_CAPTION,
0, 0, _x, _y,
hParent, NULL,
hInst, NULL
mov hwnd, eax
invoke CreateWindowEx, 0,
chr$("STATIC"), pszMessage,
WS_CHILD or WS_VISIBLE or SS_LEFT,
10, 3, sz.x, sz.y, hwnd, 101,
hInst, NULL
invoke ShowWindow, hwnd, SW_SHOWNORMAL
invoke UpdateWindow, hwnd
return hwnd
CreatePopup endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
PopupProc proc hwnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
SWITCH uMsg
CASE WM_MOVING
invoke GetWindowRect, hwnd, ADDR rc
mov edx, lParam
mov eax, rc.left
mov [edx].RECT.left, eax
mov eax, rc.top
mov [edx].RECT.top, eax
mov eax, rc.right
mov [edx].RECT.right, eax
mov eax, rc.bottom
mov [edx].RECT.bottom, eax
return TRUE
CASE WM_CLOSE
invoke DestroyWindow, hwnd
ret
CASE WM_DESTROY
invoke DestroyWindow, hwnd
ret
ENDSW
invoke DefWindowProc, hwnd, uMsg, wParam, lParam
ret
PopupProc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
WindowProc proc hwnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
SWITCH uMsg
CASE WM_KEYDOWN
SWITCH wParam
CASE VK_F2
.IF rv(IsWindow, hwndPop) == 0
invoke CreatePopup, hwnd, chr$("Title"), chr$("Test message")
mov hwndPop, eax
.ENDIF
CASE VK_F3
invoke DestroyWindow, hwndPop
ENDSW
CASE WM_CLOSE
invoke PostQuitMessage, NULL
CASE WM_DESTROY
invoke DestroyWindow, hwnd
ENDSW
invoke DefWindowProc, hwnd, uMsg, wParam, lParam
ret
WindowProc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
mov hInst, rv(GetModuleHandle, NULL)
mov wcx.cbSize, sizeof WNDCLASSEX
mov wcx.style, CS_HREDRAW or CS_VREDRAW \
or CS_BYTEALIGNWINDOW
mov wcx.lpfnWndProc, OFFSET WindowProc
mov wcx.cbClsExtra, NULL
mov wcx.cbWndExtra, NULL
m2m wcx.hInstance, hInst
mov wcx.hbrBackground, rv(GetStockObject, WHITE_BRUSH)
mov wcx.lpszMenuName, NULL
mov wcx.lpszClassName, chr$("test_class")
mov wcx.hIcon, rv(LoadIcon, NULL, IDI_APPLICATION)
mov wcx.hCursor, rv(LoadCursor, NULL, IDC_ARROW)
mov wcx.hIconSm, 0
invoke RegisterClassEx, ADDR wcx
W = 400
H = 300
invoke GetSystemMetrics, SM_CXSCREEN
shr eax, 1
sub eax, W / 2
mov _X, eax
invoke GetSystemMetrics, SM_CYSCREEN
shr eax, 1
sub eax, H / 2
mov _Y, eax
invoke CreateWindowEx, WS_EX_OVERLAPPEDWINDOW,
chr$("test_class"),
chr$("Test"),
WS_OVERLAPPED or WS_SYSMENU,
_X, _Y, W, H,
NULL, NULL,
hInst, NULL
mov hWnd, eax
invoke ShowWindow, hWnd, SW_SHOWNORMAL
invoke UpdateWindow, hWnd
msgLoop:
invoke GetMessage, ADDR msg, NULL, 0, 0
.IF eax != 0
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp msgLoop
.ENDIF
exit msg.wParam
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
Paul,
Thank you ! It seems i found one solution yesterday
MichaelW,
Today it is late. Tomorrow i will post something to you.
I am studying your example.
«single fixed-size, fixed-position popup window, with a title bar»
is what i want.
Many thanks to you
Rui
MichaelW,
First of all, many thanks for your work. You got the solution.
I was reading a lot of stuff about message processing.
I found WM_WINDOWPOSCHANGING in
Platform SDK -> User Interface Services -> Windows User Interface -> Windowing ->
Windows -> Windows Overviews -> Window Features
...
Window Size and Position -> ... Size and Position Functions
«The system sends the WM_WINDOWPOSCHANGING message to a window whose size, position,
position in the z-order, or show state is about to change. This message includes a pointer
to a WINDOWPOS .... By setting the members of WINDOWPOS, an application can affect
the window's new size, position, and appearance.»
If we set the flags member of WINDOWPOS to SWP_NOMOVE
it Retains the current position and ignores the x and y parameters.
It seems i found the solution. But it has problems !
It is about this problems i want to ask you to you see why they happen, please.
I attached Child12.zip (asm & exe) & Child13.zip (asm & exe).
See WndProcW procedure (this is the child processor).
In Child13 i used what you used (but not the STATIC)
In Child12 i used WM_WINDOWPOSCHANGING.
Try this:
. run Child12.exe and choose Child -> Open Child msg1
. click on client area
. took the window with the mouse and move
. click on title bar (press and release).
It closes the window (this is the question)
What is happening ? Have you an idea. I would like to know besause
i am trying to study this questions. The system sends CLOSE ?
Thanks !
EDIT: i saw your edit: F3
Rui
[attachment deleted by admin]
I'm not sure yet why the window disappears, but WM_CLOSE is not being called. One thing I do see that could be a problem is that you are responding to a WM_PAINT message, but you are not doing the normal processing for WM_PAINT, where you start with BeginPaint (http://msdn.microsoft.com/en-us/library/ms534894(VS.85).aspx) and end with EndPaint (http://msdn.microsoft.com/en-us/library/ms534840(VS.85).aspx).
Edit:
The problem appears to be somewhere in WndProcW. If I substitute the code from child13, then the problem goes away. When experimenting with API code it's generally best to keep your code as small and simple as possible. Large, complex code can hide problems that would be easy to see in small, simple code. This is one of the reasons why I use SWITCH CASE in window procedures.
MichaelW,
Many thanks for your answers.
I hadnt time to come here until now.
The window disappears because the system Hide it, no ? I think. But how and why ?
I converted that code to switch/case and i made WndProcZ.
Now we can experiment with WndProcW or WndProcZ (see "mov wc.lpfnWndProc, ?").
If we use WndProcW we can use PasMsgPr or PrPasMsg.
PrPasMsg uses BeginPaint, and WndProcZ uses it also.
I am experimenting SetTimer too ( comment it, put ; )
All this is in child15.zip below.
The window procedures where the messages are processed
i call it processors (if they process than processor).
One word to jj2007: Thanks for your help.
Rui
[attachment deleted by admin]
The problem is just a small logical error in your code, in a non-obvious detail.
WndProcZ proc hWnd:DWORD, iMsg:DWORD, wParam:DWORD, lParam:DWORD
SWITCH iMsg
CASE WM_WINDOWPOSCHANGING
cmp _fnomove, 1
je short @F
mov _fnomove, 1
jmp _eWndProcZ
@@: mov edx, lParam ; pointer to WINDOWPOS struc
;-------------------------------------------
; Set SWP_NOMOVE flags bit WITHOUT changing
; the value of the other bits.
;-------------------------------------------
or [edx].WINDOWPOS.flags, SWP_NOMOVE
;mov [edx].WINDOWPOS.flags, SWP_NOMOVE
I didn't test this, but I think the direct problem is with clearing the SWP_SHOWWINDOW bit.
And in case it's not clear what I mean when I refer to the flags bits, like many flags in API programming the flags member is "bitmapped". If you check the values of the SWP_ constants, you will see that each one is a power of 2, so each constant is the value of a single bit.
MichaelW,
Once more, many thanks for your Help.
I passed the problem to you because i dont know this details and
you have much experience about this type of problems and you could help me.
To me it is not obvious but i think it is to you.
In fact, it solves the problem and we dont need _fnomove flag.
My problem was this: «...like many flags in API programming
the flags member is "bitmapped"»
And if it is "bitmapped" we should use OR not mov.
Did i do some other errors, MichaelW. Please, see Child16.
rsrc file is somewhere above.
I removed SetTimer, but see it also.
And thank you MichaelW :U
EDIT: i updated Child16
Rui
[attachment deleted by admin]
The only problem I see so far is:
In WndProc, the WM_CLOSE handler would normally call the DestroyWindow function and pass it the handle of the window, and the WM_DESTROY handler would normally call the PostQuitMessage function.
Hi MichaelW,
Thank you for your answer.
I saw this today and i corrected my file Child16.
I searched MSDN for WM_CLOSE, WM_DESTROY and WM_COMMAND this afternoon.
About WM_CLOSE they say
«If an application processes this message, it should return zero.
If we pass it to DefWindowProc it calls DestroyWindow by default.»
DestroyWindow sends WM_DESTROY.
I updated Child16, but this time i used SetTimer. Am i using it
correctly ? What to do to cancel it before the timeout value? KillTimer, no ?
Rui
Because the system calls the timer procedure, it must have a specific set of parameters, as shown here (http://msdn.microsoft.com/en-us/library/ms644907(VS.85).aspx).
As far as I know the only two ways to cancel a running timer are to destroy the timer with the KillTimer function, or replace the timer with the SetTimer function.
MichaelW, Thanks.
About SetTimer it is what i expected.
I have one doubt about RegisterClassEx. It seems to me that we dont
need to define more than one place to WNDCLASSEX structure. If i need
to register 5 different classes ClassPopupX, ClassPopupY, ClassPopupZ
ClassChildU and ClassChildV we can do it calling RegistaClass (see below)
5 times at the beginning of our program (for example) and after this
we use CreateWindowEx/DestroyWindow to create/destroy the windows of one
of those 5 classes. No? Am i wrong?
.data?
_wc WNDCLASSEX <?>
;---------------------------
.code
...
RegistaClass proc pClass:DWORD, pProc:DWORD
mov _wc.cbSize, SIZEOF WNDCLASSEX
mov _wc.style, WS_STYLE0 ; style
mov _wc.cbClsExtra, NULL
mov _wc.cbWndExtra, NULL
push _hInstance ; Instance
pop _wc.hInstance
mov _wc.hbrBackground, COLOR_BACKGROUND+1
mov _wc.lpszMenuName, NULL
mov _wc.hIcon, NULL
mov _wc.hCursor, NULL
mov _wc.hIconSm, NULL
mov eax, pClass ; name of windows class
mov _wc.lpszClassName, eax
;
mov eax, pProc ; procedure name
mov _wc.lpfnWndProc, eax
invoke RegisterClassEx, addr _wc
ret
RegistaClass endp
My ChildWindows doesnt work correctly in my main program
(i have another prog where i want to use it). Between OpenExecMsg
and CloseExecMsg, when the processor is doing some tasks, if i try
to move the child window it stops the normal processing tasks.
It seems i need to create another thread. No MichaelW?
Thank you for your answers
Rui
Reusing a single class would be more efficient, and if the windows all follow that same pattern, should produce the same result.
I don't know what's going on in your other program, but with child16.exe my attempts to move a child window show only a 1 percent CPU usage, which seems very normal to me.
MichaelW, Thanks.
Whats going on in my other program is what i want to know.
Meanwhile i clicked on one folder where i have files used to assemble
the program and the contents of it disappeared. Worst: the solution is
to redo all files from a backup folder. It is not happen to me !
Now, 2 things: In one case the CPU usage is 54% and in 2 other cases
it happens that the MessageBoxes doesnt appear (see below). If i remove
OpenExecMsg everything works normally. Why ? How to force it to appear
invoke OpenExecMsg, 44 <- open child window
invoke DoSomething, p1, p2, ... <- here i use some MessageBoxes
call CloseExecMsg <- close child window
Now i am going to redo the files.
Thank you MichaelW
Rui
Hello all,
MichaelW, i caught the "cat" and the problem of MessageBoxes is solved.
After using OllyDbg (results=0) and experimenting some cases
It is working correctly.
To
show the problem with MessageBoxes i attached the files:
Quote
* Child18.zip (asm & exe ) - it uses PasMsgPr -> uses GetDC to print msg
inside Child Window
* Child19.zip (asm & exe ) - it uses PrPasMsg -> uses BeginPaint to print msg
inside Child Window
Try this:
. run Child18.exe and choose Child -> Open Child msg1
(we dont see the MessageBox) . press Enter to exit from MessageBox and to close the Child window
Now,
. run Child19.exe and choose Child -> Open Child msg1
(we see the MessageBox) Thanks
Rui
[attachment deleted by admin]