7. Вывод информации в окно. Механизм перерисовки окна. Понятие области обновления окна. Операции с областью обновления окна



страница3/21
Дата28.11.2016
Размер2.21 Mb.
Просмотров5935
Скачиваний1
1   2   3   4   5   6   7   8   9   ...   21

Символические ссылки реестра

Специальный тип раздела, известный как символические ссылки реестра, позволяет диспетчеру конфигурации связывать разделы с целю организации реестра. Символическая ссылка является разделом, перенаправляющим диспетчер конфигурации на другой раздел. Таким образом, раздел HKLM\SAM является символической ссылкой на раздел в корне куста SAM. Символические ссылки создаются путем указания функции RegCreateKey или функции RegCreateKeyEx параметра REG_CREATE_LINK. Внутри диспетчер конфигурации создаст параметр REG_LINK, называемый SymbolicLinkValue, который будет содержать путь к целевому разделу. Поскольку этот параметр относится к типу REG_LINK, а не к типу REG_SZ, он не будет виден в Regedit, но тем не менее он будет частью куста реестра, хранящегося на диске.


Структура куста

Диспетчер конфигурации логически делит куст на распределяемые единицы, называемые блоками, способом, похожим на то, как файловая система делит диск на кластеры. По определению, размер блока реестра составляет 4096 байт (4 Кб). Когда куст расширяется за счет новых данных, он всегда расширяется за счет увеличения количества блоков. Первый блок куста называется базовым блоком. Базовый блок включает в себя глобальную информацию о кусте, в которую входят:

сигнатура regf, которая идентифицирует файл как куст;

‰‰ - обновляемые последовательные номера;



  • отметка времени, показывающая, когда в последний раз в отношении куста

  • применялась операция записи1;

  • информация о ремонте или восстановлении реестра, производимом Winload;

  • номер версии формата куста;

  • контрольная сумма;

  • внутр. файловое имя файла куста (\Device\HarddiskVolume1\WINDOWS\SYSTEM32\CONFIG\SAM).

Windows упорядочивает данные реестра, которые куст хранит в контейнерах, называемых ячейками. В ячейке может храниться раздел, параметр, дескриптор безопасности, список подразделов или список параметров раздела. Четырехбайтовый символьный тег в начале данных ячейки описывает тип данных в виде сигнатуры.


Тип данных

Тип структуры

Описание

Ячейка раздела

CM_KEY_NODE

Ячейка, содержащая раздел реестра, которая также называется узлом раздела (key node). В ячейке раздела содержатся:

• сигнатура (kn для раздела, kl для узла ссылки);

• отметка времени самого последнего обновления

раздела;


• индекс ячейки, в которой содержится родительский

раздел данного раздела;

• индекс ячейки списка подразделов,

идентифицирующего подразделы данного раздела;

• индекс ячейки дескриптора безопасности данного

раздела;


• индекс ячейки строки, определяющей имя класса

данного раздела;

• имя раздела (например, CurrentControlSet).

В ней также хранится кэшированная информация,

например количество подразделов данного раздела.


Ячейка параметра

CM_KEY_VALUE

Ячейка, содержащая информацию о параметре раздела. Эта ячейка включает сигнатуру (kv), тип параметра (например, REG_ DWORD или REG_BINARY) и имя параметра (например, Boot-Execute). Ячейка параметра содержит также индекс той ячейки, в которой содержатся данные параметра

Ячейка списка подразделов

CM_KEY_INDEX

Ячейка, состоящая из списка индексов ячеек разделов, представляющих собой подразделы общего родительского раздела

Ячейка списка параметров

CM_KEY_INDEX

Ячейка, состоящая из списка индексов ячеек параметров, представляющих собой параметры общего родительского раздел

Ячейка

дескриптора

безопасности


CM_KEY_

SECURITY


Ячейка, содержащая дескриптор безопасности. Ячейки дескрипторов безопасности включают сигнатуру (ks), помещаемую в заголовок ячейки, и счетчик ссылок, в который записывается количество узлов раздела, совместно использующих дескриптор безопасности. Ячейки дескриптора безопасности могут совместно использоваться несколькими ячейками раздела

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

