Block varfileinfo что это
Программировать интерфейс – это конечно здорово, если разрабатываемое приложение будет иметь мало элементов управления (такое, как например keygen!). В противном случае может оказаться так, что львиную долю кода мы напишем для создания интерфейса (расположение контролов, их выравнивание и т.д.), и лишь несколько строк будут составлять функциональное наполнение программы. В таких случаях целесообразнее использовать ресурсы, о чем и пойдет речь в данной статье. Использование ресурсов несколько увеличит размер исполняемого файла, но я не думаю что сейчас это столь критично, чтобы отказываться от использования ресурсов в пользу программирования интерфейса. Начнем с простого, создадим форму с несколькими элементами управления, и далее, по ходу дела будем ее дорабатывать и наделять функционалом. Как работать с ресурсами в Delphi я уже писал и повторяться не буду, так что кому интересно, читаем статью «Хранение ресурсов внутри исполняемого файла и их использование». С чего же начать? Конечно же, с создания ресурса, из которого мы и получим окно. Разберем структуру этого ресурса. Объявляется окно с идентификатором DLG_WINDOW, указываются размеры и положение окна, заголовок, параметры шрифта и стили. Внутри фигурных скобок перечисляются элементы управления, после ключевого слова CONTROL указываем необходимые параметры: текст, идентификатор, класс, стили, позицию и размеры, при необходимости указывается расширенный стиль. Ничего сложного нет, суть очень напоминает программный способ создания элементов управления, разница лишь в синтаксисе. Вместо фигурных скобок допускается использование ключевых слов BEGIN и END. В качестве идентификаторов не обязательно использовать константы, но мне это представляется более удобным, так что приведенный выше код мог бы выглядеть и так: Половина дела сделана, осталось создать приложение на основе этого ресурса, для чего компилируем его, переходим в Delphi и пишем: Сложно представить себе что то проще, диалоговое окно со всеми элементами управления создается одной стройкой! Все что нужно – указать идентификатор окна и назначить ему оконную процедуру, в которой пока что обрабатывается только сообщение о закрытии программы. Сейчас программе явно не хватает индивидуальности, которую ей могла бы придать иконка. Для этого создадим еще один файл ресурсов (вообще то можно все писать и в одном файле, но в примере я буду делать отдельные файлы, полагая что это упростит освоение материала). Сначала идет идентификатор ресурса, потом его тип, и в конце путь к файлу с иконкой. Кстати, иконка не обязательно должна быть одна (в данном примере их пять), можете предоставить пользователю возможность самому выбрать ту, которая ему больше понравится. Назначить иконку окну можно в любой момент, но все же лучше сделать это в момент запуска программы, для чего нужно обработать сообщение WM_INITDIALOG: Смотрим дальше, и вот незадача, на компе уже давно тусуется Windows 7 (ну или в худшем случае XP), а контролы выглядят как в Windows 2000. Кто ж не такую программу позарится, надо срочно исправлять. Но как? Да проще некуда, добавим в ресурсы манифест, содержание которого будет примерно следующим: Создаем файл ресурса: Суть содержимого файла ресурса должна быть уже понятна – идентификатор ресурса, его тип и путь к файлу манифеста. Компилируем, и просто подключаем к программе. Разговор об интерфейсе закончим созданием главного меню. Не будем делать его навороченным, нам ведь главное понять принцип. Описание меню смеет иерархическую структуру, в которой пункты главного меню обозначаются ключевым словом POPUP, а элементы выпадающего меню ключевым словом MENUITEM. Давайте подключим это меню к программе. Теперь поговорим о функционале, и о том, как работать с элементами пользовательского интерфейса. Нажатие на кнопку или пункт системного меню генерирует сообщение WM_COMMAND, в младшем слове параметра wParam которого содержится идентификатор элемента управления, инициировавшего событие. Попробуем наделить функционалом пункт меню “Выход”. Вы заметили, что рядом с пунктом меню «Выход» указан акселератор (или, говоря иначе, комбинация горячих клавиш)? Однако пока это всего лишь часть заголовка меню, надо это исправить. К сожалению, хотя горячие клавиши и можно поместить в ресурсы, подключить их у меня не получилось, а дело здесь в следующем. Если бы мы создавали форму не из ресурса, мы сами бы написали для нее цикл обработки сообщений. А так как нажатие «горячих» клавиш не нужно транслировать в символьные сообщения, цикл выглядел бы следующим образом: Создавая форму из ресурса мы назначаем ей оконную процедуру, сообщения в которую приходят уже транслированные, и в этом вся загвоздка. Однако ситуация не безвыходная, решение существует, и заключается оно в обработке сообщения WM_MENUCHAR. Получив это сообщение мы проверяем, какие клавиши нажаты в данный момент на клавиатуре, и если нажата нужная нам комбинация, выполняем соответствующее действие. На практике это выглядит так: Для того чтобы диалоговая форма начала получать сообщение WM_MENUCHAR, меню должно быть раскрыто, или хотя бы активировано, что достигается нажатием клавиши Alt. Теперь переходим к работе с контролами. Для получения и изменения текста нужно воспользоваться функциями GetDlgItemText и SetDlgItemText. Попробуем получать текст из элемента “Edit” по мере его заполнения и выводить в элемент “Static”. Так как я делаю пример на Delphi XE, то привожу строку к типу PWideChar, если же у вас версия Delphi ниже 2009, то приводить (здесь и в дальнейшем) следует к типу PChar. В приведенном примере мы объединяем введенный пользователем текст со строкой, а почему бы эту строку не поместить в ресурс? Приветственное сообщение будем показывать после нажатия на кнопку, код в этом случае будет несколько отличаться от приведенного выше. Если при обработке сообщения от “Edit” мы получали Handle элемента управления в параметре lParam, то теперь нам нжно получить его самостоятельно, для чего нужно воспользоваться функцией GetDlgItem. Строку загружаем из ресурса, используя функцию LoadStr, передав в нее идентификатор строки. И вот, когда программа уже готова, не плохо бы включить в ресурсы краткую информацию о ней е ее разработчике. Первым идет идентификатор информационного ресурса, это значение должно равняться 1. Далее следует информация о версии файла, его типе и операционной системе, для которой он предназначен (за подробностями отправляемся в MSDN (ищите по словосочетанию “VERSIONINFO Resource”) – найдете что то вроде этого, этого или этого). Далее следует блок “StringFileInfo”, который, в свою очередь, включает в себя блоки с информацией о файле. Количество блоков может быть произвольным, в зависимости от того, на какой рынок ориентирована ваша программа. В данном примере присутствует два блока – первый для русифицированных операционных систем, второй – для англоязычных. Имя блока формируется следующим образом: язык + кодовая страница: 041904E3 = 0x0419 (1049, Russian) + 0x04E3 (1251, Cyrillic) Далее, в блоке VarFileInfo, мы указываем, поддержку каких языков мы включили в ресурс. Теперь, если мы откроем свойства файла, мы увидим нашу информацию. Правда не всю, Windows покажет нам только те предопределенные значения, о которых она знает, а именно: Comments, CompanyName, FileDescription, FileVersion, InternalName, LegalCopyright, LegalTrademarks, OriginalFilename, PrivateBuild, ProductName, ProductVersion, SpecialBuild. Научим нашу программу показывать эту информацию. Пара слов о неприятных моментах. Компилируя ресурс утилитой brcc32.exe, входящей в состов BDS 2006 и выше (а возможно и BDS 2005, не проверял), русские символы будут отображаться абракадаброй. В интернете можно найти информацию о том, что в библиотеки rw32core.dll, идущей в комплекте с этими студиями, напрочь отсутствует VERSIONINFO. Звучит это несколько странно, если учесть тот факт, что сама студия без каких либо проблем вставляет в файл этот ресурс, но все же поверим на слово. Решения тут 2 – либо все писать на английском, либо заменить эту библиотеку аналогичной из D6 или D7 (другие не проверял). Ну, вот и все, рассказал практически все, что хотел, осталось сказать несколько слов о создании файлов с ресурсами. Писать все это в ручную – дело неблагодарное, отнимающее значительную часть времени, мало чем отличающееся от ручного программирования интерфейса. Процесс создания файлов с ресурсами можно и нужно автоматизировать, и я хочу порекомендовать вам программу “Resource editor”. Благодаря визуальному редактору проектировать интерфейс так же просто, как и в Delphi, да и создание ресурсов других типов не потребует от вас много сил и времени, так что пользуйтесь, не стесняйтесь! И не забудьте в настройках на вкладке «Behaviour» установить флажок «Borland compatible». А я на этом прощаюсь, удачи в программировании. Creating a Proper Version Information ResourceOne of our biggest pet peeves is finding a driver installed on a system, written by a 3 rd party that either doesn’t have a Version-Information resource in the image at all, or has one that is blatantly incorrect. The most common Version-Information resource error that we see is a 3 rd party containing a Microsoft copyright string (!) as a result of not overriding the default values supplied in the WDK. This article will discuss what a Version-Information is and how to create one for your driver. What is a Version-Information ResourceA Version-Information (VI) resource is a type of Resource Compiler (RC) object that provides information about the executable image that contains it. The information within the VI resource typically includes the executable image’s version number, intended operating system, and original file name. This information is viewed in Windows Explorer as shown in Figure 1, and also may be retrieved programmatically using the Windows Version Information functions. For readers unfamiliar with an RC file, it is a resource-definition script file (in text format) that describes the resources used by your executable object. For applications, these objects can be cursors, icons, bitmaps, dialog boxes, fonts, version-information, strings, or user-definable objects. For drivers, only the version-information is typically specified in the RC file. For the purposes of defining a VI resource for a driver, the definitions needed to compile the RC file can be satisfied by including winver.h. The RC file is compiled with the resource compiler, which generates a compiled resource (.res) file that the linker links into your driver’s executable image. See below for a typical example of an OSR created RC file that defines a VERSIONINFO resource: As you can see above the VI resource contains a number of elements that describe the executable with which it is associated. Let us discuss the VERSIONINFO resource in the next section. One thing that should be mentioned here: This RC file in (again, above) that OSR typically uses does not follow the typical format from the examples that you find in a WDK. That’s because the OSR resource file is “fully specified” – it’s not built using a set of Microsoft-supplied macros. Contrast the OSR file above with the typical RC file from the WDK shown below: Notice that the OSR created RC does not include “ntverp.h” or “common.ver”. Why? We don’t include these files because they contain Microsoft-specific defaults that will be used if you fail to properly set all the fields in your driver’s VI resource. These defaults are appropriate for Microsoft developers, but probably not the best choice for others. Driver writers who use a WDK RC file as a template for their RC file are the ones who typically end up with a VI resource that contains things like the default Microsoft copyright because they forgot to specify a copyright of their own. Now we’re not saying that using the WDK-provided method is bad. All we are trying doing is warning you of the consequences of using that method. Namely, if you’re not careful when you use the WDK-provided method, your RC file you may end up with information in your VI resource that you did not intend to be there. So, given that, let’s talk about what is in a VERSIONINFO resource. VI resourceThe VI resource that we mention above is defined in the RC file using the VERSIONINFO statement. The VI resource itself can be defined using one of two following formats: Let’s describe the fields used in each of these formats. versionIDThis field is the version resource identifier and must be 1. As an alternative to specifying 1 in this field, devs often specify VS_VERSION_INFO.The value for VS_VERSION_INFO is defined in the include file “verrsrc.h”, but is referenced in the include file “winver.h” (typically referenced in an RC file). fixed-infoThe fixed-info section of a VI resource contains version information such as the file version and intended operating system. It is composed of the following statements: The reader should note that any field listed above that is not specified in your RC file, will default to 0. In addition, if you reexamine Figure 1 you will notice that none of the information from the fixed-info section is visible via Explorer. You should keep in mind that the information contained in the VI is really only there for informational purposes, the real information about the image is contained within the Portable Executable header (PE Header) of the image itself. block-statementThe “block-statement” section defines one or more version-information blocks. The version-information blocks can contain multiple StringFileInfo blocks and accompanying VarFileInfo blocks as defined below. VarFileInfo BlockVarFileInfo defines a Variable File information block. This block describes the language and character set used to encode the strings contained within the associated StringFileInfo block discussed in the next section. The VarFileInfo block is defined as follows: With this “Translation” statement you can specify multiple langId and charsetID pairs which will show the user that that are multiple translations for the VI in the image. So as an example let’s assume that in our RC file we wanted to have a StringFileInfo information block in U.S. English using the Unicode character set. Our VarFileInfo block would be defined as seen below: So now that we’ve indicated the language and character set to be used for our information, we need to create a StringFileInfo block in U.S. English using Unicode with the appropriate information. Let us see how it is done in the next section. StringFileInfo BlockStringFileInfo defines an information block that contains a number of string-name parameters that describe the contained image in human-readable format. This block describes the language and character set used to encode the strings contained within the block. The StringFileInfo block is defined as follows: It is worth noting that you can add your own string-name fields to this block. Unfortunately you will not be able to see them via Explorer. To see them you would have to write a program that uses the Win32 Version Information functions to retrieve them. In addition if you don’t specify a pre-defined name, its information will not be shown via Explorer. So those are the fields that are contained within a StringFileInfo block. Now, as we showed in Figure 4 we defined a VarFileInfo block that indicated that our StringFileInfo block is in U.S. English using the Unicode character set. Therefore we have to have a StringFileInfo block with a lang-charset that corresponds to what we specified in the VarFileInfo block. Since we put 0x409 (U.S. English) and 1200 (Unicode) then the setting for our lang-charset in our StringFileInfo block will be “040904b0”, where 0409 corresponds to our specified language and 04b0 corresponds to our specified character set (1200 == 0x04b0). Simple! See below for the StringFileInfo block for U.S English in Unicode. So as you can see, the VERSIONINFO block can be used to thoroughly describe the image that is embedded in and this allows the user and the developer to quickly identify the software installed on the users’ machine. Note: RC files and VERSIONINFO resources can be internationalized. All you need to do is create additional VERSIONINFO resources in your RC file in the languages you require. Now that we’ve discussed what fields are in a VERSIONINFO resource, let’s talk about creating one for our image. Creating your own VI ResourceAs mentioned earlier, an RC file is just a text script file. While it can be created with a resource editor, for example within Visual Studio, it can just as well be created by hand using your favorite text editor. Instead of starting from scratch and writing your RC file from scratch, the easiest thing to do is find an existing RC file with the required information and replace the fields that are important to your driver. We would suggest you copy the information shown earlier in the simple resource file into your WDK project’s RC file and edit it appropriately. Now when we say edit it appropriately, what we mean is that you modify the following fields with settings that are appropriate for your image (you should note that if you want your Version Information to be visible in multiple languages you are going to be required to have a StringFileInfo/VarFileInfo section for each supported language): FILEVERSION Once you have completed that you need to add the name of the “.RC” file that you created to your sources file. So in an example “Sources” file, for OSR’s “nothing” driver shown below, you can see how we added “nothingver.rc” to the “SOURCES” line. When we use the WDK “build” utility to compile our nothing driver, it will see the “nothingver.rc” file on the “SOURCES” line in our “SOURCES” file and automatically compile it and link it to the “nothing.sys” file that it builds. After you have successfully built the driver, make sure that you use Explorer to examine the information that you specified to ensure that all the information you want the user to see is there. In addition you want to make sure that there is no information present that you did not intend to be there. Remember that sometimes (depending on how the VI got created) Microsoft supplied information can sneak in, so you have to make sure that you’re supplying all the correct fields. SummaryWith the information contained within this article you can now create and add a comprehensive RC file to your driver without the risk of getting unexpected values in the various fields. This information will allow your users and support people to immediately know what version of your product and image is being run. Now that is being resourceful! VarFileInfo structureRepresents the organization of data in a file-version resource. It contains version information not dependent on a particular language and code page combination. SyntaxMemberswLength Type: WORD The length, in bytes, of the entire VarFileInfo block, including all structures indicated by the Children member. wValueLength Type: WORD This member is always equal to zero. wType Type: WORD The type of data in the version resource. This member is 1 if the version resource contains text data and 0 if the version resource contains binary data. szKey Type: WCHAR The Unicode string L»VarFileInfo». Padding Type: WORD As many zero words as necessary to align the Children member on a 32-bit boundary. Children Typically contains a list of languages that the application or DLL supports. RemarksThis structure is not a true C-language structure because it contains variable-length members. This structure was created solely to depict the organization of data in a version resource and does not appear in any of the header files shipped with the Windows Software Development Kit (SDK). The Children member of the VS_VERSIONINFO structure may contain zero or one VarFileInfo structures. VarFileInfo BLOCK statementDefines a variable information block. ParametersOne of the language identifiers specified in the Remarks section. One of the character-set identifiers specified in the Remarks section. RemarksMore than one identifier pair can be given, but each pair must be separated from the preceding pair with a comma. The langID parameter specifies one of the following language codes.
The charsetID parameter specifies one of the following character-set identifiers: Варфилеинфо BLOCK, инструкцияОпределяет блок сведений о переменной. ПараметрыОдин из идентификаторов языка, указанных в разделе «Примечания». Один из идентификаторов наборов символов, указанных в разделе «Примечания». RemarksМожно указать более одной пары идентификаторов, но каждую пару следует отделять от предшествующей пары запятыми. Параметр langID указывает один из следующих кодов языка.
Параметр чарсетид задает один из следующих идентификаторов наборов символов: |


Figure 1 – Version Resources as Viewed from Explorer


