hey
does anyone know how i can set the limits of a window being resized,
so it can't be resized smaller than a certain point
Posted on 2004-03-13 08:46:51 by someone
Posted on 2004-03-13 09:02:25 by bitRAKE
thanks, i'll have a look
Posted on 2004-03-13 09:18:22 by someone
Hi someone,

The best, easiest and most reliable way is to respond to the WM_GETMINMAXINFO message:

cmp D[uMsg],WM_GETMINMAXINFO

jne >.NextMessage
mov edi,[lParam]
mov D[edi+MINMAXINFO.ptMinTrackSize.x],MINWIDTH
mov D[edi+MINMAXINFO.ptMinTrackSize.y],MINHEIGHT
xor eax,eax
ret
Posted on 2004-03-13 10:38:19 by donkey
You can also just RECT that is giving in WM_SIZING message
Posted on 2004-03-13 11:14:11 by comrade
Donkey wins.
Posted on 2004-03-13 13:06:37 by iblis
He wins the admiration of other people who, until now, apparently didn't know that there is a window message explicitly designed for this purpose.
Posted on 2004-03-13 14:58:25 by iblis

He wins the admiration of other people who, until now, apparently didn't know that there is a window message explicitly designed for this purpose.


Not sure if I deserve any admiration, it's just that there are alot of extremely useful Windows messages that go unnoticed. One of the best examples is how to suppress WM_ERASEBKGND during a resize so you don't get flashing along the edges of child controls. I have seen large obfuscated routines to do this using various double buffering techniques but it can be done much simpler with a good knowledge of the GUI and it's messages:

cmp D[uMsg],WM_ERASEBKGND

jne >
cmp D[IsMoving],TRUE
jne >>DEFPROC
xor eax,eax
inc eax
ret
:
cmp D[uMsg],WM_ENTERSIZEMOVE
jne >
mov D[IsMoving],TRUE
xor eax,eax
ret
:
cmp D[uMsg],WM_EXITSIZEMOVE
jne >
mov D[IsMoving],FALSE
invoke InvalidateRect,[hwnd],NULL,TRUE
invoke UpdateWindow,[hwnd]
xor eax,eax
ret
:


Actually, if you look at UpdateManager (or any of my apps that allow resizing) I never process either WM_SIZING or WM_SIZE, they are only subsequent messages. That is they are only sent if you don't respond to the real messages and slow things down. It is IMHO bad GUI design to respond to those 2 messages at all, they should never have even been sent. The real messages to process are :

WM_GETMINMAXINFO
WM_ENTERSIZEMOVE
WM_EXITSIZEMOVE
WM_WINDOWPOSCHANGED
WM_WINDOWPOSCHANGING
Posted on 2004-03-13 15:36:17 by donkey
Sheesh, such fragile egos.

As Donkey sort of pointed out, you can't expect anybody to know everything there is to know about window messages. That's why this message board is here. People share their knowledge.

Donkey's solution was the best and easiest answer to the question that was asked. That's all. Don't let it soil your self-esteems.
Posted on 2004-03-13 16:50:40 by iblis
Well, if we want to be less diplomatic, WM_SIZING is completely wrong and misinformed. It demonstrates only that the programmer did not do his homework before he coded his sizing routine. Even the API reference advises against it:

By default, the DefWindowProc function sends the WM_SIZE and WM_MOVE messages to the window. The WM_SIZE and WM_MOVE messages are not sent if an application handles the WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient to perform any move or size change processing during the WM_WINDOWPOSCHANGED message without calling DefWindowProc.


Thomas's routine though a good thought problem is the wrong way to limit window size and only suceeds in adding 4 or 5 new messages and alot of code to the message loop and lets the real messages go unanswered.

But as Iblis said, there is no way that anyone can be familiar with all of the 1000's of Windows messages. It is simply not possible and so I posted the way to do it properly. I did not want to start a flame war over a tidbit of useful information.
Posted on 2004-03-13 17:20:18 by donkey
Comrade, if I knew of any in your area I'd suggest perhaps attending a few anger management classes.


Edit: 666 posts! :alright:
Posted on 2004-03-13 17:21:56 by iblis
Thanks for the improvement donkey.
Posted on 2004-03-13 18:12:59 by bitRAKE
thanks everyone, i used donkey's routine, but my version of it

.elseif uMsg==WM_GETMINMAXINFO
mov ecx, lParam
assume ecx:ptr MINMAXINFO
mov .ptMinTrackSize.x, 250
mov .ptMinTrackSize.y, 200
assume ecx:nothing