Когда система добавляет ячейки в куст и удаляет их оттуда, куст может содержать пустые приемники, перемежающиеся активными приемниками (схоже с фрагментацией диска). Когда приемник становится пустым, диспетчер конфигурации присоединяет к пустому приемнику любые примыкающие пустые приемники для формирования как можно более крупного и непрерывного пустого приемника. Диспетчер конфигурации также присоединяет друг к другу примыкающие удаленные ячейки для формирования более крупных свободных ячеек.

Ссылки, образующие структуру куста, называются индексами ячеек. Индекс ячейки является смещением ячейки в файле куста за вычетом размера базового блока. Таким образом, индекс ячейки похож на указатель из одной ячейки на другую ячейку, который диспетчер конфигурации интерпретирует относительно начала куста.

В том, чем отличаются друг от друга ячейки и приемники, нетрудно запутаться. Поэтому, чтобы разобраться в различиях, давайте посмотрим на пример плана простого куста реестра. Приводимый в качестве примера на рис. 4.3 файл куста реестра содержит базовый блок и два приемника. Первый приемник пустой, а второй приемник содержит несколько ячеек. Логически, у куста имеются только два раздела: Root и его подраздел Sub Key. У раздела Root имеются два параметра, Val 1 и Val 2. Ячейка списка подразделов определяет местонахождение подраздела, подчиненного разделу Root, а ячейка списка параметров определяет местонахождение параметров раздела Root. Пустые места во втором приемнике являются пустыми ячейками. На рис. 4.3 не показаны ячейки безопасности для двух разделов, которые присутствовали бы в кусте. Для оптимизации поисков параметров и подразделов диспетчер конфигурации сортирует ячейки списка подразделов в алфавитном порядке.


Отображение ячеек

Если кусты не растут, диспетчер конфигурации может выполнить всю свою работу по управлению реестром в той версии куста, которая содержится в памяти, как будто куст является файлом. Благодаря индексу ячейки диспетчер конфигурации может вычислить местонахождение ячейки в памяти путем простого прибавления индекса ячейки, который является смещением в файле куста, к базе образа куста в памяти. В самом начале загрузки системы именно этим и занимается Winload с кустом SYSTEM: Winload считывает весь куст SYSTEM в память в качестве куста, доступного только для чтения, и прибавляет индексы ячеек к базе образа куста в памяти для определения местонахождения ячеек. Кусты разрастаются по мере добавления новых разделов и параметров, стало быть, система должна выделять пулы выгружаемой памяти (не обязательно непрерывной) для хранения новых приемников, содержащих добавленные разделы и параметры.


Диспетчер конфигурации использует двухуровневую схему (рис. 4.4), в которой в качестве ввода берется индекс ячейки (то есть смещение в файле куста), а возвращается в качестве вывода как адрес в памяти того блока, который занят индексом ячейки, так и адрес в памяти того блока, который занят ячейкой. Следует помнить, что приемник может содержать один или несколько блоков и что кусты прирастают количеством приемников, поэтому Windows всегда представляет приемник в виде непрерывной области памяти. Поэтому все блоки внутри приемника оказываются внутри одного и того же представления диспетчера кэша.

Для реализации отображения диспетчер конфигурации логически делит индекс ячейки на два поля, точно так же, как диспетчер памяти делит на поля виртуальный адрес. Windows интерпретирует первое поле индекса ячейки, как индекс в каталоге отображения ячеек, принадлежащем кусту. Каталог отображения ячеек содержит 1024 записи, каждая из которых ссылается на таблицу отображения ячеек, состоящую из 512 записей отображений. Запись в этой таблице отображения ячеек определяется вторым полем в индексе ячейки. Эта запись определяет адреса приемника и блока памяти ячейки. Не все приемники обязательно проецируются на память, и если при поиске ячейки выдается адрес 0, диспетчер конфигурации отображает приемник в памяти, убирая, если нужно, отображение другого приемника в обслуживаемом этим диспетчером LRU-списке отображения.


