СообЧа > База Знаний > Программирование > Visual Basic > Формы и элементы управления

Вопрос

У меня у формы BorderStyle=0. Как мне программно поменять его на 1 или 2? Если написать просто form1.borderstyle=1, то ничего не происходит.

Ответ

Это невозможно сделать, потому что свойство BorderStyle доступно только для чтения во время выполнения, а, следовательно, изменению не подлежит.
Этот небольшой пример показывает как можно на лету менять структуру окна (внешний вид и не только).
Создайте форму (Form1), поместите на нее пять кнопок (Command1, Command2, Command3, Command4, Command5) и данный код.
Вся информация взята из книги «Win32 и Visual BASIC. Для профессионалов(+CD)". Автор Dan Appleman's. Большая благодарность автору! Цена книге соответствует.
В коде есть только одна проблема. После использования функции SetWindowLong, окно меняет свои свойства, но не перерисовывается. Для этого я использовал изменения размеров окна. Наверное можно использовать что-нибудь попроще с использованием SendMessage или как нибудь еще.

Option Explicit
Dim tmplong As Long
Dim tmplong1 As Long

' Основные параметры окна
Const WS_OVERLAPPED& = &H0& ' при создании — окно с рамкой и заголовком, в работе — ошибка защиты Windows
Const WS_MAXIMIZEBOX& = &H10000 ' для окна — наличие кнопки минимизировать
Const WS_TABSTOP& = &H10000 ' для других элементов — закрепление позиции табуляции
Const WS_MINIMIZEBOX& = &H20000 ' для окна — наличие кнопки свернуть
Const WS_GROUP& = &H20000 ' для остального — является началом группы элементов
Const WS_THICKFRAME& = &H40000 ' для окна — размеры окна меняются за толстую рамку
Const WS_SYSMENU& = &H80000 ' в левой части окна есть кнопка системного меню
Const WS_HSCROLL& = &H100000 ' в окне есть горизонтальная полоса прокрутки
Const WS_VSCROLL& = &H200000 ' в окне есть вертикальная полоса прокрутки
Const WS_DLGFRAME& = &H400000 ' окно с двойной рамкой но нет заголовка
Const WS_BORDER& = &H800000 ' окно с рамкой
Const WS_CAPTION& = &HC00000 ' окно с рамкой и заголовком
Const WS_MAXIMIZE& = &H1000000 ' окно развернуто
Const WS_CLIPCHILDREN& = &H2000000 ' в окне нельзя рисовать поверх других элементов (аналог свойства ClipControls)
Const WS_CLIPSIBLINGS& = &H4000000 ' запрещает дочернему окну рисовать поверх другого дочернего окна
Const WS_DISABLED& = &H8000000 ' окно заблокировано (аналог Enable = False)
Const WS_VISIBLE& = &H10000000 ' окно является видимым (аналог Visible = True)
Const WS_MINIMIZE& = &H20000000 ' окно свернуто
Const WS_CHILD& = &H40000000 ' окно является дочерним (надо установить после SetPatent)
Const WS_CHILDWINDOW& = (WS_CHILD) '
Const WS_POPUP& = &H80000000 ' окно является всплывающим
Const WS_OVERLAPPEDWINDOW& = (WS_OVERLAPPED Or WS_CAPTION Or WS_SYSMENU Or WS_THICKFRAME Or WS_MINIMIZEBOX Or WS_MAXIMIZEBOX)
Const WS_POPUPWINDOW& = (WS_POPUP Or WS_BORDER Or WS_SYSMENU)
Const WS_TILED& = WS_OVERLAPPED '
Const WS_TILEDWINDOW& = WS_OVERLAPPEDWINDOW '

