Платформа Win32 - Создание расширенных окон

Предыдущая тема Следующая тема Перейти вниз

Платформа Win32 - Создание расширенных окон

Сообщение  Замабувараев в Пт Окт 10, 2008 4:57 am

В предыдущих примерах мы создавали окна с помощью функций RegisterClass и CreateWindow, но в Win32 API существуют ещё одни функции RegisterClassEx и CreateWindowEx, которые предоставляют более широкие возможности создания окон.

RegisterClassEx и WNDCLASSEX

Для регистрации класса окна функцией RegisterClassEx необходимо инициализовать структуру WNDCLASSEX.
Описание членов этой структуры.

Код:

Type WNDCLASSEX
    Dim cbSize As Integer
    Dim style As Integer
    Dim lpfnWndProc As Any Ptr
    Dim cbClsExtra As Integer
    Dim cbWndExtra As Integer
    Dim hInstance As Integer
    Dim hIcon As HICON
    Dim hCursor As HCURSOR
    Dim hbrBackground As HBRUSH
    Dim lpszMenuName As ZString Ptr
    Dim lpszClassName As ZString Ptr
    Dim hIconSm As Integer
End Type

cbSize — это размер структуры, который можно получить так — Len(WNDCLASSEX).

Style — Набор флагов, но нам нужны только два из них - CS_HREDRAW и CS_VREDRAW, означающие прорисовку окна при горизонтальном и вертикальном изменении размера

lpfnWndProc — указатель на функцию обработки сообщений Win32 (например, @WndProc)

cbClsExtra — устанавливается в 0

cbWndExtra — устанавливается в 0 (используется только если класс регистрируется для создания диалоговых окон из ресурсов программы, в этом случае ему присваивается значение DLGWINDOWEXTRA)

hInstance — идентификатор процесса, регистрирующего класс, его можно получить так GetModuleHandle(NULL)

hIcon — идентификатор значка, получаем его так LoadIcon(NULL, IDI_APPLICATION)

hCursor — идентификатор курсора по умолчанию, используем простую стрелку LoadCursor(NULL, IDC_ARROW)

HbrBackground — кисть для отрисовки фона, получаем её таким преобразованием: Cast(HBRUSH, COLOR_BTNFACE + 1). Приведу константы системных цветов, используемых для создания кисти, их название говорит само за себя.

COLOR_ACTIVEBORDER
COLOR_ACTIVECAPTION
COLOR_APPWORKSPACE
COLOR_BACKGROUND
COLOR_BTNFACE
COLOR_BTNSHADOW
COLOR_BTNTEXT
COLOR_CAPTIONTEXT
COLOR_GRAYTEXT
COLOR_HIGHLIGHT
COLOR_HIGHLIGHTTEXT
COLOR_INACTIVEBORDER
COLOR_INACTIVECAPTION
COLOR_MENU
COLOR_MENUTEXT
COLOR_SCROLLBAR
COLOR_WINDOW
COLOR_WINDOWFRAME
COLOR_WINDOWTEXT

lpszMenuName — адрес строки с идентификатором меню из ресурсов программы

lpszClassName — адрес строки с именем класса окна

hIconSm — равено 0.

Итак, после того, как мы познакомились со структурой WNDCLASSEX, можно приступить к созданию переменной этого типа

Код:

    Dim hInst As HINSTANCE   ' Идентификатор нашего процесса
    Dim wcEx As WNDCLASSEX   ' Структура нашего класса окна
    ' Получаем идентификатор нашего процесса
    hInst = GetModuleHandle(NULL)
    ' Создаём структуру класса окна
    With wcEx
       .cbSize          = Len(WNDCLASSEX)
       .style          = CS_HREDRAW Or CS_VREDRAW
       .lpfnWndProc         = @WndProc
       .cbClsExtra       = 0
       .cbWndExtra       = 0
       .hInstance       = hInst
       .hIcon          = LoadIcon(NULL, IDI_APPLICATION)
       .hCursor            = LoadCursor(NULL, IDC_ARROW)
       .hbrBackground         = Cast(HBRUSH, COLOR_BTNFACE + 1)
       .lpszMenuName         = 0
       .lpszClassName         = @"FBWindow"
       .hIconSm            = 0
    End With
    ' Регистрируем класс окна
    RegisterClassEx(@wcEx)

Если мы не допустили ошибок при регистрации, то RegisterClassEx вернёт идентификатор нашего зарегистрированного класса окна, иначе — 0.

CreateWindowEx

Эта функция создаёт окно с набором дополнительных параметров, которые невозможно было установить функцией CreateWindow. Как результат возвращается идентификатор окна, если же произошла ошибка, то возвращается 0.

Function CreateWindowEx( _
ByVal dwExStyle As Integer, _ /' Расширенный стиль окна '/
ByVal lpClassName As ZString Ptr, _ /' Адрес строки с именем класса окна '/
ByVal lpWindowName As ZString Ptr, _ /' Адрес строки с именем окна '/
ByVal dwStyle As Integer, _ /' Стиль окна '/
ByVal X As Integer, _ /' Координата X верхнего левого угла окна '/
ByVal Y As Integer, _ /' Координата Y верхнего левого угла окна '/
ByVal nWidth As Integer, /' Ширина окна '/
ByVal nHeight As Integer, /' Высота окна '/
ByVal hWndParent As HWND, _ /' Идентификатор окна-предка '/
ByVal hMenu As HMENU, _ /' Идентификатор меню из ресурсов программы '/
ByVal hInstance As HINSTANCE, _ /' Идентификатор программы '/
ByVal lpParam As LPVOID, _ /' Адрес данных создания окна '/
) As HWND

Теперь разберём некоторый параметры более подробно

dwExStyle

Расширенный стиль окна, имеет много значений, перечислим основные из них.

WS_EX_MDICHILD — создаёт дочернее окно
WS_EX_TOPMOST — создаёт окно переднего плана (такое окно, которое остаётся видимым полностью даже при перекрытии его другим окном, например, как у программы Диспетчер Задач)
WS_EX_TRANSPARENT — создаёт прозрачное окно, такое при котором все перекрываемые им окна видны; такое окно получает сообщение WM_PAINT только после того, как все перекрывающие его окна обновлены.

dwStyle

Стиль окна, может принимать комбинацию следующих значений.

WS_BORDER — создаёт окно, которое имеет границу в виде тонкой линии
WS_CAPTION — создает окно, которое имеет область заголовка (включает стиль WS_BORDER)
WS_CHILD, WS_CHILDWINDOW — создает дочернее окно. Этот стиль не может использоваться со стилем WS_POPUP
WS_CLIPCHILDREN Исключает область, занятую дочерними окнами, когда прорисовка происходит в пределах родительского окна. Этот стиль используется, создавая родительское окно.
WS_CLIPSIBLINGS Дочерние окна зажимов друг относительно друга; то есть, когда специфическое дочернее окно получает сообщение WM_PAINT, стиль WS_CLIPSIBLINGS отсекает все другие накладывающиеся дочерние окна из области дочернего окна, которое будет обновлено. Если WS_CLIPSIBLINGS не определен и перекрытие дочерних окон произошло, это возможно, при прорисовке в пределах клиентской области дочернего окна, тянуть{рисовать} в пределах клиентской области соседнего дочернего окна.
WS_DISABLED Создает окно, которое первоначально заблокировано. Заблокированное окно не может получить ввод от пользователя.
WS_DLGFRAME Создает окно, которое имеет границу стиля, типично используемого с диалоговыми окнами. Окно с этим стилем не может иметь области заголовка.
WS_GROUP Определяет первый контрол в группе контролов. Пользователь может изменить фокус ввода клавиатуры от одного контрола в группе к следующему при использовании управляющих клавиш. Все контролы, определенные со стилем WS_GROUP после первого контрола принадлежат той же самой группе. Следующий контрол со стилем WS_GROUP заканчивает группу и запускает следующую группу.
WS_HSCROLL Создает окно, которое имеет горизонтальную полосу прокрутки.
WS_ICONIC Создает окно, которое первоначально свернуто. То же самое как стиль WS_MINIMIZE.
WS_MAXIMIZE Создает окно, которое первоначально развернуто.
WS_MAXIMIZEBOX Создает окно, которое имеет Кнопку развертывания окна.
WS_MINIMIZE Создает окно, которое первоначально свернуто. То же самое как стиль WS_ICONIC.
WS_MINIMIZEBOX Создает окно, которое имеет Кнопку свертывания окна.
WS_OVERLAPPED Создает окно которое имеет область заголовка и границу. То же самое как стиль WS_TILED.
WS_OVERLAPPEDWINDOW Создает окно со стилями WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX, и стилями WS_MAXIMIZEBOX. То же самое как стиль WS_TILEDWINDOW.
WS_POPUP Создает всплывающее окно. Этот стиль не может использоваться со стилем WS_CHILD.
WS_POPUPWINDOW Создает всплывающее окно с WS_BORDER, WS_POPUP, и стилями WS_SYSMENU. WS_CAPTION и стили WS_POPUPWINDOW должны быть объединены, чтобы сделать Системное меню видимым.
WS_SIZEBOX Создает окно, которое имеет границу установления размеров. То же самое как стиль WS_THICKFRAME.
WS_SYSMENU Создает окно, которое имеет Кнопку оконного меню в ее области заголовка. Стиль WS_CAPTION должен также быть определен.
WS_TABSTOP Определяет контрол, который может получить фокус клавиатуры, когда пользователь нажимает КЛАВИШУ ТАБУЛЯЦИИ. Нажим КЛАВИШИ ТАБУЛЯЦИИ изменяет фокус клавиатуры на следующий контрол со стилем WS_TABSTOP.
WS_THICKFRAME Создает окно, которое имеет границу установления размеров. То же самое как стиль WS_SIZEBOX.
WS_TILED Создает окно, которое имеет область заголовка и границу. То же самое как стиль WS_OVERLAPPED.
WS_TILEDWINDOW Создает окно со стилями WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX, и стилями WS_MAXIMIZEBOX. То же самое как стиль WS_OVERLAPPEDWINDOW.
WS_VISIBLE Создает окно, которое является первоначально видимым.
WS_VSCROLL Создает окно, которое имеет вертикальную полосу прокрутки.