Средства редактирования: regedit.exe, reg.exe.

regedit.exe – редактор реестра (в виде проводника).

reg.exe - редактирования системного реестра из командной строки.

Одна из многих возможностей реестра – это возможность задать автозапуск программ при старте ОС. Можно сделать автозапуск как для одного пользователя, так и для всех.



В реестре Windows 7 автозагрузка представлена в нескольких ветвях:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run] ‐ программы, запускаемые при входе в систему.

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce] ‐ программы, запускаемые только один раз при входе пользователя в систему. После этого ключи программ автоматически удаляются из данного раздела реестра. Программы, которые запускаются в этом разделе, запускаются для всех пользователей в системе.

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run] ‐ программы, которые запускаются при входе текущего пользователя в систему

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce] ‐ программы, которые запускаются только один раз при входе текущего пользователя в систему. После этого ключи программ автоматически удаляются из данного раздела реестра.

Например, чтобы автоматически запускать Блокнот при входе текущего пользователя, открываем Редактор реестра (regedit.exe), переходим в раздел [HKEY_CURRENT_USER\Software\Microsoft\Windows

\CurrentVersion\Run] и добавляем ключ: "NOTEPAD.EXE"="C:\WINDOWS\System32\notepad.exe"

Использование групповой политики для автозапуска

Откройте оснастку "Групповая политика" (gpedit.msc), перейдите на вкладку "Конфигурация компьютера ‐ Административные шаблоны ‐ Система". В правой части оснастки перейдите на пункт «Вход в систему».

По умолчанию эта политика не задана, но вы можете добавить туда программу: включаем политику, нажимаем кнопку "Показать ‐ Добавить", указываем путь к программе, при этом если запускаемая программа находится в папке ..WINDOWS\System32\ то можно указать только название программы, иначе придется указать полный путь к программе.

Функции для работы с реестром

RegCloseKey Закрывает описатель ключа реестра.

RegCreateKeyEx Создает заданный ключ реестра.

RegDeleteKey/RegDeleteKeyEx Удаляет подключ и его значения

RegEnumKeyEx Перечисляет ключи заданного открытого ключа реестра.

RegEnumValue Перечисляет значения ключей заданного открытого ключа реестра.

RegGetValue Получает тип данных и сами данные значение ключа реестра.

RegLoadKey Создает подключ в HKEY_USERS или HKEY_LOCAL_MACHINE и сохраняет заданную информацию из файла в этот подключ.

RegOpenKeyEx Открывает заданный ключ реестра

RegSaveKey/RegSaveKeyEx Сохраняет заданный ключ и его подключи в файл.

4. Понятие окна в ОС Windows. Основные элементы окна. Понятие родительского и дочернего окна. Структура программы с событийным управлением. Минимальная программа для ОС Windows с окном на экране. Создание и отображение окна.
Понятие окна в ОС Windows.

Окно — графически выделенная часть экрана, принадлежащая какому-либо объекту, с которым работает пользователь. Окна могут иметь как произвольные, так и фиксированные (это характерно для диалоговых окон) размеры. Окно может занимать весь экран или только его часть. При этом на экране может быть одновременно выведено несколько (любое количество) окон.



Основные элементы окна. Понятие родительского и дочернего окна.

Каждое окно, создаваемое приложением, имеет родительское окно. При этом само оно по отношению к родительскому является дочерним. Какое окно является "основателем рода", т. е. родительским для всех остальных окон? Окна всех приложений располагаются в окне, представляющем собой поверхность рабочего стола Workplace Shell . Это окно, которое называется Desktop Window , создается автоматически при запуске операционной системы. Однако окно Desktop Window само по себе является дочерним по отношению к другому окну - окну Object Window . Это окно не отображается и используется системой Presentation Manager для собственных нужд.

Родительское окно может иметь несколько дочерних окон, которые при этом называются окнами-братьями (или окнами-сестрами). Обратное неверно, т. е. у каждого дочернего окна может быть только одно родительское окно. Каждое дочернее окно, в свою очередь, может выступать в роли родительского окна, создавая свои дочерние окна.

Важной особенностью дочерних окон является то, что они всегда располагаются внутри своего родительского окна. Если пользователь попытается переместить дочернее окно за пределы родительского (например, при помощи мыши), будет нарисована только часть дочернего окна.

В том случае, когда в одном родительском окне создано несколько дочерних окон, они могут перекрывать друг друга.

Если пользователь перемещает родительское окно, то дочернее окно будет перемещаться вместе с ним.

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

При уничтожении родительского окна все его дочерние окна уничтожаются автоматически.
Структура программы с событийным управлением.

Минимальная программа для ОС Windows с окном на экране.

#include

int APIENTRY WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)

{

WNDCLASSEX wcex; HWND hWnd; MSG msg;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style = CS_DBLCLKS;

wcex.lpfnWndProc = WndProc;

wcex.cbClsExtra = 0;

wcex.cbWndExtra = 0;

wcex.hInstance = hInstance;

wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);

wcex.hCursor = LoadCursor(NULL, IDC_ARROW);

wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

wcex.lpszMenuName = NULL;

wcex.lpszClassName = "HelloWorldClass";

wcex.hIconSm = wcex.hIcon;

...

RegisterClassEx(&wcex);

hWnd = CreateWindow("HelloWorldClass", "Hello, World!",

WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0,

CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

ShowWindow(hWnd, nCmdShow);

UpdateWindow(hWnd);

while (GetMessage(&msg, NULL, 0, 0)) {

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return (int)msg.wParam;

}

...

LRESULT CALLBACK WndProc(HWND hWnd, UINT message,

WPARAM wParam, LPARAM lParam)

{

switch (message) {

case WM_LBUTTONDBLCLK:

MessageBox(hWnd, "Hello, World!", "Message", MB_OK);

break;

case WM_DESTROY:

PostQuitMessage(0);

break;

default:

return DefWindowProc(hWnd, message, wParam, lParam);

}

return 0;

}

Создание и отображение окна.

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

Функция CreateWindow:

HWND CreateWindow(

LPCTSTR lpClassName,

LPCTSTR lpWindowName,

DWORD dwStyle,

int x,

int y,

int nWidth,

int nHeight,

HWND hWndParent,

HMENU hMenu,

HANDLE hInstance,

LPVOID lpParam

);

1. lpClassName — Имя класса

2. lpWindowName — Имя окна

3. dwStyle — Описывает стиль создаваемого окна

4. x — Позиция по горизонтали верхнего левого угла окна в экранной системе координат.

5. y — Позиция по вертикали верхнего левого угла окна в экранной системе координат.

6. nWidth — Ширина окна в пикселях.

7. nHeight — Высота окна в пикселях.

8. hWndParent — Дескриптор окна, которое является родителем данного.

9. hMenu — Дескриптор меню.

10. hInstance — Дескриптор экземпляра приложения с которым связано данное окно.

11. lpParam — указатель на определяемые пользователем данные.

Функция CreateWindow возвращает дескриптор созданного ею окна (значение типа HWND). Если создать окно не удалось, значение дескриптора равно нулю.

Отображение окна:

Сперва мы вызываем функцию ShowWindow и передаем ей дескриптор только что созданного окна, чтобы Windows знала, какое окно должно быть показано. Мы также передаем число, определяющее в каком виде будет показано окно (обычным, свернутым, развернутым на весь экран и т.д.). После отображения окна мы должны обновить его. Это делает функция UpdateWindow; она получает один аргумент, являющийся дескриптором обновляемого окна.

ShowWindow(MainWindowHandle, show);

UpdateWindow(MainWindowHandle)

5. Структура программы с событийным управлением. Структура события – оконного сообщения Windows. Очередь сообщений. Цикл приема и обработки сообщений. Процедура обработки сообщений. Процедуры посылки сообщений. Синхронные и асинхронные сообщения
Оконные сообщения

В этой главе я расскажу, как работает подсистема передачи сообщений в Windows применительно к приложениям с графическим пользовательским интерфейсом. Разрабатывая подсистему управления окнами в Windows 2000 и Windows 98, Microsoft преследовала две основные цели:

1) обратная совместимость с 16-разрядной Windows, облегчающая перенос существующих 16-разрядных приложений;

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

