Как является Win32 событийно-ориентированным программированием, реализованным под капотом?

Генерация коррелированных равномерных случайных величин с гауссовой копулой

rho = .75; % Desired target correlation
N = 1000;  % Number of samples
Z = mvnrnd([0 0],[1 rho; rho 1], N);
U = normcdf(Z);  % Correlated U(0,1) random variables

scatterhist(U(:,1),U(:,2),'Direction','out') % Visualize (change `rho` to see impact)

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

3 Scatter plots with marginal histograms. First plot has target correlation of 0.25; second plot has target correlation of 0.75, third plot has target correlation of -0.95.

Это может быть очень полезно для быстрой генерации коррелированных распределений с использованием метода обратного преобразования (аналитически или численно). Оба варианта использования показаны ниже.

Аналитический подход

lambda = 2; alpha = 2; beta = 3;
rho = -.35; N = 1000;
Z = mvnrnd([0 0],[1 rho; rho 1], N);
U = normcdf(Z);
X = (-1/lambda)*log(U(:,1)); % Inverse Transform for Exponential
Y = beta*(-log(U(:,2))).^(1/alpha); % Inverse Transform for Weibull
corr(X,Y)
scatterhist(X,Y,'Direction','out')  

Численный подход

% Parameters
alpha = 6.7; lambda = 3;
mu = 0.1; sigma = 0.5;
rho = 0.75; N = 1000;
% Make distributions
pd_X = makedist('Gamma',alpha,lambda);
pd_Y = makedist('Lognormal',mu,sigma);
Z = mvnrnd([0 0],[1 rho; rho 1], N);
U = normcdf(Z);
% Use Inverse Transform for marginal distributions (numerically)
X = icdf(pd_X,U(:,1)); % Inverse CDF for X
Y = icdf(pd_Y,U(:,2)); % Inverse CDF for Y
corr(X,Y)
scatterhist(X,Y,'Direction','out')  

Ссылки: [118 ]
Обратное преобразование
Копулы

Гауссова связка:
Росс, Шелдон. (2013). Моделирование . Academic Press, Сан-Диего, Калифорния, 5-е издание. 103--105.

Модифицированный связанный ответ из здесь .

11
задан Shog9 21 June 2009 в 21:58
поделиться

5 ответов

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

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

Перевод сообщения используется для создания сообщений, которые не являются «настоящими» событиями. Например, сообщение WM_CONTEXTMENU «переводится» либо щелчком правой кнопкой мыши, либо клавишей контекстного меню, либо shift-F10. WM_CHAR переводится из сообщений WM_KEYDOWN. И, конечно, многие другие сообщения «переводятся» таким образом.

Сообщение отправляется в каждое окно, которое должно его получить. ОС решает в зависимости от типа сообщения, должно ли окно получать это сообщение или нет. Большинство сообщений ожидает система, т. Е. Сообщение не будет опубликовано в другом окне, пока оно не будет обработано окном. Это имеет большое влияние на широковещательные сообщения: если при обработке этого сообщения одно окно не возвращается, очередь блокируется , а другие окна больше не будут получать сообщение.

6
ответ дан 3 December 2019 в 06:47
поделиться

Это зависит от того, как ваше сообщение отправлено и как оно обрабатывается.

Когда вы вызываете SendMessage, если цель Окно принадлежит текущему потоку, вызов обходит очередь сообщений для окна, и оконный менеджер напрямую вызывает windowproc в целевом окне. Если целевое окно принадлежит другому потоку, диспетчер окон эффективно вызывает PostMessage и перекачивает оконные сообщения до тех пор, пока целевое окно не вернется из процедуры окна.

Когда вы вызываете PostMessage, оконный менеджер маршализирует параметры сообщения и вставляет соответствующий объект. в очередь сообщений для целевого окна. При следующем вызове GetMessage сообщение удаляется из очереди сообщений.

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

Как указал Стефан, TranslateMessage просто переводит клавиши ускорения - например, он преобразует последовательности ключей в сообщения WM_COMMAND.