' Расширенные параметры окна
Const WS_EX_LEFT& = &H0& ' значение по умолчанию
Const WS_EX_LTRREADING& = &H0& ' значение по умолчанию
Const WS_EX_RIGHTSCROLLBAR& = &H0& ' значение по умолчанию
Const WS_EX_DLGMODALFRAME& = &H1& ' окно имеет двойную рамку
Const WS_EX_NOPARENTNOTIFY& = &H4& ' Windows не будет уничтожать это окно
Const WS_EX_TOPMOST& = &H8& ' окно находится поверх остальных у которых бит не установлен
Const WS_EX_ACCEPTFILES& = &H10& ' окно принимает файлы при перетаскивании из диспетчера файлов (?)
Const WS_EX_TRANSPARENT& = &H20& ' окно является прозрачным и не скрывает окна под собой
Const WS_EX_MDICHILD& = &H40& ' окно имеет уменьшенный заголовок и не отображается в панели задач
Const WS_EX_TOOLWINDOW& = &H80& ' окно представляет собой кнопку, содержащую растр вместо текста
Const WS_EX_WINDOWEDGE& = &H100& ' окно имеет приподнятую рамку
Const WS_EX_CLIENTEDGE& = &H200& ' окно имеет утопленную рамку
Const WS_EX_CONTEXTHELP& = &H400& ' в заголовке есть кнопка с вопросом.
Const WS_EX_RIGHT& = &H1000& ' если WS_EX_RTLREADING установлен текст выравнивается по правому краю
Const WS_EX_RTLREADING& = &H2000& ' в иврите и арабском языке текст вывлдится справа налево
Const WS_EX_LEFTSCROLLBAR& = &H4000& ' если WS_EX_RTLREADING установлен полоса прокрутки перемещается налево
Const WS_EX_CONTROLPARENT& = &H10000 ' клавиша Tab вызывает переключение между дочерними окнами данного окна
Const WS_EX_STATICEDGE& = &H20000 ' объемное оформление
Const WS_EX_APPWINDOW& = &H40000 ' свернутое приложение помещается в панель задач

' Разновидность параметра
Const GWL_WNDPROC& = (-4) ' адрес функции окна
Const GWL_HINSTANCE& = (-6) ' манипулятор экземпляра, владеющего заданным окном
Const GWL_HWNDPARENT& = (-8) ' манипулятор родителя для заданного окна (лучше только читать, для записи SetParent)
Const GWL_ID& = (-12) ' идентификатор дочернего окна в диалоговой панели
Const GWL_STYLE& = (-16) ' СТИЛЬ ОКНА
Const GWL_EXSTYLE& = (-20) ' РАСШИРЕННЫЙ СТИЛЬ ОКНА
Const GWL_USERDATA& = (-21) ' параметры определяются приложением (что то навроде Tag)

' функции для чтения и записи информации о структуре окна
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
'Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

' приведение окна к нормальному виду (можно его нормально закрыть)
Private Sub Command1_Click()
SetWindowLong Me.hwnd, -16, tmplong 'GetWindowLong(Me.hwnd, -16) Or WS_CAPTION& Or WS_THICKFRAME&
Me.Height = Me.Height — 10
Me.Height = Me.Height + 10
End Sub

' кнопка убирает заголовок окна режим BorderStyle=2
Private Sub Command2_Click()
SetWindowLong Me.hwnd, -16, tmplong And (Not WS_CAPTION&)
Me.Height = Me.Height — 10
Me.Height = Me.Height + 10
End Sub

' кнопка убирает толстую рамку. режим BorderStyle=1
Private Sub Command3_Click()
SetWindowLong Me.hwnd, -16, tmplong And (Not WS_THICKFRAME&)
Me.Height = Me.Height — 10
Me.Height = Me.Height + 10
End Sub

' кнопка убирает толстую рамку. режим BorderStyle=0
Private Sub Command4_Click()
SetWindowLong Me.hwnd, -16, tmplong And (Not (WS_THICKFRAME& Or WS_CAPTION&))
Me.Height = Me.Height — 10
Me.Height = Me.Height + 10
End Sub

'кнопка утопляет поверхность формы
Private Sub Command5_Click()
SetWindowLong Me.hwnd, -20, tmplong1 Or WS_EX_CLIENTEDGE&
Me.Height = Me.Height — 10
Me.Height = Me.Height + 10
End Sub

' при загрузке формы желательно сохранить ее параметры в переменных
' и восстановить их при ее удалении,
' а то можно получить ошибку защиты
Private Sub Form_Load()
tmplong = GetWindowLong(Me.hwnd, -16) Or WS_VISIBLE&
tmplong1 = GetWindowLong(Me.hwnd, -20)
End Sub

Private Sub Form_Unload(Cancel As Integer)
SetWindowLong Me.hwnd, -16, tmplong And Not WS_VISIBLE&
SetWindowLong Me.hwnd, -20, tmplong1
End Sub

' Т.е. вид окна определяется набором флагов.
' Для установки SetWindowLong Me.hwnd, GWL_ … , GetWindowLong(Me.hwnd, GWL_ …) Or (сбрасываемое значение WS_ или WS_EX)
' Для сброса SetWindowLong Me.hwnd, GWL_ … , GetWindowLong(Me.hwnd, GWL_ …) And Not (сбрасываемое значение WS_ или WS_EX)

Алексей Каленов



Copyright © 2000-2004 Сообщество Чайников
Контактная информация