How do I avoid a window to be resized horizontally while maximizing?

Started by xanatose, April 03, 2011, 07:35:48 PM

Previous topic - Next topic

xanatose

I want to make a window that can be resized vertically but not horizontally.

I am handling WM_SIZING to avoid the user to resize using the border, but got problems when the window is maximized.

What will be the message to handle?

Gunner

~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

dedndave

you can set the min and max size by handling WM_GETMINMAXINFO

when you handle WM_SIZE, check the value of wParam   :U
you can handle maximize/minimize sizing seperately and also use it to detect when they switch

Tedd

Or just remove the ability to maximize - set the window style to:

WS_OVERLAPPEDWINDOW and (not WS_MAXIMIZEBOX)

(or whatever you're using, and mask out WS_MAXIMIZEBOX)
No snowflake in an avalanche feels responsible.

dedndave

not sure that will work, Tedd
the user can also maximize a window with the sysmenu or by double-clicking the title bar

i knew i had seen it someplace   :bg

QuoteWhen the system receives a command to maximize or restore a minimized window, it sends the window a WM_QUERYOPEN message. If the window procedure returns FALSE, the system ignores the maximize or restore command.

The system automatically sets the size and position of a maximized window to the system-defined defaults for a maximized window. To override these defaults, an application can either call the SetWindowPlacement function or process the WM_GETMINMAXINFO message that is received by a window when the system is about to maximize the window. WM_GETMINMAXINFO includes a pointer to a MINMAXINFO structure containing values the system uses to set the maximized size and position. Replacing these values overrides the defaults.

http://msdn.microsoft.com/en-us/library/ms632599%28v=vs.85%29.aspx#min_max

there is probably a way to create a window that cannot be maximized - maybe when you register the class
i think i read someplace you can access the sysmenu handle to disable it, there

MichaelW

When changing the style to disable the maximize button, you can force an update of the menu bar to match the new style.

;==============================================================================
    include \masm32\include\masm32rt.inc
;==============================================================================
    .data
        rc RECT <>
    .code
;==============================================================================
DlgProc proc hwndDlg:dword, uMsg:dword, wParam:dword, lParam:dword
    SWITCH uMsg
      CASE WM_INITDIALOG
        invoke GetWindowRect, hwndDlg, addr rc
      CASE WM_COMMAND
        .if wParam == 1000
          invoke GetWindowLong, hwndDlg, GWL_STYLE
          xor eax, WS_MAXIMIZEBOX
          invoke SetWindowLong, hwndDlg, GWL_STYLE, eax
          invoke DrawMenuBar, hwndDlg
        .endif
      CASE WM_SIZING
        mov edx, lParam
        push rc.left
        pop [edx].RECT.left
        push rc.right
        pop [edx].RECT.right
        return 1
      CASE WM_COMMAND
        SWITCH wParam
          CASE IDCANCEL
            invoke EndDialog, hwndDlg, 0
        ENDSW
      CASE WM_CLOSE
        invoke EndDialog, hwndDlg, 0
    ENDSW
    xor eax, eax
    ret
DlgProc endp
;==============================================================================
start:
;==============================================================================
    Dialog "Test", "MS Sans Serif",10, \
           WS_OVERLAPPEDWINDOW or DS_CENTER, \
           1,0,0,100,75,1024
    DlgButton "Swap Style",0,0,0,40,12,1000

    invoke GetModuleHandle, NULL
    CallModalDialog eax,0,DlgProc,NULL
    exit
;==============================================================================
end start


Edit: Modified the code making it possible to switch between the two styles.
eschew obfuscation

drizz

The message is WM_SYSCOMMAND.
Set your own size and return "message handled".

Main_WM_SYSCOMMAND proc hWnd,wParam,lParam
mov eax,wParam
and eax,0FFF0h
.if eax == SC_MAXIMIZE
invoke MessageBox,hWnd,T("You are about to maximize a window. Are you sure you want to do that?"),T('Clippy'),MB_YESNO or MB_ICONQUESTION
cmp eax,IDNO
je @F
.endif
invoke DefWindowProc,hWnd,WM_SYSCOMMAND,wParam,lParam
@@:
return 0
Main_WM_SYSCOMMAND endp
The truth cannot be learned ... it can only be recognized.


dedndave

well - that will work
but, i think a better way is to disable the maximize function on the menu with MF_GRAYED
this code can be in the WM_CREATE handler...
       INVOKE  GetSystemMenu,hWnd,FALSE
;now, the system menu handle is in EAX
;the control ID's are as listed in WM_SYSCOMMAND documentation
;we want to disable SC_MAXIMIZE, so...
       INVOKE  EnableMenuItem,eax,SC_MAXIMIZE,MF_BYCOMMAND or MF_GRAYED


well - that does not work as i expected - lol
let me see if i can figure out why

dedndave

ok - this works...
        INVOKE  GetSystemMenu,hWnd,FALSE
        INVOKE  RemoveMenu,eax,SC_MAXIMIZE,MF_BYCOMMAND

by god, if i can't disable it, i'll remove it altogether - lol
it also disabled the ability to maximize by double-clicking on the title bar   :U

if you use Tedd's idea to get rid of the max box, they have no way to maximize

MichaelW

Once you have removed the WS_MAXIMIZEBOX style, a call to DrawMenuBar will update the menu, disabling the Maximize command.
eschew obfuscation

dedndave

ok - well - i haven't been able to get rid of the box yet - lol

dedndave

ok - got it   :U
i forgot that the AND preceeds the OR in order of operation
WS_OVERLAPPEDWINDOW or WS_VISIBLE or WS_CLIPCHILDREN and (not WS_MAXIMIZEBOX)
(WS_OVERLAPPEDWINDOW or WS_VISIBLE or WS_CLIPCHILDREN) and (not WS_MAXIMIZEBOX)

the first one did not work - the second one does
i guess this would be simpler
WS_OVERLAPPEDWINDOW and (not WS_MAXIMIZEBOX) or WS_VISIBLE or WS_CLIPCHILDREN

Tedd

Works fine for me (WinXP sp3)

The maximize button is disabled (but still visible), it's also disabled in the system-menu, and double-clicking the titlebar does nothing.
No snowflake in an avalanche feels responsible.

dedndave

i was playing with this a little more
oddly enough, if you also remove the minimize box, you get only the close box - weird (no grayed boxes)
i suppose if you wanted to go further, you could create your own class for the title bar and make it however you wanted