Newsgroup: it.comp.lang.visual-basic
Titolo: Impedire la massimizzazione di un form con il codice

Ho creato un form per fare una ricerca su una serie di dati.
All'inizio nel form appare solo la parte in cui bisogna inserire i criteri
di ricerca (date, ID vari). Solo una volta completata la ricerca rendo
visibilea anche la parte con la tabella dei risultati.
Il mio problema è che il form deve essere massimizzabile quando è
visualizzata la griglia dei dati, ma non quando c'è visualizzata solo la
parte coi criteri di ricerca.
Inizialmente pensavo di sistemare semplicemente la cosa disabilitando il
pulsante di Maximize quando ci sono solo i criteri, per riattivarlo quando
appaiono i risultati della ricerca. Pensavo di farlo tramite la proprietà
MaxButton del form, ma poi ho scoperto che in esecuzione è di sola lettura.
Allora ho scritto del codice in Form_Resize() che, se l'utente cerca di
massimizzare il form quando non voglio, reimposta la proprietà
Form.WindowState su vbNormal, cioè lo stato normale delle finestre. Il
problema è che facendo in questo modo ottengo uno sgradevole effetto visivo.
Infatti la massimizzazione, che comunque viene avviata prima che venga
eseguito il codice in Form_Resize, avvia l'animazione della finestra che si
ingrandisce. Subito dopo però io la riporto al normale, e parte l'animazione
della finestra che si restringe.
Io invece vorrei fare in modo che non si notasse niente. La pressione del
tasto di Maximize non dovrebbe avere alcun effetto visibile.
Ho provato allora a rendere invisibile il Form durante l'evento Resize, ma
la soluzione è solo parziale.
Infatti con questo codice (il flag è la condizione che mi dice se sono
visualizzati solo i criteri o no):
Private Sub Form_Resize()
    If Me.WindowState=vbMaximized And Flag=True Then
        Me.Hide
        Me.WindowState=vbNormal
        Me.Show
    End If
End Sub
Ottengo di non visualizzare l'animazione di rimpicciolimento, ma quella di
ingrandimento appare comunque. Inoltre il far sparire e riapparire il form
crea un fastidioso sfarfallio.
Una possibile soluzione sarebbe quella di disattivare temporaneamente col
codice le animazioni delle finestre, ma è possibile?
Oppure si potrebbe impedire che il Form venga ridisegnato fino alla fine dei
ridimensionamenti. Per alcuni controlli, tipo la MSFlexGrid, si può fare
impostando a False la proprietà Redraw, ma per il Form non ho visto nessuna
proprietà corrispondente.
Qualcuno ha già affrontato e risolto problemi simili al mio?
Grazie e buona programmazione.