К сожалению, эти цели прямо противоречат друг другу. В 16-разрядной Windows передача сообщения в окно всегда осуществляется синхронно: отправитель не может продолжить работу, пока окно не обработает полученное сообщение. Обычно так и нужно. Но, если на обработку сообщения потребуется длительное время или если окно «зависнет», выполнение отправителя просто прекратится. А значит, такая операционная система не вправе претендовать на устойчивость к сбоям. Это противоречие было серьезным вызовом для команды разработчиков из Microsoft. В итоге было выбрано компромиссное решение, отвечающее двум вышеупомянутым целям.

Для начала рассмотрим некоторые базовые принципы. Один процесс в Windows может создать до 10 000 User-объектов различных типов — значков, курсоров, оконных классов, меню, таблиц клавиш-акселераторов и т. д. Когда поток из какого-либо процесса вызывает функцию, создающую один из этих объектов, последний переходит во владение процесса. Поэтому, если процесс завершается, не уничтожив данный объект явным образом, операционная система делает это за него. Однако два User-объекта (окна и ловушки) принадлежат только создавшему их потоку. И вновь, если поток создает окно или устанавливает ловушку, а потом завершается, операционная система автоматически уничтожает окно или удаляет ловушку. Этот принцип принадлежности окон и ловушек создавшему их потоку оказывает существенное влияние на механизм функционирования окон: поток, создавший окно, должен обрабатывать все его сообщения. Поясню данный принцип на примере. Допустим, поток создал окно, а затем прекратил работу. Тогда его окно уже не получит сообщение WM_DESTROY или WM_NCDESTROY, потому что поток уже завершился и обрабатывать сообщения, посылаемые этому окну, больше некому.

Это также означает, что каждому потоку, создавшему хотя бы одно окно, система выделяет очередь сообщений, используемую для их диспетчеризации. Чтобы окно в конечном счете получило эти сообщения, поток должен иметь собственный цикл выборки сообщений.
Очередь сообщений потока

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

Создавая какой-либо поток, система предполагает, что он не будет иметь отношения к поддержке пользовательского интерфейса. Это позволяет уменьшить объем выделяемых ему системных ресурсов. Но, как только поток обратится к той или иной GUI-функции (например, для проверки очереди сообщений или создания окна), система автоматически выделит ему дополнительные ресурсы, необходимые для выполнения задач, связанных с пользовательским интерфейсом. А если конкретнее, то система создает структуру THREADINFO и сопоставляет ее с этим потоком. Элементы этой структуры используются, чтобы обмануть поток — заставить его считать, будто он выполняется в среде, принадлежащей только ему. THREADINFO — это внутренняя (недокументированная) структура, идентифицирующая очередь асинхронных сообщений потока (posted-message queue), очередь синхронных сообщений потока (sent-message queue), очередь ответных сообщений (reply-message queue), очередь виртуального ввода (virtualized input queue) и флаги пробуждения (wake flags); она также включает ряд других переменных-членов, характеризующих локальное состояние ввода для данного потока. На рис. 26-1 показаны структуры THREADINFO, сопоставленные с тремя потоками.

Структура THREADINFO — фундамент всей подсистемы передачи сообщений; читая следующие разделы, время от времени посматривайте на эту иллюстрацию.


Поделитесь с Вашими друзьями:
1   2   3   4   5   6   7   8   9   ...   21


База данных защищена авторским правом ©nethash.ru 2019
обратиться к администрации

войти | регистрация
    Главная страница


загрузить материал