6
ответ дан 3 December 2019 в 06:47
поделиться

Чтобы решить последний подзапрос, отправленное сообщение отправится в WindowProc после того, как был пропущен через все хуки (WH_CALLWNDPROC)

1
ответ дан 3 December 2019 в 06:47
поделиться

Не совсем положительно по этому поводу, но мое лучшее предположение говорит:

  1. Очередь - это системный объект, к которому вы обращаетесь Win32 API вызывает. Он вообще не находится в адресном пространстве вашего процесса. Таким образом, обработчики прерываний могут получить к нему доступ (возможно, через HAL (Уровень аппаратной абстракции) ядра).

  2. В Win16 этот вызов взял различные части большого сообщения и объединил их в одно целое. Поэтому TranslateMessage добавит WM_KEYPRESS, когда найдет соответствующую последовательность WM_KEYDOWN WM_KEYUP. Это также превратило бы различные сообщения о нажатиях кнопок в сообщения с двойным щелчком, основываясь на внутренних настройках и временных отметках сообщений. Делает ли это все еще в Win32, я не знаю.

  3. DispatchMessage, вероятно, там, где обрабатываются перехватчики сообщений Windows. Так что, если в вашем окне есть крюк, он либо вызывается здесь, либо когда вызывается GetMessage. Я не уверен. Помимо этого, DispatchMessage просто ищет адрес WndProc, связанный с окном, и вызывает его. Больше ничего не нужно делать.

Надеюсь, это поможет.

1
ответ дан 3 December 2019 в 06:47
поделиться

Различные типы обработчиков прерываний ОС должны помещать сообщения в указанную «очередь сообщений», но где в адресном пространстве процесса находится эта очередь? Как это отображается в коде обработчика прерывания?

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

Отправленные сообщения помещаются непосредственно в поток. очередь для целевого окна.

Отправляемые сообщения обычно обрабатываются напрямую (в обход очереди).

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

В книгах Джеффри Рихтера есть много (все?) Кровавых подробностей. Моя версия старая (Advanced Windows). Текущая версия, похоже, называется Windows через C / C ++ .

ОС делает ОЧЕНЬ много работы, чтобы поток сообщений казался вызывающему рациональным (и относительно простым).

Что значит что значит «перевести» сообщение? Что на самом деле делает вызов TranslateMessage ()?

Он отслеживает виртуальные ключевые сообщения и, когда он распознает комбинацию нажатия / нажатия клавиши, он добавляет символьные сообщения. Если вы не вызовете TranslateMessage , вы не будете получать символьные сообщения, такие как WM_CHAR.

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

После отправки с помощью DispatchMessage (), во всех местах сообщение проходит, прежде чем попасть в мой WndProc (то есть что делает ОС с ним)?

DispatchMessage передает сообщение в WndProc для целевого окна. Попутно некоторые ловушки могут получить шанс увидеть сообщение (и, возможно, помешать ему).

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

После отправки с помощью DispatchMessage (), во всех местах сообщение проходит, прежде чем попасть в мой WndProc (то есть что делает ОС с ним)?

DispatchMessage передает сообщение в WndProc для целевого окна. Попутно некоторые ловушки могут получить шанс увидеть сообщение (и, возможно, помешать ему).

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

После отправки с помощью DispatchMessage (), во всех местах сообщение проходит, прежде чем попасть в мой WndProc (то есть что делает ОС с ним)?

DispatchMessage передает сообщение в WndProc для целевого окна. Попутно некоторые ловушки могут получить шанс увидеть сообщение (и, возможно, помешать ему).

что с ним делает ОС)?

DispatchMessage передает сообщение WndProc для целевого окна. Попутно некоторые ловушки могут получить шанс увидеть сообщение (и, возможно, помешать ему).

что с ним делает ОС)?

DispatchMessage передает сообщение WndProc для целевого окна. Попутно некоторые ловушки могут получить шанс увидеть сообщение (и, возможно, помешать ему).

4
ответ дан 3 December 2019 в 06:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: