Немного об использовании ресурсов (часть вторая)

В этой статье поговорим о строках, помещаемых в ресурсы. При создании программ, я думаю надо задумываться о том, что ваша программа может понравиться не только русскоязычному населению. Использование строк в ресурсах, значительно упрощает локализацию программ. Для таких целей специально создали множество программ для редактирования строк и др. ( Resource Hacker, Restorator  и пр.) . То есть вашу программу, независимо от вас, могут перевести на любой язык, если вы встроите такую возможность.

Для помещения строк в ресурсы нужно создать таблицу с помощью ключевого слова STRINGTABLE. И далее в блоке BEGIN ... END каждой строке обозначить свой уникальный идентификатор. То есть файл ресурсов с парочкой строк будет выглядеть примерно так:

STRINGTABLE
BEGIN
    1   "Первая строка"
    2   "Вторая строка"
END

А получение этих строк в коде возможно с помощью функции LoadString:

LoadString(_
    As HINSTANCE hInstance,_ 'хендл модуля, в ресурсах которого размещены строки
    As UINT uID,_ 'идентификатор ресурса строки  
    As LPTSTR lpBuffer,_ ' буфер куда будет помещена строка
    As Integer nBufferMax _ ' размер буфера
    )

Примерный код для получения двух строк из ресурсов:

#INCLUDE "windows.bi"
Dim As ZString*20 szBuf(1)
LoadString(0,1,szBuf(0),20)
LoadString(0,2,szBuf(1),20)
MessageBox(0, szBuf(0),szBuf(1),0)

Начальные основы по компиляции с ресурсными файлами описаны в первой статье. Поэтому я не буду повторяться.

Строки меню так же хорошо размещать в ресурсах. При том можно использовать строки из таблицы , когда меню создается динамически с помощью CreateMenu, CreatePopupMenu ... Я предпочитаю этот способ создания.

Но часто меню создают статически. То есть и пункты меню и его строки описываются в файле ресурсов. В результате при создании окна (в регистрации класса окна), нужно будет указать идентификатор меню.

Само меню в ресурсах описывается с помощью синтаксиса языка СИ.

Сначала задается идентификатор и тип ресурса (пример):

10000 MENU

Далее в блоке BEGIN... END описываются пункты меню. Пункты задаются с помощью ключевого слова POPUP , а подпункты с помощью MENUITEM (пример):

10000 MENU
BEGIN
  POPUP "Файл"
  BEGIN
    MENUITEM "Новый файл",1000
    MENUITEM "Открыть",1001
    MENUITEM SEPARATOR
    MENUITEM "Выход",1002
  END
END

Как видно подпункты также записываются в блоке BEGIN...END. Сначала идет ключевое слово MENUITEM , далее строка для подпункта и в конце идентификатор подпункта.

Код с использованием меню может быть таким:

#INCLUDE "windows.bi"
Dim msg As MSG 'структурированная переменная MSG
Dim As WNDCLASSEX wc 'структурированная переменная WNDCLASSEX
Dim As String NameClass="MyClass" ' переменная имени класса
Dim As HINSTANCE Hinst=GetModuleHandle(0) ' хендл модуля
' функция класса
Function wndproc(hwnd As HWND, msg As Uinteger,_
    wparam As WPARAM, lparam As LPARAM) As Integer
    Select Case msg
        Case WM_DESTROY
            PostQuitMessage(0)
        Case WM_COMMAND
            If Loword(wparam) = 1000 Then
                MessageBox(0,"Новый файл","",0)
            Elseif Loword(wparam) = 1001 Then
                MessageBox(0,"Открыть","",0)
            Elseif Loword(wparam) = 1002 Then
                PostQuitMessage(0)
            Endif
    End Select
    Return DefWindowProc(hwnd,msg,wparam,lparam)
End Function
' Заполнение структуры WNDCLASSEX
With wc
    .cbSize=SizeOf(WNDCLASSEX)
    .style=CS_HREDRAW Or CS_VREDRAW
    .lpfnWndProc=@WndProc
    .hInstance=Hinst
    .lpszMenuName = Cast(LPSTR,10000)
    .hIcon=LoadIcon(0,IDI_QUESTION)
    .hCursor=LoadCursor(0,IDC_HELP)
    .hbrBackground=Cast(HBRUSH,COLOR_WINDOWFRAME)
    .lpszClassName=StrPtr(NameClass)
    .hIconSm=.hIcon
End With
' Регистрация класса окна
If RegisterClassEx(@wc)=0 Then
    Print "Register error, press any key"
    Sleep
    End
Endif
'Создание окна
CreateWindowEx(0,NameClass,"Окно с меню",_
WS_VISIBLE Or WS_OVERLAPPEDWINDOW,100,100,300,300,0,0,Hinst,0)
' Цикл сообщений
While GetMessage(@msg,0,0,0)
    TranslateMessage(@msg)
    DispatchMessage(@msg)
Wend