i'm also using WM_WINDOWPOSCHANGED instead of WM_SIZE now.
thanks again
Posted on 2004-03-13 23:40:14 by someone
Hi someone,

Be sure to include the WM_ERASEBKGND stuff as well, it will reduce the amount of flicker when the window is being resized with "Show window contents while dragging" set in your options. The IsMoving variable must be global.

Yes, I use GoAsm so there is no assume directive but even in MASM I prefer not to use assume as I believe it tends to lead to bugz and is usually more trouble than it is worth. However in this case it is a tight function so there is no harm possible.
Posted on 2004-03-14 00:18:07 by donkey
hey donkey, i'm a little confused about the WM_ERASEBKGND stuff
what does it do to stop the flicker ?
i tried translating it , is this how it'd be done, i wasn't exactly sure what was meant to hapen in the WM_ERASEBKGND part

.elseif uMsg==WM_ERASEBKGND
.if dwIsMoving==TRUE
xor eax, eax
inc eax
ret
.endif
.elseif uMsg==WM_ENTERSIZEMOVE
mov dwIsMoving, TRUE
.elseif uMsg==WM_EXITSIZEMOVE
mov dwIsMoving, FALSE
invoke InvalidateRect, hWnd, NULL, TRUE
invoke UpdateWindow, hWnd

thanks
Posted on 2004-03-14 04:44:12 by someone
Heh, even some "professional" coders use WM_SIZING. You can see it in TheBat! ... the way it keeps minimum width and hights shows you they don't use the message donkey showed us. :alright:

Thanks donkey, I already changed sizing implementation in my current project :)
Posted on 2004-03-14 08:33:16 by Milos
Hi Milos,

Good to hear that I helped out a bit.

Hi someone,

The little snippet just supresses the WM_ERASEBKGND in the main window, that is what causes 99% of the flicker on resizing as it causes the any child controls to be completely erased and redrawn several times. For example take this resizable window from my DrWatson log viewer, one copy has no suppression and the other suppresses WM_ERASEBKGND with the code shown (be sure to set show window content while dragging)

The code is fairly simple on recieving the WM_ENTERSIZEMOVE it sets a flag that causes the program to respond to WM_ERASEBKGND without calling DefWindowProc, thereby effectively disabling it until it recieves a WM_EXITSIZEMOVE and the flag is reset.

 .elseif uMsg==WM_ERASEBKGND

.if dwIsMoving==TRUE
xor eax, eax
inc eax ; << remove this for Window apps as opposed to Dlg apps
ret
[b].else
; For Dlg apps just return 0, for window apps use this...
invoke DefWindowProc,hwnd,umsg,wparam,lparam
ret[/b]
.endif
.elseif uMsg==WM_ENTERSIZEMOVE
mov dwIsMoving, TRUE
.elseif uMsg==WM_EXITSIZEMOVE
mov dwIsMoving, FALSE
invoke InvalidateRect, hWnd, NULL, TRUE
invoke UpdateWindow, hWnd
Posted on 2004-03-14 09:24:00 by donkey
donkey, how do I use the drwatsonlog tool? It tells me that no log file is found, even though I just made an app crash on purpose... I had a quick look at the exe, and it seems like you're using a pretty hardcoded path?
Posted on 2004-03-14 10:53:05 by f0dder
Hi f0dder,

It does not use a hard coded path (sort of), the path for DrWatson is hardcoded unless it is overridden by a registry entry. The application checks that. If you have a JIT debugger set up DrWatson does not execute.

The path to the log file is either the contents of :

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DrWatson\LogFilePath

or

"C:\Documents and Settings\All Users\Documents\DrWatson"

The program takes that into account. However DrWatson has to be enabled as the JIT debugger, that is why I abandonned the project. The key for the current JIT debugger can be found in...

"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger"

if DrWatson is not there it is not executed. The source code for the project was posted in the RadASM forum but as I said I abandonned the project as it was unreliable and not likely to be useful to programmers who normally already have their JIT set up.
Posted on 2004-03-14 10:59:01 by donkey
I disabled my JIT debugger and set up DrWatson instead, by running "drwtsn32 -i". Then I ran a little test app with an embedded int3 to cause a crash dump. Works as expected, and I could view the log with drwatson. However, I don't have the mentioned registry key.

"C:\Documents and Settings\All Users\Documents\DrWatson" is a bad hardcode :) - the path should be retrieved via the registry or SHGetSpecialFolderPath with CSIDL_COMMON_DOCUMENTS .

Doesn't matter much since it's a discontinued project, and I have a hexeditor for testing the app ;) - and you normally seem too sensible to use hardcoded paths.
Posted on 2004-03-14 12:11:22 by f0dder