Qualcuno ha già affrontato e risolto problemi simili al mio?
Più o meno sì. Io ho risolto subclassando la form ed intercettando il
messaggio SC_MAXIMIZE. Per maggiori info sul subclassing, Sito Comune.
Ciao,
Moreno
#sirri#@#
morenosoft.com#
(togliete "#" dall'indirizzo)
Moreno Sirri VB Site - 
http://www.msvbsite.net
---------------------------------------------------------------------------
Le risposte alle tue domande le trovi sul Sito Comune di questo NewsGroup:
 
http://www.it-lang-vb.net
---------------------------------------------------------------------------

 parte coi criteri di ricerca.
Public Sub g_Remove_System_Menu(FrmHandle As Long, Rem_CLOSE As Boolean,
Optional Rem_MAXIMIZE As Boolean, Optional Rem_MINIMIZE As Boolean)
    Const MF_REMOVE = &H1000&
    Const MF_BYPOSITION = &H400&
    Dim Cnt As Long, i As Long
    'Numero di voci del menu di sistema
    i = GetSystemMenu(FrmHandle, False)
    Cnt = GetMenuItemCount(i)
    If Rem_CLOSE Then
        RemoveMenu i, Cnt - 1, MF_BYPOSITION Or MF_REMOVE
        RemoveMenu i, Cnt - 2, MF_REMOVE Or MF_BYPOSITION
    End If
    If Not IsMissing(Rem_MAXIMIZE) Then
        If Rem_MAXIMIZE Then RemoveMenu i, Cnt - 3, MF_REMOVE Or
MF_BYPOSITION
    End If
    If Not IsMissing(Rem_MINIMIZE) Then
        If Rem_MINIMIZE Then RemoveMenu i, Cnt - 4, MF_REMOVE Or
MF_BYPOSITION
    End If
    DrawMenuBar FrmHandle
End Sub
Metti questa sub in un modulo quindi richiamala cosě :
Sub Form_Load()
    g_Remove_System_Menu Me.hwnd, False, True, False
End sub
dovrebbe disabilitare il bottone di max (ma a me lo blocca soltanto ma il
risultato č uguale)
Saluti

Intanto grazie per le risposte.
Ho provato alcune cose.
- Impostare la Appearance del form a flat non elimina le animazioni del
menu. Il solo cambiamento che ho notato è stato che il fondo del form è
diventato bianco.
-Il subclassing è molto interessante, non sapevo che da VB si potessero
intercettare e cambiare le procedure usate nel trattamento delle finestre.
L'esempio che c'è sul sito l'ho provato e funziona. Tuttavia avrei bisogno
di sapere il valore numerico di SC_MAXIMIZE per poterlo usare.
-se riuscissi a eliminare temporaneamente o disabilitare il pulsante di Max,
invece di rendere inutile il click sul pulsante, sarei più contento.
La proposta di Fox Mulder mi sembra particolarmente succulenta in questo
senso perchè mi permette di modificare direttamente i menu, però il codice
postato non funziona perchè mancano le dichiarazioni delle funzioni della
DLL.
Non avevo ma provato a farle fino ad ora, però ho preso da esempio quelle
trovate sulla pagina del SubClassing e, aiutandomi con le informazioni sulle
routines com GetSystemMenu, RemoveMenu, ecc trovate nella guida di Visual
Studio ho scritto queste dichiarazioni:
Declare Function GetSystemMenu Lib "user32" (ByVal FrmHandle As Long, Revert
As Boolean) As Long
Declare Function GetMenuItemCount Lib "user32" (ByVal MenuHandle As Long) As
Integer
Declare Function RemoveMenu Lib "user32" (ByVal FrmHandle As Long, ByVal
nPos As Integer, nFlags As Integer) As Integer
Declare Function DrawMenuBar Lib "user32" (ByVal FrmHandle As Long) As
Integer
In definitiva, ho lanciato un progetto con un modulo standard contente:
Option Explicit
Declare Function GetSystemMenu Lib "user32" (ByVal FrmHandle As Long, Revert
As Boolean) As Long
Declare Function GetMenuItemCount Lib "user32" (ByVal MenuHandle As Long) As
Integer
Declare Function RemoveMenu Lib "user32" (ByVal FrmHandle As Long, ByVal
nPos As Integer, nFlags As Integer) As Integer
Declare Function DrawMenuBar Lib "user32" (ByVal FrmHandle As Long) As
Integer
Public Sub g_Remove_System_Menu(FrmHandle As Long, Rem_CLOSE As Boolean,
Optional Rem_MAXIMIZE As Boolean, Optional Rem_MINIMIZE As Boolean)
    Const MF_REMOVE = &H1000&
    Const MF_BYPOSITION = &H400&
    Dim Cnt As Long, i As Long
    'Numero di voci del menu di sistema
    i = GetSystemMenu(FrmHandle, False)
    Cnt = GetMenuItemCount(i)
    If Rem_CLOSE Then
        RemoveMenu i, Cnt - 1, MF_BYPOSITION Or MF_REMOVE
        RemoveMenu i, Cnt - 2, MF_REMOVE Or MF_BYPOSITION
    End If
    If Not IsMissing(Rem_MAXIMIZE) Then
        If Rem_MAXIMIZE Then RemoveMenu i, Cnt - 3, MF_REMOVE Or
MF_BYPOSITION
    End If
    If Not IsMissing(Rem_MINIMIZE) Then
        If Rem_MINIMIZE Then RemoveMenu i, Cnt - 4, MF_REMOVE Or
MF_BYPOSITION
    End If
    DrawMenuBar FrmHandle
End Sub
e un form con:
Private Sub Form_Load()
g_Remove_System_Menu Me.hWnd, False, True, False
End Sub
In questo modo in teoria sarebbe dovuto sparire il pulsante di Maximize,
però non funziona.
Ho provato a seguire passo passo lo svolgimento della g_Remove_System_Menu,
e il problema è che GetSystemMenu mi restituisce 0, che penso sia un valore
di errore, perchè poi la GetMenuItemCount mi dà -1 (errore).
Forse ho sbagliato le dichiarazioni delle funzioni della DLL?

di sapere il valore numerico di SC_MAXIMIZE per poterlo usare.
Et voila, direttamente da winuser.h:
#define SC_SIZE         0xF000
#define SC_MOVE         0xF010
#define SC_MINIMIZE     0xF020
#define SC_MAXIMIZE     0xF030
#define SC_NEXTWINDOW   0xF040
#define SC_PREVWINDOW   0xF050
#define SC_CLOSE        0xF060
#define SC_VSCROLL      0xF070
#define SC_HSCROLL      0xF080
#define SC_MOUSEMENU    0xF090
#define SC_KEYMENU      0xF100
#define SC_ARRANGE      0xF110
#define SC_RESTORE      0xF120
#define SC_TASKLIST     0xF130
#define SC_SCREENSAVE   0xF140
#define SC_HOTKEY       0xF150
#if(WINVER >= 0x0400)
#define SC_DEFAULT      0xF160
#define SC_MONITORPOWER 0xF170
#define SC_CONTEXTHELP  0xF180
#define SC_SEPARATOR    0xF00F
#endif /* WINVER >= 0x0400 */
hth, hal