Положение на экране и размер окна

Если мы хотим вручную указать размер окна и положение на экране, то необходимо задать значения X, Y, nWidth и nHeight, иначе можно использовать константу CW_USEDEFAULT, чтобы об этом позаботилась система.

hwndParent

Идентификатор родительского окна, задаётся при создании дочернего окна. Дочернее окно — это окно, которое отображается только в клиентской области родительского окна, при сворачивании родительского окна дочернее также сворачивается, имеет отдельной кнопки на панели задач.

Создание окна

Код:

   hWnd = CreateWindowEx(0, @"FBWindow", "Extended Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInst, 0)

Значок программы

Для того, чтобы окно имело значок, необходимо создать файл ресурсов программы (текстовый файл с расширением .RC) и поместить туда примерно такой текст:

500 ICON "ApplicationIcon.ico"

Число — это идентификатор значка, который нам потребуется (вы можете установить его самостоятельно), ApplicationIcon.ico — имя файла значка, который при компиляции должен находиться в одной папке с файлом ресурса.

Итак, при компиляции добавляем в командную строку ещё один параметр:

fbc -s gui WindowEx.bas WindowEx.rc

Получившийся файл будет отображаться в проводнике со значком, определённым в ресурсе программы, а если же значков в программу "зашито" несколько, то с самым первым.

Теперь нам необходимо присвоить зашитый в ресурсах значок нашему окну. Для этого существует два пути. Первый — явно указать его при создании класса окна (все окна, которые будут созданы от этого класса, будут иметь этот значок)

Код:

Dim wcEx As WNDCLASSEX
[ ... ]
wcEx.hIcon = LoadIcon(hInst, Cast(ZString Ptr, 500))
[ ... ]

Здесь мы указываем на наш идентификатор программы и значка.

Если же мы не задаём значок для класса окна, то его можно присвоить окну в дальнейшем, например, при инициализации, когда окно получает событие WM_CAREATE

Код:

Dim hIcon As HICON
' Загружаем значок
hIcon = LoadIcon(hInstance, Cast(ZString Ptr, 500))
' Посылаем окну сообщение о смене значка
SendMessage(hWin, WM_SETICON, NULL, Cast(LPARAM, hIcon))

Версия программы

Информация о версии программы (для отображения в проводнике в свойствах файла) тоже пишется в ресурсах программы, например, так:
Код:

1 VERSIONINFO
FILEVERSION 0,0,0,1 // Версия файла
PRODUCTVERSION 0,0,0,1 // Версия продукта
FILEOS 0x00000004 // Операционная система - NT_Windows32
FILETYPE 0x00000001 // Тип файла - приложение
BEGIN
  BLOCK "StringFileInfo"
  BEGIN
    BLOCK "FFFF04B0"
    BEGIN
      VALUE "FileVersion", "0.0.0.1\0"
      VALUE "ProductVersion", "0.0.0.1\0"
      VALUE "CompanyName", "Имя вашей компании\0"
      VALUE "FileDescription", "Описание файла\0"
      VALUE "InternalName", "Внутреннее имя\0"
      VALUE "LegalCopyright", "(c) Авторское право. All Rights Reserved.\0"
      VALUE "LegalTrademarks", "Торговая марка\0"
      VALUE "OriginalFilename", "Оригинальное имя файла\0"
      VALUE "ProductName", "Продукт\0"
      VALUE "CustomValue", "Дополнительное значение\0"
    END
  END
  BLOCK "VarFileInfo"
  BEGIN
    VALUE "Translation", 0xFFFF, 0x04B0 // Кодировка - Unicode
  END
END

Обратите внимание на идентификатор блока VERSIONINFO (1, вы можете задать его другим), и что все строки заканчиваются сочетанием "\0", что в переводе на FreeBASIC означает строки типа ZString (в Win32 используются именно они).

В следующих разделах мы познакомимся с созданием окон с предопределёнными классами — BUTTON, COMBOBOX, LISTBOX, EDIT, LISTBOX, SCROLLBAR и STATIC.

Скачать полный код примера можно отсюда
http://narod.ru/disk/3098426000/WindowEx.zip.html
avatar
Замабувараев

Сообщения : 99
Дата регистрации : 2008-08-20
Возраст : 33
Откуда : Красноярск

Посмотреть профиль http://www.freebasic.su

Вернуться к началу Перейти вниз

Re: Платформа Win32 - Создание расширенных окон

Сообщение  Eric-S в Вс Окт 12, 2008 2:47 am

Вау! Круто! Спасибо!
Теперь понятно, почему ты так долго подбирался.
Чтобы писать про listbox и другие элементы, как я понимаю нужно использовать именно расширенные окна.
Я кажеться, начал догадываться, почему у меня не получалось с обычными.

И ещё, мне кажеться, что в самом начале, нужно написать, рекламку расширенных окон, чем они лучше обычных и почему ими нужно пользоваться.
Конечно об этом можно будет догадаться прочитав всю главу, но с вступлением, думаю будет ещё понятнее.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Предыдущая тема Следующая тема Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения