<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-264654303037912405</id><updated>2012-01-28T18:38:23.667+02:00</updated><category term='Visual Studio'/><category term='interop'/><category term='mood'/><category term='installation'/><category term='documentation'/><category term='bugs'/><category term='books'/><category term='boost'/><category term='UI'/><category term='films'/><category term='assembler'/><category term='wow'/><category term='Windows'/><category term='MSI'/><category term='goal'/><category term='CQG'/><category term='RIA'/><category term='library'/><category term='threading'/><category term='ASP.NET'/><category term='Visual Studio 2008'/><category term='RSS'/><category term='ActiveX'/><category term='printer'/><category term='tips'/><category term='11g'/><category term='ORM'/><category term='Flex Builder'/><category term='torrent'/><category term='WTF'/><category term='Flex'/><category term='standarts'/><category term='.NET 4'/><category term='Diamond 2'/><category term='parking'/><category term='TR1'/><category term='review'/><category term='hotfix'/><category term='WinAPI'/><category term='WinForms'/><category term='cars'/><category term='x64'/><category term='.NET 3.5'/><category term='WL500gP'/><category term='humor'/><category term='scheme'/><category term='SCM'/><category term='LINQ'/><category term='choice'/><category term='XSLT'/><category term='MySQL'/><category term='CSS'/><category term='WWW'/><category term='Starcraft 2'/><category term='Add-in'/><category term='Nokia'/><category term='security'/><category term='Web Services'/><category term='Under the Hood'/><category term='UX'/><category term='Common Controls'/><category term='SQL Server 2005'/><category term='SP1'/><category term='XML'/><category term='Tiesto'/><category term='announce'/><category term='MSBuild'/><category term='philosophy'/><category term='samples'/><category term='SDK'/><category term='style'/><category term='Orcas'/><category term='Unicode'/><category term='ATL'/><category term='BB5'/><category term='iPhone'/><category term='color'/><category term='Windows Installer'/><category term='Eclipse'/><category term='HTML'/><category term='GPS'/><category term='Qt'/><category term='design'/><category term='mp3'/><category term='network'/><category term='subtitles'/><category term='release'/><category term='skeleton'/><category term='hardfucking'/><category term='gotcha'/><category term='Entity Framework'/><category term='stupid'/><category term='.NET'/><category term='Unix'/><category term='Must Have'/><category term='Nero'/><category term='Vista'/><category term='Windows Mobile'/><category term='CLR'/><category term='Microsoft'/><category term='restricted'/><category term='magic'/><category term='debugger'/><category term='Windows 2000'/><category term='Visual Studio 2005'/><category term='MSXML'/><category term='quote'/><category term='ActionScript'/><category term='Holy Wars'/><category term='x86'/><category term='event'/><category term='DataBinding'/><category term='wsdl'/><category term='preferences'/><category term='Oracle'/><category term='Visual Studio 2010'/><category term='WinHTTP'/><category term='C++'/><category term='RedHat'/><category term='SUN'/><category term='analysis'/><category term='best practice'/><category term='WiX'/><category term='BITS Manager'/><category term='internet'/><category term='iGo'/><category term='source control'/><category term='code'/><category term='programming languages'/><category term='Android'/><category term='driving'/><category term='Unit Testing'/><category term='hardware'/><category term='Windows 7'/><category term='DCOM'/><category term='Microsoft Office'/><category term='IDEA'/><category term='tool'/><category term='translation'/><category term='patterns'/><category term='Deplhi'/><category term='games'/><category term='music'/><category term='COM'/><category term='Java'/><category term='RHEL5'/><category term='Liquid'/><category term='quiz'/><category term='Symbian'/><category term='Google'/><category term='freaks'/><category term='Install Shield'/><category term='life'/><category term='C#'/><category term='SOAP'/><category term='6630'/><category term='ReSharper'/><category term='blogger'/><category term='Avid'/><category term='MFC'/><category term='WCF'/><category term='words'/><category term='BITS'/><category term='Linux'/><category term='WWS'/><category term='history'/><category term='MXML'/><category term='срана'/><category term='C++ Builder'/><category term='Silverlight'/><category term='problem'/><title type='text'>Hungry Mind</title><subtitle type='html'>Blog about everything in IT - C#, Java, C++, .NET, Windows, WinAPI, ...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default?start-index=101&amp;max-results=100'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>287</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-6303022259640326624</id><published>2012-01-28T18:38:00.001+02:00</published><updated>2012-01-28T18:38:23.670+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='films'/><title type='text'>Spartacus: Vengeance</title><content type='html'>&lt;p&gt;
Начался новый сезон Spartacus: Vengeance.
&lt;/p&gt;
&lt;p&gt;
Был в IMAX-е на Underworld: Awakening. Отличный экшн с кучей кровищи, поломанных костей, расчлененки и прочих радостей кинематографа. И минимум соплей.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-6303022259640326624?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/6303022259640326624/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2012/01/spartacus-vengeance.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/6303022259640326624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/6303022259640326624'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2012/01/spartacus-vengeance.html' title='Spartacus: Vengeance'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-1752766887347690189</id><published>2012-01-25T18:55:00.001+02:00</published><updated>2012-01-25T18:56:10.544+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Why not Android</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;i&gt;и не беспокоит потеря поддержки актуальности системы всего через полтора года с начала продаж?&lt;br /&gt;&lt;br /&gt;Не,
 ну, если смотреть как быстро производители клепают свои поделки, то 
через полтора года нужно думать не об поддержке системы, а о покупке 
нового девайса.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Это вселенная андроида живет по таким 
законам. Там объявляют о выходе 4-й версии и в тот же день, 8-мью часами
 позже Моторола представляет "новейший" телефон-бритву на устаревшей 
версии. Очень показательный косяк всей системы. Причем никто и никак 
точно не может сказать, когда и кто и получит ли и какое это будет 
обновление, даже нативные нексусы.&lt;br /&gt;
&lt;br /&gt;
В соседней вселенной можно 
взять телефон в 2009-м году и получить обновление операционки нового 
поколения в декабре 2011-го. День-в-день с современнейшими моделями.&lt;br /&gt;
Причем
 user-experience (нет такого термина в русском, извините) очень 
тщательно сохраняется между моделями, юзеры заметно довольней чем у 
конкурентов.&lt;br /&gt;
&lt;br /&gt;
Ковровое бомбометание моделями по всем существующим и
 выдуманным рыночным нишам говорит только об неуверенности 
производителя. Об отсутствии видения.&lt;br /&gt;
&lt;br /&gt;
Зоопарк планшетов с шагом 
экрана в 1 дюйм - ярчайший пример. Фееричное растрачивание усилий по 
всем направлениям, а в результате - вышел киндл файр и слил весь зоопарк
 с первого места из догоняющих.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://forum.ixbt.com/topic.cgi?id=16:42549-125#3872" target="_blank"&gt;http://forum.ixbt.com/topic.cgi?id=16:42549-125#3872&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-1752766887347690189?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/1752766887347690189/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2012/01/why-not-android.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/1752766887347690189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/1752766887347690189'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2012/01/why-not-android.html' title='Why not Android'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-36408098342605502</id><published>2012-01-23T14:10:00.002+02:00</published><updated>2012-01-23T17:33:06.501+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='driving'/><title type='text'>Тупой писюн за рулем</title><content type='html'>&lt;iframe width="420" height="315" src="http://www.youtube.com/embed/b0Q5olVbUWs" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-36408098342605502?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/36408098342605502/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2012/01/stupid-dick-driver.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/36408098342605502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/36408098342605502'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2012/01/stupid-dick-driver.html' title='Тупой писюн за рулем'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/b0Q5olVbUWs/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-3626972308348606121</id><published>2012-01-18T17:39:00.001+02:00</published><updated>2012-01-23T14:10:55.254+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>What a Shame</title><content type='html'>&lt;iframe width="560" height="315" src="http://www.youtube.com/embed/fKINcqollZ4" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-3626972308348606121?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/3626972308348606121/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2012/01/what-shame.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/3626972308348606121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/3626972308348606121'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2012/01/what-shame.html' title='What a Shame'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/fKINcqollZ4/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-19799916643534461</id><published>2012-01-13T13:54:00.000+02:00</published><updated>2012-01-23T14:11:02.573+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='driving'/><title type='text'>Эталон колхозника за рулем</title><content type='html'>&lt;p&gt;
Эталон тупого колхозника на дороге. Целый букет - просачивание рядом для выезда за стоп линию, наезд на пешеходный переход и проезд перекрестка на красный. Чтобы... поехать на мойку.
&lt;/p&gt;
&lt;p&gt;
За рулем, видимо, водила, депутата внутри не было.
&lt;/p&gt;
&lt;iframe width="420" height="315" src="http://www.youtube.com/embed/u8G1ra0TRzA" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-19799916643534461?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/19799916643534461/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2012/01/blog-post.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/19799916643534461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/19799916643534461'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2012/01/blog-post.html' title='Эталон колхозника за рулем'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/u8G1ra0TRzA/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-2055938036160817275</id><published>2012-01-12T00:39:00.001+02:00</published><updated>2012-01-12T00:41:25.310+02:00</updated><title type='text'>Android developers</title><content type='html'>&lt;p&gt;
&lt;a href="http://2.bp.blogspot.com/_GTM_W5mVPTU/S9icFaUOpKI/AAAAAAAAACQ/Sp_fYopwsfw/s1600/IMG_0089.jpg" imageanchor="1" style="float:left; margin-right:1em"&gt;&lt;img border="0" height="500" width="328" src="http://2.bp.blogspot.com/_GTM_W5mVPTU/S9icFaUOpKI/AAAAAAAAACQ/Sp_fYopwsfw/s1600/IMG_0089.jpg" /&gt;&lt;/a&gt;
Diana Hackborn, единственная мать ОС Android. Теперь от этой ОС и телефонов на ее основе я буду держаться еще дальше. Гы.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-2055938036160817275?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/2055938036160817275/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2012/01/android-developers.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/2055938036160817275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/2055938036160817275'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2012/01/android-developers.html' title='Android developers'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_GTM_W5mVPTU/S9icFaUOpKI/AAAAAAAAACQ/Sp_fYopwsfw/s72-c/IMG_0089.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-2955929067431696746</id><published>2012-01-08T20:55:00.000+02:00</published><updated>2012-01-09T21:52:03.599+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><title type='text'>DOTA 2 beta key</title><content type='html'>&lt;p&gt;
Получил от &lt;q&gt;добрых людей&lt;/q&gt; DOTA 2 beta gift. Блеять, оторваться не могу.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.team-dignitas.net/uploads/article_images/official-dota2-blog1-1024x640.jpg" alt="DOTA 2"/&gt;
&lt;/p&gt;
&lt;p&gt;
Интерфейс у игры конченный, сервера нестабильны. Бета - она и есть бета. Но кайфу от командной резни полные трусы.
&lt;/p&gt;
&lt;p class="warning"&gt;Если у вас есть приглашения - с удовольствием передам их товарищам, которые любят и хотят играть в DOTA 2. Не хватает 3 человека в команду. Напишите, пожалуйста, если хотите поделиться.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-2955929067431696746?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/2955929067431696746/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2012/01/dota-2-beta-key.html#comment-form' title='Комментарии: 7'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/2955929067431696746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/2955929067431696746'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2012/01/dota-2-beta-key.html' title='DOTA 2 beta key'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-3443113602708052003</id><published>2011-12-31T19:33:00.002+02:00</published><updated>2012-01-03T13:19:53.767+02:00</updated><title type='text'>Эталон ТП за рулем</title><content type='html'>&lt;iframe width="420" height="315" src="http://www.youtube.com/embed/DM_yHXBdlts" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;
Поворот с ул. Набежено-Крещатицкой на ул Нижний Вал.
Всегда найдутся уроды, поворачивающие со второго ряда направо, где только прямо; уроды, которые проезжают перекресток и сдают задом чтобы стать перед всеми. А иногда и вот такое хуйло попадается, но чаще мужского пола. А здесь - эталон ТП за рулем. ТП - тупая пизда, за рулем женщина.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-3443113602708052003?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/3443113602708052003/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/12/woman-driving.html#comment-form' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/3443113602708052003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/3443113602708052003'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/12/woman-driving.html' title='Эталон ТП за рулем'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/DM_yHXBdlts/default.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-8625227461312710642</id><published>2011-12-23T13:16:00.000+02:00</published><updated>2011-12-23T13:27:02.280+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='problem'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Cruel InvokeRequired</title><content type='html'>&lt;p&gt;Всем давно известно, что в WinForms начиная с версии 2 появилась защита от многопоточного использования элементов управления. При попытке выполнить опасные операции библиотечный код выбрасывает &lt;code&gt;InvalidOperationException&lt;/code&gt; с текстом &lt;q&gt;Cross-thread operation not valid: Control 'xxx' accessed from a thread other than the thread it was created on&lt;/q&gt;. Дальше я объясню как выполняется эта проверка и о некоторых подводных камнях этого механизма.&lt;/p&gt;
&lt;p&gt;Свойство &lt;code&gt;Handle&lt;/code&gt; класса &lt;code&gt;Control&lt;/code&gt; имеет нетривиальную логику, часть которой содержит проверку на безопасность использования даного кода из другого потока:&lt;/p&gt;
&lt;pre&gt;
[
Browsable(false), 
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
DispId(NativeMethods.ActiveX.DISPID_HWND), 
SRDescription(SR.ControlHandleDescr) 
]
public IntPtr Handle { 
   get {
       if (checkForIllegalCrossThreadCalls &amp;amp;&amp;amp;
           !inCrossThreadSafeCall &amp;amp;&amp;amp;
           InvokeRequired) { 
           throw new InvalidOperationException(SR.GetString(SR.IllegalCrossThreadCall,
                                                            Name)); 
       } 

       if (!IsHandleCreated) 
       {
           CreateHandle();
       }

       return HandleInternal;
   } 
}
&lt;/pre&gt;
&lt;p&gt;Основная часть условия - свойство &lt;code&gt;InvokeRequired&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;
[
Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced), 
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
SRDescription(SR.ControlInvokeRequiredDescr)
] 
public bool InvokeRequired {
   get {

       using (new MultithreadSafeCallScope()) 
       {
           HandleRef hwnd; 
           if (IsHandleCreated) { 
               hwnd = new HandleRef(this, Handle);
           } 
           else {
               Control marshalingControl = FindMarshalingControl();

               if (!marshalingControl.IsHandleCreated) { 
                   return false;
               } 

               hwnd = new HandleRef(marshalingControl, marshalingControl.Handle);
           } 

           int pid;
           int hwndThread = SafeNativeMethods.GetWindowThreadProcessId(hwnd, out pid);
           int currentThread = SafeNativeMethods.GetCurrentThreadId(); 
           return(hwndThread != currentThread);
       } 
   } 
}
&lt;/pre&gt;
&lt;p&gt;Что здесь происходит? В локальную переменную &lt;code&gt;hwnd&lt;/code&gt; записывается дескриптор текущего окна (если оно создано), иначе - дескриптор первого созданного окна в иерархии child-parent (метод &lt;code&gt;FindMarshalingControl&lt;/code&gt;). Если ни один родитель не создан (нет дескриптора), метод &lt;code&gt;InvokeRequired&lt;/code&gt; возвращает &lt;code&gt;false&lt;/code&gt;. Далее используются функции &lt;code&gt;GetWindowThreadProcessId&lt;/code&gt; и &lt;code&gt;GetCurrentThreadId&lt;/code&gt; чтобы определить принадлежность созданного окна текущему потому. ОС Windows запоминает идентификаторы потоков в контексте которых произошли вызовы &lt;code&gt;CreateWindow&lt;/code&gt; для создания окон.&lt;/p&gt;
&lt;p&gt;Из этого можно сделать следующие выводы:&lt;/p&gt;
&lt;ol&gt;
   &lt;li&gt;WinForms не изобретает колесо - лишь использует доступную информация для выполнения нужных проверок&lt;/li&gt;
   &lt;li&gt;Если окно не было создано (нет дексриптора), а также не были созданы все его родители - &lt;code&gt;InvokeRequired&lt;/code&gt; возвращает &lt;code&gt;false&lt;/code&gt;, что весьма логично - объект CLR может быть создан в любом потоке, но получит привязку к конкретному потоку лишь после создания&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;В результате следующий код содержит потенциальную проблему:&lt;/p&gt;
&lt;pre&gt;
void handleNotificationFromOtherThread(...)
{
   if (someControl.InvokeRequired)
   {
      someControl.BeginInvoke(handleNotificationFromOtherThread, ...);
   }
   // Thread safe code here
   ...
}
&lt;/pre&gt;
&lt;p&gt;Если уведомления прийдут до того, как хоть одно окно из иерархии будет создано, &lt;code&gt;InvokeRequired&lt;/code&gt; вернет &lt;code&gt;false&lt;/code&gt; и код выполнится в неправильном контексте. И здесь даже механизм защиты WinForms не поможет. В результате получаем многопоточный доступ к ресурсам без блокировок.&lt;/p&gt;
&lt;p&gt;Как избежать подобного сценария? Создавая окно специально для целей синхронизации доступа:&lt;/p&gt;
&lt;pre&gt;
Control sync = new Control();
sync.CreateControl();
_syncInvoke = (ISynchronizeInvoke)sync;

...

void handleNotificationFromOtherThread(...)
{
   if (_syncInvoke.InvokeRequired)
   {
      _syncInvoke.BeginInvoke(handleNotificationFromOtherThread, ...);
   }
   // Thread safe code here
   ...
}
&lt;/pre&gt;
&lt;p&gt;Код выше принудительно создает окно в нужном контексте и использует его интерфейс &lt;code&gt;ISynchronizeInvoke&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Но есть и более изящное решение - сохранить &lt;code&gt;System.Threading.SynchronizationContext.Current&lt;/code&gt; как член класса и использовать для синхронизации. WinForms сам создаст по одному окну специально для маршаллинга вызовов в каждом потоке. Этот подход лучше всего подходит для простых сценариев, когда нужно отмаршаллить все выховы в один главный поток.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-8625227461312710642?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/8625227461312710642/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/12/cruel-invokerequired.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/8625227461312710642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/8625227461312710642'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/12/cruel-invokerequired.html' title='Cruel InvokeRequired'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-3600270360122007696</id><published>2011-12-20T23:28:00.000+02:00</published><updated>2011-12-23T13:27:11.924+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><title type='text'>iPhone 4s jailbreak</title><content type='html'>&lt;p&gt;
Пока что я жмотюсь платить по 10+$ за нужные мне программы. Это не долбанные игрушки по 99 центов, а необходимые в жизни вещи типа Wallet и iGO. Ну, просто психологически не готов вывалить даже 10 у.е. за программу, которая просто хранит текст в шифрованном виде. А 100 у.е. за навигацию - перебор. Но мучения мои скоро закончатся, грядет 
&lt;a href="http://appadvice.com/appnn/2011/12/jailbreak-only-ios-hacker-pod2g-figures-out-a5-jailbreak-enigma"&gt;A5 jailbreak&lt;/a&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-3600270360122007696?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/3600270360122007696/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/12/iphone-4s-jailbreak.html#comment-form' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/3600270360122007696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/3600270360122007696'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/12/iphone-4s-jailbreak.html' title='iPhone 4s jailbreak'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-13014533060288343</id><published>2011-12-20T20:49:00.001+02:00</published><updated>2011-12-23T13:27:18.028+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><title type='text'>iPhone 4s case</title><content type='html'>&lt;p&gt;
Решил, что чехол для роботизированной сучки нужен. Прошлый телефон изрядно пострадал из-за моего обращения с ним. Бросал в рюкзак, карманы, где ключи лежали и прочая чепуха. В результате на экране куча царапин и все такое. Бамперы и прочие подобные вещи считаю жлобством, поэтому выбор пал на мешочек (pouch по-буржуйски). Выбор пал на &lt;a href="www.senacases.com/apple/iphone-4s-cases/sarach-ultraslim"&gt;Sena SARACH ULTRASLIM White-Red&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.senacases.com/apple/iphone-4s-cases/sarach-ultraslim/whitered.jpg"/&gt;
&lt;/p&gt;
&lt;p&gt;
Стоимость &lt;q&gt;там&lt;/q&gt; - 40$. У нас - 60$. Заказал, привезли. На радостях отдал деньги курьеру, а лишь после заметил, что швы с одной стороны сильно перетянуты и в результате два слоя кожи не состыкованы, а слеплены. Ну, похоже на результат удара двух тектонических плит.
&lt;/p&gt;
&lt;p&gt;
На упаковке - made in Turkey. Сука, как это все надоело! Кусок кожи стоимостью 60 у.е. сшит тяп-ляп в Турции. Вовремя позвонил курьеру и забрал обратно деньги, заебали.
&lt;/p&gt;
&lt;p&gt;
Вывод? Просить чтобы привозили несколько экземпляров на выбор или не покупать вещи по маразматичным ценам.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-13014533060288343?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/13014533060288343/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/12/iphone-4s-case.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/13014533060288343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/13014533060288343'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/12/iphone-4s-case.html' title='iPhone 4s case'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-2921661924411878387</id><published>2011-12-18T16:46:00.001+02:00</published><updated>2011-12-23T13:27:25.949+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><title type='text'>iPhone 4s and SIRI</title><content type='html'>&lt;p&gt;
Получил я наконец свой iPhone 4S White 32Gb. Первое впечатление - говно. Но после пары часов использования, подключения к iCould и пр. - я понял, что сделано для людей. Очень удобный телефон.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;На фотках белый выглядит гораздо лучше, чем в жизни. Черный на мой вкус смотрится более шикарно. Наверное из-за отражающего эффекта покрытия.&lt;/li&gt;
&lt;li&gt;SIRI требует подключение к интернету и жрет трафик. Падла отсылает сжатый звук на сервер Apple, где происходит его анализ и генерация результатов. Транслитерацию не поддерживает, поэтому контакты должны использовать английский алфавит. С СМС-ками та же проблема.&lt;/li&gt;
&lt;li&gt;После подключения симки происходило 2-3 пропадания сети Киевстар, что заставило злиться и спровоцировало поток матов. Симка то испорчена. Но после все образовалось. Не знаю почему. Возможно из-за отключения авто поиска сети и установки свежей прошивки. Перед этим я начитался о множестве проблем с пропаданием сети оператора Киевстар.&lt;/li&gt;
&lt;li&gt;Батарею не сжирает. За ночь простоя ушло 3%. Если не пользоваться активно (как задрот или жлоб в метро)- жить будет 3-4 дня, полагаю. Геолокационные сервисы включены ВСЕ.&lt;/li&gt;
&lt;li&gt;Камера понравилась. Хоть и сравнить не с чем, я никогда не пользовался телефоном как фотоаппаратом.&lt;/li&gt;
&lt;li&gt;Работает шустро, тормоза не замечены нигде.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-2921661924411878387?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/2921661924411878387/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/12/iphone-4s-and-siri.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/2921661924411878387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/2921661924411878387'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/12/iphone-4s-and-siri.html' title='iPhone 4s and SIRI'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-2397560251241693786</id><published>2011-12-07T23:33:00.001+02:00</published><updated>2011-12-07T23:33:55.379+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET 4'/><title type='text'>.NET Framework 4 Platform Update 2</title><content type='html'>&lt;p&gt;А вы в курсе, что появился уже .NET Framework 4 Platform Update 2? Многие, наверное, не знают даже, что уже полгода как у многих установлен .NET Framework 4 Platform Update 1.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/b/dotnet/archive/2011/10/27/update-4-0-2-for-the-microsoft-net-framework-4.aspx"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-2397560251241693786?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/2397560251241693786/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/12/net-framework-4-platform-update-2.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/2397560251241693786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/2397560251241693786'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/12/net-framework-4-platform-update-2.html' title='.NET Framework 4 Platform Update 2'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-2360998782481710655</id><published>2011-12-03T13:51:00.001+02:00</published><updated>2011-12-07T23:34:31.000+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>"Unsupported" C++ namespace names</title><content type='html'>&lt;p&gt;
Замечали такие вот интересные идентификаторы пространств имен: &lt;code&gt;Win32Hosts.dll!&amp;lt;CrtImplementationDetails&amp;gt;::LanguageSupport::Initialize()&lt;/code&gt;? А вот как это делается:
&lt;/p&gt;
&lt;pre class="code listing"&gt;
namespace __identifier("&amp;lt;CrtImplementationDetails&amp;gt;")
{
...
}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-2360998782481710655?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/2360998782481710655/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/12/unsupported-c-namespace-names.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/2360998782481710655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/2360998782481710655'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/12/unsupported-c-namespace-names.html' title='&quot;Unsupported&quot; C++ namespace names'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-9139403157886170246</id><published>2011-11-09T15:11:00.000+02:00</published><updated>2011-12-07T23:34:17.791+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET 4'/><title type='text'>Unable to step into .NET v4.0.30319 source</title><content type='html'>&lt;p&gt;У меня длительное время пункт меню &lt;em&gt;Go To Source Code&lt;/em&gt; недоступен, отлаживать исходный код .NET Framework невозможно. В окне Modules почти все сборки имеют Symbol Status = Symbols loaded. Проблема лишь в том, что pdb файлы маленького размера, а это значит, что информации об исходном коде в них нет. &lt;/p&gt;
&lt;p&gt;Ответ нашелся &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/refsourceserver/thread/c4d04b70-2723-44c3-841e-b302d36a87c0" target="_bank"&gt;в разделе Reference Source Server Discussion&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Решение состоит в использовании следующих версий сборок:&lt;/p&gt;
&lt;table&gt;
   &lt;thead&gt;
      &lt;tr&gt;
         &lt;th&gt;Name&lt;/th&gt;
         &lt;th&gt;Version&lt;/th&gt;
      &lt;/tr&gt;
   &lt;/thead&gt;
   &lt;tr&gt;
      &lt;td&gt;mscorlib.dll&lt;/td&gt;
      &lt;td&gt;4.0.30319.1 (RTMRel.030319-0100)&lt;/td&gt;
   &lt;/tr&gt;
   &lt;tr&gt;
      &lt;td&gt;PresentationFramework.dll&lt;/td&gt;
      &lt;td&gt;4.0.30319.1&lt;/td&gt;
   &lt;/tr&gt;
   &lt;tr&gt;
      &lt;td&gt;WindowsBase.dll&lt;/td&gt;
      &lt;td&gt;4.0.30319.1 built by: RTMRel&lt;/td&gt;
   &lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Поэтому нужен .NET Framework 4 RTM, без патчей, которые накатывает операционная система. Следующие версии сборок не имеют соответствий в базе pdb файлов хранилища Reference Source:&lt;/p&gt;
&lt;table&gt;
   &lt;thead&gt;
      &lt;tr&gt;
         &lt;th&gt;Name&lt;/th&gt;
         &lt;th&gt;Version&lt;/th&gt;
      &lt;/tr&gt;
   &lt;/thead&gt;
   &lt;tr&gt;
      &lt;td&gt;mscorlib.dll&lt;/td&gt;
      &lt;td&gt;4.0.30319.488 (RTMLDR.030319-4800)&lt;/td&gt;
   &lt;/tr&gt;
   &lt;tr&gt;
      &lt;td&gt;PresentationFramework.dll&lt;/td&gt;
      &lt;td&gt;4.0.30319.450&lt;/td&gt;
   &lt;/tr&gt;
   &lt;tr&gt;
      &lt;td&gt;WindowsBase.dll&lt;/td&gt;
      &lt;td&gt;4.0.30319.450 built by: RTMLDR&lt;/td&gt;
   &lt;/tr&gt;
&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-9139403157886170246?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/9139403157886170246/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/11/unable-to-step-into-net-v4030319-source.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/9139403157886170246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/9139403157886170246'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/11/unable-to-step-into-net-v4030319-source.html' title='Unable to step into .NET v4.0.30319 source'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-877628357807879196</id><published>2011-11-09T12:46:00.000+02:00</published><updated>2011-12-23T13:27:37.099+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><title type='text'>iPhone 4S around the world</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Китайцы наконец собрали мой &lt;i&gt;iPhone 4S 32Gb White&lt;/i&gt; и отдали в службу доставки. Теперь он отправится в Торонто, затем в Нью-Йорк, а уж после приедет в Киев :-).&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-kLqJAljY7Pk/TrpZlGwWO6I/AAAAAAAAAQ4/Tl5i59fCuAI/s1600/iPhone4SUPS.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="245" src="http://3.bp.blogspot.com/-kLqJAljY7Pk/TrpZlGwWO6I/AAAAAAAAAQ4/Tl5i59fCuAI/s320/iPhone4SUPS.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table cellspacing="0" cellpadding="0" border="0" class="dataTable"&gt;
    &lt;tbody&gt;&lt;tr&gt;
           &lt;th&gt;Location&lt;/th&gt;
           &lt;th&gt;Date&lt;/th&gt;
           &lt;th&gt;Local Time&lt;/th&gt;

           &lt;th class="full"&gt;Activity&lt;/th&gt;
             &lt;/tr&gt;
             
             

          
          &lt;tr class="odd"&gt;
             &lt;td class="nowrap"&gt;
             
               
                  Concord,
      

               
                ON,
               

               
                Canada
               
             
             &lt;/td&gt;


             
     &lt;td class="nowrap"&gt;
            
            11/14/2011
            
           &lt;/td&gt;

             
             &lt;td class="nowrap"&gt;
             
               18:45
             
     &lt;/td&gt;

             
             &lt;td&gt;Delivered
                
     
     
       
      
     

     
   
   
      
      
             &lt;/td&gt;
          &lt;/tr&gt;
          
             

          
          &lt;tr&gt;
             &lt;td class="nowrap"&gt;
             
               

               

               
             
             &lt;/td&gt;


             
     &lt;td class="nowrap"&gt;
            
            11/14/2011
            
           &lt;/td&gt;

             
             &lt;td class="nowrap"&gt;
             
               16:11
             
     &lt;/td&gt;

             
             &lt;td&gt;The customer was not available on the 1st attempt. A 2nd delivery attempt will be made
                
     
      
      
             &lt;/td&gt;

          &lt;/tr&gt;
          
             

          
          &lt;tr class="odd"&gt;
             &lt;td class="nowrap"&gt;
             
               

               

               
             
             &lt;/td&gt;


             
     &lt;td class="nowrap"&gt;
            
            11/14/2011
            
           &lt;/td&gt;

             
             &lt;td class="nowrap"&gt;

             
               7:55
             
     &lt;/td&gt;

             
             &lt;td&gt;Out for Delivery
                
     
      
      
             &lt;/td&gt;
          &lt;/tr&gt;
          
             

          
          &lt;tr&gt;
             &lt;td class="nowrap"&gt;
             
               

               

               
             
             &lt;/td&gt;


             
     &lt;td class="nowrap"&gt;
            
            11/14/2011
            
           &lt;/td&gt;

             
             &lt;td class="nowrap"&gt;
             
               5:49
             
     &lt;/td&gt;

             
             &lt;td&gt;Arrival Scan
                
     
      
      
             &lt;/td&gt;
          &lt;/tr&gt;

          
             

          
          &lt;tr class="odd"&gt;
             &lt;td class="nowrap"&gt;
             
               
                  Mount Hope,
      

               
                ON,
               

               
                Canada
               
             
             &lt;/td&gt;


             
     &lt;td class="nowrap"&gt;
            
            11/14/2011
            
           &lt;/td&gt;

             
             &lt;td class="nowrap"&gt;

             
               4:50
             
     &lt;/td&gt;

             
             &lt;td&gt;Departure Scan
                
     
      
      
             &lt;/td&gt;
          &lt;/tr&gt;
          
             

          
          &lt;tr&gt;
             &lt;td class="nowrap"&gt;
             
               
                  Buffalo,
      

               
                NY,
               

               
                United States
               
             
             &lt;/td&gt;

             
     &lt;td class="nowrap"&gt;
            
            11/13/2011
            
           &lt;/td&gt;

             
             &lt;td class="nowrap"&gt;
             
               23:33
             
     &lt;/td&gt;

             
             &lt;td&gt;Departure Scan
                
     
      
      
             &lt;/td&gt;
          &lt;/tr&gt;

          
             

          
          &lt;tr class="odd"&gt;
             &lt;td class="nowrap"&gt;
             
               

               

               
             
             &lt;/td&gt;


             
     &lt;td class="nowrap"&gt;
            
            11/13/2011
            
           &lt;/td&gt;

             
             &lt;td class="nowrap"&gt;
             
               23:32
             
     &lt;/td&gt;

             
             &lt;td&gt;Arrival Scan
                
     
      
      
             &lt;/td&gt;
          &lt;/tr&gt;
          
             

          
          &lt;tr&gt;
             &lt;td class="nowrap"&gt;
             
               
                  Mount Hope,
      

               
                ON,
               

               
                Canada
               
             
             &lt;/td&gt;


             
     &lt;td class="nowrap"&gt;

            
            11/13/2011
            
           &lt;/td&gt;

             
             &lt;td class="nowrap"&gt;
             
               10:07
             
     &lt;/td&gt;

             
             &lt;td&gt;Arrival Scan
                
     
      
      
             &lt;/td&gt;
          &lt;/tr&gt;
          
             

          
          &lt;tr class="odd"&gt;

             &lt;td class="nowrap"&gt;
             
               
                  Louisville,
      

               
                KY,
               

               
                United States
               
             
             &lt;/td&gt;


             
     &lt;td class="nowrap"&gt;
            
            11/12/2011
            
           &lt;/td&gt;

             
             &lt;td class="nowrap"&gt;
             
               11:25
             
     &lt;/td&gt;

             
             &lt;td&gt;Departure Scan
                
     
      
      
             &lt;/td&gt;
          &lt;/tr&gt;
          
             

          
          &lt;tr&gt;
             &lt;td class="nowrap"&gt;
             
               
                  Anchorage,
      

               
                AK,
               

               
                United States
               
             
             &lt;/td&gt;


             
     &lt;td class="nowrap"&gt;

            
            11/11/2011
            
           &lt;/td&gt;

             
             &lt;td class="nowrap"&gt;
             
               4:56
             
     &lt;/td&gt;

             
             &lt;td&gt;Arrival Scan
                
     
      
      
             &lt;/td&gt;
          &lt;/tr&gt;
          
             

          
          &lt;tr class="odd"&gt;

             &lt;td class="nowrap"&gt;
             
               
                  Chek Lap Kok,
      

               

               
                Hong Kong
               
             
             &lt;/td&gt;


             
     &lt;td class="nowrap"&gt;
            
            11/11/2011
            
           &lt;/td&gt;

             
             &lt;td class="nowrap"&gt;
             
               12:59
             
     &lt;/td&gt;

             
             &lt;td&gt;Departure Scan
                
     
      
      
             &lt;/td&gt;
          &lt;/tr&gt;
          
             

          
          &lt;tr&gt;
             &lt;td class="nowrap"&gt;
             
               
                  Chek Lap Kok,
      

               

               
                Hong Kong
               
             
             &lt;/td&gt;


             
     &lt;td class="nowrap"&gt;

            
            11/09/2011
            
           &lt;/td&gt;

             
             &lt;td class="nowrap"&gt;
             
               16:30
             
     &lt;/td&gt;

             
             &lt;td&gt;Arrival Scan
                
     
      
      
             &lt;/td&gt;
          &lt;/tr&gt;
          
             

          
          &lt;tr class="odd"&gt;

             &lt;td class="nowrap"&gt;
             
               
                  Shenzhen,
      

               

               
                China
               
             
             &lt;/td&gt;


             
     &lt;td class="nowrap"&gt;
            
            11/09/2011
            
           &lt;/td&gt;

             
             &lt;td class="nowrap"&gt;
             
               15:15
             
     &lt;/td&gt;

             
             &lt;td&gt;Departure Scan
                
     
      
      
             &lt;/td&gt;
          &lt;/tr&gt;
          
             

          
          &lt;tr&gt;
             &lt;td class="nowrap"&gt;
             
               

               

               
             
             &lt;/td&gt;


             
     &lt;td class="nowrap"&gt;
            
            11/09/2011
            
           &lt;/td&gt;

             
             &lt;td class="nowrap"&gt;
             
               13:30
             
     &lt;/td&gt;

             
             &lt;td&gt;Origin Scan
                
     
      
      
             &lt;/td&gt;
          &lt;/tr&gt;
          
             

          
          &lt;tr class="odd"&gt;
             &lt;td class="nowrap"&gt;
             
               

               

               
                China
               
             
             &lt;/td&gt;


             
     &lt;td class="nowrap"&gt;
            
            11/09/2011
            
           &lt;/td&gt;

             
             &lt;td class="nowrap"&gt;
             
               0:15
             
     &lt;/td&gt;

             
             &lt;td&gt;Order Processed: Ready for UPS
                
     
      
      
             &lt;/td&gt;
          &lt;/tr&gt;

          
   &lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-877628357807879196?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/877628357807879196/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/11/iphone-4s-around-world.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/877628357807879196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/877628357807879196'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/11/iphone-4s-around-world.html' title='iPhone 4S around the world'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-kLqJAljY7Pk/TrpZlGwWO6I/AAAAAAAAAQ4/Tl5i59fCuAI/s72-c/iPhone4SUPS.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-4994241676223843414</id><published>2011-10-25T17:08:00.001+03:00</published><updated>2011-10-25T17:09:00.300+03:00</updated><title type='text'>Oakley Polarized Juliet</title><content type='html'>&lt;p&gt;Заказал себе Oakley Polarized Juliet. 400$ в США, без примерки, естественно. Я идиот?&lt;/p&gt;
&lt;img src="http://www.oakley.com/images/catalog/generated/750x350/8a/4dd2f1f03bbb5.jpg"/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-4994241676223843414?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/4994241676223843414/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/10/oakley-polarized-juliet.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/4994241676223843414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/4994241676223843414'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/10/oakley-polarized-juliet.html' title='Oakley Polarized Juliet'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-4739330224459149593</id><published>2011-10-16T21:38:00.001+03:00</published><updated>2011-10-16T21:39:23.897+03:00</updated><title type='text'>Вот так нужно с тупыми бабами за рулем!</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://0.gvt0.com/vi/nixY_-lmb1Q/0.jpg" height="266" width="320"&gt;&lt;param name="movie" value="http://www.youtube.com/v/nixY_-lmb1Q&amp;fs=1&amp;source=uds" /&gt;

&lt;param name="bgcolor" value="#FFFFFF" /&gt;

&lt;embed width="320" height="266"  src="http://www.youtube.com/v/nixY_-lmb1Q&amp;fs=1&amp;source=uds" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-4739330224459149593?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/4739330224459149593/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/10/woman-driving.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/4739330224459149593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/4739330224459149593'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/10/woman-driving.html' title='Вот так нужно с тупыми бабами за рулем!'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-5150580815799080903</id><published>2011-10-11T00:09:00.000+03:00</published><updated>2011-12-07T23:35:14.186+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='library'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>ICU quick starter</title><content type='html'>&lt;p&gt;Часто бывает необходимо выполнить преобразование текста из одной кодировки в другую. Скажем, отослать на HTTP сервер строку в Windows-1251, а после декодировать ответ.&lt;/p&gt;
&lt;p&gt;WinAPI как всегда выручает - функции &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd319072(v=vs.85).aspx" target="_blank" title="MultiByteToWideChar function"&gt;&lt;code&gt;MultiByteToWideChar&lt;/code&gt;&lt;/a&gt; и &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd374130(v=VS.85).aspx" target="_blank" title="WideCharToMultiByte function"&gt;&lt;code&gt;WideCharToMultiByte&lt;/code&gt;&lt;/a&gt; делают преобразование из UTF-16 в необходимую кодировку и обратно. &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=VS.85).aspx" target="_blank" title="Code Page Identifiers"&gt;Список поддерживаемых кодовых страниц&lt;/a&gt; велик, но нет механизма для получения идентификатора кодировки по имени. Поэтому я задался целью найти альтернативу этим функциям. И я ее нашел - библиотека &lt;a href="http://site.icu-project.org" target="_blank" title="ICU - International Components for Unicode"&gt;ICU&lt;/a&gt;. Есть еще iconv, но меня она оттолкнула всей этой гнушной чепухой, не захотелось даже возиться. А вот ICU вполне прилежно поставляется с проектными файлами для свежайшей версии Visual Studio.&lt;/p&gt;
&lt;p&gt;Собрать ICU проще простого:&lt;/p&gt;
&lt;ol&gt;
   &lt;li&gt;Скачиваем архив с исходными кодами со &lt;a href="http://site.icu-project.org/download" target="_blank" title="Downloading ICU"&gt;странички проекта&lt;/a&gt;, под колонкой ICU4C;&lt;/li&gt;
   &lt;li&gt;Разворачиваем содержимое и открываем &lt;code&gt;source\allinone\allinone.sln&lt;/code&gt;;&lt;/li&gt;
   &lt;li&gt;Собираем обе конфигурации - &lt;code&gt;Debug&lt;/code&gt; и &lt;code&gt;Release&lt;/code&gt;;&lt;/li&gt;
   &lt;li&gt;Запускаем &lt;code&gt;bin\icuinfo.exe&lt;/code&gt;, проверяем, что &lt;code&gt;ICU Initialization returned: U_ZERO_ERROR&lt;/code&gt;;&lt;/li&gt;
   &lt;li&gt;Файл &lt;code&gt;bin\icudtXY.dll&lt;/code&gt; должен быть внушительного размера - около 20 мегабайт.
   &lt;p&gt;В случае получения ошибок &lt;code&gt;U_FILE_ACCESS_ERROR&lt;/code&gt; или &lt;code&gt;U_MISSING_RESOURCE_ERROR&lt;/code&gt; - проверяем размер файла. Если слишком маленький - пересобираем проект &lt;code&gt;makedata&lt;/code&gt;, у меня один раз случилось подобное, долго не мог понять в чем дело. Нашел на сайте следующее:&lt;/p&gt;
   &lt;p&gt;Why am I seeing a small ( only a few K ) instead of a large ( several megabytes ) data shared library (icudt)? Opening ICU services fails with U_MISSING_RESOURCE_ERROR and u_init() returns failure.&lt;/p&gt;
   &lt;p&gt;ICU libraries always must link with the ICU data library. However, so that ICU can bootstrap itself, it first builds a 'stub' data library, in icu\source\stubdata, so that the tools can function. You should only use this in production if you are NOT using DLL-mode data access, in which case you are accessing ICU data as individual files, as an archive (.dat) file, or some other means. Normally, you should be using the larger library built from icu\source\data. If you see this issue after ICU has completed building, re-run 'make' in icu\source\data, or the 'makedata' project in Visual Studio. &lt;/p&gt;
   &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Размер &lt;code&gt;bin\icudtXY.dll&lt;/code&gt; можно уменьшить с помощью &lt;a href="http://apps.icu-project.org/datacustom/" target="_blank" title="ICU Data Library Customizer"&gt;ICU Data Library Customizer&lt;/a&gt;. Файл &lt;code&gt;icudt48l.dat&lt;/code&gt; из скачанного архива необходимо раскрыть в папку &lt;code&gt;source\data\in&lt;/code&gt; (а может и &lt;code&gt;source\data\out&lt;/code&gt;, точно не помню) и пересобрать проект &lt;code&gt;makedata&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Рассмотрим пример использования этой замечательной библиотеки. Попытаемся получить строку &lt;q&gt;Приветик, ICU!&lt;/q&gt; в кодировке &lt;code&gt;Windows 1251&lt;/code&gt;, затем обратно в &lt;code&gt;UTF-16&lt;/code&gt; и сравнить с оригиналом:&lt;/p&gt;
&lt;pre class="code spoiler"&gt;
&lt;span&gt;#include&lt;/span&gt; &lt;span style="color: magenta;"&gt;"stdafx.h"&lt;/span&gt;
 
&lt;span style="color: orangered;"&gt;#include&lt;/span&gt; &lt;span style="color: magenta;"&gt;&amp;lt;cassert&amp;gt;&lt;/span&gt;
 
&lt;span style="color: orangered;"&gt;#include&lt;/span&gt; &lt;span style="color: magenta;"&gt;&amp;lt;unicode/ucnv.h&amp;gt;&lt;/span&gt;
&lt;span style="color: orangered;"&gt;#include&lt;/span&gt; &lt;span style="color: magenta;"&gt;&amp;lt;unicode/ucsdet.h&amp;gt;&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;int&lt;/span&gt; _tmain&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;int&lt;/span&gt; argc&lt;span style="color: #800040;"&gt;,&lt;/span&gt; _TCHAR&lt;span style="color: #800040;"&gt;*&lt;/span&gt; argv&lt;span style="color: #800040;"&gt;[])&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; &lt;span style="color: navy;"&gt;wchar_t&lt;/span&gt; &lt;span style="color: #800040;"&gt;*&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt; sourceUTF16 &lt;span style="color: #800040;"&gt;=&lt;/span&gt; L&lt;span style="color: magenta;"&gt;"Приветик, ICU!"&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; size_t len &lt;span style="color: #800040;"&gt;=&lt;/span&gt; wcslen&lt;span style="color: #800040;"&gt;(&lt;/span&gt;sourceUTF16&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   UErrorCode uError&lt;span style="color: #800040;"&gt;(&lt;/span&gt;U_ZERO_ERROR&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   &lt;span style="color: #7ca78b;"&gt;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;/span&gt;
   UConverter &lt;span style="color: #800040;"&gt;*&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt; pConverter &lt;span style="color: #800040;"&gt;=&lt;/span&gt; ucnv_open&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: magenta;"&gt;"windows-1251"&lt;/span&gt;&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;uError&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;U_FAILURE&lt;span style="color: #800040;"&gt;(&lt;/span&gt;uError&lt;span style="color: #800040;"&gt;))&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: #800040;"&gt;-&lt;/span&gt;&lt;span style="color: #e33104;"&gt;1&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   &lt;span style="color: #7ca78b;"&gt;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;/span&gt;
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; &lt;span style="color: navy;"&gt;char&lt;/span&gt; &lt;span style="color: #800040;"&gt;*&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt; pszCharsetInternalName &lt;span style="color: #800040;"&gt;=&lt;/span&gt; ucnv_getName&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pConverter&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;uError&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   assert&lt;span style="color: #800040;"&gt;(&lt;/span&gt;U_SUCCESS&lt;span style="color: #800040;"&gt;(&lt;/span&gt;uError&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
   assert&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pszCharsetInternalName&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; &lt;span style="color: navy;"&gt;char&lt;/span&gt; &lt;span style="color: #800040;"&gt;*&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt; pszCharsetIANAName &lt;span style="color: #800040;"&gt;=&lt;/span&gt; ucnv_getStandardName&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pszCharsetInternalName&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: magenta;"&gt;"IANA"&lt;/span&gt;&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;uError&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   assert&lt;span style="color: #800040;"&gt;(&lt;/span&gt;U_SUCCESS&lt;span style="color: #800040;"&gt;(&lt;/span&gt;uError&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
   assert&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pszCharsetIANAName&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; size_t minCharSize &lt;span style="color: #800040;"&gt;=&lt;/span&gt; ucnv_getMinCharSize&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pConverter&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; size_t maxCharSize &lt;span style="color: #800040;"&gt;=&lt;/span&gt; ucnv_getMaxCharSize&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pConverter&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   &lt;span style="color: #7ca78b;"&gt;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;/span&gt;
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; &lt;span style="color: navy;"&gt;wchar_t&lt;/span&gt; &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pSourceW &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;sourceUTF16&lt;span style="color: #800040;"&gt;[&lt;/span&gt;&lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;];&lt;/span&gt;
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; &lt;span style="color: navy;"&gt;wchar_t&lt;/span&gt; &lt;span style="color: #800040;"&gt;*&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt; pSourceLimitW &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;sourceUTF16&lt;span style="color: #800040;"&gt;[&lt;/span&gt;len&lt;span style="color: #800040;"&gt;];&lt;/span&gt;
   
   &lt;span style="color: navy;"&gt;char&lt;/span&gt; &lt;span style="color: #800040;"&gt;*&lt;/span&gt;targetEncoding &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: navy;"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: navy;"&gt;char&lt;/span&gt; &lt;span style="color: #800040;"&gt;*&amp;gt;(&lt;/span&gt;_alloca&lt;span style="color: #800040;"&gt;(&lt;/span&gt;maxCharSize &lt;span style="color: #800040;"&gt;*&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;len &lt;span style="color: #800040;"&gt;+&lt;/span&gt; &lt;span style="color: #e33104;"&gt;1&lt;/span&gt;&lt;span style="color: #800040;"&gt;)));&lt;/span&gt;
   &lt;span style="color: navy;"&gt;char&lt;/span&gt; &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pTarget &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;targetEncoding&lt;span style="color: #800040;"&gt;[&lt;/span&gt;&lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;];&lt;/span&gt;
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; &lt;span style="color: navy;"&gt;char&lt;/span&gt; &lt;span style="color: #800040;"&gt;*&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt; pTargetLimit &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;targetEncoding&lt;span style="color: #800040;"&gt;[&lt;/span&gt;len&lt;span style="color: #800040;"&gt;];&lt;/span&gt;
   ucnv_fromUnicode&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pConverter&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;pTarget&lt;span style="color: #800040;"&gt;,&lt;/span&gt; pTargetLimit&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;pSourceW&lt;span style="color: #800040;"&gt;,&lt;/span&gt; pSourceLimitW&lt;span style="color: #800040;"&gt;,&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: navy;"&gt;true&lt;/span&gt;&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;uError&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   assert&lt;span style="color: #800040;"&gt;(&lt;/span&gt;U_SUCCESS&lt;span style="color: #800040;"&gt;(&lt;/span&gt;uError&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pTarget &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: magenta;"&gt;'\0'&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
 
   &lt;span style="color: #7ca78b;"&gt;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;/span&gt;
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; &lt;span style="color: navy;"&gt;char&lt;/span&gt; &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pSource &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;targetEncoding&lt;span style="color: #800040;"&gt;[&lt;/span&gt;&lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;];&lt;/span&gt;
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; &lt;span style="color: navy;"&gt;char&lt;/span&gt; &lt;span style="color: #800040;"&gt;*&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt; pSourceLimit &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;targetEncoding&lt;span style="color: #800040;"&gt;[&lt;/span&gt;len&lt;span style="color: #800040;"&gt;];&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;wchar_t&lt;/span&gt; &lt;span style="color: #800040;"&gt;*&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt; targetUTF16 &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: navy;"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: navy;"&gt;wchar_t&lt;/span&gt; &lt;span style="color: #800040;"&gt;*&amp;gt;(&lt;/span&gt;_alloca&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;sizeof&lt;/span&gt;&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;wchar_t&lt;/span&gt;&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;*&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;len &lt;span style="color: #800040;"&gt;+&lt;/span&gt; &lt;span style="color: #e33104;"&gt;1&lt;/span&gt;&lt;span style="color: #800040;"&gt;)));&lt;/span&gt;
   &lt;span style="color: navy;"&gt;wchar_t&lt;/span&gt; &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pTargetW &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;targetUTF16&lt;span style="color: #800040;"&gt;[&lt;/span&gt;&lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;];&lt;/span&gt;
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; &lt;span style="color: navy;"&gt;wchar_t&lt;/span&gt; &lt;span style="color: #800040;"&gt;*&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt; pTargetLimitW &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;targetUTF16&lt;span style="color: #800040;"&gt;[&lt;/span&gt;len&lt;span style="color: #800040;"&gt;];&lt;/span&gt;
   ucnv_toUnicode&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pConverter&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;pTargetW&lt;span style="color: #800040;"&gt;,&lt;/span&gt; pTargetLimitW&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;pSource&lt;span style="color: #800040;"&gt;,&lt;/span&gt; pSourceLimit&lt;span style="color: #800040;"&gt;,&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: navy;"&gt;true&lt;/span&gt;&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;uError&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   assert&lt;span style="color: #800040;"&gt;(&lt;/span&gt;U_SUCCESS&lt;span style="color: #800040;"&gt;(&lt;/span&gt;uError&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pTargetW &lt;span style="color: #800040;"&gt;=&lt;/span&gt; L&lt;span style="color: magenta;"&gt;'\0'&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
 
   &lt;span style="color: #7ca78b;"&gt;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;/span&gt;
   ucnv_close&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pConverter&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Разберем по порядку:&lt;/p&gt;
&lt;ol&gt;
   &lt;li&gt;Включение заголовочных файлов &lt;code&gt;unicode/ucnv.h&lt;/code&gt; и &lt;code&gt;unicode/ucsdet.h&lt;/code&gt; из папки &lt;code&gt;include&lt;/code&gt;;&lt;/li&gt;
   &lt;li&gt;Открытие конвертера функцией &lt;code&gt;ucnv_open&lt;/code&gt;.
   &lt;p&gt;В качестве параметра передаем имя кодовой страницы или ее аналог, один из многих альтернативных имен, поддерживаемых ICU.&lt;/p&gt;
   &lt;/li&gt;
   &lt;li&gt;В отладочных целях получаем внутреннее и стандартное имена открытого конвертера функциями &lt;code&gt;ucnv_getName&lt;/code&gt; и &lt;code&gt;ucnv_getStandardName&lt;/code&gt;;&lt;/li&gt;
   &lt;li&gt;Основная часть - аллокация памяти под результат и использование конвертера по назначению (функции &lt;code&gt;ucnv_fromUnicode&lt;/code&gt; и &lt;code&gt;ucnv_toUnicode&lt;/code&gt;);&lt;/li&gt;
   &lt;li&gt;Освобождение ресурсов, закрытие конвертера функцией &lt;code&gt;ucnv_close&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Линкеру понадобятся &lt;code&gt;icuuc.lib&lt;/code&gt; и &lt;code&gt;icuin.lib&lt;/code&gt; для успешного создания исполняемого файла. А ему, в свою очередь, - библиотеки &lt;code&gt;icuuc48.dll&lt;/code&gt;, &lt;code&gt;icudt48.dll&lt;/code&gt; и &lt;code&gt;icuin48.dll&lt;/code&gt; для успешного запуска.&lt;/p&gt;
&lt;p&gt;В результате выполнения получаем следующий результат:&lt;/p&gt;
&lt;img alt="ICU proof of concept" src="https://sites.google.com/site/chabster/bloggerpictures/ProofOfConcept.png" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-5150580815799080903?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/5150580815799080903/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/10/icu-quick-starter.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/5150580815799080903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/5150580815799080903'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/10/icu-quick-starter.html' title='ICU quick starter'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-2335287155623176992</id><published>2011-09-01T12:56:00.000+03:00</published><updated>2011-12-07T23:35:27.153+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='MFC'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>CEdit with an ellipsis</title><content type='html'>&lt;p&gt;Sometimes developers are devoted to absolutely rediculous tasks. Like having an established conception broken for some reason. You spend a lot of time cracking things up to acomplish your mission. Recently I was working on an edit control with an ellipsis if the text does not fit.&lt;/p&gt;
&lt;p&gt;I came up with painting the edit in case it's not focused:&lt;/p&gt;
&lt;pre class="listing code"&gt;
&lt;span style="color: navy;"&gt;class&lt;/span&gt; CEllipsisEdit &lt;span style="color: #800040;"&gt;:&lt;/span&gt; &lt;span style="color: navy;"&gt;public&lt;/span&gt; CEdit
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   DECLARE_DYNAMIC&lt;span style="color: #800040;"&gt;(&lt;/span&gt;CEllipsisEdit&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;protected&lt;/span&gt;&lt;span style="color: #800040;"&gt;:&lt;/span&gt;
   COLORREF GetBkColor&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;protected&lt;/span&gt;&lt;span style="color: #800040;"&gt;:&lt;/span&gt;
   CBrush m_bkBrush&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;protected&lt;/span&gt;&lt;span style="color: #800040;"&gt;:&lt;/span&gt;
   DECLARE_MESSAGE_MAP&lt;span style="color: #800040;"&gt;()&lt;/span&gt;
   afx_msg &lt;span style="color: navy;"&gt;void&lt;/span&gt; OnPaint&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
 
&lt;span style="color: #800040;"&gt;};&lt;/span&gt;
&lt;/pre&gt;
&lt;pre class="listing code"&gt;
&lt;span style="color: orangered;"&gt;#include&lt;/span&gt; &lt;span style="color: magenta;"&gt;"EllipsisEdit.h"&lt;/span&gt;
 
IMPLEMENT_DYNAMIC&lt;span style="color: #800040;"&gt;(&lt;/span&gt;CEllipsisEdit&lt;span style="color: #800040;"&gt;,&lt;/span&gt; CEdit&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
 
&lt;span style="color: #7ca78b;"&gt;// CEllipsisEdit message map&lt;/span&gt;
 
BEGIN_MESSAGE_MAP&lt;span style="color: #800040;"&gt;(&lt;/span&gt;CEllipsisEdit&lt;span style="color: #800040;"&gt;,&lt;/span&gt; CEdit&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
   ON_WM_PAINT&lt;span style="color: #800040;"&gt;()&lt;/span&gt;
END_MESSAGE_MAP&lt;span style="color: #800040;"&gt;()&lt;/span&gt;
 
&lt;span style="color: #7ca78b;"&gt;// CEllipsisEdit message handlers&lt;/span&gt;
 
COLORREF CEllipsisEdit&lt;span style="color: #800040;"&gt;::&lt;/span&gt;GetBkColor&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_hWnd&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: navy;"&gt;const&lt;/span&gt; HWND hParentWnd &lt;span style="color: #800040;"&gt;=&lt;/span&gt; GetParent&lt;span style="color: #800040;"&gt;()-&amp;gt;&lt;/span&gt;GetSafeHwnd&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
      &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(::&lt;/span&gt;GetWindowThreadProcessId&lt;span style="color: #800040;"&gt;(&lt;/span&gt;hParentWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;==&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;GetWindowThreadProcessId&lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;))&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
         CDC dc&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
         dc&lt;span style="color: #800040;"&gt;.&lt;/span&gt;CreateCompatibleDC&lt;span style="color: #800040;"&gt;(&lt;/span&gt;NULL&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
         &lt;span style="color: navy;"&gt;const&lt;/span&gt; &lt;span style="color: navy;"&gt;bool&lt;/span&gt; enabled &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;GetStyle&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt; WS_DISABLED&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;==&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
         &lt;span style="color: navy;"&gt;const&lt;/span&gt; UINT colorMsg &lt;span style="color: #800040;"&gt;=&lt;/span&gt; enabled &lt;span style="color: #800040;"&gt;?&lt;/span&gt; WM_CTLCOLOREDIT &lt;span style="color: #800040;"&gt;:&lt;/span&gt; WM_CTLCOLORSTATIC&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
 
         &lt;span style="color: #800040;"&gt;::&lt;/span&gt;SendMessage&lt;span style="color: #800040;"&gt;(&lt;/span&gt;hParentWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; colorMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: navy;"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;WPARAM&lt;span style="color: #800040;"&gt;&amp;gt;(&lt;/span&gt;dc&lt;span style="color: #800040;"&gt;.&lt;/span&gt;m_hDC&lt;span style="color: #800040;"&gt;),&lt;/span&gt; &lt;span style="color: navy;"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;LPARAM&lt;span style="color: #800040;"&gt;&amp;gt;(&lt;/span&gt;m_hWnd&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
 
         &lt;span style="color: navy;"&gt;return&lt;/span&gt; dc&lt;span style="color: #800040;"&gt;.&lt;/span&gt;GetBkColor&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
      &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;GetSysColor&lt;span style="color: #800040;"&gt;(&lt;/span&gt;COLOR_WINDOW&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;void&lt;/span&gt; CEllipsisEdit&lt;span style="color: #800040;"&gt;::&lt;/span&gt;OnPaint&lt;span style="color: #800040;"&gt;()&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(::&lt;/span&gt;GetFocus&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: #800040;"&gt;==&lt;/span&gt; m_hWnd&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: navy;"&gt;__super&lt;/span&gt;&lt;span style="color: #800040;"&gt;::&lt;/span&gt;OnPaint&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
      &lt;span style="color: navy;"&gt;return&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   CString text&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   GetWindowText&lt;span style="color: #800040;"&gt;(&lt;/span&gt;text&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(!&lt;/span&gt;m_bkBrush&lt;span style="color: #800040;"&gt;.&lt;/span&gt;m_hObject&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
      m_bkBrush&lt;span style="color: #800040;"&gt;.&lt;/span&gt;CreateSolidBrush&lt;span style="color: #800040;"&gt;(&lt;/span&gt;GetBkColor&lt;span style="color: #800040;"&gt;());&lt;/span&gt;
   
   CPaintDC dc&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;this&lt;/span&gt;&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   
   RECT rc &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt; &lt;span style="color: #800040;"&gt;};&lt;/span&gt;   
   GetClientRect&lt;span style="color: #800040;"&gt;(&amp;amp;&lt;/span&gt;rc&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   dc&lt;span style="color: #800040;"&gt;.&lt;/span&gt;FillRect&lt;span style="color: #800040;"&gt;(&amp;amp;&lt;/span&gt;rc&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;m_bkBrush&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   
   GetRect&lt;span style="color: #800040;"&gt;(&amp;amp;&lt;/span&gt;rc&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   dc&lt;span style="color: #800040;"&gt;.&lt;/span&gt;SetBkMode&lt;span style="color: #800040;"&gt;(&lt;/span&gt;TRANSPARENT&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   dc&lt;span style="color: #800040;"&gt;.&lt;/span&gt;SelectObject&lt;span style="color: #800040;"&gt;(&lt;/span&gt;GetFont&lt;span style="color: #800040;"&gt;());&lt;/span&gt;
   dc&lt;span style="color: #800040;"&gt;.&lt;/span&gt;DrawText&lt;span style="color: #800040;"&gt;(&lt;/span&gt;text&lt;span style="color: #800040;"&gt;,&lt;/span&gt; text&lt;span style="color: #800040;"&gt;.&lt;/span&gt;GetLength&lt;span style="color: #800040;"&gt;(),&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;rc&lt;span style="color: #800040;"&gt;,&lt;/span&gt; DT_SINGLELINE &lt;span style="color: #800040;"&gt;|&lt;/span&gt; DT_NOPREFIX &lt;span style="color: #800040;"&gt;|&lt;/span&gt; DT_WORD_ELLIPSIS&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;There were several problems:&lt;/p&gt;
&lt;ol&gt;
   &lt;li&gt;Edit control would paint itself synchronously. No WM_PAINT message is sent, just GetDC(hwnd) and the paint code, no way to sabstitute painting.&lt;/li&gt;
   &lt;li&gt;Edit control doesn't have non-client area, borders are drawn in client area.&lt;/li&gt;
   &lt;li&gt;Have to somehow determine text background color.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Synchronous paint seems to be an issue only with focused control. Borders are drawn as usual for unknown reason. Background color shall be determined by sending &lt;code&gt;WM_CTLCOLOREDIT&lt;/code&gt; or &lt;code&gt;WM_CTLCOLORSTATIC&lt;/code&gt; to parent or just a &lt;code&gt;COLOR_WINDOW&lt;/code&gt; system color as a fallback.&lt;/p&gt;
&lt;p&gt;Please note that &lt;code&gt;WM_CTLCOLOR&lt;/code&gt;-related messages are not sent to parent widows in different threads! Also don't forget to add &lt;code&gt;DT_NOPREFIX&lt;/code&gt; flag when invoking &lt;code&gt;DrawText&lt;/code&gt; method.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-2335287155623176992?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/2335287155623176992/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/09/cedit-with-ellipsis.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/2335287155623176992'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/2335287155623176992'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/09/cedit-with-ellipsis.html' title='CEdit with an ellipsis'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-177229177253184515</id><published>2011-08-22T18:32:00.000+03:00</published><updated>2011-12-07T23:35:00.925+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WinAPI'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='MFC'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Implementing popups in MFC (part 1)</title><content type='html'>&lt;p&gt;Создание всплывающих окон - задача не из легких. Особенно если это не банальная контекстная подсказка, а, скажем, окно с элементами управления или необходимостью пользовательского взаимодействия (мышь, клавиатура). Самый распостраненный случай всплывающего окна - Combo Box.&lt;/p&gt;
&lt;h2&gt;Великий и могучий Combo Box.&lt;/h2&gt;
&lt;p&gt;Combo Box - это сложный элемент управления, как правило состоящий из списка (List Box), поля ввода (Text Box) и несколько кастрированной кнопки (Button).&lt;/p&gt;
&lt;p&gt;Особенности работы Combo Box:&lt;/p&gt;
&lt;ul&gt;
   &lt;li&gt;При нажатии на кнопку (это не единственный способ) появляется &lt;q&gt;выпадающий список&lt;/q&gt;&lt;/li&gt;
   &lt;li&gt;Это окно по своей сути является стандартным List Box-ом, но на стероидах (с именем класса &lt;code&gt;ComboLBox&lt;/code&gt;)&lt;/li&gt;
   &lt;li&gt;Фокус ввода остается на самом Combo Box-е, всплывшее окно со списком &lt;em&gt;не активируется&lt;/em&gt;&lt;/li&gt;
   &lt;li&gt;Выпадающее окно производит захват мыши вызовом &lt;code&gt;SetCapture&lt;/code&gt;, в результате чего &lt;em&gt;все мышиные сообщения для всех окон процесса&lt;/em&gt; попадают исключительно в оконную процедуру всплывшего окна&lt;/li&gt;
   &lt;li&gt;При щелчке мышью вне выпадающего окна - оно скрывается сразу же при обработке &lt;code&gt;WM_?BUTTONDOWN&lt;/code&gt;, при этом захват мыши отменяется вызовом &lt;code&gt;ReleaseCapture&lt;/code&gt;, что приводит к получению &lt;code&gt;WM_?BUTTONUP&lt;/code&gt; окном, которое находилось под курсором в момент отжатия кнопки&lt;/li&gt;
   &lt;li&gt;При щелчке внутри выпадающего окна, оно реагирует закрытием во время обработки &lt;code&gt;WM_?BUTTONUP&lt;/code&gt;&lt;/li&gt;
   &lt;li&gt;Список реагирует на нажатия стрелочных кнопок (вверх, вниз); очевидно, что сообщения &lt;code&gt;WM_KEYDOWN&lt;/code&gt; приходят в сам Combo Box, а он их передает в выпадающий список&lt;/li&gt;
   &lt;li&gt;При потере Combo Box-ом фокуса ввода - список прячется&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Важные выводы:&lt;/p&gt;
&lt;ol&gt;
   &lt;li&gt;ComboBox работает правильно вне зависимости от наличия окон в различных UI потоках&lt;/li&gt;
   &lt;li&gt;Во время отображения окна выпадающего списка лишь оно из всех окон процесса получает мышиные сообщения - соответственно не должно происходить никаких реакций на движение курсором мыши вне этого окна (всплывающие подсказки, подсветка кнопок, изменение картинки курсора и т.д.)&lt;/li&gt;
   &lt;li&gt;Щелчок мышью вне окна &lt;q&gt;съедается&lt;/q&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;А если не Combo Box?&lt;/h2&gt;
&lt;p&gt;В ОС существует множество выпадающих окон кроме Combo Box. Среди них - Date and Time Picker, меню (стандартное меню ОС, &lt;q&gt;навороченное&lt;/q&gt; меню типа Ribbon или другие реализации, например WPF) и множество других. И я вас уверяю - единой концепции взаимодействия с пользователем у них нет...&lt;/p&gt;
&lt;table style="width: 100%"&gt;
   &lt;tr&gt;
      &lt;td style="width: 0%" valign="top"&gt;&lt;img alt="Window menu" src="https://sites.google.com/site/chabster/implementing-popups-in-mfc/WindowsMenu.png" /&gt;&lt;/td&gt;
      &lt;td&gt;
         &lt;p&gt;Стандартное меню, которое предоставляет операционная система, работает безотказно, но весьма ограничено в отображаемом контенте и функциональности. Я остановил процесс по таймеру во время трекинга меню функцией &lt;code&gt;TrackPopupMenu&lt;/code&gt;. Эта функция блокирует выполнение программы и реализована ядром. Но при этом цикл сообщений крутится внутри нее, поэтому программа остается отзывчивой:&lt;/p&gt;
         &lt;pre class="code"&gt;
&amp;gt; Win32App.exe!CTopLevelWnd::OnTimer(unsigned int nIDEvent)  Line 211 C++
  Win32App.exe!CWnd::OnWndMsg(unsigned int message, unsigned int wParam, long lParam, long * pResult)  Line 2411 C++
  Win32App.exe!CWnd::WindowProc(unsigned int message, unsigned int wParam, long lParam)  Line 2087 + 0x20 bytes C++
  Win32App.exe!AfxCallWndProc(CWnd * pWnd, HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam)  Line 257 + 0x1c bytes C++
  Win32App.exe!AfxWndProc(HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam)  Line 420 C++
  user32.dll!_InternalCallWinProc@20()  + 0x23 bytes 
  user32.dll!_UserCallWinProcCheckWow@32()  + 0xb3 bytes 
  user32.dll!_DispatchClientMessage@20()  + 0x4b bytes 
  user32.dll!___fnDWORD@4()  + 0x24 bytes 
  ntdll.dll!_KiUserCallbackDispatcher@12()  + 0x2e bytes 
  user32.dll!_DispatchClientMessage@20()  
  user32.dll!_NtUserTrackPopupMenuEx@24()  + 0xc bytes 
  user32.dll!_TrackPopupMenu@28()  + 0x1b bytes 
  Win32App.exe!CMenu::TrackPopupMenu(unsigned int nFlags, int x, int y, CWnd * pWnd, const tagRECT * lpRect)  Line 1310 + 0x26 bytes C++
&lt;/pre&gt;
         &lt;p&gt;Я даже не поленился и просмотрел исходный код в ворованных архивах Windows 2000. Это меню &lt;em&gt;очень тесно интегрировано&lt;/em&gt; с оконными процедурами и всем, что обслуживает UI. Не мудрено, что во время останова программы, когда на экране меню, вся система начала вести себя немного &lt;q&gt;странно&lt;/q&gt;.&lt;/p&gt;
         &lt;p&gt;В отличии от Combo Box, контекстное меню ОС &lt;em&gt;не съедает&lt;/em&gt; щелчок вне окна меню, но при этом так же не пропускает &lt;code&gt;WM_MOUSEMOVE&lt;/code&gt; и &lt;code&gt;WM_NCMOUSEMOVE&lt;/code&gt;.&lt;/p&gt;
      &lt;/td&gt;
   &lt;/tr&gt;
&lt;/table&gt;
&lt;p /&gt;
&lt;table style="width: 100%"&gt;
   &lt;tr&gt;
      &lt;td style="width: 0%" valign="top"&gt;&lt;img alt="Codejock menu" src="https://sites.google.com/site/chabster/implementing-popups-in-mfc/CodejockMenu.png" /&gt;&lt;/td&gt;
      &lt;td valign="top"&gt;
         &lt;p&gt;А это реализация &lt;q&gt;навороченного меню&lt;/q&gt; библиотекой Codejock Xtreme Toolkit Pro. &lt;code&gt;WM_MOUSEMOVE&lt;/code&gt; и &lt;code&gt;WM_NCMOUSEMOVE&lt;/code&gt; не блокируются, даже контекстная подсказка выскочила, что не очень то правильно. Точней они не блокируются для текущих контекстных окон (а их там два), блокируются для оставшихся тулбаров этой библиотеки (Ribbon в даном случае), а для остальных окон приложения (полоса прокрутки, область редактирования текста, бордера и пр.) - снова не блокируются.&lt;/p&gt;
         &lt;p&gt;Как и в случае с контекстным меню ОС, &lt;em&gt;не съедает&lt;/em&gt; щелчек вне окон контекста.&lt;/p&gt;
         &lt;p&gt;Собственная реализация &lt;code&gt;TrackPopupMenu&lt;/code&gt; устанавливает различные хуки для слежения за сообщениями, механизм &lt;code&gt;SetCapture&lt;/code&gt;/&lt;code&gt;ReleaseCapture&lt;/code&gt; здесь уже не при делах.&lt;/p&gt;
         &lt;p&gt;Кстати, прототип этой реализации - Microsoft Office 2007/2010, в котором &lt;code&gt;WM_MOUSEMOVE&lt;/code&gt; блокируется для всех окон вне контекста, а &lt;code&gt;WM_NCMOUSEMOVE&lt;/code&gt; работает слегка через жопу - при наведении на бордер окна курсор меняет свой внешний вид, кнопки минимизации, максимизации и закрытия окон прикидываются мертвыми, но если пошуршать курсором у правого-верхнего края окна, то крестик будет предательски нам подмигивать, выдавая ошибку в реализации этой задумки. Scenic Ribbon в, скажем, MS Paint имеет те же проблемы.&lt;/p&gt;
      &lt;/td&gt;
   &lt;/tr&gt;
&lt;/table&gt;
&lt;p /&gt;
&lt;table style="width: 100%"&gt;
   &lt;tr&gt;
      &lt;td style="width: 0%" valign="top"&gt;&lt;img alt="Visual Studio 2010 menu" src="https://sites.google.com/site/chabster/implementing-popups-in-mfc/VS2010Menu.png" /&gt;&lt;/td&gt;
      &lt;td valign="top"&gt;
         &lt;p&gt;На этой картинке находится кусочек &lt;q&gt;навороченного меню&lt;/q&gt; Visual Studio 2010, очевидно реализованного управляемым кодом. &lt;code&gt;WM_MOUSEMOVE&lt;/code&gt; блокируется, а вот в случае &lt;code&gt;WM_NCMOUSEMOVE&lt;/code&gt; все несколько сложнее. По моим наблюдениям не блокируется движение мышью по заголовку окна, кнопки минимизации, максимизации и закрытия окон реагируют на наведение подсветкой, но при этом контекстная подсказка не появляется (как это сделано - пока что загадка). При наведении на полосу прокрутки никакой реакции нет.&lt;/p&gt;
         &lt;p&gt;Как и в случае с контекстным меню ОС, &lt;em&gt;не съедает&lt;/em&gt; щелчек вне окон контекста.&lt;/p&gt;
      &lt;/td&gt;
   &lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Я хочу отметить, что все эти &lt;q&gt;менюшки&lt;/q&gt; - обыкновенные окна, ничего сверхестественного. И они никогда не активируются и не крадут фокус ввода. Истинные джентльмены.&lt;/p&gt;
&lt;h2&gt;Предательские реализации всплывающих контекстных окон&lt;/h2&gt;
&lt;table style="width: 100%"&gt;
   &lt;tr&gt;
      &lt;td style="width: 0%" valign="top"&gt;&lt;img alt="Explorer menu" src="https://sites.google.com/site/chabster/implementing-popups-in-mfc/ExplorerMenu.png" /&gt;&lt;/td&gt;
      &lt;td valign="top"&gt;
         &lt;p&gt;Контекстная подсказка этой кнопочки гордо сообщает нам о возможности &lt;q&gt;Change your view&lt;/q&gt;. А при нажатии появляется якобы контекстное меню, которое почему-то приводит к деактивации главного окна Explorer. Взгляните на цвет заголовка, он ясно дает понять - окно более не активно. Предательское окно ворует фокус ввода, он находится на элементе управления типа Slider. Причем рамка фокуса изначально не отображается, лишь когда нажать клавиши стрелок (вверх или вниз).&lt;/p&gt;
         &lt;p&gt;При этом на блокировку &lt;code&gt;WM_??MOUSEMOVE&lt;/code&gt; нет даже намека - все элементы управления реагируют на перемещение курсора, всплывают подсказки, причем под этим меню. А самое вкусное - &lt;code&gt;WM_?BUTTONDOWN&lt;/code&gt; проглатывается, а последующий &lt;code&gt;WM_?BUTTONUP&lt;/code&gt; проходит. Результат схлопывания меню зависит от реализации элемента управления, по которому был произведен щелчок, - ответная реакция на &lt;code&gt;WM_?BUTTONDOWN&lt;/code&gt; или же на &lt;code&gt;WM_?BUTTONUP&lt;/code&gt;.&lt;/p&gt;
         &lt;p&gt;Кстати, открыл для себя что градация слайдера имеет дискретную структуру с 4 шагами снизу (где разделители нарисованы) и непрерывную (с очень мелким шагом) в области, где разделителей нет. Иконки плавно меняют свой размер.&lt;/p&gt;
         &lt;p&gt;Весьма странная реализация, если сравнить с предыдущими.&lt;/p&gt;
      &lt;/td&gt;
   &lt;/tr&gt;
&lt;/table&gt;
&lt;h2&gt;Альтернативный подход&lt;/h2&gt;
&lt;p&gt;Открыв контекстное меню Firefox, вы убедитесь, что оно никак не влияет на остальные окна, что, впрочем, выглядит вполне логично. Щелчки обрабатываются как обычно, но перед этим меню пропадает с экрана.&lt;/p&gt;
&lt;p&gt;С другой стороны, отсутствие реакции окон на движение мышью подсказывает пользователю, что где-то открыто контекстное меню или модальный диалог, но лишь потому, что ОС Windows работает подобным образом.&lt;/p&gt;
&lt;h2&gt;Реализация собственных контекстных меню&lt;/h2&gt;
&lt;p&gt;Прежде чем заниматься кодированием, следует определить технические требования к реализации всплывающего окна. Как видите - нюансов достаточное количество. Технических нюансов, которые в результате влияют на удобство интерфейса:&lt;/p&gt;
&lt;ol&gt;
   &lt;li&gt;Реакция окон (этого же приложения) вне контекста на перемещение указателя мыши&lt;/li&gt;
   &lt;li&gt;Щелчки мышью по окнам (этого же приложения) вне контекста&lt;/li&gt;
   &lt;li&gt;Деактивация активного окна приложения&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Отслеживание мыши&lt;/h3&gt;
&lt;p&gt;Для слежения за мышью есть такие подходы:&lt;/p&gt;
&lt;ul&gt;
   &lt;li&gt;&lt;code&gt;SetCapture&lt;/code&gt;/&lt;code&gt;ReleaseCapture&lt;/code&gt;&lt;p&gt;С помощью этих функций можно произвести захват/освобождение мыши и направить все сообщения в оконную процедуру одного окна. Но именно с этим связана огромная проблема - мы же хотим отображать сложные окна с элементами управления, которые тоже должны получать мышиные сообщения. В результате обработчики &lt;code&gt;WM_??MOUSE??&lt;/code&gt; выпадающего окна должны будут сами обеспечивать попадание нужных сообщений в оконные процедуры дочерних окон. Нужных - хорошо написано, а на деле - всех возможных. Фактически мы будем эмулировать то, что делает сама ОС Windows. Может показаться, что достаточно лишь найти окно под курсором функцией &lt;code&gt;WindowFromPoint&lt;/code&gt; и вызвать оконную процедуру найденного окна, но на самом деле нюансов огромное множество, как и эмулируемых сообщений.&lt;/p&gt;
   &lt;p&gt;Сам по себе этот сценарий не позволяет контролировать механизм проглатывания щелчков вне контекста. Допустим, при щелчке мы хотим спрятать выпадающее окно, а после этого получить реакцию на щелчок окном, по которому он был произведен. Из-за &lt;code&gt;SetCapture&lt;/code&gt; сообщение &lt;code&gt;WM_LBUTTONDOWN&lt;/code&gt; &lt;em&gt;извлекается из очереди&lt;/em&gt; и попадает в оконную процедуру выпадающего окна, где код определяет положение курсора и прячет окно, если оно находилось вне его области. Далее нужно обеспечить обработку этого сообщения, для этого вызываем &lt;code&gt;AfxCallWndProc&lt;/code&gt; (или просто &lt;code&gt;SendMessage&lt;/code&gt;). И делаем мы это из обработчика &lt;code&gt;WM_LBUTTONDOWN&lt;/code&gt; нашего выпадающего окна! А что если реакцией на щелчок будет повторное выпадение окна (возможно вовсе не этого)? Мы пополним стек потока на добрую дюжину вызовов. И вот здесь все зависит от цикла сообщений. Есть два варианта:&lt;/p&gt;
   &lt;ol&gt;
      &lt;li&gt;Показать окно и выйти из метода &lt;code&gt;ShowPopup&lt;/code&gt; (&lt;em&gt;неблокирующий вызов&lt;/em&gt;).&lt;p&gt;Цикл сообщений при этом остается прежним (как он реализован в приложении), проблем со стеком здесь быть не должно, но это вносит свои трудности в удобство использования такого программного интерфейса - нельзя держать объекты на стеке (окна, контроллеры, политики и т.д.), при выходе из обработчика окно продолжает &lt;q&gt;висеть&lt;/q&gt; на экране и следить за обстановкой, ожидая момента, когда можно спрятаться и уничтожить все следы своего сущевствования, уведомив владельца о произошедшем.&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;Показать окно и запустить свой цикл сообщений в методе &lt;code&gt;ShowPopup&lt;/code&gt; (как это делает &lt;code&gt;TrackPopupMenu&lt;/code&gt;, &lt;em&gt;блокирующий вызов&lt;/em&gt;).&lt;p&gt;В этом случае мы можем вызвать переполнение стека банальными щелчками мыши, которые постоянно приводят к пропаданию текущего выпадающего окна и появлению нового - метод &lt;code&gt;ShowPopup&lt;/code&gt; будет вызываться рекурсивно, каждый раз запуская новый цикл сообщений. Это весомый аргумент против. А бороться с ним крайне сложно. Фактически нужно куда-то сохранить полученное сообщение, которое привело к закрытию выпадающего окна, и уведомить внешний цикл сообщений, что его нужно обработать. К сожалению MFC такой тонкой настройки не предоставляет, придется заменить его цикл сообщений своим (банально скопировав код MFC и добавив туда &lt;q&gt;свое&lt;/q&gt;). Это уже как-то слишком сложно для поддержки выпадающих окон.&lt;/p&gt;
      &lt;/li&gt;
   &lt;/ol&gt;
   &lt;p&gt;И последний, самый важный нюанс &lt;code&gt;SetCapture&lt;/code&gt;: захват может производиться лишь одним окном и вложенность захвата не поддерживается. Это означает, что любой элемент управления, использующий функцию &lt;code&gt;SetCapture&lt;/code&gt;, приведет к снятию установленного захвата и поломке выдающего окна. С подобным, вероятно, можно бороться, но это весьма затратно и совершенно не перспективно для исследования.&lt;/p&gt;
   &lt;p&gt;Очевидно, что этот путь обречен на хардфакинг и успешность его сомнительна, отбрасываем.&lt;/p&gt;
   &lt;/li&gt;
   &lt;li&gt;Перехватчики (hooks) &lt;code&gt;WH_GETMESSAGE&lt;/code&gt;, &lt;code&gt;WH_MOUSE&lt;/code&gt; и &lt;code&gt;WH_MOUSE_LL&lt;/code&gt;&lt;p&gt;С их помощью можно следить за очередью сообщений, отлавливать интересные события. Перехватчики - единственный способ гарантированно получить доступ к содержимому очереди сообщений. Можно было написать свой цикл сообщений (вариант блокирующего вызова &lt;code&gt;ShowPopup&lt;/code&gt;) и в промежутке между &lt;code&gt;GetMessage&lt;/code&gt; и &lt;code&gt;DispatchMessage&lt;/code&gt; выполнять анализ и предпринимать действия. Но есть одна проблема - циклы сообщений могут запускаться в результате реакций на действия пользователя. К примеру, если открыть Date and Time picker, - он запускал вложенный цикл сообщений в версиях ОС Windows до Vista, а также в версиях Common Controls до 6-й. Все это приводит к неконтролируемой потере управления над циклом сообщений и, как последствие, невозможности отлавливать интересующие события.&lt;/p&gt;
   &lt;p&gt;Перехватчики &lt;code&gt;WH_GETMESSAGE&lt;/code&gt; и &lt;code&gt;WH_MOUSE&lt;/code&gt; получают управление перед возвратом функциями &lt;code&gt;GetMessage&lt;/code&gt; и &lt;code&gt;PeekMessage&lt;/code&gt; управления в случае наличия сообщения в очереди (удовлетворяющего критериям). Однако &lt;code&gt;WH_MOUSE&lt;/code&gt; позволяет выполнять лишь мониторинг сообщений, а &lt;code&gt;WH_GETMESSAGE&lt;/code&gt; - модифицировать ко всему прочему. &lt;code&gt;WH_MOUSE_LL&lt;/code&gt; в этом плане похож на своего собрата &lt;code&gt;WH_MOUSE&lt;/code&gt;, но система дает ему управление перед тем, как поместить сообщение в очередь. Это дает возможность спрятать всплывающее окно прежде, чем цикл сообщений получит щелчок мышью, который к этому привел.&lt;/p&gt;
   &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Стратегии реализации&lt;/h3&gt;
&lt;p&gt;Реализация набора классов, которые позволяют показывать всплывающие окна, зависит от следующих факторов:&lt;/p&gt;
&lt;ul&gt;
   &lt;li&gt;Механизм работы метода &lt;code&gt;ShowPopup&lt;/code&gt; - блокирующий или неблокирующий&lt;/li&gt;
   &lt;li&gt;Необходимость проглатывания сообщений, которые приводят к закрытию всплывающего окна&lt;/li&gt;
   &lt;li&gt;Фильтрация перемещений указателя мыши&lt;/li&gt;
   &lt;li&gt;Отсутствие привязки к библиотеке, с момощью которой окно было создано (MFC, ATL, ...) - возможность работы с окнами, передаваемыми по дескриптору (&lt;code&gt;HWND&lt;/code&gt;)&lt;/li&gt;
   &lt;li&gt;Возможность предоставить некую политику функционирования, с помощью которой можно сделать тонкую настройку всего механизма и реализовать сложные сценарии&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Я остановился на блокирующем &lt;code&gt;ShowPopup&lt;/code&gt;, с внутренним циклом обработки сообщений и возможностью настройки поведения через политику. Интерфейс моего класса &lt;code&gt;CPopupController&lt;/code&gt; выглядит следующим образом:&lt;/p&gt;
&lt;pre class="code"&gt;
&lt;span style="color: navy;"&gt;public&lt;/span&gt;&lt;span style="color: #800040;"&gt;:&lt;/span&gt;
   CPopupController&lt;span style="color: #800040;"&gt;(&lt;/span&gt;IPopupEnvironment &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pEnvironment&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;public&lt;/span&gt;&lt;span style="color: #800040;"&gt;:&lt;/span&gt;
   &lt;span style="color: navy;"&gt;void&lt;/span&gt; ShowPopup&lt;span style="color: #800040;"&gt;(&lt;/span&gt;HWND hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; HWND hOwner&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt; POINT &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;ptAnchor&lt;span style="color: #800040;"&gt;,&lt;/span&gt; IPopupPolicy &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pPopupPolicy &lt;span style="color: #800040;"&gt;=&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;void&lt;/span&gt; DismissPopup&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Для начала разберемся в каких случаях всплывающее окно должно быть закрыто без привязки к его внутренностям (поведение меню):&lt;/p&gt;
&lt;ol&gt;
   &lt;li&gt;Деактивация приложения (foreground thread больше не является потоком этого приложения)&lt;/li&gt;
   &lt;li&gt;Щелчки вне контекста&lt;/li&gt;
   &lt;li&gt;Уничтожение окна&lt;/li&gt;
   &lt;li&gt;Изменение состояний окна на такие, в которых режим меню смысла больше не имеет (окно invisible, disabled etc.)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Реализовать это поведение достаточно просто - привязаться к всплывающему окну и реагировать на сообщения, присылаемые ОС Windows. Для этого можно использовать класс &lt;a href="http://chabster.blogspot.com/2011/08/how-to-subclass-window-multiple-times.html"&gt;&lt;code&gt;CWindowSubclass&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="code listing"&gt;
BEGIN_MSG_MAP&lt;span style="color: #800040;"&gt;(&lt;/span&gt;CPopupController&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
   MESSAGE_HANDLER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;WM_ACTIVATE&lt;span style="color: #800040;"&gt;,&lt;/span&gt; OnActivate&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
   MESSAGE_HANDLER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;WM_ACTIVATEAPP&lt;span style="color: #800040;"&gt;,&lt;/span&gt; OnActivateApp&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
   MESSAGE_HANDLER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;WM_SHOWWINDOW&lt;span style="color: #800040;"&gt;,&lt;/span&gt; OnShowWindow&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
   MESSAGE_HANDLER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;WM_ENABLE&lt;span style="color: #800040;"&gt;,&lt;/span&gt; OnEnable&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
   MESSAGE_HANDLER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;WM_SYSCOMMAND&lt;span style="color: #800040;"&gt;,&lt;/span&gt; OnSysCommand&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
   MESSAGE_HANDLER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;WM_MOUSEACTIVATE&lt;span style="color: #800040;"&gt;,&lt;/span&gt; OnMouseActivate&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
   MESSAGE_HANDLER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;WM_DESTROY&lt;span style="color: #800040;"&gt;,&lt;/span&gt; OnDestroy&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
END_MSG_MAP&lt;span style="color: #800040;"&gt;()&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="code listing"&gt;
LRESULT CPopupController&lt;span style="color: #800040;"&gt;::&lt;/span&gt;OnActivate&lt;span style="color: #800040;"&gt;(&lt;/span&gt;UINT uMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; WPARAM wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; LPARAM lParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; BOOL &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;bHandled&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   UNREFERENCED_PARAMETER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;uMsg&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   UNREFERENCED_PARAMETER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;lParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;wParam &lt;span style="color: #800040;"&gt;==&lt;/span&gt; WA_INACTIVE&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;IPopupPolicy &lt;span style="color: #800040;"&gt;*&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt; pPopupPolicy &lt;span style="color: #800040;"&gt;=&lt;/span&gt; GetPopupPolicy&lt;span style="color: #800040;"&gt;())&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
         &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;pPopupPolicy&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;DismissPopupOnLosingActivation&lt;span style="color: #800040;"&gt;())&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
            DismissPopup&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
         &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
      &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
      &lt;span style="color: navy;"&gt;else&lt;/span&gt;
         DismissPopup&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
   bHandled &lt;span style="color: #800040;"&gt;=&lt;/span&gt; FALSE&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
LRESULT CPopupController&lt;span style="color: #800040;"&gt;::&lt;/span&gt;OnActivateApp&lt;span style="color: #800040;"&gt;(&lt;/span&gt;UINT uMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; WPARAM wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; LPARAM lParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; BOOL &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;bHandled&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   UNREFERENCED_PARAMETER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;uMsg&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   UNREFERENCED_PARAMETER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;lParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;wParam &lt;span style="color: #800040;"&gt;==&lt;/span&gt; FALSE&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      DismissPopup&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   bHandled &lt;span style="color: #800040;"&gt;=&lt;/span&gt; FALSE&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
LRESULT CPopupController&lt;span style="color: #800040;"&gt;::&lt;/span&gt;OnShowWindow&lt;span style="color: #800040;"&gt;(&lt;/span&gt;UINT uMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; WPARAM wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; LPARAM lParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; BOOL &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;bHandled&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   UNREFERENCED_PARAMETER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;uMsg&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   UNREFERENCED_PARAMETER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;lParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;wParam &lt;span style="color: #800040;"&gt;==&lt;/span&gt; FALSE&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      DismissPopup&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   bHandled &lt;span style="color: #800040;"&gt;=&lt;/span&gt; FALSE&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
LRESULT CPopupController&lt;span style="color: #800040;"&gt;::&lt;/span&gt;OnEnable&lt;span style="color: #800040;"&gt;(&lt;/span&gt;UINT uMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; WPARAM wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; LPARAM lParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; BOOL &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;bHandled&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   UNREFERENCED_PARAMETER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;uMsg&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   UNREFERENCED_PARAMETER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;lParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;wParam &lt;span style="color: #800040;"&gt;==&lt;/span&gt; FALSE&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      DismissPopup&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   bHandled &lt;span style="color: #800040;"&gt;=&lt;/span&gt; FALSE&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
LRESULT CPopupController&lt;span style="color: #800040;"&gt;::&lt;/span&gt;OnSysCommand&lt;span style="color: #800040;"&gt;(&lt;/span&gt;UINT uMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; WPARAM wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; LPARAM lParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; BOOL &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;bHandled&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   UNREFERENCED_PARAMETER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;uMsg&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   UNREFERENCED_PARAMETER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;lParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;wParam &lt;span style="color: #800040;"&gt;==&lt;/span&gt; SC_CLOSE&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      DismissPopup&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
   
   bHandled &lt;span style="color: #800040;"&gt;=&lt;/span&gt; FALSE&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
LRESULT CPopupController&lt;span style="color: #800040;"&gt;::&lt;/span&gt;OnMouseActivate&lt;span style="color: #800040;"&gt;(&lt;/span&gt;UINT uMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; WPARAM wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; LPARAM lParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; BOOL &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;bHandled&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   UNREFERENCED_PARAMETER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;uMsg&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   UNREFERENCED_PARAMETER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;wParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   UNREFERENCED_PARAMETER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;lParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_pPopupPolicy&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: navy;"&gt;const&lt;/span&gt; IPopupPolicy&lt;span style="color: #800040;"&gt;::&lt;/span&gt;eMouseActivateResult maResult &lt;span style="color: #800040;"&gt;=&lt;/span&gt; m_pPopupPolicy&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;MouseActivateAction&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
      &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;maResult &lt;span style="color: #800040;"&gt;!=&lt;/span&gt; IPopupPolicy&lt;span style="color: #800040;"&gt;::&lt;/span&gt;eDefaultMouseActivateAction&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
         &lt;span style="color: navy;"&gt;return&lt;/span&gt; maResult&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
      &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   bHandled &lt;span style="color: #800040;"&gt;=&lt;/span&gt; FALSE&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
LRESULT CPopupController&lt;span style="color: #800040;"&gt;::&lt;/span&gt;OnDestroy&lt;span style="color: #800040;"&gt;(&lt;/span&gt;UINT uMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; WPARAM wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; LPARAM lParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; BOOL &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;bHandled&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   UNREFERENCED_PARAMETER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;uMsg&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   UNREFERENCED_PARAMETER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;wParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   UNREFERENCED_PARAMETER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;lParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   
   ContinueMessageLoop&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;false&lt;/span&gt;&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   bHandled &lt;span style="color: #800040;"&gt;=&lt;/span&gt; FALSE&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Суть обработчиков - словить условия закрытия окна и, собственно, закрыть, выполнив все необходимые очистки. Исключение составляет обработчик &lt;code&gt;WM_DESTROY&lt;/code&gt; - здесь мы просто устанавливаем флаг, который заставит завершить цикл сообщений.&lt;/p&gt;
&lt;p&gt;Если вдруг код приложения по какой-то причине спрячет окно, уничтожит его, или же поменяет его состояние на disabled, - контроллер автоматически выполнит закрытие режима меню.&lt;/p&gt;
&lt;p&gt;Следующий шаг - игра в &lt;q&gt;кошки-мышки&lt;/q&gt;. Будем гоняться за мышью и лапкой (точней рукой сурового программиста) давать ей по носу. Для этого нам необходим перехватчик сообщений &lt;code&gt;WH_GETMESSAGE&lt;/code&gt;. Здесь в игру вступает класс &lt;code&gt;CPopupManager&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="code listing"&gt;
&lt;span style="color: navy;"&gt;bool&lt;/span&gt; EnterPopupMode&lt;span style="color: #800040;"&gt;(&lt;/span&gt;CPopupController &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pController&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
&lt;span style="color: navy;"&gt;bool&lt;/span&gt; IsPopupMode&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: navy;"&gt;void&lt;/span&gt; ExitPopupMode&lt;span style="color: #800040;"&gt;(&lt;/span&gt;CPopupController &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pController&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Задача этого класса - быть связующим звеном между контроллером выпадающего окна и ОС. В числе прочего - устанавливать необходимые перехватчики и передавать управление контроллеру. По-сути, это менеджер контроллеров, общий для UI потока (в случае многопоточного UI все гораздо сложней, но решаемо благодаря таким людям, как Я).&lt;/p&gt;
&lt;p&gt;Полная версия менеджера выглядит следующим образом:&lt;/p&gt;
&lt;pre class="code listing"&gt;
&lt;span style="color: orangered;"&gt;#pragma&lt;/span&gt; &lt;span style="color: orangered;"&gt;once&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;class&lt;/span&gt; CPopupController&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;class&lt;/span&gt; CPopupManager &lt;span style="color: #800040;"&gt;:&lt;/span&gt; &lt;span style="color: navy;"&gt;public&lt;/span&gt; CNoTrackObject
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;public&lt;/span&gt;&lt;span style="color: #800040;"&gt;:&lt;/span&gt;
   CPopupManager&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;static&lt;/span&gt; CPopupManager &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;Instance&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;bool&lt;/span&gt; EnterPopupMode&lt;span style="color: #800040;"&gt;(&lt;/span&gt;CPopupController &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pController&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;bool&lt;/span&gt; IsPopupMode&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: navy;"&gt;void&lt;/span&gt; ExitPopupMode&lt;span style="color: #800040;"&gt;(&lt;/span&gt;CPopupController &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pController&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;private&lt;/span&gt;&lt;span style="color: #800040;"&gt;:&lt;/span&gt;
   &lt;span style="color: navy;"&gt;static&lt;/span&gt; LRESULT CALLBACK GetMsgProc&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;int&lt;/span&gt; nCode&lt;span style="color: #800040;"&gt;,&lt;/span&gt; WPARAM wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; LPARAM lParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;static&lt;/span&gt; LRESULT CALLBACK CBTProc&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;int&lt;/span&gt; nCode&lt;span style="color: #800040;"&gt;,&lt;/span&gt; WPARAM wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; LPARAM lParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   
   &lt;span style="color: navy;"&gt;bool&lt;/span&gt; PreFilterMessage&lt;span style="color: #800040;"&gt;(&lt;/span&gt;LPMSG pMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: navy;"&gt;bool&lt;/span&gt; preview&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;bool&lt;/span&gt; ActivatingWindow&lt;span style="color: #800040;"&gt;(&lt;/span&gt;HWND hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; LPCBTACTIVATESTRUCT pCBAS&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;bool&lt;/span&gt; SettingFocus&lt;span style="color: #800040;"&gt;(&lt;/span&gt;HWND hSetFocusWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; HWND hKillFocusWnd&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;private&lt;/span&gt;&lt;span style="color: #800040;"&gt;:&lt;/span&gt;
   CPopupController &lt;span style="color: #800040;"&gt;*&lt;/span&gt;m_pController&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   HHOOK m_hGetMessageHook&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   HHOOK m_hCBTHook&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
 
&lt;span style="color: #800040;"&gt;};&lt;/span&gt;
&lt;/pre&gt;
&lt;pre class="code listing"&gt;
&lt;span style="color: orangered;"&gt;#include&lt;/span&gt; &lt;span style="color: magenta;"&gt;"stdafx.h"&lt;/span&gt;
&lt;span style="color: orangered;"&gt;#include&lt;/span&gt; &lt;span style="color: magenta;"&gt;"PopupManager.h"&lt;/span&gt;
&lt;span style="color: orangered;"&gt;#include&lt;/span&gt; &lt;span style="color: magenta;"&gt;"PopupController.h"&lt;/span&gt;
&lt;span style="color: orangered;"&gt;#include&lt;/span&gt; &lt;span style="color: magenta;"&gt;"PopupPolicy.h"&lt;/span&gt;
 
CProcessLocal&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;CPopupManager&lt;span style="color: #800040;"&gt;&amp;gt;&lt;/span&gt; afxPopupManager&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
 
CPopupManager&lt;span style="color: #800040;"&gt;::&lt;/span&gt;CPopupManager&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: #800040;"&gt;:&lt;/span&gt; m_pController&lt;span style="color: #800040;"&gt;(&lt;/span&gt;NULL&lt;span style="color: #800040;"&gt;),&lt;/span&gt; m_hGetMessageHook&lt;span style="color: #800040;"&gt;(&lt;/span&gt;NULL&lt;span style="color: #800040;"&gt;),&lt;/span&gt; m_hCBTHook&lt;span style="color: #800040;"&gt;(&lt;/span&gt;NULL&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
CPopupManager &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;CPopupManager&lt;span style="color: #800040;"&gt;::&lt;/span&gt;Instance&lt;span style="color: #800040;"&gt;()&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt;&lt;span style="color: #800040;"&gt;(*&lt;/span&gt;afxPopupManager&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;bool&lt;/span&gt; CPopupManager&lt;span style="color: #800040;"&gt;::&lt;/span&gt;EnterPopupMode&lt;span style="color: #800040;"&gt;(&lt;/span&gt;CPopupController &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pController&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   ATLASSERT&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pController &lt;span style="color: #800040;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #800040;"&gt;!&lt;/span&gt;IsPopupMode&lt;span style="color: #800040;"&gt;());&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(!&lt;/span&gt;pController &lt;span style="color: #800040;"&gt;||&lt;/span&gt; IsPopupMode&lt;span style="color: #800040;"&gt;())&lt;/span&gt;
      &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: navy;"&gt;false&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
 
   m_hGetMessageHook &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;SetWindowsHookEx&lt;span style="color: #800040;"&gt;(&lt;/span&gt;WH_GETMESSAGE&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;CPopupManager&lt;span style="color: #800040;"&gt;::&lt;/span&gt;GetMsgProc&lt;span style="color: #800040;"&gt;,&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;GetCurrentThreadId&lt;span style="color: #800040;"&gt;());&lt;/span&gt;
   ATLASSERT&lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_hGetMessageHook&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;pController&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;GetPopupPolicy&lt;span style="color: #800040;"&gt;())&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      m_hCBTHook &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;SetWindowsHookEx&lt;span style="color: #800040;"&gt;(&lt;/span&gt;WH_CBT&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;CPopupManager&lt;span style="color: #800040;"&gt;::&lt;/span&gt;CBTProc&lt;span style="color: #800040;"&gt;,&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;GetCurrentThreadId&lt;span style="color: #800040;"&gt;());&lt;/span&gt;
      ATLASSERT&lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_hCBTHook&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   m_pController &lt;span style="color: #800040;"&gt;=&lt;/span&gt; pController&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: navy;"&gt;true&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;bool&lt;/span&gt; CPopupManager&lt;span style="color: #800040;"&gt;::&lt;/span&gt;IsPopupMode&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; m_pController &lt;span style="color: #800040;"&gt;!=&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;void&lt;/span&gt; CPopupManager&lt;span style="color: #800040;"&gt;::&lt;/span&gt;ExitPopupMode&lt;span style="color: #800040;"&gt;(&lt;/span&gt;CPopupController &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pController&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   ATLASSERT&lt;span style="color: #800040;"&gt;(&lt;/span&gt;IsPopupMode&lt;span style="color: #800040;"&gt;());&lt;/span&gt;
   ATLASSERT&lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_pController &lt;span style="color: #800040;"&gt;==&lt;/span&gt; pController&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   m_pController &lt;span style="color: #800040;"&gt;=&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_hCBTHook&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      ATLVERIFY&lt;span style="color: #800040;"&gt;(::&lt;/span&gt;UnhookWindowsHookEx&lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_hCBTHook&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
      m_hCBTHook &lt;span style="color: #800040;"&gt;=&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_hGetMessageHook&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      ATLVERIFY&lt;span style="color: #800040;"&gt;(::&lt;/span&gt;UnhookWindowsHookEx&lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_hGetMessageHook&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
      m_hGetMessageHook &lt;span style="color: #800040;"&gt;=&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;     
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
LRESULT CPopupManager&lt;span style="color: #800040;"&gt;::&lt;/span&gt;GetMsgProc&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;int&lt;/span&gt; nCode&lt;span style="color: #800040;"&gt;,&lt;/span&gt; WPARAM wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; LPARAM lParam&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;nCode &lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: navy;"&gt;return&lt;/span&gt;&lt;span style="color: #800040;"&gt;(::&lt;/span&gt;CallNextHookEx&lt;span style="color: #800040;"&gt;(&lt;/span&gt;NULL&lt;span style="color: #800040;"&gt;,&lt;/span&gt; nCode&lt;span style="color: #800040;"&gt;,&lt;/span&gt; wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; lParam&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;nCode &lt;span style="color: #800040;"&gt;==&lt;/span&gt; HC_ACTION&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      LPMSG &lt;span style="color: navy;"&gt;const&lt;/span&gt; pMsg &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: navy;"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;LPMSG&lt;span style="color: #800040;"&gt;&amp;gt;(&lt;/span&gt;lParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
      &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;WM_MOUSEFIRST &lt;span style="color: #800040;"&gt;&amp;lt;=&lt;/span&gt; pMsg&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;message &lt;span style="color: #800040;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pMsg&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;message &lt;span style="color: #800040;"&gt;&amp;lt;=&lt;/span&gt; WM_MOUSELAST
          &lt;span style="color: #800040;"&gt;||&lt;/span&gt; WM_NCMOUSEMOVE &lt;span style="color: #800040;"&gt;&amp;lt;=&lt;/span&gt; pMsg&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;message &lt;span style="color: #800040;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pMsg&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;message &lt;span style="color: #800040;"&gt;&amp;lt;=&lt;/span&gt; WM_NCXBUTTONDBLCLK
          &lt;span style="color: #800040;"&gt;||&lt;/span&gt; WM_KEYFIRST &lt;span style="color: #800040;"&gt;&amp;lt;=&lt;/span&gt; pMsg&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;message &lt;span style="color: #800040;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pMsg&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;message &lt;span style="color: #800040;"&gt;&amp;lt;=&lt;/span&gt; WM_KEYLAST&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
         &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;Instance&lt;span style="color: #800040;"&gt;().&lt;/span&gt;PreFilterMessage&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; wParam &lt;span style="color: #800040;"&gt;==&lt;/span&gt; PM_NOREMOVE&lt;span style="color: #800040;"&gt;))&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
            &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
         &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
      &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;return&lt;/span&gt;&lt;span style="color: #800040;"&gt;(::&lt;/span&gt;CallNextHookEx&lt;span style="color: #800040;"&gt;(&lt;/span&gt;NULL&lt;span style="color: #800040;"&gt;,&lt;/span&gt; nCode&lt;span style="color: #800040;"&gt;,&lt;/span&gt; wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; lParam&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
LRESULT CPopupManager&lt;span style="color: #800040;"&gt;::&lt;/span&gt;CBTProc&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;int&lt;/span&gt; nCode&lt;span style="color: #800040;"&gt;,&lt;/span&gt; WPARAM wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; LPARAM lParam&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;nCode &lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: navy;"&gt;return&lt;/span&gt;&lt;span style="color: #800040;"&gt;(::&lt;/span&gt;CallNextHookEx&lt;span style="color: #800040;"&gt;(&lt;/span&gt;NULL&lt;span style="color: #800040;"&gt;,&lt;/span&gt; nCode&lt;span style="color: #800040;"&gt;,&lt;/span&gt; wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; lParam&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;nCode &lt;span style="color: #800040;"&gt;==&lt;/span&gt; HCBT_ACTIVATE&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: #7ca78b;"&gt;// The system is about to activate a window.&lt;/span&gt;
      &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;Instance&lt;span style="color: #800040;"&gt;().&lt;/span&gt;ActivatingWindow&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;HWND&lt;span style="color: #800040;"&gt;&amp;gt;(&lt;/span&gt;wParam&lt;span style="color: #800040;"&gt;),&lt;/span&gt; &lt;span style="color: navy;"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;LPCBTACTIVATESTRUCT&lt;span style="color: #800040;"&gt;&amp;gt;(&lt;/span&gt;lParam&lt;span style="color: #800040;"&gt;)))&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
         &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
      &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
   &lt;span style="color: navy;"&gt;else&lt;/span&gt; &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;nCode &lt;span style="color: #800040;"&gt;==&lt;/span&gt; HCBT_SETFOCUS&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: #7ca78b;"&gt;// A window is about to receive the keyboard focus.&lt;/span&gt;
      &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;Instance&lt;span style="color: #800040;"&gt;().&lt;/span&gt;SettingFocus&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;HWND&lt;span style="color: #800040;"&gt;&amp;gt;(&lt;/span&gt;wParam&lt;span style="color: #800040;"&gt;),&lt;/span&gt; &lt;span style="color: navy;"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;HWND&lt;span style="color: #800040;"&gt;&amp;gt;(&lt;/span&gt;lParam&lt;span style="color: #800040;"&gt;)))&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
         &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
      &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;return&lt;/span&gt;&lt;span style="color: #800040;"&gt;(::&lt;/span&gt;CallNextHookEx&lt;span style="color: #800040;"&gt;(&lt;/span&gt;NULL&lt;span style="color: #800040;"&gt;,&lt;/span&gt; nCode&lt;span style="color: #800040;"&gt;,&lt;/span&gt; wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; lParam&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;bool&lt;/span&gt; CPopupManager&lt;span style="color: #800040;"&gt;::&lt;/span&gt;PreFilterMessage&lt;span style="color: #800040;"&gt;(&lt;/span&gt;LPMSG pMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: navy;"&gt;bool&lt;/span&gt; preview&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   ATLASSERT&lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_pController&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_pController&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
      &lt;span style="color: navy;"&gt;return&lt;/span&gt; m_pController&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;PreFilterMessage&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; preview&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: navy;"&gt;false&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;bool&lt;/span&gt; CPopupManager&lt;span style="color: #800040;"&gt;::&lt;/span&gt;ActivatingWindow&lt;span style="color: #800040;"&gt;(&lt;/span&gt;HWND hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; LPCBTACTIVATESTRUCT pCBAS&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   ATLASSERT&lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_pController&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_pController&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
      &lt;span style="color: navy;"&gt;return&lt;/span&gt; m_pController&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;ActivatingWindow&lt;span style="color: #800040;"&gt;(&lt;/span&gt;hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; pCBAS&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: navy;"&gt;false&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;bool&lt;/span&gt; CPopupManager&lt;span style="color: #800040;"&gt;::&lt;/span&gt;SettingFocus&lt;span style="color: #800040;"&gt;(&lt;/span&gt;HWND hSetFocusWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; HWND hKillFocusWnd&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   ATLASSERT&lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_pController&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_pController&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
      &lt;span style="color: navy;"&gt;return&lt;/span&gt; m_pController&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;SettingFocus&lt;span style="color: #800040;"&gt;(&lt;/span&gt;hSetFocusWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; hKillFocusWnd&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: navy;"&gt;false&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;В случае наличия политики также устанавливается перехватчик &lt;code&gt;WH_CBT&lt;/code&gt;, который необходим для слежения за фокусом ввода и активациями окон.&lt;/p&gt;
&lt;p&gt;Возвращаемся к кошкам-мышкам:&lt;/p&gt;
&lt;pre class="code listing"&gt;
&lt;span style="color: navy;"&gt;bool&lt;/span&gt; CPopupController&lt;span style="color: #800040;"&gt;::&lt;/span&gt;PreFilterMessage&lt;span style="color: #800040;"&gt;(&lt;/span&gt;LPMSG pMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: navy;"&gt;bool&lt;/span&gt; preview&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;IPopupPolicy &lt;span style="color: #800040;"&gt;*&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt; pPopupPolicy &lt;span style="color: #800040;"&gt;=&lt;/span&gt; GetPopupPolicy&lt;span style="color: #800040;"&gt;())&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: navy;"&gt;const&lt;/span&gt; IPopupPolicy&lt;span style="color: #800040;"&gt;::&lt;/span&gt;ePreFilterResult preFilterResult &lt;span style="color: #800040;"&gt;=&lt;/span&gt; pPopupPolicy&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;PreFilterMessage&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; preview&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
      &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;preFilterResult &lt;span style="color: #800040;"&gt;==&lt;/span&gt; IPopupPolicy&lt;span style="color: #800040;"&gt;::&lt;/span&gt;ePreFilterBlockMessage&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
         pMsg&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;message &lt;span style="color: #800040;"&gt;=&lt;/span&gt; WM_NULL&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
         &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: navy;"&gt;true&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
      &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
      &lt;span style="color: navy;"&gt;else&lt;/span&gt; &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;preFilterResult &lt;span style="color: #800040;"&gt;==&lt;/span&gt; IPopupPolicy&lt;span style="color: #800040;"&gt;::&lt;/span&gt;ePreFilterAcceptMessage&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
         &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: navy;"&gt;false&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
      &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
      &lt;span style="color: #7ca78b;"&gt;// eContinueRouting&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;Dismissing&lt;span style="color: #800040;"&gt;())&lt;/span&gt;
      &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: navy;"&gt;false&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   
   &lt;span style="color: navy;"&gt;bool&lt;/span&gt; dismiss &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: navy;"&gt;false&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; HWND hCapture &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;GetCapture&lt;span style="color: #800040;"&gt;();&lt;/span&gt;   
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; &lt;span style="color: navy;"&gt;bool&lt;/span&gt; isMouseButtonAction &lt;span style="color: #800040;"&gt;=&lt;/span&gt; IsMouseButtonAction&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pMsg&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;message&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;hCapture&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;isMouseButtonAction&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
         POINT ptAction &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt; GET_X_LPARAM&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pMsg&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;lParam&lt;span style="color: #800040;"&gt;),&lt;/span&gt;  GET_Y_LPARAM&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pMsg&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;lParam&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;};&lt;/span&gt;
         ATLVERIFY&lt;span style="color: #800040;"&gt;(::&lt;/span&gt;ClientToScreen&lt;span style="color: #800040;"&gt;(&lt;/span&gt;hCapture&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;ptAction&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
 
         &lt;span style="color: navy;"&gt;const&lt;/span&gt; HWND hActionWnd &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;WindowFromPoint&lt;span style="color: #800040;"&gt;(&lt;/span&gt;ptAction&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
         dismiss &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;!&lt;/span&gt;hActionWnd &lt;span style="color: #800040;"&gt;||&lt;/span&gt; hActionWnd &lt;span style="color: #800040;"&gt;!=&lt;/span&gt; hCapture &lt;span style="color: #800040;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #800040;"&gt;!&lt;/span&gt;IsOwnerOrSelf&lt;span style="color: #800040;"&gt;(&lt;/span&gt;GetPopupHWnd&lt;span style="color: #800040;"&gt;(),&lt;/span&gt; hActionWnd&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
      &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
   &lt;span style="color: navy;"&gt;else&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;isMouseButtonAction&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
         dismiss &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;!&lt;/span&gt;IsOwnerOrSelf&lt;span style="color: #800040;"&gt;(&lt;/span&gt;GetPopupHWnd&lt;span style="color: #800040;"&gt;(),&lt;/span&gt; pMsg&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;hwnd&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
      &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
      &lt;span style="color: navy;"&gt;else&lt;/span&gt; &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;pMsg&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;message &lt;span style="color: #800040;"&gt;==&lt;/span&gt; WM_MOUSEMOVE&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
         pMsg&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;message &lt;span style="color: #800040;"&gt;=&lt;/span&gt; WM_NULL&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
         &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: navy;"&gt;true&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
      &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;dismiss&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      DismissPopup&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; dismiss&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Это код делает следующее:&lt;/p&gt;
&lt;ol&gt;
   &lt;li&gt;В первую очередь дает возможность политике фильтровать сообщения&lt;/li&gt;
   &lt;li&gt;Ничего не делает если режим меню в состоянии закрытия&lt;/li&gt;
   &lt;li&gt;Выясняет состояние захвата мыши и совершаемое мышью действие&lt;/li&gt;
   &lt;li&gt;Если мышь захвачена неким окном - нужно выяснить какому окну предназначено сообщение в случае, если бы захват мыши не был установлен вовсе&lt;/li&gt;
   &lt;li&gt;Если целевое окно - то, которое выполнило захват, одно из его дочерних окон, а также само выпадающее окно (вместе с его содержимым) - сообщение нужно пропустить&lt;/li&gt;
   &lt;li&gt;В противном случае - выйти из режима меню&lt;/li&gt;
   &lt;li&gt;Когда захвата мыши нет - выйти из режима меню в случае, когда произвели щелчок по окну вне контекста, а также проглотить сообщение &lt;code&gt;WM_MOUSEMOVE&lt;/code&gt; вне контекста. &lt;code&gt;WM_NCMOUSEMOVE&lt;/code&gt; я решил пропускать - ничего страшного в этом нет, пускай полосы прокрутки и остальные неклиентские элементы реагируют на происходящее&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Зачем нужны все эти танцы с захватом мыши? Чтобы работали элементы управления типа Combo Box, Button и пр. Combo Box, как было описано выше, сам показывает выпадающее окно, используя &lt;code&gt;SetCapture&lt;/code&gt; для фильтрации мыши.&lt;/p&gt;
&lt;p&gt;Далее рассмотрим подготовку и вход в режим меню. Этим занимается метод &lt;code&gt;ShowPopup&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="code listing"&gt;
&lt;span style="color: navy;"&gt;void&lt;/span&gt; CPopupController&lt;span style="color: #800040;"&gt;::&lt;/span&gt;ShowPopup&lt;span style="color: #800040;"&gt;(&lt;/span&gt;HWND hPopup&lt;span style="color: #800040;"&gt;,&lt;/span&gt; HWND hOwner&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt; POINT &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;ptAnchor&lt;span style="color: #800040;"&gt;,&lt;/span&gt; IPopupPolicy &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pPopupPolicy&lt;span style="color: #7ca78b;"&gt;/* = NULL*/&lt;/span&gt;&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   CPopupManager &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;manager &lt;span style="color: #800040;"&gt;=&lt;/span&gt; CPopupManager&lt;span style="color: #800040;"&gt;::&lt;/span&gt;Instance&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
 
   ATLASSERT&lt;span style="color: #800040;"&gt;(!&lt;/span&gt;manager&lt;span style="color: #800040;"&gt;.&lt;/span&gt;IsPopupMode&lt;span style="color: #800040;"&gt;());&lt;/span&gt;
   ATLASSERT&lt;span style="color: #800040;"&gt;(!&lt;/span&gt;m_hPopup&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;manager&lt;span style="color: #800040;"&gt;.&lt;/span&gt;IsPopupMode&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: #800040;"&gt;||&lt;/span&gt; m_hPopup&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
      &lt;span style="color: navy;"&gt;return&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; &lt;span style="color: navy;"&gt;bool&lt;/span&gt; popupOk &lt;span style="color: #800040;"&gt;=&lt;/span&gt; hPopup &lt;span style="color: #800040;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;IsWindow&lt;span style="color: #800040;"&gt;(&lt;/span&gt;hPopup&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;IsWindowEnabled&lt;span style="color: #800040;"&gt;(&lt;/span&gt;hPopup&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
                               &lt;span style="color: #800040;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #800040;"&gt;(::&lt;/span&gt;GetWindowLongPtr&lt;span style="color: #800040;"&gt;(&lt;/span&gt;hPopup&lt;span style="color: #800040;"&gt;,&lt;/span&gt; GWL_STYLE&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt; WS_CHILD&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;==&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;
                               &lt;span style="color: #800040;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;GetWindowThreadProcessId&lt;span style="color: #800040;"&gt;(&lt;/span&gt;hPopup&lt;span style="color: #800040;"&gt;,&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;==&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;GetCurrentThreadId&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
   ATLASSERT&lt;span style="color: #800040;"&gt;(&lt;/span&gt;popupOk&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(!&lt;/span&gt;popupOk&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
      &lt;span style="color: navy;"&gt;return&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;hOwner &lt;span style="color: #800040;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;IsWindow&lt;span style="color: #800040;"&gt;(&lt;/span&gt;hOwner&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #800040;"&gt;(::&lt;/span&gt;GetWindowLongPtr&lt;span style="color: #800040;"&gt;(&lt;/span&gt;hOwner&lt;span style="color: #800040;"&gt;,&lt;/span&gt; GWL_STYLE&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt; WS_CHILD&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;!=&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      ATLASSERT&lt;span style="color: #800040;"&gt;(&lt;/span&gt;FALSE&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
      hOwner &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;GetAncestor&lt;span style="color: #800040;"&gt;(&lt;/span&gt;hOwner&lt;span style="color: #800040;"&gt;,&lt;/span&gt; GA_ROOT&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
   &lt;span style="color: navy;"&gt;else&lt;/span&gt;
      hOwner &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;GetActiveWindow&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; &lt;span style="color: navy;"&gt;bool&lt;/span&gt; ownerOk &lt;span style="color: #800040;"&gt;=&lt;/span&gt; hOwner &lt;span style="color: #800040;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;GetWindowThreadProcessId&lt;span style="color: #800040;"&gt;(&lt;/span&gt;hOwner&lt;span style="color: #800040;"&gt;,&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;==&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;GetCurrentThreadId&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
   ATLASSERT&lt;span style="color: #800040;"&gt;(&lt;/span&gt;ownerOk&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(!&lt;/span&gt;ownerOk&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
      &lt;span style="color: navy;"&gt;return&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   
   m_hPopup &lt;span style="color: #800040;"&gt;=&lt;/span&gt; hPopup&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   ATLASSERT&lt;span style="color: #800040;"&gt;(&lt;/span&gt;GetPopupHWnd&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: #800040;"&gt;==&lt;/span&gt; hPopup&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   m_state&lt;span style="color: #800040;"&gt;.&lt;/span&gt;reset&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;const&lt;/span&gt; CWindowSubclass &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;window &lt;span style="color: #800040;"&gt;=&lt;/span&gt; CWindowSubclass&lt;span style="color: #800040;"&gt;(&lt;/span&gt;GetPopupHWnd&lt;span style="color: #800040;"&gt;(),&lt;/span&gt; &lt;span style="color: navy;"&gt;this&lt;/span&gt;&lt;span style="color: #800040;"&gt;))&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;const&lt;/span&gt; PopupScope &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;popupScope &lt;span style="color: #800040;"&gt;=&lt;/span&gt; PopupScope&lt;span style="color: #800040;"&gt;(&lt;/span&gt;manager&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: navy;"&gt;this&lt;/span&gt;&lt;span style="color: #800040;"&gt;))&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
         &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;pPopupPolicy&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
            m_pPopupPolicy &lt;span style="color: #800040;"&gt;=&lt;/span&gt; pPopupPolicy&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
 
         SetLastError&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;);&lt;/span&gt;         
         &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(!::&lt;/span&gt;SetWindowLongPtr&lt;span style="color: #800040;"&gt;(&lt;/span&gt;GetPopupHWnd&lt;span style="color: #800040;"&gt;(),&lt;/span&gt; GWL_HWNDPARENT&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: navy;"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;LONG_PTR&lt;span style="color: #800040;"&gt;&amp;gt;(&lt;/span&gt;hOwner&lt;span style="color: #800040;"&gt;)))&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
            ATLVERIFY&lt;span style="color: #800040;"&gt;(&lt;/span&gt;GetLastError&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: #800040;"&gt;==&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
         &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
         &lt;span style="color: navy;"&gt;const&lt;/span&gt; DWORD swpFlags &lt;span style="color: #800040;"&gt;=&lt;/span&gt; SWP_NOSIZE &lt;span style="color: #800040;"&gt;|&lt;/span&gt; SWP_NOSENDCHANGING
                                &lt;span style="color: #800040;"&gt;|&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_pPopupPolicy &lt;span style="color: #800040;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; m_pPopupPolicy&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;ShowWithoutActivation&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: #800040;"&gt;?&lt;/span&gt; SWP_NOACTIVATE &lt;span style="color: #800040;"&gt;:&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
         RECT rcWindow &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt; ptAnchor&lt;span style="color: #800040;"&gt;.&lt;/span&gt;x&lt;span style="color: #800040;"&gt;,&lt;/span&gt; ptAnchor&lt;span style="color: #800040;"&gt;.&lt;/span&gt;y&lt;span style="color: #800040;"&gt;,&lt;/span&gt; ptAnchor&lt;span style="color: #800040;"&gt;.&lt;/span&gt;x&lt;span style="color: #800040;"&gt;,&lt;/span&gt; ptAnchor&lt;span style="color: #800040;"&gt;.&lt;/span&gt;y &lt;span style="color: #800040;"&gt;};&lt;/span&gt;
         ATLVERIFY&lt;span style="color: #800040;"&gt;(::&lt;/span&gt;GetWindowRect&lt;span style="color: #800040;"&gt;(&lt;/span&gt;GetPopupHWnd&lt;span style="color: #800040;"&gt;(),&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;rcWindow&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
         &lt;span style="color: navy;"&gt;const&lt;/span&gt; SIZE szWindow &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt; rcWindow&lt;span style="color: #800040;"&gt;.&lt;/span&gt;right &lt;span style="color: #800040;"&gt;-&lt;/span&gt; rcWindow&lt;span style="color: #800040;"&gt;.&lt;/span&gt;left&lt;span style="color: #800040;"&gt;,&lt;/span&gt; rcWindow&lt;span style="color: #800040;"&gt;.&lt;/span&gt;bottom &lt;span style="color: #800040;"&gt;-&lt;/span&gt; rcWindow&lt;span style="color: #800040;"&gt;.&lt;/span&gt;top &lt;span style="color: #800040;"&gt;};&lt;/span&gt;
         ATLVERIFY&lt;span style="color: #800040;"&gt;(::&lt;/span&gt;CalculatePopupWindowPosition&lt;span style="color: #800040;"&gt;(&amp;amp;&lt;/span&gt;ptAnchor&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;szWindow&lt;span style="color: #800040;"&gt;,&lt;/span&gt; TPM_LEFTALIGN&lt;span style="color: #800040;"&gt;,&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;rcWindow&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
 
         ATLVERIFY&lt;span style="color: #800040;"&gt;(::&lt;/span&gt;SetWindowPos&lt;span style="color: #800040;"&gt;(&lt;/span&gt;GetPopupHWnd&lt;span style="color: #800040;"&gt;(),&lt;/span&gt; HWND_TOP&lt;span style="color: #800040;"&gt;,&lt;/span&gt; rcWindow&lt;span style="color: #800040;"&gt;.&lt;/span&gt;left&lt;span style="color: #800040;"&gt;,&lt;/span&gt; rcWindow&lt;span style="color: #800040;"&gt;.&lt;/span&gt;top&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;,&lt;/span&gt; swpFlags&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
 
         &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(!::&lt;/span&gt;IsWindowVisible&lt;span style="color: #800040;"&gt;(&lt;/span&gt;GetPopupHWnd&lt;span style="color: #800040;"&gt;()))&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
            &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(!::&lt;/span&gt;AnimateWindow&lt;span style="color: #800040;"&gt;(&lt;/span&gt;GetPopupHWnd&lt;span style="color: #800040;"&gt;(),&lt;/span&gt; &lt;span style="color: #e33104;"&gt;200&lt;/span&gt;&lt;span style="color: #800040;"&gt;,&lt;/span&gt; AW_BLEND&lt;span style="color: #800040;"&gt;))&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
               ATLVERIFY&lt;span style="color: #800040;"&gt;(::&lt;/span&gt;SetWindowPos&lt;span style="color: #800040;"&gt;(&lt;/span&gt;GetPopupHWnd&lt;span style="color: #800040;"&gt;(),&lt;/span&gt; HWND_TOP&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;,&lt;/span&gt; swpFlags &lt;span style="color: #800040;"&gt;|&lt;/span&gt; SWP_NOMOVE &lt;span style="color: #800040;"&gt;|&lt;/span&gt; SWP_SHOWWINDOW&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
            &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
         &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
         &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(!&lt;/span&gt;Dismissing&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;IsWindowVisible&lt;span style="color: #800040;"&gt;(&lt;/span&gt;GetPopupHWnd&lt;span style="color: #800040;"&gt;()))&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
            &lt;span style="color: navy;"&gt;do&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
               RunMessageLoop&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
            &lt;span style="color: #800040;"&gt;}&lt;/span&gt; &lt;span style="color: navy;"&gt;while&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;Dismissing&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;false&lt;/span&gt;&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; m_pPopupPolicy &lt;span style="color: #800040;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; m_pPopupPolicy&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;CancelDismiss&lt;span style="color: #800040;"&gt;());&lt;/span&gt;
         &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
         &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;pPopupPolicy&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
            m_pPopupPolicy &lt;span style="color: #800040;"&gt;=&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;;&lt;/span&gt;         
      &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(::&lt;/span&gt;IsWindowVisible&lt;span style="color: #800040;"&gt;(&lt;/span&gt;GetPopupHWnd&lt;span style="color: #800040;"&gt;()))&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: #800040;"&gt;::&lt;/span&gt;ShowWindow&lt;span style="color: #800040;"&gt;(&lt;/span&gt;GetPopupHWnd&lt;span style="color: #800040;"&gt;(),&lt;/span&gt; SW_HIDE&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   m_hPopup &lt;span style="color: #800040;"&gt;=&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Что здесь происходит:&lt;/p&gt;
&lt;ol&gt;
   &lt;li&gt;Проверки состояний менеджера (нельзя входить в режим меню рекурсивно);&lt;/li&gt;
   &lt;li&gt;Проверки входящих параметров, состояний окон и т.д.;&lt;/li&gt;
   &lt;li&gt;Контекстный (scoped) сабклассинг окна;&lt;/li&gt;
   &lt;li&gt;Контекстный (scoped) вход в режим меню;&lt;/li&gt;
   &lt;li&gt;Привязка окна-владельца к выпадающему окну;&lt;/li&gt;
   &lt;li&gt;Определение позиции выпадающего окна и его показ (с анимацией, если это возможно);&lt;/li&gt;
   &lt;li&gt;Цикл циклов сообщений;&lt;/li&gt;
   &lt;li&gt;Очистка состояния.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Цикл сообщений выглядит следующим образом:&lt;/p&gt;
&lt;pre class="code listing"&gt;
&lt;span style="color: navy;"&gt;void&lt;/span&gt; CPopupController&lt;span style="color: #800040;"&gt;::&lt;/span&gt;RunMessageLoop&lt;span style="color: #800040;"&gt;()&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   ContinueMessageLoop&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;true&lt;/span&gt;&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   
   MSG dummy&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: navy;"&gt;while&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;ContinueMessageLoop&lt;span style="color: #800040;"&gt;())&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: navy;"&gt;while&lt;/span&gt; &lt;span style="color: #800040;"&gt;(::&lt;/span&gt;PeekMessage&lt;span style="color: #800040;"&gt;(&amp;amp;&lt;/span&gt;dummy&lt;span style="color: #800040;"&gt;,&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;,&lt;/span&gt; PM_NOREMOVE&lt;span style="color: #800040;"&gt;))&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
         &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(!&lt;/span&gt;ContinueMessageLoop&lt;span style="color: #800040;"&gt;())&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
            &lt;span style="color: navy;"&gt;break&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
         &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
         &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(!&lt;/span&gt;PumpMessage&lt;span style="color: #800040;"&gt;())&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
            &lt;span style="color: #800040;"&gt;::&lt;/span&gt;PostQuitMessage&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
            DismissPopup&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
            &lt;span style="color: navy;"&gt;break&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
         &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
         &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(!&lt;/span&gt;ContinueMessageLoop&lt;span style="color: #800040;"&gt;())&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
            &lt;span style="color: navy;"&gt;break&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
         &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
      &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
      &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;ContinueMessageLoop&lt;span style="color: #800040;"&gt;())&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
         &lt;span style="color: #800040;"&gt;::&lt;/span&gt;WaitMessage&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
      &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Я вот только что прикинул - цикл сообщений можно было бы перенести в менеджер. Подумаю на досуге.&lt;/p&gt;
&lt;p&gt;Важный момент - использование &lt;code&gt;PeekMessage&lt;/code&gt; с параметром &lt;code&gt;PM_NOREMOVE&lt;/code&gt;. Это сделано для того, чтобы иметь возможность выйти из режима меню до обработки сообщения. Как следствие - иметь возможность не проглатывать сообщение, которое привело к закрытию меню.&lt;/p&gt;
&lt;p&gt;Обратите внимание на реализацию PumpMessage:&lt;/p&gt;
&lt;pre class="code listing"&gt;
&lt;span style="color: navy;"&gt;bool&lt;/span&gt; CPopupController&lt;span style="color: #800040;"&gt;::&lt;/span&gt;PumpMessage&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; m_pEnvironment&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;PumpMessage&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Теперь пример использования этого &lt;q&gt;чуда&lt;/q&gt;:&lt;/p&gt;
&lt;pre class="code listing"&gt;
&lt;span style="color: navy;"&gt;void&lt;/span&gt; CChildView&lt;span style="color: #800040;"&gt;::&lt;/span&gt;OnRButtonUp&lt;span style="color: #800040;"&gt;(&lt;/span&gt;UINT nFlags&lt;span style="color: #800040;"&gt;,&lt;/span&gt; CPoint point&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   POINT ptPopup &lt;span style="color: #800040;"&gt;=&lt;/span&gt; point&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   ClientToScreen&lt;span style="color: #800040;"&gt;(&amp;amp;&lt;/span&gt;ptPopup&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   
   &lt;span style="color: navy;"&gt;struct&lt;/span&gt; XPopupPolicy &lt;span style="color: #800040;"&gt;:&lt;/span&gt; IPopupPolicy
   &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: #7ca78b;"&gt;//virtual bool ShowWithoutActivation() { return false; }&lt;/span&gt;
      &lt;span style="color: #7ca78b;"&gt;//virtual eMouseActivateResult MouseActivateAction() { return eNoActivate; }&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;};&lt;/span&gt;
   
   CPopupDlg popup&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   popup&lt;span style="color: #800040;"&gt;.&lt;/span&gt;Create&lt;span style="color: #800040;"&gt;(&lt;/span&gt;IDD_POPUP&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;AfxGetMainWnd&lt;span style="color: #800040;"&gt;());&lt;/span&gt;
   XPopupPolicy xPopupPolicy&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   CMFCPopupEnvironment mfcPopupEnv&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   CPopupController popupController&lt;span style="color: #800040;"&gt;(&amp;amp;&lt;/span&gt;mfcPopupEnv&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   popupController&lt;span style="color: #800040;"&gt;.&lt;/span&gt;ShowPopup&lt;span style="color: #800040;"&gt;(&lt;/span&gt;popup&lt;span style="color: #800040;"&gt;.&lt;/span&gt;GetSafeHwnd&lt;span style="color: #800040;"&gt;(),&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;AfxGetMainWnd&lt;span style="color: #800040;"&gt;()-&amp;gt;&lt;/span&gt;GetSafeHwnd&lt;span style="color: #800040;"&gt;(),&lt;/span&gt; ptPopup&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: #800040;"&gt;&amp;amp;&lt;/span&gt;xPopupPolicy&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;__super&lt;/span&gt;&lt;span style="color: #800040;"&gt;::&lt;/span&gt;OnRButtonUp&lt;span style="color: #800040;"&gt;(&lt;/span&gt;nFlags&lt;span style="color: #800040;"&gt;,&lt;/span&gt; point&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Мой диалог содержит пару кнопок и выпадающий список. Все это отлично работает.&lt;/p&gt;
&lt;p&gt;На этом я заканчиваю первую часть. В следующий раз я расскажу что такое политика и опишу сложный сценарий выпадающего окна с переходами между полем ввода на форме в него (меню) и обратно без закрытия (а это весьма сложно, поверьте).&lt;/p&gt;
&lt;p&gt;Код в свободный доступ не выкладываю, жадный. Спасибо за внимание.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-177229177253184515?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/177229177253184515/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/08/implementing-popups-in-mfc-part-1.html#comment-form' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/177229177253184515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/177229177253184515'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/08/implementing-popups-in-mfc-part-1.html' title='Implementing popups in MFC (part 1)'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-630188172970279396</id><published>2011-08-20T20:45:00.000+03:00</published><updated>2011-08-20T20:45:37.718+03:00</updated><title type='text'>Wide monitor in portrait mode</title><content type='html'>&lt;p&gt;
А вы пробовали установить портретный режим для широкоформатных мониторов?
&lt;/p&gt;
&lt;a href="http://4.bp.blogspot.com/-t44ua3-5L8Q/Tk_yobQ1Y_I/AAAAAAAAAQk/ajWT35D8Q-0/s1600/IMAGE_038.jpg" imageanchor="1" style=""&gt;&lt;img border="0" height="192" width="320" src="http://4.bp.blogspot.com/-t44ua3-5L8Q/Tk_yobQ1Y_I/AAAAAAAAAQk/ajWT35D8Q-0/s320/IMAGE_038.jpg" /&gt;&lt;/a&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-630188172970279396?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/630188172970279396/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/08/wide-monitor-in-portrait-mode.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/630188172970279396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/630188172970279396'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/08/wide-monitor-in-portrait-mode.html' title='Wide monitor in portrait mode'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-t44ua3-5L8Q/Tk_yobQ1Y_I/AAAAAAAAAQk/ajWT35D8Q-0/s72-c/IMAGE_038.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-1305956420545740411</id><published>2011-08-05T15:10:00.000+03:00</published><updated>2011-08-05T15:10:29.740+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='problem'/><category scheme='http://www.blogger.com/atom/ns#' term='ATL'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>How to subclass a window multiple times</title><content type='html'>&lt;p&gt;Иногда бывает необходимо привязаться к окну и добавить логики по обработке оконных сообщений. Механизм имеет всем известное название сабклассинг. MFC, как и многие библиотеки, поддерживает сабклассинг окон. Проблема лишь в том, что сделать это можно лишь один раз. А если надо много раз? А если к нам попадает хэндл окна и мы понятия не имеем кем оно было создано? Проблемка, однако. Но на помощь как всегда приходит могучий ATL.&lt;/p&gt;&lt;pre class="code listing"&gt;&lt;span style="color: orangered;"&gt;#pragma&lt;/span&gt; &lt;span style="color: orangered;"&gt;once&lt;/span&gt;
 
&lt;span style="color: orangered;"&gt;#include&lt;/span&gt; &lt;span style="color: magenta;"&gt;&amp;lt;atlwin.h&amp;gt;&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;class&lt;/span&gt; CWindowSubclass
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;public&lt;/span&gt;&lt;span style="color: #800040;"&gt;:&lt;/span&gt;
   CWindowSubclass&lt;span style="color: #800040;"&gt;(&lt;/span&gt;CMessageMap &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pObject&lt;span style="color: #800040;"&gt;,&lt;/span&gt; DWORD msgMapID &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   CWindowSubclass&lt;span style="color: #800040;"&gt;(&lt;/span&gt;HWND hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; CMessageMap &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pObject&lt;span style="color: #800040;"&gt;,&lt;/span&gt; DWORD msgMapID &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;~&lt;/span&gt;CWindowSubclass&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;public&lt;/span&gt;&lt;span style="color: #800040;"&gt;:&lt;/span&gt;   
   &lt;span style="color: navy;"&gt;void&lt;/span&gt; SwitchMessageMap&lt;span style="color: #800040;"&gt;(&lt;/span&gt;DWORD msgMapID&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   BOOL SubclassWindow&lt;span style="color: #800040;"&gt;(&lt;/span&gt;HWND hWnd&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   HWND UnsubclassWindow&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;bool&lt;/span&gt; force &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: navy;"&gt;false&lt;/span&gt;&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   HWND GetHWnd&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: navy;"&gt;operator&lt;/span&gt; &lt;span style="color: navy;"&gt;bool&lt;/span&gt;&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;private&lt;/span&gt;&lt;span style="color: #800040;"&gt;:&lt;/span&gt;   
   &lt;span style="color: navy;"&gt;static&lt;/span&gt; LRESULT CALLBACK WindowProc&lt;span style="color: #800040;"&gt;(&lt;/span&gt;HWND hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; UINT uMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; WPARAM wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; LPARAM lParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   LRESULT DefWindowProc&lt;span style="color: #800040;"&gt;(&lt;/span&gt;UINT uMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; WPARAM wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; LPARAM lParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;   
 
&lt;span style="color: navy;"&gt;private&lt;/span&gt;&lt;span style="color: #800040;"&gt;:&lt;/span&gt;
   HWND m_hWnd&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   CWndProcThunk m_thunk&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   WNDPROC m_pfnSuperWindowProc&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   CMessageMap &lt;span style="color: #800040;"&gt;*&lt;/span&gt;m_pObject&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   DWORD m_msgMapID&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;};&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code listing"&gt;&lt;span style="color: orangered;"&gt;#include&lt;/span&gt; &lt;span style="color: magenta;"&gt;"stdafx.h"&lt;/span&gt;
&lt;span style="color: orangered;"&gt;#include&lt;/span&gt; &lt;span style="color: magenta;"&gt;"WindowSubclass.h"&lt;/span&gt;
 
CWindowSubclass&lt;span style="color: #800040;"&gt;::&lt;/span&gt;CWindowSubclass&lt;span style="color: #800040;"&gt;(&lt;/span&gt;CMessageMap &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pObject&lt;span style="color: #800040;"&gt;,&lt;/span&gt;  DWORD msgMapID&lt;span style="color: #7ca78b;"&gt;/* = 0*/&lt;/span&gt;&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;:&lt;/span&gt;  m_hWnd&lt;span style="color: #800040;"&gt;(&lt;/span&gt;NULL&lt;span style="color: #800040;"&gt;),&lt;/span&gt;         
      m_pObject&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pObject&lt;span style="color: #800040;"&gt;),&lt;/span&gt;
      m_msgMapID&lt;span style="color: #800040;"&gt;(&lt;/span&gt;msgMapID&lt;span style="color: #800040;"&gt;),&lt;/span&gt;
      m_pfnSuperWindowProc&lt;span style="color: #800040;"&gt;(&lt;/span&gt;NULL&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
CWindowSubclass&lt;span style="color: #800040;"&gt;::&lt;/span&gt;CWindowSubclass&lt;span style="color: #800040;"&gt;(&lt;/span&gt;HWND hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt;  CMessageMap &lt;span style="color: #800040;"&gt;*&lt;/span&gt;pObject&lt;span style="color: #800040;"&gt;,&lt;/span&gt; DWORD msgMapID&lt;span style="color: #7ca78b;"&gt;/* = 0*/&lt;/span&gt;&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;:&lt;/span&gt;  m_hWnd&lt;span style="color: #800040;"&gt;(&lt;/span&gt;NULL&lt;span style="color: #800040;"&gt;),&lt;/span&gt;
      m_pObject&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pObject&lt;span style="color: #800040;"&gt;),&lt;/span&gt;
      m_msgMapID&lt;span style="color: #800040;"&gt;(&lt;/span&gt;msgMapID&lt;span style="color: #800040;"&gt;),&lt;/span&gt;
      m_pfnSuperWindowProc&lt;span style="color: #800040;"&gt;(&lt;/span&gt;NULL&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   SubclassWindow&lt;span style="color: #800040;"&gt;(&lt;/span&gt;hWnd&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
CWindowSubclass&lt;span style="color: #800040;"&gt;::~&lt;/span&gt;CWindowSubclass&lt;span style="color: #800040;"&gt;()&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_hWnd&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      UnsubclassWindow&lt;span style="color: #800040;"&gt;(&lt;/span&gt;TRUE&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
HWND CWindowSubclass&lt;span style="color: #800040;"&gt;::&lt;/span&gt;GetHWnd&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt;&lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_hWnd&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
CWindowSubclass&lt;span style="color: #800040;"&gt;::&lt;/span&gt;&lt;span style="color: navy;"&gt;operator&lt;/span&gt; &lt;span style="color: navy;"&gt;bool&lt;/span&gt;&lt;span style="color: #800040;"&gt;()&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; m_hWnd &lt;span style="color: #800040;"&gt;!=&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
&lt;span style="color: navy;"&gt;void&lt;/span&gt; CWindowSubclass&lt;span style="color: #800040;"&gt;::&lt;/span&gt;SwitchMessageMap&lt;span style="color: #800040;"&gt;(&lt;/span&gt;DWORD msgMapID&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   m_msgMapID &lt;span style="color: #800040;"&gt;=&lt;/span&gt; msgMapID&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
LRESULT CWindowSubclass&lt;span style="color: #800040;"&gt;::&lt;/span&gt;DefWindowProc&lt;span style="color: #800040;"&gt;(&lt;/span&gt;UINT uMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt;  WPARAM wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt;  LPARAM lParam&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
&lt;span style="color: orangered;"&gt;#ifdef&lt;/span&gt; STRICT
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;CallWindowProc&lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_pfnSuperWindowProc&lt;span style="color: #800040;"&gt;,&lt;/span&gt; m_hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; uMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; lParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
&lt;span style="color: orangered;"&gt;#else&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;CallWindowProc&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;FARPROC&lt;span style="color: #800040;"&gt;&amp;gt;(&lt;/span&gt;m_pfnSuperWindowProc&lt;span style="color: #800040;"&gt;),&lt;/span&gt; m_hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; uMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; lParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
&lt;span style="color: orangered;"&gt;#endif&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
LRESULT CWindowSubclass&lt;span style="color: #800040;"&gt;::&lt;/span&gt;WindowProc&lt;span style="color: #800040;"&gt;(&lt;/span&gt;HWND hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt;  UINT uMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt;  WPARAM wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt;  LPARAM lParam&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   CWindowSubclass &lt;span style="color: #800040;"&gt;*&lt;/span&gt; &lt;span style="color: navy;"&gt;const&lt;/span&gt; pThis &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: navy;"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;CWindowSubclass &lt;span style="color: #800040;"&gt;*&amp;gt;(&lt;/span&gt;hWnd&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   ATLASSERT&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pThis&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(!&lt;/span&gt;pThis&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   ATLASSERT&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pThis&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;m_hWnd&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   ATLASSERT&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pThis&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;m_pObject&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(!&lt;/span&gt;pThis&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;m_hWnd &lt;span style="color: #800040;"&gt;||&lt;/span&gt; &lt;span style="color: #800040;"&gt;!&lt;/span&gt;pThis&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;m_pObject&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: navy;"&gt;return&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
   LRESULT lRes &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #e33104;"&gt;0&lt;/span&gt;&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   BOOL bRet &lt;span style="color: #800040;"&gt;=&lt;/span&gt; pThis&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;m_pObject&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;ProcessWindowMessage&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pThis&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;m_hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; uMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; lParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; lRes&lt;span style="color: #800040;"&gt;,&lt;/span&gt; pThis&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;m_msgMapID&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(!&lt;/span&gt;bRet&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;uMsg &lt;span style="color: #800040;"&gt;!=&lt;/span&gt; WM_NCDESTROY&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
         lRes &lt;span style="color: #800040;"&gt;=&lt;/span&gt; pThis&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;DefWindowProc&lt;span style="color: #800040;"&gt;(&lt;/span&gt;uMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; lParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
      &lt;span style="color: navy;"&gt;else&lt;/span&gt;
      &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
         &lt;span style="color: navy;"&gt;const&lt;/span&gt; LONG_PTR pfnWndProc &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;GetWindowLongPtr&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pThis&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;m_hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; GWLP_WNDPROC&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
         lRes &lt;span style="color: #800040;"&gt;=&lt;/span&gt; pThis&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;DefWindowProc&lt;span style="color: #800040;"&gt;(&lt;/span&gt;uMsg&lt;span style="color: #800040;"&gt;,&lt;/span&gt; wParam&lt;span style="color: #800040;"&gt;,&lt;/span&gt; lParam&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
         &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;pThis&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;m_pfnSuperWindowProc &lt;span style="color: #800040;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #800040;"&gt;::&lt;/span&gt;GetWindowLongPtr&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pThis&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;m_hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; GWLP_WNDPROC&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;==&lt;/span&gt; pfnWndProc&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
            &lt;span style="color: #800040;"&gt;::&lt;/span&gt;SetWindowLongPtr&lt;span style="color: #800040;"&gt;(&lt;/span&gt;pThis&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;m_hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; GWLP_WNDPROC&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: navy;"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;LONG_PTR&lt;span style="color: #800040;"&gt;&amp;gt;(&lt;/span&gt;pThis&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;m_pfnSuperWindowProc&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
         &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
         pThis&lt;span style="color: #800040;"&gt;-&amp;gt;&lt;/span&gt;m_hWnd &lt;span style="color: #800040;"&gt;=&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
      &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; lRes&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
 
BOOL CWindowSubclass&lt;span style="color: #800040;"&gt;::&lt;/span&gt;SubclassWindow&lt;span style="color: #800040;"&gt;(&lt;/span&gt;HWND hWnd&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;      
   ATLASSUME&lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_hWnd &lt;span style="color: #800040;"&gt;==&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   ATLASSERT&lt;span style="color: #800040;"&gt;(::&lt;/span&gt;IsWindow&lt;span style="color: #800040;"&gt;(&lt;/span&gt;hWnd&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; BOOL result &lt;span style="color: #800040;"&gt;=&lt;/span&gt; m_thunk&lt;span style="color: #800040;"&gt;.&lt;/span&gt;Init&lt;span style="color: #800040;"&gt;(&lt;/span&gt;WindowProc&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: navy;"&gt;this&lt;/span&gt;&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;result &lt;span style="color: #800040;"&gt;==&lt;/span&gt; FALSE&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
      &lt;span style="color: navy;"&gt;return&lt;/span&gt; result&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; WNDPROC pProc &lt;span style="color: #800040;"&gt;=&lt;/span&gt; m_thunk&lt;span style="color: #800040;"&gt;.&lt;/span&gt;GetWNDPROC&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; WNDPROC pfnWndProc &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: navy;"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;WNDPROC&lt;span style="color: #800040;"&gt;&amp;gt;(::&lt;/span&gt;SetWindowLongPtr&lt;span style="color: #800040;"&gt;(&lt;/span&gt;hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; GWLP_WNDPROC&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: navy;"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;LONG_PTR&lt;span style="color: #800040;"&gt;&amp;gt;(&lt;/span&gt;pProc&lt;span style="color: #800040;"&gt;)));&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;pfnWndProc &lt;span style="color: #800040;"&gt;==&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
      &lt;span style="color: navy;"&gt;return&lt;/span&gt; FALSE&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   m_pfnSuperWindowProc &lt;span style="color: #800040;"&gt;=&lt;/span&gt; pfnWndProc&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   m_hWnd &lt;span style="color: #800040;"&gt;=&lt;/span&gt; hWnd&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; TRUE&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;
 
HWND CWindowSubclass&lt;span style="color: #800040;"&gt;::&lt;/span&gt;UnsubclassWindow&lt;span style="color: #800040;"&gt;(&lt;/span&gt;&lt;span style="color: navy;"&gt;bool&lt;/span&gt; force&lt;span style="color: #7ca78b;"&gt;/* = false*/&lt;/span&gt;&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&lt;span style="color: #800040;"&gt;{&lt;/span&gt;
   ATLASSUME&lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_hWnd &lt;span style="color: #800040;"&gt;!=&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;);&lt;/span&gt;
 
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; WNDPROC pOurProc &lt;span style="color: #800040;"&gt;=&lt;/span&gt; m_thunk&lt;span style="color: #800040;"&gt;.&lt;/span&gt;GetWNDPROC&lt;span style="color: #800040;"&gt;();&lt;/span&gt;
   &lt;span style="color: navy;"&gt;const&lt;/span&gt; WNDPROC pActiveProc &lt;span style="color: #800040;"&gt;=&lt;/span&gt; &lt;span style="color: navy;"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;WNDPROC&lt;span style="color: #800040;"&gt;&amp;gt;(::&lt;/span&gt;GetWindowLongPtr&lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; GWLP_WNDPROC&lt;span style="color: #800040;"&gt;));&lt;/span&gt;
 
   HWND hWnd &lt;span style="color: #800040;"&gt;=&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(&lt;/span&gt;force &lt;span style="color: #800040;"&gt;||&lt;/span&gt; pOurProc &lt;span style="color: #800040;"&gt;==&lt;/span&gt; pActiveProc&lt;span style="color: #800040;"&gt;)&lt;/span&gt; &lt;span style="color: #800040;"&gt;{&lt;/span&gt;
      &lt;span style="color: navy;"&gt;if&lt;/span&gt; &lt;span style="color: #800040;"&gt;(!::&lt;/span&gt;SetWindowLongPtr&lt;span style="color: #800040;"&gt;(&lt;/span&gt;m_hWnd&lt;span style="color: #800040;"&gt;,&lt;/span&gt; GWLP_WNDPROC&lt;span style="color: #800040;"&gt;,&lt;/span&gt; &lt;span style="color: navy;"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: #800040;"&gt;&amp;lt;&lt;/span&gt;LONG_PTR&lt;span style="color: #800040;"&gt;&amp;gt;(&lt;/span&gt;m_pfnSuperWindowProc&lt;span style="color: #800040;"&gt;)))&lt;/span&gt;
         &lt;span style="color: navy;"&gt;return&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
 
      m_pfnSuperWindowProc &lt;span style="color: #800040;"&gt;=&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
      hWnd &lt;span style="color: #800040;"&gt;=&lt;/span&gt; m_hWnd&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
      m_hWnd &lt;span style="color: #800040;"&gt;=&lt;/span&gt; NULL&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
   &lt;span style="color: #800040;"&gt;}&lt;/span&gt;
   &lt;span style="color: navy;"&gt;return&lt;/span&gt; hWnd&lt;span style="color: #800040;"&gt;;&lt;/span&gt;
&lt;span style="color: #800040;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Использовать этот класс проще простого, достаточно передать наследника &lt;code&gt;ATL::CMessageMap&lt;/code&gt; в качестве параметра конструктора вместе с дескриптором окна. Плюс привычная для ATL конструкция:&lt;/p&gt;&lt;pre class="code"&gt;BEGIN_MSG_MAP&lt;span style="color: #800040;"&gt;(&lt;/span&gt;MyCMessageMapDerivedClass&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;MESSAGE_HANDLER&lt;span style="color: #800040;"&gt;(&lt;/span&gt;WM_MESSAGE&lt;span style="color: #800040;"&gt;,&lt;/span&gt;&amp;nbsp;OnMessage&lt;span style="color: #800040;"&gt;)&lt;/span&gt;
END_MSG_MAP&lt;span style="color: #800040;"&gt;()&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Класс можно использовать множество раз для одного окна. За это спасибо механизму переходников ATL. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-1305956420545740411?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/1305956420545740411/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/08/how-to-subclass-window-multiple-times.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/1305956420545740411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/1305956420545740411'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/08/how-to-subclass-window-multiple-times.html' title='How to subclass a window multiple times'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-4586128785068753535</id><published>2011-07-17T22:27:00.002+03:00</published><updated>2011-07-18T14:22:31.181+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WinAPI'/><category scheme='http://www.blogger.com/atom/ns#' term='Under the Hood'/><title type='text'>Focus and Windows activation (part 1)</title><content type='html'>&lt;p&gt;Недавно я плотно занимался созданием выпадающего окна, в котором есть кнопки, поле ввода, а также элемент управления типа "список". В одном случае окно работало независимо, как меню, в другом - привязывалось к полю ввода на родительской форме (собственное поле ввода не отображалось), текст которого служил фильтром для элементов списка. Создание выпадающих окон - очень сложная задача, много нюансов связанных с активацией окон, фокусом ввода, определением ситуаций когда окно необходимо закрыть и т.д. Эта статья - попытка доходчиво объяснить на примерах как работает активация окон и как функционирует фокус ввода.&lt;/p&gt;&lt;p&gt;Любой UI поток имеет состояние. Это состояние хранится где-то в недрах ОС, но доступно из пользовательского режима при помощи следующих функций:&lt;/p&gt;&lt;ul&gt; &lt;li&gt;&lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms633506(v=vs.85).aspx"&gt;GetGUIThreadInfo&lt;/a&gt;&lt;/code&gt;&lt;p&gt;Это, пожалуй, самая-самая функция, которая демонстрирует составляющие UI состояния потока. Возвращаемая структура &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms632604(v=vs.85).aspx"&gt;GUITHREADINFO&lt;/a&gt;&lt;/code&gt; хранит следующие значения:&lt;/p&gt; &lt;pre&gt; typedef struct tagGUITHREADINFO {
  DWORD cbSize;
  DWORD flags;
  HWND  hwndActive;
  HWND  hwndFocus;
  HWND  hwndCapture;
  HWND  hwndMenuOwner;
  HWND  hwndMoveSize;
  HWND  hwndCaret;
  RECT  rcCaret;
} GUITHREADINFO, *PGUITHREADINFO;
&lt;/pre&gt; &lt;ol&gt;  &lt;li&gt;&lt;code&gt;&lt;em&gt;flags&lt;/em&gt;&lt;/code&gt;&lt;p&gt;Флажки состояний потока - мигающая каретка, меню, окно в процессе изменения размера или положения и т.п.&lt;/p&gt;  &lt;/li&gt;
  &lt;li&gt;&lt;code&gt;&lt;em&gt;hwndActive&lt;/em&gt;&lt;/code&gt;&lt;p&gt;Дескриптор активного окна потока.&lt;/p&gt;  &lt;/li&gt;
  &lt;li&gt;&lt;code&gt;&lt;em&gt;hwndFocus&lt;/em&gt;&lt;/code&gt;&lt;p&gt;Дескриптор окна потока, которое имеет логический фокус.&lt;/p&gt;  &lt;/li&gt;
  &lt;li&gt;&lt;code&gt;&lt;em&gt;hwndCapture&lt;/em&gt;&lt;/code&gt;&lt;p&gt;Дескриптор окна потока, которое захватило мышь вызовом &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms646262(v=vs.85).aspx"&gt;SetCapture&lt;/a&gt;&lt;/code&gt;.&lt;/p&gt;  &lt;/li&gt;
  &lt;li&gt;&lt;code&gt;&lt;em&gt;hwndMenuOwner&lt;/em&gt;&lt;/code&gt;&lt;p&gt;Дескриптор окна потока, которое владеет текущим меню.&lt;/p&gt;  &lt;/li&gt;
  &lt;li&gt;&lt;code&gt;&lt;em&gt;hwndMoveSize&lt;/em&gt;&lt;/code&gt;&lt;p&gt;Дескриптор окна потока, которое в процессе изменения размера или положения.&lt;/p&gt;  &lt;/li&gt;
  &lt;li&gt;&lt;code&gt;&lt;em&gt;hwndCaret&lt;/em&gt;&lt;/code&gt;&lt;p&gt;Дескриптор окна потока, которое отображает каретку.&lt;/p&gt;  &lt;/li&gt;
  &lt;li&gt;&lt;code&gt;&lt;em&gt;rcCaret&lt;/em&gt;&lt;/code&gt;&lt;p&gt;Прямоугольная область каретки.&lt;/p&gt;  &lt;/li&gt;
 &lt;/ol&gt; &lt;/li&gt;
 &lt;li&gt;&lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms646292(v=vs.85).aspx"&gt;GetActiveWindow&lt;/a&gt;&lt;/code&gt;&lt;p&gt;Возвращает значение &lt;code&gt;hwndActive&lt;/code&gt; структуры &lt;code&gt;GUITHREADINFO&lt;/code&gt; текущего потока.&lt;/p&gt; &lt;/li&gt;
 &lt;li&gt;&lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms646294(VS.85).aspx"&gt;GetFocus&lt;/a&gt;&lt;/code&gt;&lt;p&gt;Возвращает значение &lt;code&gt;hwndFocus&lt;/code&gt; структуры &lt;code&gt;GUITHREADINFO&lt;/code&gt; текущего потока.&lt;/p&gt; &lt;/li&gt;
 &lt;li&gt;&lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms646257(v=vs.85).aspx"&gt;GetCapture&lt;/a&gt;&lt;/code&gt;&lt;p&gt;Возвращает значение &lt;code&gt;hwndCapture&lt;/code&gt; структуры &lt;code&gt;GUITHREADINFO&lt;/code&gt; текущего потока.&lt;/p&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;В системе может быть активно множество потоков, каждый из которых, являясь UI потоком (&lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms633525(v=VS.85).aspx"&gt;IsGUIThread&lt;/a&gt;&lt;/code&gt; возвращает истину, а также позволяет явно активировать поток в качестве UI потока; эта активация выполняется автоматически в момент первого использования функций для работы с окнами), имеет вышеописанное состояние. Но пользовательский ввод с клавиатуры попадает лишь в определенное окно, дескриптор которого совпадает с &lt;code&gt;hwndFocus&lt;/code&gt; &lt;em&gt;одного&lt;/em&gt; из потоков. Почему так происходит? Потому, что существует глобальное состояние рабочего стола ОС, а в него входят так называемые &lt;em&gt;Foreground Thread&lt;/em&gt; и &lt;em&gt;Foreground Window&lt;/em&gt;. &lt;em&gt;Foreground Window&lt;/em&gt; - это окно верхнего уровня, которое содержит (или же само таковым является) элемент управления с физическим фокусом. Логический фокус - это состояние потока, физический фокус - состояние рабочего стола и привязка клавиатуры к потоку и окну. &lt;em&gt;Foreground Thread&lt;/em&gt; владеет окном с физическим фокусом, в этот поток будут попадать клавиатурные сообщения. &lt;em&gt;Foreground Thread&lt;/em&gt; не обязательно владеет &lt;em&gt;Foreground Window&lt;/em&gt;, поскольку элемент управления может быть создать в другом потоке и размещен на окне верхнего уровня. Функция &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms633505(v=vs.85).aspx"&gt;GetForegroundWindow&lt;/a&gt;&lt;/code&gt; позволяет узнать какое окно сейчас активно с точки зрения пользовательского ввода.&lt;/p&gt;&lt;p&gt;Стоит заметить, что &lt;em&gt;Active Window&lt;/em&gt; и &lt;em&gt;Foreground Window&lt;/em&gt; - это top-level окна, без стиля &lt;code&gt;WS_CHILD&lt;/code&gt;, а &lt;code&gt;Focus Window&lt;/code&gt; может быть как top-level окном, так и любым его дочерним окном.&lt;/p&gt;&lt;h2&gt;Тестовое приложение.&lt;/h2&gt;&lt;p&gt;Тестовое приложение состоит из нескольких оконных классов - &lt;code&gt;CTopLevelWnd&lt;/code&gt;, &lt;code&gt;CTracingButton&lt;/code&gt; и &lt;code&gt;CTracingEdit&lt;/code&gt;. Обработчики интересных нам сообщений содержат трассировочный код, который отправляет полезную информацию в лог. Текст окон содержит идентификатор оконного потока, а за ним - дескриптор окна.&lt;/p&gt;&lt;p&gt;&lt;code&gt;Трассировочная информация содержит следующие элементы:&lt;/code&gt;&lt;/p&gt;&lt;ol&gt; &lt;li&gt;&lt;code&gt;--&amp;gt;&lt;/code&gt; отмечает точку входа в обработчик, &lt;code&gt;&amp;lt;--&lt;/code&gt; - выхода; &lt;code&gt;&amp;lt;-&amp;gt;&lt;/code&gt; идентифицирует операцию;&lt;/li&gt;
 &lt;li&gt;далее следует идентификатор текущего потока;&lt;/li&gt;
 &lt;li&gt;после имя класса (если мы попали в обработчик оконного сообщения);&lt;/li&gt;
 &lt;li&gt;в скобках указывается дескриптор окна (если это окно либо элемент управления);&lt;/li&gt;
 &lt;li&gt;потом имя функции или метода с параметрами;&lt;/li&gt;
 &lt;li&gt;завершает это все статус рабочего стола/потока - &lt;em&gt;Foreground Window (FW)&lt;/em&gt;, &lt;em&gt;Active Window (AW)&lt;/em&gt; и &lt;em&gt;Focused Window (F)&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;На все потоки установлены хуки &lt;code&gt;WH_GETMESSAGE&lt;/code&gt; и &lt;code&gt;WH_CBT&lt;/code&gt;, трассирующие интересные события.&lt;/p&gt;&lt;p&gt;Цикл сообщений - свой. Каждому вызову &lt;code&gt;GetMessage&lt;/code&gt; предшествует &lt;code&gt;PeekMessage&lt;/code&gt; с флагом &lt;code&gt;PM_NOREMOVE&lt;/code&gt;. Это сделано для того, чтобы мы видели сообщения, которые вытягивает сам поток, а также сообщения, которые вынимает оттуда ОС без нашего ведома.&lt;/p&gt;&lt;h2&gt;Сценарий 1 - активация\деактивация окна приложения.&lt;/h2&gt;&lt;p&gt;&lt;img alt="Scenario 1" src="https://sites.google.com/site/chabster/focus-and-windows-activation/Scenario1.png" style="float: right" /&gt; Рассмотрим следующий сценарий: окно приложения неактивно, окно Notepad активно. Пользователь производит щелчок мышью по текстовому полю ввода окна приложения. Окно активируется, заголовок меняет свой внешний вид, фокус ввода получает поле ввода. Далее щелчок по окну Notepad. Окно деактивируется. Трассировочный лог происходящего приведен ниже, вместе с детальным разбором всех событий.&lt;/p&gt;&lt;div style="clear: both"&gt;&lt;/div&gt;&lt;pre&gt;&amp;lt;-&amp;gt; 1AC4: GetMsgProc(wParam = PM_NOREMOVE, lParam = { message = WM_LBUTTONDOWN } { FW = 0, AW = 0, F = 0 }
--&amp;gt; 1AC4: CTracingEdit(1709F4)::OnMouseActivate(pDesktopWnd = B0B70, nHitTest = 1, message = 513) { FW = 0, AW = 0, F = 0 }
   --&amp;gt; 1AC4: CTopLevelWnd(B0B70)::OnMouseActivate(pDesktopWnd = B0B70, nHitTest = 1, message = 513) { FW = 0, AW = 0, F = 0 }
   &amp;lt;-- 1AC4: CTopLevelWnd(B0B70)::OnMouseActivate(pDesktopWnd = B0B70, nHitTest = 1, message = 513) { FW = 0, AW = 0, F = 0 }
&amp;lt;-- 1AC4: CTopLevelWnd(1709F4)::OnMouseActivate(pDesktopWnd = B0B70, nHitTest = 1, message = 513) { FW = 0, AW = 0, F = 0 }
&amp;lt;-&amp;gt; 1AC4: CBTProc(HCBT_ACTIVATE, hWnd = B0B70, AS = { hWndActive = 0, fMouse = 1 }) { FW = 0, AW = 0, F = 0 }
--&amp;gt; 1AC4: CTopLevelWnd(B0B70)::OnActivateApp(bActive = 1, dwThreadID = 0) { FW = B0B70, AW = B0B70, F = 0 }
&amp;lt;-- 1AC4: CTopLevelWnd(B0B70)::OnActivateApp(bActive = 1, dwThreadID = 0) { FW = B0B70, AW = B0B70, F = 0 }
--&amp;gt; 1AC4: CTopLevelWnd(B0B70)::OnNcActivate(bActive = 1) { FW = B0B70, AW = B0B70, F = 0 }
&amp;lt;-- 1AC4: CTopLevelWnd(B0B70)::OnNcActivate(bActive = 1) { FW = B0B70, AW = B0B70, F = 0 }
--&amp;gt; 1AC4: CTopLevelWnd(B0B70)::OnActivate(nState = 2, pWndOther = 0, bMinimized = 0) { FW = B0B70, AW = B0B70, F = 0 }
   &amp;lt;-&amp;gt; 1AC4: CBTProc(HCBT_SETFOCUS, hSetFocusWnd = B0B70, hKillFocusWnd = 0) { FW = B0B70, AW = B0B70, F = 0 }
   --&amp;gt; 1AC4: CTopLevelWnd(B0B70)::OnSetFocus(pOldWnd = 0) { FW = B0B70, AW = B0B70, F = B0B70 }
   &amp;lt;-- 1AC4: CTopLevelWnd(B0B70)::OnSetFocus(pOldWnd = 0) { FW = B0B70, AW = B0B70, F = B0B70 }
&amp;lt;-- 1AC4: CTopLevelWnd(B0B70)::OnActivate(nState = 2, pWndOther = 0, bMinimized = 0) { FW = B0B70, AW = B0B70, F = B0B70 }
&amp;lt;-&amp;gt; 1AC4: GetMsgProc(wParam = PM_REMOVE, lParam = { message = WM_LBUTTONDOWN } { FW = B0B70, AW = B0B70, F = B0B70 }
--&amp;gt; 1AC4: CTracingEdit(1709F4)::OnLButtonDown(nFlags = 1, point = {114, 10}) { FW = B0B70, AW = B0B70, F = B0B70 }
   &amp;lt;-&amp;gt; 1AC4: CBTProc(HCBT_SETFOCUS, hSetFocusWnd = 1709F4, hKillFocusWnd = B0B70) { FW = B0B70, AW = B0B70, F = B0B70 }
   --&amp;gt; 1AC4: CTopLevelWnd(B0B70)::OnKillFocus(pNewWnd = 1709F4) { FW = B0B70, AW = B0B70, F = 1709F4 }
   &amp;lt;-- 1AC4: CTopLevelWnd(B0B70)::OnKillFocus(pNewWnd = 1709F4) { FW = B0B70, AW = B0B70, F = 1709F4 }
   --&amp;gt; 1AC4: CTracingEdit(1709F4)::OnSetFocus(pOldWnd = B0B70) { FW = B0B70, AW = B0B70, F = 1709F4 }
   &amp;lt;-- 1AC4: CTracingEdit(1709F4)::OnSetFocus(pOldWnd = B0B70) { FW = B0B70, AW = B0B70, F = 1709F4 }
&amp;lt;-- 1AC4: CTracingEdit(1709F4)::OnLButtonDown(nFlags = 1, point = {114, 10}) { FW = B0B70, AW = B0B70, F = 1709F4 }
&amp;lt;-&amp;gt; 1AC4: GetMsgProc(wParam = PM_NOREMOVE, lParam = { message = WM_LBUTTONUP } { FW = B0B70, AW = B0B70, F = 1709F4 }
&amp;lt;-&amp;gt; 1AC4: GetMsgProc(wParam = PM_REMOVE, lParam = { message = WM_LBUTTONUP } { FW = B0B70, AW = B0B70, F = 1709F4 }
--&amp;gt; 1AC4: CTracingEdit(1709F4)::OnLButtonUp(nFlags = 0, point = {114, 10}) { FW = B0B70, AW = B0B70, F = 1709F4 }
&amp;lt;-- 1AC4: CTracingEdit(1709F4)::OnLButtonUp(nFlags = 0, point = {114, 10}) { FW = B0B70, AW = B0B70, F = 1709F4 }

--&amp;gt; 1AC4: CTopLevelWnd(B0B70)::OnNcActivate(bActive = 0) { FW = 0, AW = B0B70, F = 1709F4 }
&amp;lt;-- 1AC4: CTopLevelWnd(B0B70)::OnNcActivate(bActive = 0) { FW = 20830, AW = B0B70, F = 1709F4 }
--&amp;gt; 1AC4: CTopLevelWnd(B0B70)::OnActivate(nState = 0, pWndOther = 0, bMinimized = 0) { FW = 20830, AW = B0B70, F = 1709F4 }
&amp;lt;-- 1AC4: CTopLevelWnd(B0B70)::OnActivate(nState = 0, pWndOther = 0, bMinimized = 0) { FW = 20830, AW = B0B70, F = 1709F4 }
--&amp;gt; 1AC4: CTopLevelWnd(B0B70)::OnActivateApp(bActive = 0, dwThreadID = 370) { FW = 20830, AW = 0, F = 1709F4 }
&amp;lt;-- 1AC4: CTopLevelWnd(B0B70)::OnActivateApp(bActive = 0, dwThreadID = 370) { FW = 20830, AW = 0, F = 1709F4 }
--&amp;gt; 1AC4: CTracingEdit(1709F4)::OnKillFocus(pNewWnd = 0) { FW = 20830, AW = 0, F = 0 }
&amp;lt;-- 1AC4: CTracingEdit(1709F4)::OnKillFocus(pNewWnd = 0) { FW = 20830, AW = 0, F = 0 }

&lt;/pre&gt;&lt;ol&gt; &lt;li&gt;&lt;br /&gt;
 &lt;pre&gt;&amp;lt;-&amp;gt; 1AC4: GetMsgProc(wParam = PM_NOREMOVE, lParam = { message = WM_LBUTTONDOWN } { FW = 0, AW = 0, F = 0 }&lt;/pre&gt; &lt;p&gt;В очереди появилось сообщение &lt;code&gt;WM_LBUTTONDOWN&lt;/code&gt;. Но ОС пока еще ничего не делает. Действия ниже ОС выполняет лишь когда сообщение &lt;em&gt;изымается&lt;/em&gt; из очереди вызовом &lt;code&gt;GetMessage&lt;/code&gt; или &lt;code&gt;PeekMessage&lt;/code&gt; с флагом &lt;code&gt;PM_REMOVE&lt;/code&gt; (а именно эти вызовы будут выше по стеку нежели выполняющийся далее код).&lt;/p&gt; &lt;/li&gt;
 &lt;li&gt;&lt;br /&gt;
 &lt;pre&gt;--&amp;gt; 1AC4: CTracingEdit(1709F4)::OnMouseActivate(pDesktopWnd = B0B70, nHitTest = 1, message = 513) { FW = 0, AW = 0, F = 0 }
   --&amp;gt; 1AC4: CTopLevelWnd(B0B70)::OnMouseActivate(pDesktopWnd = B0B70, nHitTest = 1, message = 513) { FW = 0, AW = 0, F = 0 }
   &amp;lt;-- 1AC4: CTopLevelWnd(B0B70)::OnMouseActivate(pDesktopWnd = B0B70, nHitTest = 1, message = 513) { FW = 0, AW = 0, F = 0 }
&amp;lt;-- 1AC4: CTopLevelWnd(1709F4)::OnMouseActivate(pDesktopWnd = B0B70, nHitTest = 1, message = 513) { FW = 0, AW = 0, F = 0 }&lt;/pre&gt; &lt;p&gt;Вызван обработчик сообщения &lt;code&gt;WM_MOUSEACTIVATE&lt;/code&gt; класса &lt;code&gt;CTracingEdit&lt;/code&gt;. ОС посылает это сообщение окну, которое находилось под курсором мыши во время щелчка. Код возврата сообщает ОС что следует делать далее - активировать окно или нет, пропускать сообщение о нажатии или же удалить его из очереди. Обработчик по умолчанию посылает это же сообщение родительскому окну. Обработкик корневых окон возвращает &lt;code&gt;MA_ACTIVATE&lt;/code&gt;, что приводит к активации окна и получению сообщений о щелчке.&lt;/p&gt; &lt;p&gt;При такой схеме элемент управления может определить реакцию окна.&lt;/p&gt; &lt;p&gt;Стоит заметить, что сообщение синхронное и его обработчик вызывается из кода режима ядра, управление которому передается вызовом функции &lt;code&gt;GetMessage&lt;/code&gt; из кода приложения. Если быть совсем точным, то процедура активации в даном сценарии происходит за один вызов &lt;code&gt;GetMessage&lt;/code&gt;, которая в результате вернет &lt;code&gt;WM_LBUTTONDOWN&lt;/code&gt; (см. далее).&lt;/p&gt; &lt;pre&gt;&amp;gt;	Win32App.exe!CTracingEdit::OnMouseActivate(CWnd * pDesktopWnd, unsigned int nHitTest, unsigned int message)  Line 115	C++
 	Win32App.exe!CWnd::OnWndMsg(unsigned int message, unsigned int wParam, long lParam, long * pResult)  Line 2375 + 0x2f bytes	C++
 	Win32App.exe!CWnd::WindowProc(unsigned int message, unsigned int wParam, long lParam)  Line 2087 + 0x20 bytes	C++
 	Win32App.exe!AfxCallWndProc(CWnd * pWnd, HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam)  Line 257 + 0x1c bytes	C++
 	Win32App.exe!AfxWndProc(HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam)  Line 420	C++
 	user32.dll!_InternalCallWinProc@20()  + 0x23 bytes	
 	user32.dll!_UserCallWinProcCheckWow@32()  + 0xb3 bytes	
 	user32.dll!_DispatchClientMessage@20()  + 0x4b bytes	
 	user32.dll!___fnDWORD@4()  + 0x24 bytes	
 	ntdll.dll!_KiUserCallbackDispatcher@12()  + 0x2e bytes	
 	user32.dll!_DispatchClientMessage@20() 	
 	user32.dll!_NtUserGetMessage@16()  + 0xc bytes	
 	user32.dll!_GetMessageW@16()  + 0x2b bytes	
 	Win32App.exe!AfxInternalPumpMessage()  Line 153 + 0x13 bytes	C++
 	Win32App.exe!AfxPumpMessage()  Line 193	C++
 	Win32App.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow)  Line 135 + 0x5 bytes	C++
&lt;/pre&gt; &lt;/li&gt;
 &lt;li&gt;&lt;br /&gt;
 &lt;pre&gt;&amp;lt;-&amp;gt; 1AC4: CBTProc(HCBT_ACTIVATE, hWnd = B0B70, AS = { hWndActive = 0, fMouse = 1 }) { FW = 0, AW = 0, F = 0 }&lt;/pre&gt; &lt;p&gt;ОС сообщает приложению, что окно &lt;code&gt;B0B70&lt;/code&gt; сейчас &lt;em&gt;будет&lt;/em&gt; активировано. Обратите внимание, что &lt;em&gt;Foreground Window (FW)&lt;/em&gt;, &lt;em&gt;Active Window (AW)&lt;/em&gt; и &lt;em&gt;Focused Window (F)&lt;/em&gt; - не определены (равны нулю).&lt;/p&gt; &lt;/li&gt;
 &lt;li&gt;&lt;br /&gt;
 &lt;pre&gt;--&amp;gt; 1AC4: CTopLevelWnd(B0B70)::OnActivateApp(bActive = 1, dwThreadID = 0) { FW = B0B70, AW = B0B70, F = 0 }
&amp;lt;-- 1AC4: CTopLevelWnd(B0B70)::OnActivateApp(bActive = 1, dwThreadID = 0) { FW = B0B70, AW = B0B70, F = 0 }&lt;/pre&gt; &lt;p&gt;Обработчик сообщения &lt;code&gt;WM_ACTIVATEAPP. &lt;/code&gt;Посылается всем окнам верхнего уровня, которые принадлежат потоку активируемого окна, тоесть &lt;code&gt;1AC4&lt;/code&gt;. Окно в этом сценарии всего одно. &lt;em&gt;Foreground Window (FW)&lt;/em&gt; и &lt;em&gt;Active Window (AW)&lt;/em&gt; &lt;em&gt;уже&lt;/em&gt; установлены. &lt;/p&gt; &lt;/li&gt;
 &lt;li&gt;&lt;br /&gt;
 &lt;pre&gt;--&amp;gt; 1AC4: CTopLevelWnd(B0B70)::OnNcActivate(bActive = 1) { FW = B0B70, AW = B0B70, F = 0 }
&amp;lt;-- 1AC4: CTopLevelWnd(B0B70)::OnNcActivate(bActive = 1) { FW = B0B70, AW = B0B70, F = 0 }&lt;/pre&gt; &lt;p&gt;Обработчик сообщения &lt;code&gt;WM_NCACTIVATE&lt;/code&gt;. Код возврата в этом случае игнорируется.&lt;/p&gt; &lt;/li&gt;
 &lt;li&gt;&lt;br /&gt;
 &lt;pre&gt;--&amp;gt; 1AC4: CTopLevelWnd(B0B70)::OnActivate(nState = 2, pWndOther = 0, bMinimized = 0) { FW = B0B70, AW = B0B70, F = 0 }&lt;/pre&gt; &lt;p&gt;Обработчик сообщения &lt;code&gt;WM_ACTIVATE&lt;/code&gt;. По умолчанию вызывает &lt;code&gt;SetFocus(self)&lt;/code&gt;, устанавливает фокус на активируемое окно.&lt;/p&gt; &lt;/li&gt;
 &lt;li&gt;&lt;br /&gt;
 &lt;pre&gt;&amp;lt;-&amp;gt; 1AC4: CBTProc(HCBT_SETFOCUS, hSetFocusWnd = B0B70, hKillFocusWnd = 0) { FW = B0B70, AW = B0B70, F = 0 }&lt;/pre&gt; &lt;p&gt;ОС сообщает приложению, что фокус ввода &lt;em&gt;собирается&lt;/em&gt; переместиться из ниоткуда &lt;code&gt;(hKillFocusWnd = 0)&lt;/code&gt; в окно &lt;code&gt;B0B70&lt;/code&gt; (это &lt;code&gt;CTopLevelWnd&lt;/code&gt;). &lt;em&gt;Focused Window (F)&lt;/em&gt; пока что неопределен.&lt;/p&gt; &lt;/li&gt;
 &lt;li&gt;&lt;br /&gt;
 &lt;pre&gt;--&amp;gt; 1AC4: CTopLevelWnd(B0B70)::OnSetFocus(pOldWnd = 0) { FW = B0B70, AW = B0B70, F = B0B70 }
&amp;lt;-- 1AC4: CTopLevelWnd(B0B70)::OnSetFocus(pOldWnd = 0) { FW = B0B70, AW = B0B70, F = B0B70 }&lt;/pre&gt; &lt;p&gt;Уведомление о попадании фокуса в окно.&lt;/p&gt; &lt;/li&gt;
 &lt;li&gt;&lt;br /&gt;
 &lt;pre&gt;&amp;lt;-- 1AC4: CTopLevelWnd(B0B70)::OnActivate(nState = 2, pWndOther = 0, bMinimized = 0) { FW = B0B70, AW = B0B70, F = B0B70 }&lt;/pre&gt; &lt;p&gt;Выход из обработчика &lt;code&gt;WM_ACTIVATE&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt;
 &lt;li&gt;&lt;br /&gt;
 &lt;pre&gt;&amp;lt;-&amp;gt; 1AC4: GetMsgProc(wParam = PM_REMOVE, lParam = { message = WM_LBUTTONDOWN } { FW = B0B70, AW = B0B70, F = B0B70 }&lt;/pre&gt; &lt;p&gt;Здесь ОС сделала все, что хотела, поэтому собирается вернуть управление в приложение.&lt;/p&gt; &lt;/li&gt;
 &lt;li&gt;&lt;br /&gt;
 &lt;pre&gt;--&amp;gt; 1AC4: CTracingEdit(1709F4)::OnLButtonDown(nFlags = 1, point = {116, 13}) { FW = B0B70, AW = B0B70, F = B0B70 }&lt;/pre&gt; &lt;p&gt;Нажатие мыши наконец дошло до элемента управления.&lt;/p&gt; &lt;/li&gt;
 &lt;li&gt;&lt;br /&gt;
 &lt;pre&gt;&amp;lt;-&amp;gt; 1AC4: CBTProc(HCBT_SETFOCUS, hSetFocusWnd = 1709F4, hKillFocusWnd = B0B70) { FW = B0B70, AW = B0B70, F = B0B70 }&lt;/pre&gt; &lt;p&gt;Эдемент управления реагирует на сообщение изменением фокуса. Поле ввода забирает фокус на себя, о чем говорят следующие строки.&lt;/p&gt; &lt;/li&gt;
 &lt;li&gt;&lt;br /&gt;
 &lt;pre&gt;--&amp;gt; 1AC4: CTopLevelWnd(B0B70)::OnKillFocus(pNewWnd = 1709F4) { FW = B0B70, AW = B0B70, F = 1709F4 }
&amp;lt;-- 1AC4: CTopLevelWnd(B0B70)::OnKillFocus(pNewWnd = 1709F4) { FW = B0B70, AW = B0B70, F = 1709F4 }
--&amp;gt; 1AC4: CTracingEdit(1709F4)::OnSetFocus(pOldWnd = B0B70) { FW = B0B70, AW = B0B70, F = 1709F4 }
&amp;lt;-- 1AC4: CTracingEdit(1709F4)::OnSetFocus(pOldWnd = B0B70) { FW = B0B70, AW = B0B70, F = 1709F4 }&lt;/pre&gt; &lt;/li&gt;
 &lt;li&gt;&lt;br /&gt;
 &lt;pre&gt;&amp;lt;-- 1AC4: CTracingEdit(1709F4)::OnLButtonDown(nFlags = 1, point = {116, 13}) { FW = B0B70, AW = B0B70, F = 1709F4 }&lt;/pre&gt; &lt;p&gt;Здесь мы наконец возвращаемся к циклу сообщений.&lt;/p&gt; &lt;/li&gt;
 &lt;li&gt;&lt;br /&gt;
 &lt;pre&gt;&amp;lt;-&amp;gt; 1AC4: GetMsgProc(wParam = PM_NOREMOVE, lParam = { message = WM_LBUTTONUP } { FW = B0B70, AW = B0B70, F = 1709F4 }
&amp;lt;-&amp;gt; 1AC4: GetMsgProc(wParam = PM_REMOVE, lParam = { message = WM_LBUTTONUP } { FW = B0B70, AW = B0B70, F = 1709F4 }&lt;/pre&gt; &lt;p&gt;И получаем из очереди &lt;code&gt;WM_LBUTTONUP&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt;
 &lt;li&gt;&lt;br /&gt;
 &lt;pre&gt;--&amp;gt; 1AC4: CTracingEdit(1709F4)::OnLButtonUp(nFlags = 0, point = {116, 13}) { FW = B0B70, AW = B0B70, F = 1709F4 }
&amp;lt;-- 1AC4: CTracingEdit(1709F4)::OnLButtonUp(nFlags = 0, point = {116, 13}) { FW = B0B70, AW = B0B70, F = 1709F4 }&lt;/pre&gt; &lt;p&gt;Обработчик которого не делает ничего полезного.&lt;/p&gt; &lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Какие выводы можно сделать из вышенаписанного? &lt;/p&gt;&lt;ol&gt; &lt;li&gt;Элементы управления могут управлять активацией корневых окон.&lt;/li&gt;
 &lt;li&gt;Код ОС, активирующий окна и устанавливающий фокус ввода, выполняется после попадания асинхронного сообщения в очередь и до изымания этого сообщения из очереди приложением (если окно активируется мышью). В противном случае - просто ниже по стеку от вызовов &lt;code&gt;GetMessage&lt;/code&gt; или &lt;code&gt;PeekMessage&lt;/code&gt; с флагом &lt;code&gt;PM_REMOVE&lt;/code&gt;.&lt;/li&gt;
 &lt;li&gt;Если окно активируется не мышью, а другим способом (Alt-TAB, например), - происходит все то же, за исключением обработчиков &lt;code&gt;WM_MOUSEACTIVATE&lt;/code&gt;, &lt;code&gt;WM_LBUTTONDOWN&lt;/code&gt; + &lt;code&gt;WM_LBUTTONUP&lt;/code&gt; (&lt;code&gt;GetMessage&lt;/code&gt; не изымает асинхронные сообщения из очереди, а все процедуры активации происходят без выхода из &lt;code&gt;GetMessage&lt;/code&gt;).&lt;/li&gt;
 &lt;li&gt;ОС не восстанавливает фокус ввода. Если окно было активно и фокус ввода находился на кнопке - то при деактивации и последующей активации он автоматически не вернется обратно на кнопку. За этим нужно сделить самостоятельно. Или воспользоваться оконными процедурами диалоговых окон, которые выполняют эти действия за нас.&lt;/li&gt;
 &lt;li&gt;Лучшее место для восстановления фокуса - обработчик &lt;code&gt;WM_ACTIVATE&lt;/code&gt;. Если при выходе из него фокус все еще неопределен - ОС устанавливает его на активируемое окно, так же, как делает это обработчик &lt;code&gt;WM_ACTIVATE&lt;/code&gt; по умолчанию.&lt;/li&gt;
 &lt;li&gt;При щелчке на элементы управления (кнопки, списки, поля воода) ОС автоматически не устанавливает фокус ввода в целевое окно. Этим занимаются сами элементы управления, обрабатывая &lt;code&gt;WM_?BUTTONDOWN&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;При деактивации окна вызываются обработчики сообщений &lt;code&gt;WM_NCACTIVATE&lt;/code&gt;, &lt;code&gt;WM_ACTIVATE&lt;/code&gt;, &lt;code&gt;WM_ACTIVATEAPP&lt;/code&gt;, &lt;code&gt;WM_KILLFOCUS&lt;/code&gt;. Обратите внимание как изменяется состояние рабочего стола и потока во время вызова обработчиков по умолчанию. Например на момент входа в &lt;code&gt;CTopLevelWnd::OnNcActivate&lt;/code&gt; &lt;em&gt;Foreground Window&lt;/em&gt; неопределен (равен нулю), а после вызова обработчика по умолчанию - он уже равен дескриптору окна Notepad. Поскольку пачка всех этих сообщений обрабатывается синхронно - то они посылаются последовательно активирующимся окнам и деактивирующимся, даже если окна принадлежат разным потокам или даже процессам.&lt;/p&gt;&lt;p&gt;В следующей части мы рассмотрим этот сценарий более детально - посмотрим как перемешиваются сообщения активирущегося окна и деактивирующегося. И как можно управлять активацией, вместе с ломанием стереотипа о том, что на рабочем столе может быть лишь одно активированное окно, а также единственное окно с логическим фокусом ввода.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-4586128785068753535?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/4586128785068753535/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/07/focus-and-windows-activation-part-1.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/4586128785068753535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/4586128785068753535'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/07/focus-and-windows-activation-part-1.html' title='Focus and Windows activation (part 1)'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-3022308269664845113</id><published>2011-07-01T22:47:00.000+03:00</published><updated>2011-07-01T22:47:58.364+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WinAPI'/><category scheme='http://www.blogger.com/atom/ns#' term='problem'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Object Oriented WinAPI hooks</title><content type='html'>&lt;p&gt;Some time ago I was playing with a &lt;code&gt;WH_GETMESSAGE&lt;/code&gt; message hook to 
intercept any mouse and keyboard input. The hook was installed in several UI threads 
controlled by different application modules. In order to install a message hook, 
you issue the following code:&lt;/p&gt;
&lt;pre&gt;
const HHOOK hHook = ::SetWindowsHookEx(WH_GETMESSAGE, &amp;amp;GetMsgProc, NULL, ::GetCurrentThreadId());
&lt;/pre&gt;
&lt;p&gt;and your &lt;code&gt;GetMsgProc&lt;/code&gt; looks like this one:&lt;/p&gt;
&lt;pre&gt;
LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam)
{
   // Extra work here...
   return ::CallNextHookEx(NULL, code, wParam, lParam);
}
&lt;/pre&gt;
&lt;p&gt;What if you need to pass control over to some object, invoke a member function? 
Keep in mind that &lt;code&gt;GetMsgProc&lt;/code&gt; is a free function (that doesn't receive 
hook handle in its parameters). Therefore you can't use anything to map invocation 
context to OOP world citizens. You could use a global object to overcome this issue, 
but still you can't install more than one message hook with the same callback function.&lt;/p&gt;
&lt;p&gt;So the only thing that can map to an object ... is the callback function itself. 
Hopefully, we are able to create that function on the fly, in memory:&lt;/p&gt;
&lt;pre&gt;
struct IGetMessageHookTarget
{
   virtual LRESULT GetMsgProc(int code, WPARAM wParam, LPARAM lParam)
   {
      return ::CallNextHookEx(NULL, code, wParam, lParam);
   }
};

class GetMessageHook : IGetMessageHookTarget
{
   static const size_t ProcSize = 18;
public:
   GetMessageHook() {
      BYTE getMsgProcBytes[ProcSize] =
      {
         0x55,                           // push        ebp
         0x8B, 0xEC,                     // mov         ebp,esp
         0xA1, 0x00, 0x00, 0x00, 0x00,   // mov         eax,dword ptr ds:[this]
         0xB9, 0x00, 0x00, 0x00, 0x00,   // mov         ecx,this
         0x8B, 0x10,                     // mov         edx,dword ptr [eax]
         0x5D,                           // pop         ebp
         0xFF, 0xE2,                     // jmp         edx
      };

      *reinterpret_cast&amp;lt;size_t *&amp;gt;(&amp;amp;getMsgProcBytes[4]) = reinterpret_cast&amp;lt;size_t&amp;gt;(this);
      *reinterpret_cast&amp;lt;size_t *&amp;gt;(&amp;amp;getMsgProcBytes[4 + 1 + sizeof(size_t)]) = reinterpret_cast&amp;lt;size_t&amp;gt;(this);

      const HANDLE hCurrentProcess = ::GetCurrentProcess();
      _getMsgProcBytes = ::VirtualAllocEx(hCurrentProcess, NULL, ProcSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
      CopyMemory(_getMsgProcBytes, getMsgProcBytes, sizeof(getMsgProcBytes));
      ::VirtualProtectEx(hCurrentProcess, _getMsgProcBytes, ProcSize, PAGE_EXECUTE, NULL);
      
      _hHook = ::SetWindowsHookEx(WH_GETMESSAGE, reinterpret_cast&amp;lt;HOOKPROC&amp;gt;(_getMsgProcBytes), NULL, ::GetCurrentThreadId());
   }

   ~GetMessageHook() {
      ::UnhookWindowsHookEx(_hHook);
      ::VirtualFreeEx(::GetCurrentProcess(), _getMsgProcBytes, ProcSize, MEM_RELEASE);
   }

protected:
   virtual LRESULT GetMsgProc(int code, WPARAM wParam, LPARAM lParam)
   {
      return ::CallNextHookEx(NULL, code, wParam, lParam);
   }

private:
   HHOOK _hHook;
   LPVOID _getMsgProcBytes;
};
&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;GetMessageHook&lt;/code&gt; constructor creates an in-memory code that passes 
control over to &lt;code&gt;GetMsgProc&lt;/code&gt; member function. Believe me - it works. 
At least on x86.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-3022308269664845113?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/3022308269664845113/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/07/object-oriented-winapi-hooks.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/3022308269664845113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/3022308269664845113'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/07/object-oriented-winapi-hooks.html' title='Object Oriented WinAPI hooks'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-4845337655975225571</id><published>2011-05-27T09:37:00.000+03:00</published><updated>2011-05-27T09:37:53.884+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>Herman Miller Embody and Aeron</title><content type='html'>&lt;p&gt;
В семье пополнение...
&lt;/p&gt;
&lt;p&gt;
&lt;a href="https://sites.google.com/site/chabster/bloggerpictures/HermanMiller.jpg?attredirects=0" imageanchor="1" style=""&gt;&lt;img border="0" height="776" width="1296" src="https://sites.google.com/site/chabster/bloggerpictures/HermanMiller.jpg?attredirects=0" /&gt;&lt;/a&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-4845337655975225571?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/4845337655975225571/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/05/herman-miller-embody-and-aeron.html#comment-form' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/4845337655975225571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/4845337655975225571'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/05/herman-miller-embody-and-aeron.html' title='Herman Miller Embody and Aeron'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-937457217001184487</id><published>2011-05-20T15:02:00.000+03:00</published><updated>2011-05-20T15:02:15.453+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><title type='text'>Cavalcade of Cartoon Comedy</title><content type='html'>&lt;p&gt;
Наткнулся на серию мультфильмов-пародий, называется Кавалькада мультипликационных комедий / Cavalcade of Cartoon Comedy (Seth MacFarlane / Сет Макфарлейн) 2008 г.
&lt;/p&gt;
&lt;iframe width="425" height="349" src="http://www.youtube.com/embed/9oWe0Y7YT34" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-937457217001184487?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/937457217001184487/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/05/cavalcade-of-cartoon-comedy.html#comment-form' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/937457217001184487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/937457217001184487'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/05/cavalcade-of-cartoon-comedy.html' title='Cavalcade of Cartoon Comedy'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/9oWe0Y7YT34/default.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-3699333133661115778</id><published>2011-05-18T20:49:00.002+03:00</published><updated>2011-07-17T22:28:36.611+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='problem'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='MFC'/><category scheme='http://www.blogger.com/atom/ns#' term='Under the Hood'/><title type='text'>How to prevent MFC dialog closing on Enter and Escape keys</title><content type='html'>&lt;p&gt;In this article I explain how to prevent an MFC dialog from handling the Enter  and Escape keys and not pass it on. With all required details for you to completely  understand why does it work the way it does. There are several possible solutions,  so you can choose the most suitable one.&lt;/p&gt;&lt;p&gt;The problem is the following: you have a dialog, no matter - top level window  or just a child container; you press Escape or Enter keys - the dialog disappears,  even if there are no OK and Cancel buttons on the dialog. It's very funny seeing  a child dialog drops out it's parent.&lt;/p&gt;&lt;p&gt;Let's see why this happens:&lt;/p&gt;&lt;pre&gt;OrderXMLReaderShell.exe!CFilterEditorDlgBase::OnCancel()  Line 61 C++
  mfc100ud.dll!_AfxDispatchCmdMsg(CCmdTarget * pTarget, unsigned int nID, int nCode, void (void)* pfn, void * pExtra, unsigned int nSig, AFX_CMDHANDLERINFO * pHandlerInfo)  Line 82 C++
  mfc100ud.dll!CCmdTarget::OnCmdMsg(unsigned int nID, int nCode, void * pExtra, AFX_CMDHANDLERINFO * pHandlerInfo)  Line 381 + 0x27 bytes C++
  mfc100ud.dll!CDialog::OnCmdMsg(unsigned int nID, int nCode, void * pExtra, AFX_CMDHANDLERINFO * pHandlerInfo)  Line 87 + 0x18 bytes C++
  mfc100ud.dll!CWnd::OnCommand(unsigned int wParam, long lParam)  Line 2729 C++
  mfc100ud.dll!CWnd::OnWndMsg(unsigned int message, unsigned int wParam, long lParam, long * pResult)  Line 2101 + 0x1e bytes C++
  mfc100ud.dll!CWnd::WindowProc(unsigned int message, unsigned int wParam, long lParam)  Line 2087 + 0x20 bytes C++
  mfc100ud.dll!AfxCallWndProc(CWnd * pWnd, HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam)  Line 257 + 0x1c bytes C++
  mfc100ud.dll!AfxWndProc(HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam)  Line 420 C++
  mfc100ud.dll!AfxWndProcBase(HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam)  Line 420 + 0x15 bytes C++
  user32.dll!_InternalCallWinProc@20()  + 0x23 bytes 
  user32.dll!_UserCallWinProcCheckWow@32()  + 0xb3 bytes 
  user32.dll!_SendMessageWorker@20()  + 0xee bytes 
  user32.dll!_SendMessageW@16()  + 0x49 bytes 
  user32.dll!_IsDialogMessageW@8()  + 0xef46 bytes 
&amp;gt; mfc100ud.dll!CWnd::IsDialogMessageW(tagMSG * lpMsg)  Line 198 C++
  mfc100ud.dll!CWnd::PreTranslateInput(tagMSG * lpMsg)  Line 4713 C++
  mfc100ud.dll!CDialog::PreTranslateMessage(tagMSG * pMsg)  Line 82 C++
  OrderXMLReaderShell.exe!CFindDlg::PreTranslateMessage(tagMSG * pMsg)  Line 56 C++
  mfc100ud.dll!CWnd::WalkPreTranslateTree(HWND__ * hWndStop, tagMSG * pMsg)  Line 3311 + 0x14 bytes C++
  mfc100ud.dll!AfxInternalPreTranslateMessage(tagMSG * pMsg)  Line 233 + 0x12 bytes C++
  mfc100ud.dll!CWinThread::PreTranslateMessage(tagMSG * pMsg)  Line 777 + 0x9 bytes C++
  mfc100ud.dll!AfxPreTranslateMessage(tagMSG * pMsg)  Line 252 + 0x11 bytes C++
  mfc100ud.dll!AfxInternalPumpMessage()  Line 178 + 0x18 bytes C++
  mfc100ud.dll!CWinThread::PumpMessage()  Line 900 C++
  mfc100ud.dll!CWinThread::Run()  Line 629 + 0xd bytes C++
  mfc100ud.dll!CWinApp::Run()  Line 832 C++
  mfc100ud.dll!AfxWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow)  Line 47 + 0xd bytes C++
  OrderXMLReaderShell.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow)  Line 26 C++
  OrderXMLReaderShell.exe!__tmainCRTStartup()  Line 547 + 0x2c bytes C
  OrderXMLReaderShell.exe!wWinMainCRTStartup()  Line 371 C
  kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes 
  ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes 
  ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes 
&lt;/pre&gt;&lt;p&gt;The execution flow got into &lt;a href="http://msdn.microsoft.com/en-us/library/kw3wtttf.aspx"&gt;&lt;code&gt;CDialog::OnCancel&lt;/code&gt;&lt;/a&gt; &lt;code&gt;virtual&lt;/code&gt; method. Here is the default MFC's implementation:&lt;/p&gt;&lt;pre&gt;void CDialog::OnCancel()
{
 EndDialog(IDCANCEL);
}
&lt;/pre&gt;&lt;p&gt;It simply ends the dialog, thus destroying the window.&lt;/p&gt;&lt;p&gt;Lets find out how do we get there. The control flow is the following:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Escape key is down&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WM_KEYDOWN&lt;/code&gt; message is queued into message queue&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AfxInternalPumpMessage&lt;/code&gt; gets the message from the queue and   invokes &lt;code&gt;AfxPreTranslateMessage&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CWnd::IsDialogMessage&lt;/code&gt; is reached&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IsDialogMessage&lt;/code&gt; WinAPI function is called by &lt;code&gt;CWnd::IsDialogMessage&lt;/code&gt;;   this function is the core of dialog management - it does things like keyboard   navigation.&lt;/li&gt;
&lt;li&gt;There is a &lt;code&gt;user32.dll!_SendMessageW@16()&lt;/code&gt; call from &lt;code&gt;IsDialogMessageW&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Which brings us to &lt;code&gt;CWnd::OnCommand&lt;/code&gt; with &lt;code&gt;wParam&lt;/code&gt;   equals to &lt;code&gt;IDCANCEL&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;End finally to &lt;code&gt;CDialog::OnCancel&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;code&gt;IsDialogMessageW&lt;/code&gt; examines the message and invokes &lt;code&gt;SendMessage(hwndDlg,  WM_COMMAND, MAKELONG(IDCANCEL, BN_CLICKED), ...);&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Short summary - MFC calls &lt;code&gt;IsDialogMessage&lt;/code&gt; API function, which in  turns emulates &lt;code&gt;IDCANCEL&lt;/code&gt; button click, which is being handled by MFC  eventually destroying the dialog.&lt;/p&gt;&lt;p&gt;It is not obvious why &lt;code&gt;IsDialogMessageW&lt;/code&gt; emulates &lt;code&gt;IDOK&lt;/code&gt;  and &lt;code&gt;IDCANCEL&lt;/code&gt; button clicks. I believe this is done to make developer's  life easier. Imagine you have no control over the message loop, can't do any message  pre translation. You'll have to handle Enter and Escape keys for every control on  the dialog. That's pain.&lt;/p&gt;&lt;p&gt;What can we do to solve the problem? You can't change OS behavior for sure, but  can do the following:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Override &lt;code&gt;CDialog::OnOK/OnCancel&lt;/code&gt; and do nothing  &lt;p&gt;The following applies:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Dialog is not destroyed on Enter or Escape&lt;/li&gt;
&lt;li&gt;Focused inline controls don't receive &lt;code&gt;WM_KEYDOWN&lt;/code&gt; for   &lt;code&gt;VK_ENTER&lt;/code&gt; and &lt;code&gt;VK_ESCAPE&lt;/code&gt; codes&lt;/li&gt;
&lt;li&gt;OK/Cancel button clicks have no effect&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Override &lt;code&gt;CDialog::PreTranslateMessage&lt;/code&gt; and don't call the base   if &lt;code&gt;pMsg-&amp;gt;message == WM_KEYDOWN &amp;amp;&amp;amp; (pMsg-&amp;gt;wParam == VK_ESCAPE   || pMsg-&amp;gt;wParam == VK_RETURN)&lt;/code&gt;  &lt;p&gt;If &lt;code&gt;CDialog::PreTranslateMessage&lt;/code&gt; returns &lt;code&gt;TRUE&lt;/code&gt; the   following applies:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Dialog is not destroyed on Enter or Escape&lt;/li&gt;
&lt;li&gt;Focused inline controls don't receive &lt;code&gt;WM_KEYDOWN&lt;/code&gt; for   &lt;code&gt;VK_RETURN&lt;/code&gt; and &lt;code&gt;VK_ESCAPE&lt;/code&gt; codes, unless you do dispatch    them before &lt;code&gt;CDialog::PreTranslateMessage&lt;/code&gt; returns&lt;/li&gt;
&lt;li&gt;OK/Cancel button clicks have desired effect&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;If &lt;code&gt;CDialog::PreTranslateMessage&lt;/code&gt; returns &lt;code&gt;FALSE&lt;/code&gt; the   following applies:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;MFC calls parent's &lt;code&gt;PreTranslateMessage&lt;/code&gt; (which brings us    back if the parent is a CDialog instance)&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Override &lt;code&gt;CWinThread::PreTranslateMessage&lt;/code&gt;, examine the message   and don't call the base  &lt;p&gt;The following applies:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;CWnd::WalkPreTranslateTree&lt;/code&gt; is not invoked, thus   &lt;span style="color: red;"&gt;disabling message pre translation along with   &lt;code&gt;IsDialogMessage&lt;/code&gt; call&lt;/span&gt; (specific messages &lt;em&gt;only&lt;/em&gt;, it's not as scary as it seems, but hits the performance and hard to implement properly)   &lt;p&gt;If &lt;code&gt;CWinThread::PreTranslateMessage&lt;/code&gt; returns &lt;code&gt;TRUE&lt;/code&gt;    the following applies:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Message is not dispatched&lt;/li&gt;
&lt;li&gt;Focused inline controls don't receive &lt;code&gt;WM_KEYDOWN&lt;/code&gt; for    &lt;code&gt;VK_RETURN&lt;/code&gt; and &lt;code&gt;VK_ESCAPE&lt;/code&gt; codes&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;If &lt;code&gt;CWinThread::PreTranslateMessage&lt;/code&gt; returns &lt;code&gt;FALSE&lt;/code&gt;    the following applies:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Message is dispatched&lt;/li&gt;
&lt;li&gt;Focused inline controls receive &lt;code&gt;WM_KEYDOWN&lt;/code&gt; for    &lt;code&gt;VK_RETURN&lt;/code&gt; and &lt;code&gt;VK_ESCAPE&lt;/code&gt; codes&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;The behavior is application wide&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;The very best option would be to override &lt;code&gt;CWnd::IsDialogMessage&lt;/code&gt;  and return in case of &lt;code&gt;VK_RETURN&lt;/code&gt; and &lt;code&gt;VK_ESCAPE&lt;/code&gt;, but this  is impossible since &lt;code&gt;CWnd::IsDialogMessage&lt;/code&gt; is not &lt;code&gt;virtual&lt;/code&gt;. &lt;code&gt;CWnd::IsDialogMessage&lt;/code&gt; is an API function wrapper, the closest item  to modify the behavior.&lt;/p&gt;&lt;p&gt;So which method is the best? Each does the trick, but... Option 3 has serious  drawback. Option 1 and 2 are class specific. I vote for option 2. You could create  some base CDialog class with the trick and use it for all your dialogs.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-3699333133661115778?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/3699333133661115778/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/05/how-to-prevent-mfc-dialog-closing-on.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/3699333133661115778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/3699333133661115778'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/05/how-to-prevent-mfc-dialog-closing-on.html' title='How to prevent MFC dialog closing on Enter and Escape keys'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-1816620611308807362</id><published>2011-05-15T23:55:00.002+03:00</published><updated>2011-05-15T23:55:41.489+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WWW'/><title type='text'>Funny site error</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://sites.google.com/site/chabster/bloggerpictures/SC2SiteError.png?attredirects=0" imageanchor="1" style="clear:left; float:left;margin-right:1em; margin-bottom:1em"&gt;&lt;img border="0" height="665" width="996" src="https://sites.google.com/site/chabster/bloggerpictures/SC2SiteError.png?attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-1816620611308807362?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/1816620611308807362/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/05/funny-site-error.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/1816620611308807362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/1816620611308807362'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/05/funny-site-error.html' title='Funny site error'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-5104602654597158482</id><published>2011-04-20T22:25:00.000+03:00</published><updated>2011-04-20T22:25:26.615+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTF'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><title type='text'>Misspelling</title><content type='html'>&lt;img src="https://sites.google.com/site/chabster/bloggerpictures/Portal2.png" alt="Portal 2 installer"/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-5104602654597158482?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/5104602654597158482/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/04/misspelling.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/5104602654597158482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/5104602654597158482'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/04/misspelling.html' title='Misspelling'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-6533451882616674121</id><published>2011-03-29T19:19:00.001+03:00</published><updated>2011-03-29T20:38:12.612+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WinAPI'/><category scheme='http://www.blogger.com/atom/ns#' term='problem'/><category scheme='http://www.blogger.com/atom/ns#' term='Common Controls'/><category scheme='http://www.blogger.com/atom/ns#' term='WinForms'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Fucking Date and Time Picker Controls or how to close DateTimePicker programmatically</title><content type='html'>&lt;p&gt;Только что закончил фикс милейшего дефекта. &lt;code&gt;DateTimePicker&lt;/code&gt; вываливал 
окно календаря и при щелчках мышью по заголовку родительского окна или в другие 
области оно оставалось висеть пока не выбрана дата.&lt;/p&gt;
&lt;p&gt;Происходило это потому, что элемент управления &lt;code&gt;DateTimePicker&lt;/code&gt; был 
создан в потоке отличном от потока окна верхнего уровня, в котором он находится. 
Да, знаю, многозадачный UI - это зло, но имеем то, что имеем.&lt;/p&gt;
&lt;p&gt;В результате исследования выяснилось, что начиная с Windows Vista этой проблемы 
больше нет - окно закрывается в любом случае (маленькая поправочка - при использовании 
6-й версии библиотеки comctl32). На Windows XP проблема имеет место быть в не зависимости 
от версии comctl32.&lt;/p&gt;
&lt;p&gt;Помимо внедрения механизма, который позволяет перехватывать по запросу асинхронные 
сообщения со всех UI потоков, возникла еще одна задачка - програмно закрыть окно 
календаря.&lt;/p&gt;
&lt;p&gt;Сначала показалось, что задачка из простых - было найдено сообщение
&lt;a href="http://msdn.microsoft.com/en-us/library/bb761753(v=vs.85).aspx"&gt;&lt;code&gt;DTM_CLOSEMONTHCAL&lt;/code&gt;&lt;/a&gt;, 
которое выполняет нужную функцию. После попытки разобраться почему вариант не рабочий 
выяснилось, что &lt;q&gt;Minimum supported client - Windows Vista&lt;/q&gt;. А нам для Windows 
XP. Блядь-блядь-блядь!!!&lt;/p&gt;
&lt;p&gt;Хрен с ним, решение все равно есть. Достаточно лишь понять как работает &lt;code&gt;
DateTimePicker&lt;/code&gt;. А он закрывает month calendar при нажатии клавиши Escape, 
а также при некоторых манипуляциях мышью. Также следует учесть, что элемент управления 
не теряет фокус во время отображения окна month calendar, а само выпадающее окно 
никогда не активируется.&lt;/p&gt;
&lt;p&gt;Первое, что пришло в голову, - эмулировать нажатие Escape когда month calendar 
нужно закрыть програмно - выполнить &lt;code&gt;SendKeys.SendWait("{ESC}");&lt;/code&gt;. Вариант 
оказался не рабочий. Причина весьма коварна - вызов этого метода запускает вложенный 
цикл сообщений и крутит его до тех пор, пока внедренные сообщения о нажатии клавиш 
не будут обработаны. А еще &lt;code&gt;DateTimePicker&lt;/code&gt; запускает свой цикл сообщений, 
когда показывает окно календаря:&lt;/p&gt;
&lt;pre&gt;
  &lt;span style="color: #FF0000;"&gt;user32.dll!_NtUserGetMessage@16()&lt;/span&gt;  + 0xc bytes 
  &lt;span style="color: #FF0000;"&gt;comctl32.dll!_DPLBD_MonthCal@8()&lt;/span&gt;  + 0x244 bytes 
  comctl32.dll!_DPLButtonDown@12()  + 0x79 bytes 
  comctl32.dll!_DatePickWndProc@16()  + 0x56b bytes 
  user32.dll!_InternalCallWinProc@20()  + 0x28 bytes 
  user32.dll!_UserCallWinProcCheckWow@32()  + 0xb7 bytes 
  user32.dll!_CallWindowProcAorW@24()  + 0x51 bytes 
  user32.dll!_CallWindowProcW@20()  + 0x1b bytes 
  System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m) Line 810 + 0x31 bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Control.DefWndProc(ref System.Windows.Forms.Message m) Line 5729 + 0xa bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Control.WmMouseDown(ref System.Windows.Forms.Message m, System.Windows.Forms.MouseButtons button, int clicks) Line 12909 + 0xc bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) Line 13761 C#
  System.Windows.Forms.dll!System.Windows.Forms.DateTimePicker.WndProc(ref System.Windows.Forms.Message m) Line 1686 C#
&lt;/pre&gt;
&lt;p&gt;В этом цикле содержится логика закрытия окна календаря. Одно из ее составляющих 
- ожидание сообщения &lt;code&gt;WM_KEYDOWN&lt;/code&gt; с &lt;code&gt;VK_ESC&lt;/code&gt;. Сообщение при 
этом глотается, до окна оно не доходит. Именно поэтому первая попытка провалилась. 
Выход - использовать &lt;code&gt;SendKeys.Send("{ESC}");&lt;/code&gt;, неблокирующий вызов, 
который не запускает вложенный цикл обработки сообщений, просто вставляет в очередь 
необходимые сообщения, которые в последствии обрабатываются циклом сообщений внутри
&lt;code&gt;DPLBD_MonthCal&lt;/code&gt;. Мне он тоже не подошел т.к. активировалось другое окно 
и оно же получало нажатие Escape. В результате я просто делаю &lt;code&gt;Win32.PostMessage(Handle, 
Win32.WM_KEYDOWN, Win32.VK_ESC, IntPtr.Zero);&lt;/code&gt; и все пучком. Код стероидов:&lt;/p&gt;
&lt;pre&gt;
/// &amp;lt;summary&amp;gt;
/// Month calendar visibility.
/// &amp;lt;/summary&amp;gt;
public bool IsMonthCalendarShown
{
    get
    {
        return (IsHandleCreated
                &amp;amp;&amp;amp; Win32.SendMessage(Handle, Win32.DTM_GETMONTHCAL, IntPtr.Zero, IntPtr.Zero) != IntPtr.Zero);
    }
}

/// &amp;lt;summary&amp;gt;
/// Closes month calendar if visible.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;remarks&amp;gt;
/// This is guaranteed to work on Windows Vista and above. Under Windows XP this method uses a hack.
/// &amp;lt;/remarks&amp;gt;
public void CloseMonthCalendar()
{
    if (!IsMonthCalendarShown)
    {
        return;
    }

    if (Win32.HasVistaAPI)
    {
        Win32.SendMessage(Handle, Win32.DTM_CLOSEMONTHCAL, IntPtr.Zero, IntPtr.Zero);
    }
    else
    {
        // NOTE: SendKeys.Send[Wait] can't be used here!
        // comctl32 runs its own message loop and awaits for WM_KEYDOWN with VK_ESC. It doesn't dispatch that however,
        // rather closes the month calendar instead. SendKeys.SendWait calls Application.DoEvents() which
        // runs message loop and does dispatch WM_KEY**** messages. So the month calendar is not closed.
        // SendKeys.Send might send input to wrong window (one being activated by mouse).
        //
        // HACK: So the only option here is to post WM_KEYDOWN with VK_ESC.
        //
        Win32.PostMessage(Handle, Win32.WM_KEYDOWN, Win32.VK_ESC, IntPtr.Zero);
    }
}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-6533451882616674121?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/6533451882616674121/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/03/fucking-date-and-time-picker-controls.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/6533451882616674121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/6533451882616674121'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/03/fucking-date-and-time-picker-controls.html' title='Fucking Date and Time Picker Controls or how to close DateTimePicker programmatically'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-3304215992668259764</id><published>2011-03-26T16:20:00.001+02:00</published><updated>2011-03-26T16:21:45.089+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTF'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>SendKeys suck</title><content type='html'>&lt;p&gt;Недавно пришлось поколупаться в исходном коде класса
&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx"&gt;
&lt;code&gt;SendKeys&lt;/code&gt;&lt;/a&gt;. Его отвратительное качество меня просто поразило. 
Но самый больший ахуй случился когда я там наткнулся на следующий WTF: &lt;/p&gt;
&lt;pre class="code listing"&gt;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] 
private static void LoadSendMethodFromConfig()
{ 
   if (!sendMethod.HasValue) 
   {
       sendMethod = SendMethodTypes.Default; 

       try
       {
           // read SendKeys value from config file, not case sensitive 
           string value = System.Configuration.ConfigurationManager.AppSettings.Get("SendKeys");
 
           if (value.Equals("JournalHook", StringComparison.OrdinalIgnoreCase)) 
               sendMethod = SendMethodTypes.JournalHook;
           else if (value.Equals("SendInput", StringComparison.OrdinalIgnoreCase)) 
               sendMethod = SendMethodTypes.SendInput;
       }
       catch {} // ignore any exceptions to keep existing SendKeys behavior
   } 
}
&lt;/pre&gt;
&lt;p&gt;Если в файле конфигурации приложения отсутствует настройка &lt;code&gt;SendKeys&lt;/code&gt; 
- &lt;code&gt;value.Equals&lt;/code&gt; вываливает &lt;code&gt;NullReferenceException&lt;/code&gt;, который 
успешно тушится блоком &lt;code&gt;catch {}&lt;/code&gt;. Это пиздец, господа. Класс писал студент 
в качестве тестового задания для Microsoft? Не удивительно, что во фреймворке столько 
говнокода, ведь студента видимо приняли.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-3304215992668259764?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/3304215992668259764/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/03/sendkeys-suck.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/3304215992668259764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/3304215992668259764'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/03/sendkeys-suck.html' title='SendKeys suck'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-6227362323069039871</id><published>2011-02-22T23:20:00.000+02:00</published><updated>2011-02-22T23:20:01.932+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='problem'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='MFC'/><title type='text'>How to make CDialog inherit parent background color</title><content type='html'>&lt;p&gt;Частенько бывает удобно встраивать один диалог в другой в качестве дочернего 
элемента управления. Все просто - ставим стили:&lt;/p&gt;
&lt;pre class="code"&gt;
STYLE DS_CONTROL | WS_CHILD
EXSTYLE WS_EX_CONTROLPARENT
&lt;/pre&gt;
&lt;p&gt;и создаем окно вызовом &lt;code&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/yhth57kd.aspx" target="_blank"&gt;
CDialog::Create&lt;/a&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Одна из проблем - диалог не запрашивает у родителя цвет для своего фона. В результате 
вложенный диалог другого цвета. Одно из решений - пробрасывать обработку сообщения
&lt;code&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/bb432504%2528v=vs.85%2529.aspx" target="_blank"&gt;
WM_CTLCOLOR&lt;/a&gt;&lt;/code&gt; выше по иерархии окон:&lt;/p&gt;
&lt;pre class="listing code"&gt;
&lt;span style="color: blue"&gt;struct&lt;/span&gt; AFX_CTLCOLOR
&lt;span style="color: navy"&gt;{&lt;/span&gt;
 HWND hWnd&lt;span style="color: navy"&gt;;&lt;/span&gt;
 HDC hDC&lt;span style="color: navy"&gt;;&lt;/span&gt;
 UINT nCtlType&lt;span style="color: navy"&gt;;&lt;/span&gt;
&lt;span style="color: navy"&gt;};&lt;/span&gt;
 
afx_msg HBRUSH CFontChooser&lt;span style="color: navy"&gt;::&lt;/span&gt;OnCtlColor&lt;span style="color: navy"&gt;(&lt;/span&gt;CDC &lt;span style="color: navy"&gt;*&lt;/span&gt;pDC&lt;span style="color: navy"&gt;,&lt;/span&gt; CWnd &lt;span style="color: navy"&gt;*&lt;/span&gt;pWnd&lt;span style="color: navy"&gt;,&lt;/span&gt; UINT nCtlColor&lt;span style="color: navy"&gt;)&lt;/span&gt; &lt;span style="color: navy"&gt;{&lt;/span&gt;
 &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: navy"&gt;(&lt;/span&gt;GetStyle&lt;span style="color: navy"&gt;()&lt;/span&gt; &lt;span style="color: navy"&gt;&amp;amp;&lt;/span&gt; WS_CHILD&lt;span style="color: navy"&gt;)&lt;/span&gt; &lt;span style="color: navy"&gt;{&lt;/span&gt;
 AFX_CTLCOLOR ctl&lt;span style="color: navy"&gt;;&lt;/span&gt;
 ctl&lt;span style="color: navy"&gt;.&lt;/span&gt;hDC &lt;span style="color: navy"&gt;=&lt;/span&gt; pDC&lt;span style="color: navy"&gt;-&amp;gt;&lt;/span&gt;GetSafeHdc&lt;span style="color: navy"&gt;();&lt;/span&gt;
 ctl&lt;span style="color: navy"&gt;.&lt;/span&gt;hWnd &lt;span style="color: navy"&gt;=&lt;/span&gt; pWnd&lt;span style="color: navy"&gt;-&amp;gt;&lt;/span&gt;GetSafeHwnd&lt;span style="color: navy"&gt;();&lt;/span&gt;
 ctl&lt;span style="color: navy"&gt;.&lt;/span&gt;nCtlType &lt;span style="color: navy"&gt;=&lt;/span&gt; nCtlColor&lt;span style="color: navy"&gt;;&lt;/span&gt;
 
 &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: navy"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: navy"&gt;&amp;lt;&lt;/span&gt;HBRUSH&lt;span style="color: navy"&gt;&amp;gt;(&lt;/span&gt;GetParent&lt;span style="color: navy"&gt;()-&amp;gt;&lt;/span&gt;SendMessage&lt;span style="color: navy"&gt;(&lt;/span&gt;WM_CTLCOLOR&lt;span style="color: navy"&gt;,&lt;/span&gt; &lt;span style="color: blue"&gt;0&lt;/span&gt;&lt;span style="color: navy"&gt;,&lt;/span&gt; &lt;span style="color: blue"&gt;reinterpret_cast&lt;/span&gt;&lt;span style="color: navy"&gt;&amp;lt;&lt;/span&gt;LPARAM&lt;span style="color: navy"&gt;&amp;gt;(&amp;amp;&lt;/span&gt;ctl&lt;span style="color: navy"&gt;))));&lt;/span&gt;
 &lt;span style="color: navy"&gt;}&lt;/span&gt;
 
 &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: navy"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;__super&lt;/span&gt;&lt;span style="color: navy"&gt;::&lt;/span&gt;OnCtlColor&lt;span style="color: navy"&gt;(&lt;/span&gt;pDC&lt;span style="color: navy"&gt;,&lt;/span&gt; pWnd&lt;span style="color: navy"&gt;,&lt;/span&gt; nCtlColor&lt;span style="color: navy"&gt;));&lt;/span&gt;
&lt;span style="color: navy"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Проблемка здесь в том, что &lt;code&gt;WM_CTLCOLOR&lt;/code&gt; эмулируется средствами MFC. 
Для этого используется локальная для библиотечного cpp-файла структурка &lt;code&gt;AFX_CTLCOLOR&lt;/code&gt;. 
Которую пришлось сдублировать у себя в коде...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-6227362323069039871?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/6227362323069039871/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/02/how-to-make-cdialog-inherit-parent.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/6227362323069039871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/6227362323069039871'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/02/how-to-make-cdialog-inherit-parent.html' title='How to make CDialog inherit parent background color'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-6603793231211305682</id><published>2011-02-22T13:16:00.003+02:00</published><updated>2011-03-26T16:25:44.308+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>Russian mentality</title><content type='html'>&lt;p&gt;Вот что такое Россия с точки зрения охраны секретных сведений?&lt;/p&gt;
&lt;p&gt;С одной стороны, русские подвержены тотальной шпиономании, побуждающей их ревностно 
оберегать самые невинные сведения, которые нетрудно почерпнуть из открытых источников, 
даже из прессы. К любому незнакомому человеку, особенно в военный период, относятся 
с овчарочьей подозрительностью. Но если уж казенный человек тебя признал за &lt;i&gt;своего&lt;/i&gt;, 
все шлагбаумы, или, выражаясь по-туземному, рогатки поднимаются, инструкции и запреты 
идут к черту.&lt;/p&gt;
&lt;p&gt;Взять хоть эту гостиницу. К каждому приезжающему отношение сверхбдительное: извольте 
документы на прописку, да по какой надобности изволили прибыть, да нельзя ли получить 
телеграфное подтверждение от командирующей инстанции. Военный порт, неприступная 
крепость! Горничная баба Катя в первую же отлучку обшарила весь багаж, аж носовые 
платки перебрала (это Зепп установил по приставшему к батисту длинному полуседому 
волосу). То ли тетка в морской контрразведке подрабатывает, то ли просто энтузиастка 
— под предлогом патриотической бдительности удовлетворяет женское любопытство. И 
что же? Довольно было угостить пожилую фрау чаем, выслушать рассказ о нелегкой женской 
доле, самому посетовать на горькую судьбину вдовца с шестью крошками на руках (имелись 
и фотокарточки крошек, а как же)&amp;nbsp;— и сделалась Катюша верной союзницей. Стала 
называть «сынком», все секреты выложила — и про полового Мишку, который филер, и 
про обязательную «лепортацию» о каждом постояльце. А всё потому что Зепп стал для 
нее &lt;i&gt;свой&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Своим &lt;/i&gt;в России можно всё, правила написаны для чужих. Поэтому и законы 
здесь не более чем условность, удобная для сильных и досадная для слабых. Недаром 
сакральный лозунг русских — «жить по правде». Но правда-то у каждого своя. Это право, 
то бишь закон, для всех общий, а общее — оно заведомо не &lt;i&gt;свое&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;Именно здесь, на стыке &lt;i&gt;общего &lt;/i&gt;и &lt;i&gt;своего&lt;/i&gt;, казенного и личного, угадывалась 
замочная скважина. Только Зепп никак не мог нащупать ее отмычкой.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-6603793231211305682?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/6603793231211305682/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/02/russian-mentality.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/6603793231211305682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/6603793231211305682'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/02/russian-mentality.html' title='Russian mentality'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-8019931745320865556</id><published>2011-01-30T21:33:00.000+02:00</published><updated>2011-01-30T21:33:36.898+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='CLR'/><title type='text'>How to force raw pointer marshaling when doing automatic COM marshaling</title><content type='html'>&lt;p&gt;Иногда требуется запретить выполнять стандартный маршалинг указателя на интерфейс средствами OLE32. Например, я хочу использовать некий интерфейс &lt;code&gt;IFoo&lt;/code&gt; из .NET-а, реализация которого попала в CLR из неуправляемого кода, при этом информации в реестре по этому интерфейсу нет (proxy/stub и tlb не зарегистрированы). Как было неоднократно показано в предыдущих заметках о взаимодействии управляемого и неуправляемого кода, при попытке использовать &lt;code&gt;IFoo&lt;/code&gt; из другого потока получим исключение.&lt;/p&gt;
&lt;p&gt;Избежать автоматического маршалинга указателя на интерфейс можно, самостоятельно реализовав &lt;a href="http://msdn.microsoft.com/en-us/library/dd542707%28v=vs.85%29.aspx" target="_blank" alt="IMarshal Interface"&gt;&lt;code&gt;IMarshal&lt;/code&gt;&lt;/a&gt;. Но тут кроется еще одна засада - метод &lt;code&gt;GetUnmarshalClass&lt;/code&gt; обязан возвратить CLSID класса, который будет выполнять роль proxy. И этот класс должен быть зарегистрирован, что нам явно не подходит.&lt;/p&gt;

&lt;p&gt;На помощь приходит функция &lt;a href="http://msdn.microsoft.com/en-us/library/ms694500%28v=vs.85%29.aspx" target="_blank" alt="CoCreateFreeThreadedMarshaler Function"&gt;&lt;code&gt;CoCreateFreeThreadedMarshaler&lt;/code&gt;&lt;/a&gt;, которая выполняет всю грязную работу по получению необходимой функциональности. Результирующий объект нужно подключить, как tear-off реализацию &lt;code&gt;IMarshal&lt;/code&gt; к требуемому классу.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-8019931745320865556?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/8019931745320865556/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/01/how-to-force-raw-pointer-marshaling.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/8019931745320865556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/8019931745320865556'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/01/how-to-force-raw-pointer-marshaling.html' title='How to force raw pointer marshaling when doing automatic COM marshaling'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-4981202360268859886</id><published>2011-01-17T19:04:00.000+02:00</published><updated>2011-01-17T19:04:09.993+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>RCW vs Garbage Collector</title><content type='html'>&lt;p&gt;Недавно столкнулись с проблемой - вызов &lt;code&gt;&lt;span style="color: #2b91af"&gt;GC&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;WaitForPendingFinalizers&lt;/span&gt;();&lt;/code&gt; 
блокировал работу приложения. На мысли навела следующая часть стека:&lt;/p&gt;
&lt;pre class="code listing"&gt;
  [In a sleep, wait, or join] 
  ntdll.dll!_KiFastSystemCallRet@0()  
  ntdll.dll!_NtWaitForMultipleObjects@20()  + 0xc bytes 
  KernelBase.dll!_WaitForMultipleObjectsEx@20()  - 0x54 bytes 
  kernel32.dll!_WaitForMultipleObjectsExImplementation@20()  + 0x8e bytes 
  user32.dll!_RealMsgWaitForMultipleObjectsEx@20()  + 0xd7 bytes 
  ole32.dll!CCliModalLoop::BlockFn()  + 0x96 bytes 
  ole32.dll!_CoWaitForMultipleHandles@20()  - 0x51b9 bytes 
  [Managed to Native Transition] 
  mscorlib.dll!System.GC.WaitForPendingFinalizers() + 0x2c bytes 
&lt;/pre&gt;
&lt;p&gt;Блокировка происходит из &lt;code&gt;ole32.dll&lt;/code&gt;. После просмотра стеков всех 
остальных потоков был найден следующий любопытный житель нашего процесса:&lt;/p&gt;
&lt;pre class="code listing"&gt;
&amp;gt; ntdll.dll!_KiFastSystemCallRet@0()  
  ntdll.dll!_ZwWaitForSingleObject@12()  + 0xc bytes 
  KernelBase.dll!_WaitForSingleObjectEx@12()  + 0x6c bytes 
  kernel32.dll!_WaitForSingleObjectExImplementation@12()  + 0x43 bytes 
  kernel32.dll!_WaitForSingleObject@8()  + 0x12 bytes 
  ole32.dll!GetToSTA()  + 0x72 bytes 
  ole32.dll!CRpcChannelBuffer::SwitchAptAndDispatchCall()  - 0x1939 bytes 
  ole32.dll!CRpcChannelBuffer::SendReceive2()  + 0xa6 bytes 
  ole32.dll!CAptRpcChnl::SendReceive()  + 0x5b7 bytes 
  ole32.dll!CCtxComChnl::SendReceive()  - 0x14b97 bytes 
  ole32.dll!NdrExtpProxySendReceive()  + 0x43 bytes 
  rpcrt4.dll!@NdrpProxySendReceive@4()  + 0xe bytes 
  rpcrt4.dll!_NdrClientCall2()  + 0x144 bytes 
  ole32.dll!_ObjectStublessClient@8()  + 0x7a bytes 
  ole32.dll!_ObjectStubless@0()  + 0xf bytes 
  ole32.dll!CObjectContext::InternalContextCallback()  - 0x511f bytes 
  ole32.dll!CObjectContext::ContextCallback()  + 0x8f bytes 
  clr.dll!CtxEntry::EnterContext()  + 0x119 bytes 
  clr.dll!RCWCleanupList::ReleaseRCWListInCorrectCtx()  + 0x2bb bytes 
  clr.dll!RCWCleanupList::CleanupAllWrappers()  - 0x2ef04 bytes 
  clr.dll!SyncBlockCache::CleanupSyncBlocks()  + 0xa6a bytes 
  clr.dll!Thread::DoExtraWorkForFinalizer()  - 0x4c12 bytes 
  clr.dll!WKS::GCHeap::FinalizerThreadWorker()  + 0x8b bytes 
  clr.dll!Thread::DoExtraWorkForFinalizer()  + 0x3e0ff bytes 
  clr.dll!Thread::ShouldChangeAbortToUnload()  - 0x5f4 bytes 
  clr.dll!Thread::ShouldChangeAbortToUnload()  - 0x539 bytes 
  clr.dll!ManagedThreadBase_NoADTransition()  + 0x35 bytes 
  clr.dll!ManagedThreadBase::FinalizerBase()  + 0xf bytes 
  clr.dll!WKS::GCHeap::FinalizerThreadStart()  + 0xfb bytes 
  clr.dll!Thread::intermediateThreadProc()  + 0x48 bytes 
  kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes 
  ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes 
  ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes 
&lt;/pre&gt;
&lt;p&gt;Перед нами стек так называемого Finalizer Thread, который выполняет работу по 
освобождению ресурсов. Из стека стало ясно, что этот поток пытается избавиться от 
ненужных RCW. Для этого он вызывает метод &lt;code&gt;Release&lt;/code&gt; каждого COM-объекта, 
но пытается сделать это в другом контексте. Очевидно, что этот контекст - это апартмент 
из которого объект попал в CLR. В моем случае поток, соответствующий этому апартменту, 
не обрабатывал асинхронные сообщения, а именно ими обменивается &lt;code&gt;ole32.dll&lt;/code&gt; 
для маршалинга вызовов между контекстами.&lt;/p&gt;
&lt;p&gt;Ахтунг состоит в том, что Finalizer Thread является чужеродным контекстом для 
всех COM-объектов, которые попали в CLR (за исключением тех, которые были созданы 
в контексте самого Finalizer Thread, а это вполне реальная ситуация). Как же в результате 
происходит освобождение ресурсов, если вызов &lt;code&gt;&lt;span style="color: #2b91af"&gt;
GC&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;WaitForPendingFinalizers&lt;/span&gt;();&lt;/code&gt; 
блокируется до полной очистки всего накопившегося мусора? Ответ находится на вешине 
первого стека:&lt;/p&gt;
&lt;pre class="code listing"&gt;
&amp;gt; CPPHost.exe!CNETFormControllerCallback::~CNETFormControllerCallback()  Line 13 C++
  CPPHost.exe!ATL::CComObjectNoLock&amp;lt;CNETFormControllerCallback&amp;gt;::~CComObjectNoLock&amp;lt;CNETFormControllerCallback&amp;gt;()  Line 3037 + 0xf bytes C++
  CPPHost.exe!ATL::CComObjectNoLock&amp;lt;CNETFormControllerCallback&amp;gt;::`scalar deleting destructor&amp;#39;()  + 0x2b bytes C++
  CPPHost.exe!ATL::CComObjectNoLock&amp;lt;CNETFormControllerCallback&amp;gt;::Release()  Line 3049 + 0x35 bytes C++
  CPPHost.exe!ATL::_QIThunk::Release()  Line 2692 + 0x10 bytes C++
  ole32.dll!CRemoteUnknown::DoCallback()  + 0x3b bytes 
  rpcrt4.dll!_Invoke@12()  + 0x2a bytes 
  rpcrt4.dll!_NdrStubCall2@16()  + 0x22f bytes 
  ole32.dll!_CStdStubBuffer_Invoke@12()  + 0x70 bytes 
  ole32.dll!SyncStubInvoke()  + 0x34 bytes 
  ole32.dll!StubInvoke()  + 0x7b bytes 
  ole32.dll!CCtxComChnl::ContextInvoke()  + 0xe6 bytes 
  ole32.dll!MTAInvoke()  + 0x1a bytes 
  ole32.dll!STAInvoke()  + 0x4a bytes 
  ole32.dll!AppInvoke()  + 0x92 bytes 
  ole32.dll!ComInvokeWithLockAndIPID()  + 0x27c bytes 
  ole32.dll!ComInvoke()  + 0x71 bytes 
  ole32.dll!ThreadDispatch()  + 0x1a bytes 
  ole32.dll!ThreadWndProc()  + 0xa0 bytes 
  user32.dll!_InternalCallWinProc@20()  + 0x23 bytes 
  user32.dll!_UserCallWinProcCheckWow@32()  + 0xb3 bytes 
  user32.dll!_DispatchMessageWorker@8()  + 0xe6 bytes 
  user32.dll!_DispatchMessageW@4()  + 0xf bytes 
  ole32.dll!CCliModalLoop::PeekRPCAndDDEMessage()  + 0x241 bytes 
  ole32.dll!CCliModalLoop::BlockFn()  - 0x5d50 bytes 
  ole32.dll!_CoWaitForMultipleHandles@20()  - 0x51b9 bytes 
  [Managed to Native Transition] 
  mscorlib.dll!System.GC.WaitForPendingFinalizers() + 0x2c bytes 
  NETLibrary.dll!NETLibrary.NETFormController.GCAndWaitForPendingFinalizers() Line 33 + 0x5 bytes C#
  [Native to Managed Transition] 
  CPPHost.exe!NETLibrary::INETFormController::GCAndWaitForPendingFinalizers()  Line 67 + 0x10 bytes C++
  CPPHost.exe!wmain(int argc=1, wchar_t * * argv=0x006832d8)  Line 107 C++
&lt;/pre&gt;
&lt;p&gt;Здесь видно, что &lt;code&gt;&lt;span style="color: #2b91af"&gt;GC&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;WaitForPendingFinalizers&lt;/span&gt;();&lt;/code&gt; 
блокирует выполнение потока вызовом
&lt;a href="http://msdn.microsoft.com/en-us/library/ms680732(v=vs.85).aspx"&gt;&lt;code&gt;CoWaitForMultipleHandles&lt;/code&gt;&lt;/a&gt;, 
который крутит цикл сообщений для обработки входящих COM-вызовов. Мощно, да?&lt;/p&gt;
&lt;p&gt;Допустим, что COM-объект попал в CLR из потока, отличного от того, в котором 
происходит вызов &lt;code&gt;&lt;span style="color: #2b91af"&gt;GC&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;WaitForPendingFinalizers&lt;/span&gt;();&lt;/code&gt;, 
но сам поток к моменту вызова не может обработать входящий вызов (поток завершил 
работу, например):&lt;/p&gt;
&lt;pre class="code listing"&gt;
&amp;gt; CPPHost.exe!CNETFormControllerCallback::~CNETFormControllerCallback()  Line 13 C++
  CPPHost.exe!ATL::CComObjectNoLock&amp;lt;CNETFormControllerCallback&amp;gt;::~CComObjectNoLock&amp;lt;CNETFormControllerCallback&amp;gt;()  Line 3037 + 0xf bytes C++
  CPPHost.exe!ATL::CComObjectNoLock&amp;lt;CNETFormControllerCallback&amp;gt;::`scalar deleting destructor&amp;#39;()  + 0x2b bytes C++
  CPPHost.exe!ATL::CComObjectNoLock&amp;lt;CNETFormControllerCallback&amp;gt;::Release()  Line 3049 + 0x35 bytes C++
  CPPHost.exe!ATL::_QIThunk::Release()  Line 2692 + 0x10 bytes C++
  clr.dll!ReleaseTransitionHelper()  + 0xe bytes 
  clr.dll!SafeReleaseHelper()  + 0x6b bytes 
  clr.dll!SafeRelease()  + 0x2f bytes 
  clr.dll!IUnkEntry::Free()  + 0x4e bytes 
  clr.dll!RCW::ReleaseAllInterfaces()  + 0x1a bytes 
  clr.dll!RCW::ReleaseAllInterfacesCallBack()  + 0x178b5c bytes 
  clr.dll!RCW::Cleanup()  + 0x22 bytes 
  clr.dll!RCWCleanupList::ReleaseRCWListRaw()  + 0x18 bytes 
  clr.dll!RCWCleanupList::ReleaseRCWListInCorrectCtx()  + 0x17a15e bytes 
  clr.dll!RCWCleanupList::CleanupAllWrappers()  - 0x2ef04 bytes 
  clr.dll!SyncBlockCache::CleanupSyncBlocks()  + 0xa6a bytes 
  clr.dll!Thread::DoExtraWorkForFinalizer()  - 0x4c12 bytes 
  clr.dll!WKS::GCHeap::FinalizerThreadWorker()  + 0x8b bytes 
  clr.dll!Thread::DoExtraWorkForFinalizer()  + 0x3e0ff bytes 
  clr.dll!Thread::ShouldChangeAbortToUnload()  - 0x5f4 bytes 
  clr.dll!Thread::ShouldChangeAbortToUnload()  - 0x539 bytes 
  clr.dll!ManagedThreadBase_NoADTransition()  + 0x35 bytes 
  clr.dll!ManagedThreadBase::FinalizerBase()  + 0xf bytes 
  clr.dll!WKS::GCHeap::FinalizerThreadStart()  + 0xfb bytes 
  clr.dll!Thread::intermediateThreadProc()  + 0x48 bytes 
  kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes 
  ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes 
  ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes 
&lt;/pre&gt;
&lt;p&gt;В таком случае COM-объект освобождается прямо в контексте Finalizer Thread, что, 
понятное дело, может привести к проблемам синхронизации, а то и вовсе катастрофой, 
если код оъекта был выгружен из памяти!&lt;/p&gt;
&lt;p&gt;Последний случай - поток работает, в нем инициализирован апартмент, но он не 
обрабатывает асинхронные сообщения, Finalizer Thread рано или поздно подвисает...&lt;/p&gt;
&lt;p&gt;Какие выводы можно сделать из всего этого?&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;CLR пытается быть a good COM citizen и выполняет автоматический маршалинг 
 вызовов в нужные контексты;&lt;/li&gt;
 &lt;li&gt;из-за специфики среды выполнения разрушение RCW происходит в выделенном 
 потоке, поэтому во время этой операции за кадром выполняется множество действий, 
 которые могут привести к блокировкам;&lt;/li&gt;
 &lt;li&gt;уничтожением RCW Finalizer Thread занимается уже после того, как были вызваны 
 методы
 &lt;a href="http://msdn.microsoft.com/en-us/library/system.object.finalize.aspx"&gt;
 &lt;code&gt;Finalize&lt;/code&gt;&lt;/a&gt; объектов в соответствующей очереди, поэтому во время 
 вызова
 &lt;a href="http://msdn.microsoft.com/en-us/library/system.object.finalize.aspx"&gt;
 &lt;code&gt;Finalize&lt;/code&gt;&lt;/a&gt; можно пользоваться RCW, но очень нежелательно (блокировки, 
 заваленные вызовы &lt;code&gt;QueryInterface&lt;/code&gt; если &lt;code&gt;tlb&lt;/code&gt; не зарегистрирована 
 и т.д.);&lt;/li&gt;
 &lt;li&gt;блокировать поток желательно вызовом
 &lt;a href="http://msdn.microsoft.com/en-us/library/ms680732(v=vs.85).aspx"&gt;
 &lt;code&gt;CoWaitForMultipleHandles&lt;/code&gt;&lt;/a&gt;;&lt;/li&gt;
 &lt;li&gt;Избегать передачи COM-объектов из потоков, в которых нет работающего цикла 
 сообщений!&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-4981202360268859886?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/4981202360268859886/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2011/01/rcw-vs-garbage-collector.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/4981202360268859886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/4981202360268859886'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2011/01/rcw-vs-garbage-collector.html' title='RCW vs Garbage Collector'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-4464149075221224038</id><published>2010-12-07T20:03:00.001+02:00</published><updated>2010-12-07T20:06:51.367+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='problem'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='WinForms'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='MFC'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Advanced C++ and .NET interop</title><content type='html'>&lt;p&gt;В этой статье речь пойдет о проблемах использования элементов управления WinForms 
из нативного приложения, MFC например.&lt;/p&gt;
&lt;p&gt;В &lt;a href="http://chabster.blogspot.com/2010/09/c-and-net-interop.html"&gt;предыдущем 
выпуске&lt;/a&gt; серии статей о взаимодействии управляемого и неуправляемого кода мы 
выяснили, что .NET форма испытывает некие трудности при использовании ее метода
&lt;code&gt;Show&lt;/code&gt; из неуправляемого приложения - фокус не работает, не двигается 
по нажатию клавиши &lt;code&gt;Tab&lt;/code&gt;. Пришло время разобраться почему так происходит.&lt;/p&gt;
&lt;p&gt;Движением фокуса в контейнерах WinForms занимается пачка методов, самый важный 
из которых -
&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.containercontrol.processtabkey.aspx"&gt;
&lt;code&gt;ContainerControl::ProcessTabKey&lt;/code&gt;&lt;/a&gt;. Давайте выясним каким образом 
поток выполнения попадает в этот метод:&lt;/p&gt;
&lt;pre class="listing"&gt;
&amp;gt; WinFormsMFCHost.exe!WinFormsMFCHost::SampleForm::ProcessTabKey(bool forward = true) Line 48 C++
  System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.ProcessDialogKey(System.Windows.Forms.Keys keyData = LButton | Back) Line 1141 + 0x19 bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Form.ProcessDialogKey(System.Windows.Forms.Keys keyData) Line 5245 + 0x9 bytes C#
  WinFormsMFCHost.exe!WinFormsMFCHost::SampleForm::ProcessDialogKey(System::Windows::Forms::Keys keyData = System::Windows::Forms::Keys::Tab) Line 43 + 0xb bytes C++
  System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.ProcessDialogKey(System.Windows.Forms.Keys keyData) Line 1152 + 0x16 bytes C#
  WinFormsMFCHost.exe!WinFormsMFCHost::SampleControl::ProcessDialogKey(System::Windows::Forms::Keys keyData = System::Windows::Forms::Keys::Tab) Line 42 + 0xb bytes C++
  System.Windows.Forms.dll!System.Windows.Forms.Control.ProcessDialogKey(System.Windows.Forms.Keys keyData) Line 10170 + 0x14 bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Control.PreProcessMessage(ref System.Windows.Forms.Message msg) Line 9864 + 0xf bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Control.PreProcessControlMessageInternal(System.Windows.Forms.Control target = {System.Windows.Forms.TabControl}, ref System.Windows.Forms.Message msg = {System.Windows.Forms.Message}) Line 9949 + 0x10 bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.&lt;span style="color: #FF0000;"&gt;PreTranslateMessage&lt;/span&gt;(ref System.Windows.Forms.NativeMethods.MSG msg = {System.Windows.Forms.NativeMethods.MSG}) Line 3618 + 0xb bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.LocalModalMessageLoop(System.Windows.Forms.Form form = {WinFormsMFCHost.SampleForm}) Line 3503 + 0xb bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = 0x00000004, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.Application.ModalApplicationContext}) Line 3429 + 0xd bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) Line 3306 + 0xa bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Application.RunDialog(System.Windows.Forms.Form form) Line 1517 + 0x2b bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window owner) Line 6122 + 0x8 bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Form.ShowDialog() Line 6022 + 0x7 bytes C#
&lt;/pre&gt;
&lt;p&gt;Самая важная часть стека выделена красным. .NET использует концепцию пре трансляции 
сообщений. Она очень похожа на механизм, который используется в MFC. Суть его простая 
- в цикле сообщений перед их диспатчеризацией выполняется &lt;code&gt;CWnd::WalkPreTranslateTree&lt;/code&gt; 
активного окна, которая в свою очередь вызывает
&lt;a href="http://msdn.microsoft.com/en-us/library/kkbhxcs2(VS.80).aspx"&gt;&lt;code&gt;CWnd::PreTranslateMessage&lt;/code&gt;&lt;/a&gt;. 
Сообщения можно съедать, изменять и вообще выполнять любую другую логику. Например 
- управлять фокусом. Логично ведь - элемент управления сам не может знать как ему 
перемещать фокус внутри контейнера (форма, диалог - не важно). И вот тут к нам пришла 
засада - если цикл сообщений крутит не .NET, а MFC например, - &lt;code&gt;ThreadContext::PreTranslateMessage&lt;/code&gt; 
не будет вызван, соответственно все необходимые методы далее по стеку. Фокус не 
перемещается.&lt;/p&gt;
&lt;p&gt;И вот я задался вопросом - как же работают программы типа Visual Studio, Excel, 
Word, Outlook, где .NET интегрирован и работает нормально - показывает формы, диалоги, 
используются пользовательские элементы управления (наследники &lt;code&gt;UserControl&lt;/code&gt;). 
Ответ я нашел в исходниках WinForms после длительного хардфакинга в рефлекторе и 
отладчике. Все банально - WinForms использует скрытый интерфейс для взаимодействия 
с хост-приложением. Этот интерфейс позволяет проталкивать необходимый вызов
&lt;code&gt;ThreadContext::PreTranslateMessage&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Посмотрим что происходит при вызове метода &lt;code&gt;Show&lt;/code&gt; формы:&lt;/p&gt;
&lt;pre class="listing"&gt;
&amp;gt; System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.ComponentManager.get() Line 2549 + 0x17 bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.FormActivated(bool activate) Line 2975 + 0x7 bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Form.WmActivate(ref System.Windows.Forms.Message m = {System.Windows.Forms.Message}) Line 6842 + 0x2d bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Form.WndProc(ref System.Windows.Forms.Message m) Line 7433 C#
  System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) Line 14109 + 0xe bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) Line 14164 + 0xb bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg = 0x00000006, System.IntPtr wparam, System.IntPtr lparam) Line 779 + 0xe bytes C#
  user32.dll!_InternalCallWinProc@20()  + 0x23 bytes 
  user32.dll!_UserCallWinProcCheckWow@32()  + 0xb3 bytes 
  user32.dll!_DispatchClientMessage@20()  + 0x4b bytes 
  user32.dll!___fnDWORD@4()  + 0x24 bytes 
  ntdll.dll!_KiUserCallbackDispatcher@12()  + 0x2e bytes 
  user32.dll!_NtUserShowWindow@8()  + 0xc bytes 
  [Managed to Native Transition] 
  System.Windows.Forms.dll!System.Windows.Forms.Control.SetVisibleCore(bool value = true) Line 11762 + 0x46f bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.Form.SetVisibleCore(bool value = true) Line 2684 C#
  System.Windows.Forms.dll!System.Windows.Forms.Control.Show() Line 12059 + 0x10 bytes C#
&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;ComponentManager&lt;/code&gt; - WTF? Код: &lt;/p&gt;
&lt;pre class="listing"&gt;&lt;span style="color: blue"&gt;internal&lt;/span&gt; &lt;span style="color: #2b91af"&gt;UnsafeNativeMethods&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IMsoComponentManager&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ComponentManager&lt;/span&gt; { 
      &lt;span style="color: blue"&gt;get&lt;/span&gt; {
 
         &lt;span style="color: #8b2be3"&gt;Debug&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;WriteLineIf&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;CompModSwitches&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;MSOComponentManager&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;TraceInfo&lt;/span&gt;, &lt;span style="color: magenta"&gt;&amp;quot;Application.ComponentManager.Get:&amp;quot;&lt;/span&gt;); 
 
         &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: #8b2be3"&gt;componentManager&lt;/span&gt; &lt;span style="color: #800040"&gt;==&lt;/span&gt; &lt;span style="color: blue"&gt;null&lt;/span&gt;) { 
 
            &lt;span style="color: #7ca78b"&gt;// The CLR is a good COM citizen and will pump messages when things are waiting.&lt;/span&gt;
            &lt;span style="color: #7ca78b"&gt;// This is nice; it keeps the world responsive.  But, it is also very hard for&lt;/span&gt;
            &lt;span style="color: #7ca78b"&gt;// us because most of the code below causes waits, and the likelihood that &lt;/span&gt;
            &lt;span style="color: #7ca78b"&gt;// a message will come in and need a component manager is very high.  Recursing&lt;/span&gt;
            &lt;span style="color: #7ca78b"&gt;// here is very very bad, and will almost certainly lead to application failure &lt;/span&gt;
            &lt;span style="color: #7ca78b"&gt;// later on as we come out of the recursion.  So, we guard it here and return &lt;/span&gt;
            &lt;span style="color: #7ca78b"&gt;// null.  EVERYONE who accesses the component manager must handle a NULL return!&lt;/span&gt;
            &lt;span style="color: #7ca78b"&gt;// &lt;/span&gt;
            &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: #8b2be3"&gt;fetchingComponentManager&lt;/span&gt;) {
                  &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;null&lt;/span&gt;;
            }
 
            &lt;span style="color: #8b2be3"&gt;fetchingComponentManager&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;true&lt;/span&gt;;
            &lt;span style="color: blue"&gt;try&lt;/span&gt; { 
                  &lt;span style="color: #2b91af"&gt;UnsafeNativeMethods&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IMsoComponentManager&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;msocm&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;null&lt;/span&gt;; 
                  &lt;span style="color: #8b2be3"&gt;Application&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;OleRequired&lt;/span&gt;();
 
                  &lt;span style="color: #7ca78b"&gt;// Attempt to obtain the Host Application MSOComponentManager&lt;/span&gt;
                  &lt;span style="color: #7ca78b"&gt;//&lt;/span&gt;
                  &lt;span style="color: #2b91af"&gt;IntPtr&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;msgFilterPtr&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;IntPtr&lt;/span&gt;)&lt;span style="color: #e33104"&gt;0&lt;/span&gt;;
 
                  &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;NativeMethods&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;Succeeded&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;UnsafeNativeMethods&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;CoRegisterMessageFilter&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;NativeMethods&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;NullHandleRef&lt;/span&gt;, &lt;span style="color: blue"&gt;ref&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;msgFilterPtr&lt;/span&gt;)) &lt;span style="color: #800040"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;msgFilterPtr&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;IntPtr&lt;/span&gt;)&lt;span style="color: #e33104"&gt;0&lt;/span&gt;) {
 
                     &lt;span style="color: #2b91af"&gt;IntPtr&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dummy&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;IntPtr&lt;/span&gt;)&lt;span style="color: #e33104"&gt;0&lt;/span&gt;; 
                     &lt;span style="color: #2b91af"&gt;UnsafeNativeMethods&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;CoRegisterMessageFilter&lt;/span&gt;(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;HandleRef&lt;/span&gt;(&lt;span style="color: blue"&gt;null&lt;/span&gt;, &lt;span style="color: #8b2be3"&gt;msgFilterPtr&lt;/span&gt;), &lt;span style="color: blue"&gt;ref&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dummy&lt;/span&gt;);
 
                     &lt;span style="color: blue"&gt;object&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;msgFilterObj&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;GetObjectForIUnknown&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;msgFilterPtr&lt;/span&gt;);
                     &lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;Release&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;msgFilterPtr&lt;/span&gt;);
 
                     &lt;span style="color: #2b91af"&gt;UnsafeNativeMethods&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IOleServiceProvider&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;sp&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;msgFilterObj&lt;/span&gt; &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;UnsafeNativeMethods&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IOleServiceProvider&lt;/span&gt;; 
                     &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: #8b2be3"&gt;sp&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: blue"&gt;null&lt;/span&gt;) {
                        &lt;span style="color: blue"&gt;try&lt;/span&gt; { 
                              &lt;span style="color: #2b91af"&gt;IntPtr&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;retval&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IntPtr&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;Zero&lt;/span&gt;; 
 
                              &lt;span style="color: #7ca78b"&gt;// PERF ALERT ([....]): Using typeof() of COM object spins up COM at JIT time. &lt;/span&gt;
                              &lt;span style="color: #7ca78b"&gt;// Guid compModGuid = typeof(UnsafeNativeMethods.SMsoComponentManager).GUID;&lt;/span&gt;
                              &lt;span style="color: #7ca78b"&gt;//&lt;/span&gt;
                              &lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;compModGuid&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt;(&lt;span style="color: magenta"&gt;&amp;quot;000C060B-0000-0000-C000-000000000046&amp;quot;&lt;/span&gt;);
                              &lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;iid&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt;(&lt;span style="color: magenta"&gt;&amp;quot;{000C0601-0000-0000-C000-000000000046}&amp;quot;&lt;/span&gt;); 
                              &lt;span style="color: blue"&gt;int&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;hr&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;sp&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;QueryService&lt;/span&gt;(
                                             &lt;span style="color: blue"&gt;ref&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;compModGuid&lt;/span&gt;, 
                                             &lt;span style="color: blue"&gt;ref&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;iid&lt;/span&gt;, 
                                             &lt;span style="color: blue"&gt;out&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;retval&lt;/span&gt;);
 
                              &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;NativeMethods&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;Succeeded&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;hr&lt;/span&gt;) &lt;span style="color: #800040"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;retval&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IntPtr&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;Zero&lt;/span&gt;) {
 
                                 &lt;span style="color: #7ca78b"&gt;// Now query for hte message filter.&lt;/span&gt;
 
                                 &lt;span style="color: #2b91af"&gt;IntPtr&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pmsocm&lt;/span&gt;;
 
                                 &lt;span style="color: blue"&gt;try&lt;/span&gt; { 
                                    &lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IID_IMsoComponentManager&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;UnsafeNativeMethods&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IMsoComponentManager&lt;/span&gt;)&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;GUID&lt;/span&gt;;
                                    &lt;span style="color: #8b2be3"&gt;hr&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;QueryInterface&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;retval&lt;/span&gt;, &lt;span style="color: blue"&gt;ref&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IID_IMsoComponentManager&lt;/span&gt;, &lt;span style="color: blue"&gt;out&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pmsocm&lt;/span&gt;); 
                                 }
                                 &lt;span style="color: blue"&gt;finally&lt;/span&gt; {
                                    &lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;Release&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;retval&lt;/span&gt;);
                                 } 
 
                                 &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;NativeMethods&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;Succeeded&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;hr&lt;/span&gt;) &lt;span style="color: #800040"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pmsocm&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IntPtr&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;Zero&lt;/span&gt;) { 
 
                                    &lt;span style="color: #7ca78b"&gt;// Ok, we have a native component manager.  Hand this over to&lt;/span&gt;
                                    &lt;span style="color: #7ca78b"&gt;// our broker object to get a proxy we can use &lt;/span&gt;
                                    &lt;span style="color: blue"&gt;try&lt;/span&gt; {
                                          &lt;span style="color: #8b2be3"&gt;msocm&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ComponentManagerBroker&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;GetComponentManager&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;pmsocm&lt;/span&gt;);
                                    }
                                    &lt;span style="color: blue"&gt;finally&lt;/span&gt; { 
                                          &lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;Release&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;pmsocm&lt;/span&gt;);
                                    } 
                                 } 
 
                                 &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: #8b2be3"&gt;msocm&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: blue"&gt;null&lt;/span&gt;) { 
 
                                    &lt;span style="color: #7ca78b"&gt;// If the resulting service is the same pUnk as the&lt;/span&gt;
                                    &lt;span style="color: #7ca78b"&gt;// message filter (a common implementation technique),&lt;/span&gt;
                                    &lt;span style="color: #7ca78b"&gt;// then we want to null msgFilterObj at this point so &lt;/span&gt;
                                    &lt;span style="color: #7ca78b"&gt;// we don&amp;#39;t call RelaseComObject on it below.  That would&lt;/span&gt;
                                    &lt;span style="color: #7ca78b"&gt;// also release the RCW for the component manager pointer. &lt;/span&gt;
                                    &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: #8b2be3"&gt;msgFilterPtr&lt;/span&gt; &lt;span style="color: #800040"&gt;==&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;retval&lt;/span&gt;) { 
                                          &lt;span style="color: #8b2be3"&gt;msgFilterObj&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;null&lt;/span&gt;;
                                    } 
 
                                    &lt;span style="color: #8b2be3"&gt;externalComponentManager&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;true&lt;/span&gt;;
                                    &lt;span style="color: #8b2be3"&gt;Debug&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;WriteLineIf&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;CompModSwitches&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;MSOComponentManager&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;TraceInfo&lt;/span&gt;, &lt;span style="color: magenta"&gt;&amp;quot;Using MSO Component manager&amp;quot;&lt;/span&gt;);
 
                                    &lt;span style="color: #7ca78b"&gt;// Now attach app domain unload events so we can&lt;/span&gt;
                                    &lt;span style="color: #7ca78b"&gt;// detect when we need to revoke our component &lt;/span&gt;
                                    &lt;span style="color: #7ca78b"&gt;// &lt;/span&gt;
                                    &lt;span style="color: #2b91af"&gt;AppDomain&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;CurrentDomain&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DomainUnload&lt;/span&gt; &lt;span style="color: #800040"&gt;+=&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;EventHandler&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;OnDomainUnload&lt;/span&gt;);
                                    &lt;span style="color: #2b91af"&gt;AppDomain&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;CurrentDomain&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ProcessExit&lt;/span&gt; &lt;span style="color: #800040"&gt;+=&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;EventHandler&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;OnDomainUnload&lt;/span&gt;); 
                                 }
                              }
                        }
                        &lt;span style="color: blue"&gt;catch&lt;/span&gt; { 
                        }
                     } 
 
                     &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: #8b2be3"&gt;msgFilterObj&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: blue"&gt;null&lt;/span&gt; &lt;span style="color: #800040"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IsComObject&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;msgFilterObj&lt;/span&gt;)) {
                        &lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ReleaseComObject&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;msgFilterObj&lt;/span&gt;); 
                     }
                  }
 
                  &lt;span style="color: #7ca78b"&gt;// Otherwise, we implement component manager ourselves &lt;/span&gt;
                  &lt;span style="color: #7ca78b"&gt;//&lt;/span&gt;
                  &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: #8b2be3"&gt;msocm&lt;/span&gt; &lt;span style="color: #800040"&gt;==&lt;/span&gt; &lt;span style="color: blue"&gt;null&lt;/span&gt;) { 
                     &lt;span style="color: #8b2be3"&gt;msocm&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ComponentManager&lt;/span&gt;(); 
                     &lt;span style="color: #8b2be3"&gt;externalComponentManager&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;false&lt;/span&gt;;
 
                     &lt;span style="color: #7ca78b"&gt;// We must also store this back into the message filter for others&lt;/span&gt;
                     &lt;span style="color: #7ca78b"&gt;// to use.&lt;/span&gt;
                     &lt;span style="color: #7ca78b"&gt;//&lt;/span&gt;
                     &lt;span style="color: #7ca78b"&gt;// &lt;/span&gt;
                     &lt;span style="color: #8b2be3"&gt;Debug&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;WriteLineIf&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;CompModSwitches&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;MSOComponentManager&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;TraceInfo&lt;/span&gt;, &lt;span style="color: magenta"&gt;&amp;quot;Using our own component manager&amp;quot;&lt;/span&gt;);
                  } 
 
                  &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: #8b2be3"&gt;msocm&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: blue"&gt;null&lt;/span&gt; &lt;span style="color: #800040"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;componentID&lt;/span&gt; &lt;span style="color: #800040"&gt;==&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;INVALID_ID&lt;/span&gt;) {
                     &lt;span style="color: #7ca78b"&gt;// Finally, if we got a compnent manager, register ourselves with it. &lt;/span&gt;
                     &lt;span style="color: #7ca78b"&gt;//&lt;/span&gt;
                     &lt;span style="color: #8b2be3"&gt;Debug&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;WriteLineIf&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;CompModSwitches&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;MSOComponentManager&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;TraceInfo&lt;/span&gt;, &lt;span style="color: magenta"&gt;&amp;quot;Registering MSO component with the component manager&amp;quot;&lt;/span&gt;);
                     &lt;span style="color: #2b91af"&gt;NativeMethods&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;MSOCRINFOSTRUCT&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;info&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;NativeMethods&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;MSOCRINFOSTRUCT&lt;/span&gt;();
                     &lt;span style="color: #8b2be3"&gt;info&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;cbSize&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;SizeOf&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;NativeMethods&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;MSOCRINFOSTRUCT&lt;/span&gt;)); 
                     &lt;span style="color: #8b2be3"&gt;info&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;uIdleTimeInterval&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #e33104"&gt;0&lt;/span&gt;;
                     &lt;span style="color: #8b2be3"&gt;info&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;grfcrf&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #2b91af"&gt;NativeMethods&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;MSOCM&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;msocrfPreTranslateAll&lt;/span&gt; &lt;span style="color: #800040"&gt;|&lt;/span&gt; &lt;span style="color: #2b91af"&gt;NativeMethods&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;MSOCM&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;msocrfNeedIdleTime&lt;/span&gt;; 
                     &lt;span style="color: #8b2be3"&gt;info&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;grfcadvf&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #2b91af"&gt;NativeMethods&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;MSOCM&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;msocadvfModal&lt;/span&gt;; 
 
                     &lt;span style="color: #2b91af"&gt;IntPtr&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;localComponentID&lt;/span&gt;; 
                     &lt;span style="color: blue"&gt;bool&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;result&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;msocm&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FRegisterComponent&lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;, &lt;span style="color: #8b2be3"&gt;info&lt;/span&gt;, &lt;span style="color: blue"&gt;out&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;localComponentID&lt;/span&gt;);
                     &lt;span style="color: #8b2be3"&gt;componentID&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;unchecked&lt;/span&gt;((&lt;span style="color: blue"&gt;int&lt;/span&gt;)(&lt;span style="color: blue"&gt;long&lt;/span&gt;)&lt;span style="color: #8b2be3"&gt;localComponentID&lt;/span&gt;);
                     &lt;span style="color: #8b2be3"&gt;Debug&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;Assert&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;componentID&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;INVALID_ID&lt;/span&gt;, &lt;span style="color: magenta"&gt;&amp;quot;Our ID sentinel was returned as a valid ID&amp;quot;&lt;/span&gt;);
 
                     &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: #8b2be3"&gt;result&lt;/span&gt; &lt;span style="color: #800040"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #800040"&gt;!&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;msocm&lt;/span&gt; &lt;span style="color: blue"&gt;is&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ComponentManager&lt;/span&gt;)) {
                        &lt;span style="color: #8b2be3"&gt;messageLoopCount&lt;/span&gt;&lt;span style="color: #800040"&gt;++&lt;/span&gt;; 
                     } 
 
                     &lt;span style="color: #8b2be3"&gt;Debug&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;Assert&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;result&lt;/span&gt;, &lt;span style="color: magenta"&gt;&amp;quot;Failed to register WindowsForms with the ComponentManager -- DoEvents and modal dialogs will be broken. size: &amp;quot;&lt;/span&gt; &lt;span style="color: #800040"&gt;+&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;info&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;cbSize&lt;/span&gt;); 
                     &lt;span style="color: #8b2be3"&gt;Debug&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;WriteLineIf&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;CompModSwitches&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;MSOComponentManager&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;TraceInfo&lt;/span&gt;, &lt;span style="color: magenta"&gt;&amp;quot;ComponentManager.FRegisterComponent returned &amp;quot;&lt;/span&gt; &lt;span style="color: #800040"&gt;+&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;result&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ToString&lt;/span&gt;());
                     &lt;span style="color: #8b2be3"&gt;Debug&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;WriteLineIf&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;CompModSwitches&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;MSOComponentManager&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;TraceInfo&lt;/span&gt;, &lt;span style="color: magenta"&gt;&amp;quot;ComponentManager.FRegisterComponent assigned a componentID == [0x&amp;quot;&lt;/span&gt; &lt;span style="color: #800040"&gt;+&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Convert&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ToString&lt;/span&gt;(&lt;span style="color: #8b2be3"&gt;componentID&lt;/span&gt;, &lt;span style="color: #e33104"&gt;16&lt;/span&gt;) &lt;span style="color: #800040"&gt;+&lt;/span&gt; &lt;span style="color: magenta"&gt;&amp;quot;]&amp;quot;&lt;/span&gt;);
                     &lt;span style="color: #8b2be3"&gt;componentManager&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;msocm&lt;/span&gt;;
                  } 
            }
            &lt;span style="color: blue"&gt;finally&lt;/span&gt; { 
                  &lt;span style="color: #8b2be3"&gt;fetchingComponentManager&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;false&lt;/span&gt;; 
            }
         } 
 
         &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;componentManager&lt;/span&gt;;
      }
}
&lt;/pre&gt;
&lt;p&gt;Нихуя себе! Сказал я себе. Этот метод выполняет следующие действия:&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;Дважды вызывает
 &lt;a href="http://msdn.microsoft.com/en-us/library/ms693324(VS.85).aspx"&gt;
 &lt;code&gt;CoRegisterMessageFilter&lt;/code&gt;&lt;/a&gt; чтобы получить реализацию &lt;code&gt;IMessageFilter&lt;/code&gt; 
 для текущего потока;&lt;/li&gt;
 &lt;li&gt;Запрашивает у полученного объекта интерфейс &lt;code&gt;IOleServiceProvider&lt;/code&gt;, 
 который на самом деле - &lt;code&gt;IServiceProvider&lt;/code&gt;, объявление находится 
 в файле &lt;code&gt;ServProv.h&lt;/code&gt;;&lt;/li&gt;
 &lt;li&gt;Вызывает метод &lt;code&gt;QueryService&lt;/code&gt; для получения реализации необходимой 
 службы - &lt;code&gt;IMsoComponentManager&lt;/code&gt;.
 &lt;pre&gt;&lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;const&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;GUID&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;SERVICEID_MSO_COMPONENT_MANAGER&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x000C060B&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x0000&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x0000&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt; &lt;span style="color: #e33104"&gt;0xC0&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x00&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x00&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x00&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x00&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x00&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x00&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x46&lt;/span&gt; &lt;span style="color: #800040"&gt;}&lt;/span&gt; &lt;span style="color: #800040"&gt;};&lt;/span&gt;&lt;/pre&gt;
 &lt;/li&gt;
 &lt;li&gt;Если действия выше неудачны - используется своя реализация &lt;code&gt;IMsoComponentManager&lt;/code&gt;;&lt;/li&gt;
 &lt;li&gt;Далее &lt;code&gt;ThreadContext&lt;/code&gt; регистрирует себя в менеджере с помощью 
 метода &lt;code&gt;FRegisterComponent&lt;/code&gt; (&lt;code&gt;ThreadContext&lt;/code&gt; поддерживает 
 интерфейс &lt;code&gt;IMsoComponent&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Задача стала ясна - реализовать COM-объект с необходимыми интерфейсами, зарегистрировать 
его вызовом &lt;code&gt;CoRegisterMessageFilter&lt;/code&gt; и проталкивать сообщения из
&lt;a href="http://msdn.microsoft.com/en-us/library/67d74wsy(VS.80).aspx"&gt;&lt;code&gt;CWinThread::PreTranslateMessage&lt;/code&gt;&lt;/a&gt; 
во все активные &lt;code&gt;IMsoComponent&lt;/code&gt; вызывая &lt;code&gt;IMsoComponent::FPreTranslateMessage&lt;/code&gt;. 
На самом деле все чуть сложней - активный компонент максимум один, но зато есть 
еще так называемый tracking компонент. Например при открытии конекстного меню
&lt;code&gt;ThreadContext&lt;/code&gt; становится tracking, а при закрытии возвращается в обычное 
состояние. При этом он не обязательно будет активным.&lt;/p&gt;
&lt;p&gt;Погуглив на тему &lt;code&gt;IMsoComponentManager&lt;/code&gt; и &lt;code&gt;IMsoComponent&lt;/code&gt;, 
я не нашел никакой полезной информации. Ни tlb, ни idl. С какой-то попытки наткнулся 
на файл &lt;code&gt;msoci.h&lt;/code&gt; в неком SVN репозитарии и выяснил, что он является 
частью Visual Studio 2010 SDK и лежит в папке &lt;code&gt;C:\Program Files\Microsoft Visual 
Studio 2010 SDK\VisualStudioIntegration\Common\Inc\office10&lt;/code&gt;. Очень порадовала 
документация к методам. Ведь она там есть! Причем детальное описание.&lt;/p&gt;
&lt;p&gt;Собственно, реализация &lt;code&gt;IMsoComponentManager&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="listing"&gt;&lt;span style="color: orangered"&gt;#pragma&lt;/span&gt; &lt;span style="color: orangered"&gt;once&lt;/span&gt;
&lt;span style="color: orangered"&gt;#include&lt;/span&gt; &lt;span style="color: magenta"&gt;&amp;quot;objidl.h&amp;quot;&lt;/span&gt;
&lt;span style="color: orangered"&gt;#include&lt;/span&gt; &lt;span style="color: magenta"&gt;&amp;lt;ServProv.h&amp;gt;&lt;/span&gt;
&lt;span style="color: orangered"&gt;#include&lt;/span&gt; &lt;span style="color: magenta"&gt;&amp;lt;msoci.h&amp;gt;&lt;/span&gt;
&lt;span style="color: orangered"&gt;#include&lt;/span&gt; &lt;span style="color: magenta"&gt;&amp;lt;unordered_map&amp;gt;&lt;/span&gt;
 
&lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt; &lt;span style="color: #800040"&gt;:&lt;/span&gt; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt;
                          &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IServiceProvider&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt;
                          &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IMsoComponentManager&lt;/span&gt;
&lt;span style="color: #800040"&gt;{&lt;/span&gt;
 
&lt;span style="color: blue"&gt;public&lt;/span&gt;&lt;span style="color: #800040"&gt;:&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;();&lt;/span&gt;
   &lt;span style="color: blue"&gt;virtual&lt;/span&gt; &lt;span style="color: #800040"&gt;~&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;();&lt;/span&gt;
 
&lt;span style="color: blue"&gt;public&lt;/span&gt;&lt;span style="color: #800040"&gt;:&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;PreTranslateMessage&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;MSG&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pMsg&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
 
&lt;span style="color: blue"&gt;public&lt;/span&gt;&lt;span style="color: #800040"&gt;:&lt;/span&gt;
   &lt;span style="color: #7ca78b"&gt;// IUnknown&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;HRESULT&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;QueryInterface&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;REFIID&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;riid&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;LPVOID&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppvObj&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;AddRef&lt;/span&gt;&lt;span style="color: #800040"&gt;();&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;Release&lt;/span&gt;&lt;span style="color: #800040"&gt;();&lt;/span&gt;
   
&lt;span style="color: blue"&gt;private&lt;/span&gt;&lt;span style="color: #800040"&gt;:&lt;/span&gt;
   &lt;span style="color: #7ca78b"&gt;// IMessageFilter&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;HandleInComingCall&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwCallType&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;HTASK&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;htaskCaller&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwTickCount&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;LPINTERFACEINFO&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;lpInterfaceInfo&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;RetryRejectedCall&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;HTASK&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;htaskCallee&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwTickCount&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwRejectType&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;MessagePending&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;HTASK&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;htaskCallee&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwTickCount&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwPendingType&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
 
&lt;span style="color: blue"&gt;private&lt;/span&gt;&lt;span style="color: #800040"&gt;:&lt;/span&gt;
   &lt;span style="color: #7ca78b"&gt;// IServiceProvider&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;HRESULT&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;QueryService&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;REFGUID&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;guidService&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;REFIID&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;riid&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;LPVOID&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppvObj&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
 
&lt;span style="color: blue"&gt;private&lt;/span&gt;&lt;span style="color: #800040"&gt;:&lt;/span&gt;
   &lt;span style="color: #7ca78b"&gt;// IMsoComponentManager&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;FDebugMessage&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;HMSOINST&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;hinst&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;UINT&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;message&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;WPARAM&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;wParam&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;LPARAM&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;lParam&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;FRegisterComponent&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IMsoComponent&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;piComponent&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: blue"&gt;const&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;MSOCRINFO&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pcrinfo&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pdwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;FRevokeComponent&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;FUpdateComponentRegistration&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: blue"&gt;const&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;MSOCRINFO&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pcrinfo&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;FOnComponentActivate&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;FSetTrackingComponent&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;grftrack&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;OnComponentEnterState&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;uStateID&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;uContext&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;cpicmExclude&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IMsoComponentManager&lt;/span&gt; &lt;span style="color: #800040"&gt;**&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;rgpicmExclude&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwReserved&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;FOnComponentExitState&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;uStateID&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;uContext&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;cpicmExclude&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IMsoComponentManager&lt;/span&gt; &lt;span style="color: #800040"&gt;**&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;rgpicmExclude&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;FInState&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;uStateID&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;LPVOID&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pvoid&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;FContinueIdle&lt;/span&gt;&lt;span style="color: #800040"&gt;();&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;FPushMessageLoop&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;uReason&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pvLoopData&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;FCreateSubComponentManager&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IUnknown&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pUnkOuter&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IUnknown&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pUnkServProv&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;REFIID&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;riid&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;LPVOID&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppvObj&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;FGetParentComponentManager&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IMsoComponentManager&lt;/span&gt; &lt;span style="color: #800040"&gt;**&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppicm&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;FGetActiveComponent&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwgac&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IMsoComponent&lt;/span&gt; &lt;span style="color: #800040"&gt;**&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppic&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;MSOCRINFO&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pcrinfo&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwReserved&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
 
&lt;span style="color: blue"&gt;private&lt;/span&gt;&lt;span style="color: #800040"&gt;:&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_refCount&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;   
 
   &lt;span style="color: blue"&gt;typedef&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CComPtr&lt;/span&gt;&lt;span style="color: #800040"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IMsoComponent&lt;/span&gt;&lt;span style="color: #800040"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IMsoComponentPtr&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
   &lt;span style="color: blue"&gt;struct&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;MsoComponentRegistration&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IMsoComponentPtr&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ComponentPtr&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;MSOCRINFO&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;Info&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt; &lt;span style="color: #800040"&gt;};&lt;/span&gt;
   &lt;span style="color: blue"&gt;typedef&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;std&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;tr1&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;unordered_map&lt;/span&gt;&lt;span style="color: #800040"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;MsoComponentRegistration&lt;/span&gt;&lt;span style="color: #800040"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;component_registrations_t&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
   &lt;span style="color: blue"&gt;typedef&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;std&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;tr1&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;unordered_map&lt;/span&gt;&lt;span style="color: #800040"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IMsoComponentPtr&lt;/span&gt;&lt;span style="color: #800040"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;tracking_components_t&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
 
   &lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_nextComponentId&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_activeComponentId&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;IMsoComponentPtr&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_activeComponentPtr&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;component_registrations_t&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_components&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;tracking_components_t&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_tracking&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
   &lt;span style="color: blue"&gt;bool&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_trackingIteration&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;tracking_components_t&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_track&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;tracking_components_t&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_untrack&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
 
&lt;span style="color: #800040"&gt;};&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="listing"&gt;&lt;span style="color: orangered"&gt;#include&lt;/span&gt; &lt;span style="color: magenta"&gt;&amp;quot;stdafx.h&amp;quot;&lt;/span&gt;
&lt;span style="color: orangered"&gt;#include&lt;/span&gt; &lt;span style="color: magenta"&gt;&amp;quot;COMMessageFilter.h&amp;quot;&lt;/span&gt;
&lt;span style="color: orangered"&gt;#define&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;INIT_MSO_GUIDS&lt;/span&gt;
&lt;span style="color: orangered"&gt;#include&lt;/span&gt; &lt;span style="color: magenta"&gt;&amp;lt;msoguids.h&amp;gt;&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;()&lt;/span&gt; &lt;span style="color: #800040"&gt;:&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_refCount&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #e33104"&gt;0&lt;/span&gt;&lt;span style="color: #800040"&gt;),&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_nextComponentId&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #e33104"&gt;0&lt;/span&gt;&lt;span style="color: #800040"&gt;),&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_activeComponentId&lt;/span&gt;&lt;span style="color: #800040"&gt;(-&lt;/span&gt;&lt;span style="color: #e33104"&gt;1&lt;/span&gt;&lt;span style="color: #800040"&gt;),&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_trackingIteration&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;false&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #7ca78b"&gt;/*virtual*/&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::~&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;()&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;PreTranslateMessage&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;MSG&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pMsg&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;bRet&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;FALSE&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
   
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(!&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_tracking&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;empty&lt;/span&gt;&lt;span style="color: #800040"&gt;())&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
      &lt;span style="color: #7ca78b"&gt;// Tracking ones first&lt;/span&gt;
      &lt;span style="color: #8b2be3"&gt;_trackingIteration&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;true&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
      &lt;span style="color: blue"&gt;for&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;tracking_components_t&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;const_reverse_iterator&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_tracking&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;rbegin&lt;/span&gt;&lt;span style="color: #800040"&gt;();&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_tracking&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;rend&lt;/span&gt;&lt;span style="color: #800040"&gt;();&lt;/span&gt; &lt;span style="color: #800040"&gt;++&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
         &lt;span style="color: #8b2be3"&gt;bRet&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;bRet&lt;/span&gt; &lt;span style="color: #800040"&gt;||&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt;&lt;span style="color: #800040"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;second&lt;/span&gt;&lt;span style="color: #800040"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FPreTranslateMessage&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pMsg&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
      &lt;span style="color: #800040"&gt;}&lt;/span&gt;
      &lt;span style="color: #8b2be3"&gt;_trackingIteration&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;false&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
 
      &lt;span style="color: #7ca78b"&gt;// Insert tracked components&lt;/span&gt;
      &lt;span style="color: #8b2be3"&gt;_tracking&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;insert&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_track&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;begin&lt;/span&gt;&lt;span style="color: #800040"&gt;(),&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_track&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;end&lt;/span&gt;&lt;span style="color: #800040"&gt;());&lt;/span&gt;
      &lt;span style="color: #8b2be3"&gt;_track&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;clear&lt;/span&gt;&lt;span style="color: #800040"&gt;();&lt;/span&gt;
 
      &lt;span style="color: #7ca78b"&gt;// Delete untracked components&lt;/span&gt;
      &lt;span style="color: blue"&gt;for&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;tracking_components_t&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;const_iterator&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_untrack&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;begin&lt;/span&gt;&lt;span style="color: #800040"&gt;();&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_untrack&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;end&lt;/span&gt;&lt;span style="color: #800040"&gt;();&lt;/span&gt; &lt;span style="color: #800040"&gt;++&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
         &lt;span style="color: #8b2be3"&gt;_tracking&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;erase&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt;&lt;span style="color: #800040"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;first&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
      &lt;span style="color: #800040"&gt;}&lt;/span&gt;
      &lt;span style="color: #8b2be3"&gt;_untrack&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;clear&lt;/span&gt;&lt;span style="color: #800040"&gt;();&lt;/span&gt;
 
      &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;bRet&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt;
         &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;bRet&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
   &lt;span style="color: #7ca78b"&gt;// Active one&lt;/span&gt;
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_activeComponentPtr&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt;
      &lt;span style="color: #8b2be3"&gt;bRet&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_activeComponentPtr&lt;/span&gt;&lt;span style="color: #800040"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FPreTranslateMessage&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pMsg&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;         
 
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;bRet&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;HRESULT&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;QueryInterface&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;REFIID&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;riid&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;LPVOID&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppvObj&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(!&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppvObj&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt;
      &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;E_POINTER&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;riid&lt;/span&gt; &lt;span style="color: #800040"&gt;==&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IID_IUnknown&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
      &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppvObj&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;static_cast&lt;/span&gt;&lt;span style="color: #800040"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IUnknown&lt;/span&gt; &lt;span style="color: #800040"&gt;*&amp;gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;static_cast&lt;/span&gt;&lt;span style="color: #800040"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IMessageFilter&lt;/span&gt; &lt;span style="color: #800040"&gt;*&amp;gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
   &lt;span style="color: #800040"&gt;}&lt;/span&gt;
   &lt;span style="color: blue"&gt;else&lt;/span&gt; &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;riid&lt;/span&gt; &lt;span style="color: #800040"&gt;==&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IID_IMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
      &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppvObj&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;static_cast&lt;/span&gt;&lt;span style="color: #800040"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IMessageFilter&lt;/span&gt; &lt;span style="color: #800040"&gt;*&amp;gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #800040"&gt;}&lt;/span&gt;
   &lt;span style="color: blue"&gt;else&lt;/span&gt; &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;riid&lt;/span&gt; &lt;span style="color: #800040"&gt;==&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IID_IServiceProvider&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
      &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppvObj&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;static_cast&lt;/span&gt;&lt;span style="color: #800040"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IServiceProvider&lt;/span&gt; &lt;span style="color: #800040"&gt;*&amp;gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #800040"&gt;}&lt;/span&gt;
   &lt;span style="color: blue"&gt;else&lt;/span&gt; &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;riid&lt;/span&gt; &lt;span style="color: #800040"&gt;==&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IID_IMsoComponentManager&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
      &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppvObj&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;static_cast&lt;/span&gt;&lt;span style="color: #800040"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IMsoComponentManager&lt;/span&gt; &lt;span style="color: #800040"&gt;*&amp;gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #800040"&gt;}&lt;/span&gt;
   &lt;span style="color: blue"&gt;else&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
      &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppvObj&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;NULL&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
      &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;E_NOINTERFACE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
   &lt;span style="color: #8b2be3"&gt;AddRef&lt;/span&gt;&lt;span style="color: #800040"&gt;();&lt;/span&gt;
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;S_OK&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;AddRef&lt;/span&gt;&lt;span style="color: #800040"&gt;()&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;InterlockedIncrement&lt;/span&gt;&lt;span style="color: #800040"&gt;(&amp;amp;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_refCount&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;Release&lt;/span&gt;&lt;span style="color: #800040"&gt;()&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: blue"&gt;const&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;count&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;InterlockedDecrement&lt;/span&gt;&lt;span style="color: #800040"&gt;(&amp;amp;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_refCount&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;count&lt;/span&gt; &lt;span style="color: #800040"&gt;==&lt;/span&gt; &lt;span style="color: #e33104"&gt;0&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt;
      &lt;span style="color: blue"&gt;delete&lt;/span&gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;count&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #7ca78b"&gt;// IMessageFilter&lt;/span&gt;
&lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;HandleInComingCall&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwCallType&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;HTASK&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;htaskCaller&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwTickCount&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;LPINTERFACEINFO&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;lpInterfaceInfo&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;SERVERCALL_RETRYLATER&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;RetryRejectedCall&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;HTASK&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;htaskCallee&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwTickCount&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwRejectType&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #e33104"&gt;100&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;MessagePending&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;HTASK&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;htaskCallee&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwTickCount&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwPendingType&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;PENDINGMSG_WAITNOPROCESS&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #7ca78b"&gt;// IOleServiceProvider&lt;/span&gt;
&lt;span style="color: #8b2be3"&gt;HRESULT&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;QueryService&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;REFGUID&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;guidService&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;REFIID&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;riid&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;LPVOID&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppvObj&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;TRACE&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_T&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: magenta"&gt;&amp;quot;CCOMMessageFilter::QueryService\n&amp;quot;&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(!&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppvObj&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt;
      &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;E_POINTER&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
 
   &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppvObj&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;NULL&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;const&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;GUID&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;SERVICEID_MSO_COMPONENT_MANAGER&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x000C060B&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x0000&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x0000&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt; &lt;span style="color: #e33104"&gt;0xC0&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x00&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x00&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x00&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x00&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x00&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x00&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #e33104"&gt;0x46&lt;/span&gt; &lt;span style="color: #800040"&gt;}&lt;/span&gt; &lt;span style="color: #800040"&gt;};&lt;/span&gt;
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;guidService&lt;/span&gt; &lt;span style="color: #800040"&gt;==&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;SERVICEID_MSO_COMPONENT_MANAGER&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
      &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;QueryInterface&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;riid&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ppvObj&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
   &lt;span style="color: #800040"&gt;}&lt;/span&gt;
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;E_NOINTERFACE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FDebugMessage&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;HMSOINST&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;hinst&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;UINT&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;message&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;WPARAM&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;wParam&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;LPARAM&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;lParam&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;TRACE&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_T&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: magenta"&gt;&amp;quot;CCOMMessageFilter::FDebugMessage\n&amp;quot;&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;TRUE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FRegisterComponent&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IMsoComponent&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;piComponent&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: blue"&gt;const&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;MSOCRINFO&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pcrinfo&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pdwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;TRACE&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_T&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: magenta"&gt;&amp;quot;CCOMMessageFilter::FRegisterComponent\n&amp;quot;&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(!&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;piComponent&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt;
      &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;E_POINTER&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(!&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pcrinfo&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt;
      &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;E_POINTER&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(!&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pdwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt;
      &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;E_POINTER&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   
   &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pdwComponentID&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_nextComponentId&lt;/span&gt;&lt;span style="color: #800040"&gt;++;&lt;/span&gt;
   &lt;span style="color: blue"&gt;const&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;MsoComponentRegistration&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;reg&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;piComponent&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pcrinfo&lt;/span&gt; &lt;span style="color: #800040"&gt;};&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;_components&lt;/span&gt;&lt;span style="color: #800040"&gt;[*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pdwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;]&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;reg&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
   
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;TRUE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FRevokeComponent&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;TRACE&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_T&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: magenta"&gt;&amp;quot;CCOMMessageFilter::FRevokeComponent\n&amp;quot;&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
   
   &lt;span style="color: #8b2be3"&gt;_components&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;erase&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_trackingIteration&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
      &lt;span style="color: blue"&gt;const&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;tracking_components_t&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;const_iterator&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_tracking&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;find&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
      &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_tracking&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;end&lt;/span&gt;&lt;span style="color: #800040"&gt;())&lt;/span&gt;
         &lt;span style="color: #8b2be3"&gt;_untrack&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;insert&lt;/span&gt;&lt;span style="color: #800040"&gt;(*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #800040"&gt;}&lt;/span&gt;
   &lt;span style="color: blue"&gt;else&lt;/span&gt;
      &lt;span style="color: #8b2be3"&gt;_tracking&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;erase&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt; &lt;span style="color: #800040"&gt;==&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_activeComponentId&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
      &lt;span style="color: #8b2be3"&gt;_activeComponentId&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #800040"&gt;-&lt;/span&gt;&lt;span style="color: #e33104"&gt;1&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
      &lt;span style="color: #8b2be3"&gt;_activeComponentPtr&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;Release&lt;/span&gt;&lt;span style="color: #800040"&gt;();&lt;/span&gt;
   &lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;TRUE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FUpdateComponentRegistration&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: blue"&gt;const&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;MSOCRINFO&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pcrinfo&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;TRACE&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_T&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: magenta"&gt;&amp;quot;CCOMMessageFilter::FUpdateComponentRegistration\n&amp;quot;&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(!&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pcrinfo&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt;
      &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;E_POINTER&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;const&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;component_registrations_t&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;iterator&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_components&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;find&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_components&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;end&lt;/span&gt;&lt;span style="color: #800040"&gt;())&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
      &lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt;&lt;span style="color: #800040"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;second&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;Info&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pcrinfo&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
      &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;TRUE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FALSE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FOnComponentActivate&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;TRACE&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_T&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: magenta"&gt;&amp;quot;CCOMMessageFilter::FOnComponentActivate\n&amp;quot;&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;const&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;component_registrations_t&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;iterator&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_components&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;find&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_components&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;end&lt;/span&gt;&lt;span style="color: #800040"&gt;())&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
      &lt;span style="color: #8b2be3"&gt;_activeComponentId&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt;&lt;span style="color: #800040"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;first&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
      &lt;span style="color: #8b2be3"&gt;_activeComponentPtr&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt;&lt;span style="color: #800040"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;second&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ComponentPtr&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
      &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;TRUE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FALSE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FSetTrackingComponent&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;grftrack&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;TRACE&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_T&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: magenta"&gt;&amp;quot;CCOMMessageFilter::FSetTrackingComponent\n&amp;quot;&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;const&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;bTrack&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;grftrack&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(!&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;bTrack&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
      &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_trackingIteration&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
         &lt;span style="color: blue"&gt;const&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;tracking_components_t&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;const_iterator&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_tracking&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;find&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
         &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_tracking&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;end&lt;/span&gt;&lt;span style="color: #800040"&gt;())&lt;/span&gt;
            &lt;span style="color: #8b2be3"&gt;_untrack&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;insert&lt;/span&gt;&lt;span style="color: #800040"&gt;(*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
         &lt;span style="color: blue"&gt;else&lt;/span&gt;
            &lt;span style="color: #8b2be3"&gt;_track&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;erase&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
      &lt;span style="color: #800040"&gt;}&lt;/span&gt;
      &lt;span style="color: blue"&gt;else&lt;/span&gt;
         &lt;span style="color: #8b2be3"&gt;_tracking&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;erase&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
 
      &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;TRUE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;const&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;component_registrations_t&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;iterator&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_components&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;find&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_components&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;end&lt;/span&gt;&lt;span style="color: #800040"&gt;())&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
      &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_trackingIteration&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt;
         &lt;span style="color: #8b2be3"&gt;_track&lt;/span&gt;&lt;span style="color: #800040"&gt;[&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;]&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt;&lt;span style="color: #800040"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;second&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ComponentPtr&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
      &lt;span style="color: blue"&gt;else&lt;/span&gt;
         &lt;span style="color: #8b2be3"&gt;_tracking&lt;/span&gt;&lt;span style="color: #800040"&gt;[&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;]&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt;&lt;span style="color: #800040"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;second&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ComponentPtr&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
 
      &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;TRUE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FALSE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;OnComponentEnterState&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;uStateID&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;uContext&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;cpicmExclude&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IMsoComponentManager&lt;/span&gt; &lt;span style="color: #800040"&gt;**&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;rgpicmExclude&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwReserved&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;TRACE&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_T&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: magenta"&gt;&amp;quot;CCOMMessageFilter::OnComponentEnterState\n&amp;quot;&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FOnComponentExitState&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;uStateID&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;uContext&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;cpicmExclude&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IMsoComponentManager&lt;/span&gt; &lt;span style="color: #800040"&gt;**&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;rgpicmExclude&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;TRACE&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_T&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: magenta"&gt;&amp;quot;CCOMMessageFilter::FOnComponentExitState\n&amp;quot;&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;TRUE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FInState&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;uStateID&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;LPVOID&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pvoid&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;TRACE&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_T&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: magenta"&gt;&amp;quot;CCOMMessageFilter::FInState\n&amp;quot;&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;TRUE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FContinueIdle&lt;/span&gt;&lt;span style="color: #800040"&gt;()&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;TRACE&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_T&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: magenta"&gt;&amp;quot;CCOMMessageFilter::FContinueIdle\n&amp;quot;&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;TRUE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FPushMessageLoop&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwComponentID&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ULONG&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;uReason&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pvLoopData&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;TRACE&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_T&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: magenta"&gt;&amp;quot;CCOMMessageFilter::FPushMessageLoop\n&amp;quot;&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FALSE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FCreateSubComponentManager&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IUnknown&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pUnkOuter&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IUnknown&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pUnkServProv&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;REFIID&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;riid&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;LPVOID&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppvObj&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;TRACE&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_T&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: magenta"&gt;&amp;quot;CCOMMessageFilter::FCreateSubComponentManager\n&amp;quot;&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(!&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppvObj&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt;
      &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;E_POINTER&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
 
   &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppvObj&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;NULL&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FALSE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FGetParentComponentManager&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IMsoComponentManager&lt;/span&gt; &lt;span style="color: #800040"&gt;**&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppicm&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;TRACE&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_T&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: magenta"&gt;&amp;quot;CCOMMessageFilter::FGetParentComponentManager\n&amp;quot;&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(!&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppicm&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt;
      &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;E_POINTER&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
 
   &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppicm&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;NULL&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FALSE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;STDMETHODCALLTYPE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FGetActiveComponent&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwgac&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;IMsoComponent&lt;/span&gt; &lt;span style="color: #800040"&gt;**&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppic&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;MSOCRINFO&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pcrinfo&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;DWORD&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwReserved&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;TRACE&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_T&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: magenta"&gt;&amp;quot;CCOMMessageFilter::FGetActiveComponent\n&amp;quot;&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppic&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt;
      &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppic&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;NULL&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
 
   &lt;span style="color: #8b2be3"&gt;DWORD_PTR&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;componentId&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #800040"&gt;-&lt;/span&gt;&lt;span style="color: #e33104"&gt;1&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;dwgac&lt;/span&gt; &lt;span style="color: #800040"&gt;==&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;msogacTracking&lt;/span&gt; &lt;span style="color: #800040"&gt;||&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwgac&lt;/span&gt; &lt;span style="color: #800040"&gt;==&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;msogacTrackingOrActive&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
      &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(!&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;_tracking&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;empty&lt;/span&gt;&lt;span style="color: #800040"&gt;())&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
         &lt;span style="color: #8b2be3"&gt;componentId&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_tracking&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;rbegin&lt;/span&gt;&lt;span style="color: #800040"&gt;()-&amp;gt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;first&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
      &lt;span style="color: #800040"&gt;}&lt;/span&gt;
   &lt;span style="color: #800040"&gt;}&lt;/span&gt;
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;componentId&lt;/span&gt; &lt;span style="color: #800040"&gt;==&lt;/span&gt; &lt;span style="color: #800040"&gt;-&lt;/span&gt;&lt;span style="color: #e33104"&gt;1&lt;/span&gt; &lt;span style="color: #800040"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;dwgac&lt;/span&gt; &lt;span style="color: #800040"&gt;==&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;msogacActive&lt;/span&gt; &lt;span style="color: #800040"&gt;||&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;dwgac&lt;/span&gt; &lt;span style="color: #800040"&gt;==&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;msogacTrackingOrActive&lt;/span&gt;&lt;span style="color: #800040"&gt;))&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
      &lt;span style="color: #8b2be3"&gt;componentId&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_activeComponentId&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
   &lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
    &lt;span style="color: blue"&gt;const&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;component_registrations_t&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;iterator&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_components&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;find&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;componentId&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
    &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;_components&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;end&lt;/span&gt;&lt;span style="color: #800040"&gt;())&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
       &lt;span style="color: #8b2be3"&gt;MsoComponentRegistration&lt;/span&gt; &lt;span style="color: #800040"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;reg&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;pos&lt;/span&gt;&lt;span style="color: #800040"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;second&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
       &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pcrinfo&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt;
         &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pcrinfo&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;reg&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;Info&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
       &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppic&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt;
         &lt;span style="color: #8b2be3"&gt;reg&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ComponentPtr&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;CopyTo&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;ppic&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
       &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;TRUE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
    &lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FALSE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Использование:&lt;/p&gt;
&lt;pre class="listing"&gt;&lt;span style="color: #7ca78b"&gt;/*virtual*/&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CWinFormsMFCHostApp&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;PreTranslateMessage&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;MSG&lt;/span&gt; &lt;span style="color: #800040"&gt;*&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pMsg&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: blue"&gt;const&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;bRet&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;m_pComponentManager&lt;/span&gt;&lt;span style="color: #800040"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;PreTranslateMessage&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pMsg&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;bRet&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt;
      &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;bRet&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;__super&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;PreTranslateMessage&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;pMsg&lt;/span&gt;&lt;span style="color: #800040"&gt;));&lt;/span&gt;
&lt;span style="color: #800040"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Инициализация:&lt;/p&gt;
&lt;pre class="listing"&gt;&lt;span style="color: #8b2be3"&gt;&lt;span style="color: #7ca78b"&gt;/*virtual*/&lt;/span&gt; BOOL&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CWinFormsMFCHostApp&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;InitInstance&lt;/span&gt;&lt;span style="color: #800040"&gt;()&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;INITCOMMONCONTROLSEX&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;InitCtrls&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;InitCtrls&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;dwSize&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;sizeof&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;InitCtrls&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;InitCtrls&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;dwICC&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ICC_WIN95_CLASSES&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;InitCommonControlsEx&lt;/span&gt;&lt;span style="color: #800040"&gt;(&amp;amp;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;InitCtrls&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;__super&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;InitInstance&lt;/span&gt;&lt;span style="color: #800040"&gt;();&lt;/span&gt;
 
   &lt;span style="color: blue"&gt;if&lt;/span&gt; &lt;span style="color: #800040"&gt;(!&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;AfxOleInit&lt;/span&gt;&lt;span style="color: #800040"&gt;())&lt;/span&gt; &lt;span style="color: #800040"&gt;{&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;   AfxMessageBox&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;IDP_OLE_INIT_FAILED&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: blue"&gt;   return&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;FALSE&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;span style="color: #800040"&gt;}&lt;/span&gt;
 
   &lt;span style="color: #8b2be3"&gt;AfxEnableControlContainer&lt;/span&gt;&lt;span style="color: #800040"&gt;();&lt;/span&gt;
 
   &lt;span style="color: #8b2be3"&gt;m_pComponentManager&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CCOMMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;();&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;m_pComponentManager&lt;/span&gt;&lt;span style="color: #800040"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;AddRef&lt;/span&gt;&lt;span style="color: #800040"&gt;();&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;CoRegisterMessageFilter&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;m_pComponentManager&lt;/span&gt;&lt;span style="color: #800040"&gt;,&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;NULL&lt;/span&gt;&lt;span style="color: #800040"&gt;);&lt;/span&gt;
   &lt;/pre&gt;
&lt;p&gt;В результате получаем рабочую во всех смыслах .NET форму.&lt;/p&gt;
&lt;p&gt;Я, кстати, удивился, что контекстное меню продолжает нормально работать при отсутствии 
управляемого цикла сообщений. Эти гады, оказалось, проверяют на наличие цикла сообщений 
(а эта проверка, кстати, лезет в &lt;code&gt;ComponentManager&lt;/code&gt;), а если его нет 
- создают хук, отправляя все пойманные сообщения в &lt;code&gt;ThreadContext::PreTranslateMessage&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;Microsoft not only eats it&amp;#39;s own dogfood, but sometimes devours it. Not even 
giving a chance to taste...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-4464149075221224038?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/4464149075221224038/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2010/12/advanced-c-and-net-interop.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/4464149075221224038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/4464149075221224038'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2010/12/advanced-c-and-net-interop.html' title='Advanced C++ and .NET interop'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-6555443024836733267</id><published>2010-12-02T19:36:00.001+02:00</published><updated>2010-12-20T18:30:12.112+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET 4'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio 2010'/><title type='text'>Run tlbexp from post build event</title><content type='html'>Долго искал, как в Visual Studio 2010 безопасно вызвать &lt;code&gt;tlbexp.exe&lt;/code&gt;, &lt;code&gt;regasm.exe&lt;/code&gt; или любую другую утилиту .NET Framework SDK. Безопасно - без хардкода абсолютного пути! Решение нашлось:
&lt;br /&gt;
&lt;pre class="code"&gt;"$(FrameworkSdkDir)\bin\NETFX 4.0 Tools\tlbexp" $(TargetPath) /out:$(SolutionDir)\$(ConfigurationName)\$(TargetName).tlb&amp;nbsp;&lt;/pre&gt;
&lt;p&gt;Стоит также обратить внимание на следующие перменные:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$(WindowsSdkDir)&lt;/li&gt;
&lt;li&gt;$(WindowsSdkMSBuildTools)&lt;/li&gt;
&lt;li&gt;$(WindowsSdkNetFx35ToolsDir)&lt;/li&gt;
&lt;li&gt;$(WindowsSdkNetFx40ToolsDir)&lt;/li&gt;
&lt;li&gt;$(WindowsSDKVersionOverride)&lt;/li&gt;
&lt;li&gt;$(FrameworkSDKRoot)&lt;/li&gt;
&lt;li&gt;$(SDK35ToolsPath)&lt;/li&gt;
&lt;li&gt;$(SDK40ToolsPath)&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-6555443024836733267?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/6555443024836733267/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2010/12/run-tlbexp-from-post-build-event.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/6555443024836733267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/6555443024836733267'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2010/12/run-tlbexp-from-post-build-event.html' title='Run tlbexp from post build event'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-7608191137525642895</id><published>2010-10-31T17:31:00.002+02:00</published><updated>2011-01-20T14:29:24.996+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='choice'/><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>Ergonomic chairs in Kiev</title><content type='html'>&lt;p&gt;Недавно занялся поиском эргономичного кресла для дома. На работе у меня Hermal 
Miller Aeron, очень удобное кресло. Можно часами сидеть, дискомфорта не вызывает.&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;Herman Miller
 &lt;p&gt;Я нашел несколько мест, где можно приобрести кресла этой фирмы:&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;&lt;a href="http://www.denza.com.ua/"&gt;DenzaWorkspace&lt;/a&gt;&lt;p&gt;Здесь можно 
  заказать кресла Herman Miller, но опробовать их, вроди, &lt;s&gt;нет возможности&lt;/s&gt; можно у них в офисе, наличие уточняйте. Есть &lt;a href="http://hmconstructor.denza.com.ua/index.php?r=construct/chair&amp;id=2&amp;lang=ru"&gt;конструктор кресел&lt;/a&gt;!&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.liganova.kiev.ua/news/ID_80.html"&gt;Лига-Нова&lt;/a&gt;&lt;p&gt;
  С недавнего времени тоже занимается &lt;font color="red"&gt;(upd: уже &lt;em&gt;не&lt;/em&gt; занимается, upd: они просто перепродавали кресла от Denza)&lt;/font&gt; продажей кресел Herman Miller, Aeron 
  и Mira можно опробовать в магазине &amp;quot;Крісла Стільці Столи&amp;quot; по адресу Украина, 
  01011, г. Киев, б-р Леси Украинки, 34 , тел.: (044) 461-91-91.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href="http://macuser.in.ua/workplace.html"&gt;MACUser &lt;font color="red"&gt;в Харькове&lt;/font&gt;&lt;/a&gt;&lt;p&gt;
  Свершилось чудо! Сегодня на склад компании macuser.in.ua прибыли долгожданные эргономичные офисные кресела Herman Miller.&lt;/p&gt;
  &lt;/li&gt;
 &lt;/ol&gt;
 &lt;p&gt;А вот сегодня я нашел место, где можно посидеть во всех замечательных креслах 
 Herman Miller - Aeron, Embody, Mirra, Celle. Это
 &lt;a href="http://www.domosphera.kiev.ua/"&gt;Домосфера&lt;/a&gt; по адресу Столичное шоссе 
 101, тел.: (044) 252-70-94. После входа (1-й этаж) держаться правой стороны, 
 кресла тяжело будет не заметить. &lt;/p&gt;
 &lt;p&gt;Стоимость у нас - 2000+/-400 у.е. в зависимости от модели.&lt;/p&gt;
 &lt;/li&gt;
 &lt;li&gt;Steel Case&lt;p&gt;Интернет прям заполнен сравнениями их флагмана
 &lt;a href="http://www.steelcase.eu/en/products/category/seating/executive-chairs/leap-premium/pages/overview.aspx"&gt;
 Leap&lt;/a&gt; с Aeron-ом, написано, что исходя из иследований оно лучше.&lt;/p&gt;
 &lt;p&gt;Заказать или приобрести можно в компании
 &lt;a href="http://www.office-solutions.com.ua/our_company/contacts/"&gt;Office Solutions&lt;/a&gt; 
 по адресу ул. Николая Гринченко, 4 03038 Киев, Украина, тел: +38 (044) 459-02-90. 
 Там же можно опробовать много моделей. Я посидел на всем доступном, Leap понравился, 
 но его ебаническая цена в евро и оплата по безналу убили всякое желание покупать. 
 Еще и цену озвучили без НДС. Кстати, американские стулья и варианты их исполнения 
 отличаются от европейских, а эта компания работает с европейским производителем 
 продукции.&lt;/p&gt;
 &lt;/li&gt;
 &lt;li&gt;Другие кресла ебанической стоимости можно поспрашивать в следующих местах:
 &lt;ol&gt;
  &lt;li&gt;&lt;a href="http://www.office-shop.com.ua/ru/contacts/"&gt;Студия МАТИСС&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://nemetskaja-mebel.uaprom.net/"&gt;Студия немецкой мебели&lt;/a&gt;.&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;Есть еще бюджетный вариант немецких ортопедических кресел, которые собираются 
 в Украине:
 &lt;ol&gt;
  &lt;li&gt;&lt;a href="http://altima.ua/i/cPath/1422_1373"&gt;Альтима&lt;/a&gt;.&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/264654303037912405-7608191137525642895?l=chabster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chabster.blogspot.com/feeds/7608191137525642895/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://chabster.blogspot.com/2010/10/ergonomic-chairs-in-kiev.html#comment-form' title='Комментарии: 5'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/7608191137525642895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/264654303037912405/posts/default/7608191137525642895'/><link rel='alternate' type='text/html' href='http://chabster.blogspot.com/2010/10/ergonomic-chairs-in-kiev.html' title='Ergonomic chairs in Kiev'/><author><name>Chabster</name><uri>http://www.blogger.com/profile/14003906116514303118</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://2.bp.blogspot.com/-3_-y_j_GlqE/TWqIazKWw4I/AAAAAAAAAPk/7lQbCzMImQ8/s220/IMG_0739_CROPPED_22.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-264654303037912405.post-4941656967783579297</id><published>2010-09-26T15:58:00.004+03:00</published><updated>2010-09-26T16:10:21.512+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='problem'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>C++ and .NET interop</title><content type='html'>&lt;p&gt;Речь пойдет о механизме и нюансах исполнения .NET кода из C++ и, соответственно, тонкостях взаимодействия неуправляемого 
кода и управляемого (С++ с CLR).&lt;/p&gt;
&lt;p&gt;Сценарий таков: С++ приложение инициализирует CLR engine в своем процессе, загружает .NET сборки и использует .NET объекты. 
Обращение к методам и свойствам объектов происходит через COM интерфейсы, в нашем варианте другого механизма нет.&lt;/p&gt;
&lt;p&gt;Конкретный случай - нужно показать форму .NET и взаимодействовать с ней (вызывать методы и получать уведомления).&lt;/p&gt;
&lt;p&gt;Рассмотрим диаграмму классов .NET библиотеки:&lt;br /&gt;
&lt;img alt="NETLibrary class diagram" src="http://sites.google.com/site/chabster/articles/2010/cpp-and-net-interop/NET_HLD.png" /&gt;&lt;/p&gt;
&lt;p&gt;Главное действующее лицо - &lt;span style="color: #2b91af"&gt;NETForm&lt;/span&gt;, остальные классы нужны для взаимодействия через 
COM (их можно вообще вынести в отдельную сборку, а &lt;code&gt;NETForm&lt;/code&gt; создавать так, будто это просто .NET форма).&lt;/p&gt;
&lt;p&gt;C++ будет использовать интерфейс &lt;span style="color: #2b91af"&gt;INETFormController&lt;/span&gt; для взаимодействия с классом
&lt;span style="color: #2b91af"&gt;NETFormController&lt;/span&gt;, который в свою очередь будет адаптером для
&lt;span style="color: #2b91af"&gt;NETForm&lt;/span&gt;.&lt;/p&gt;
&lt;pre class="listing"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; &lt;span style="color: blueviolet"&gt;System&lt;/span&gt;;
&lt;span style="color: blue"&gt;using&lt;/span&gt; &lt;span style="color: blueviolet"&gt;System&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: blueviolet"&gt;Runtime&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: blueviolet"&gt;InteropServices&lt;/span&gt;;
 
&lt;span style="color: blue"&gt;namespace&lt;/span&gt; &lt;span style="color: blueviolet"&gt;NETLibrary&lt;/span&gt;
{
   [&lt;span style="color: #2b91af"&gt;ComVisible&lt;/span&gt;(&lt;span style="color: blue"&gt;true&lt;/span&gt;)]
   [&lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt;(&lt;span style="color: magenta"&gt;&amp;quot;AB185BF6-B576-46F8-880B-16484A2893FD&amp;quot;&lt;/span&gt;)]
   [&lt;span style="color: #2b91af"&gt;InterfaceType&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ComInterfaceType&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: navy"&gt;InterfaceIsIUnknown&lt;/span&gt;)]
   &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;interface&lt;/span&gt; &lt;span style="color: #2b91af"&gt;INETFormController&lt;/span&gt;
   {
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: crimson"&gt;AddCallback&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;INETFormControllerCallback&lt;/span&gt; &lt;span style="color: navy"&gt;callback&lt;/span&gt;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: crimson"&gt;Show&lt;/span&gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: crimson"&gt;Close&lt;/span&gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: crimson"&gt;RequestNotification&lt;/span&gt;();
   }
}&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;INETFormControllerCallback&lt;/code&gt; - это
&lt;a href="http://msdn.microsoft.com/en-us/library/aa367166.aspx" target="_blank"&gt;COM source интерфейс&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="listing"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; &lt;span style="color: blueviolet"&gt;System&lt;/span&gt;;
&lt;span style="color: blue"&gt;using&lt;/span&gt; &lt;span style="color: blueviolet"&gt;System&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: blueviolet"&gt;Runtime&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: blueviolet"&gt;InteropServices&lt;/span&gt;;
 
&lt;span style="color: blue"&gt;namespace&lt;/span&gt; &lt;span style="color: blueviolet"&gt;NETLibrary&lt;/span&gt;
{
   [&lt;span style="color: #2b91af"&gt;ComVisible&lt;/span&gt;(&lt;span style="color: blue"&gt;true&lt;/span&gt;)]
   [&lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt;(&lt;span style="color: magenta"&gt;&amp;quot;466444F6-2206-4E61-BE39-D3D781E8D8DB&amp;quot;&lt;/span&gt;)]
   [&lt;span style="color: #2b91af"&gt;InterfaceType&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ComInterfaceType&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: navy"&gt;InterfaceIsIUnknown&lt;/span&gt;)]
   &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;interface&lt;/span&gt; &lt;span style="color: #2b91af"&gt;INETFormControllerCallback&lt;/span&gt;
   {
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: crimson"&gt;Shown&lt;/span&gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: crimson"&gt;ButtonClicked&lt;/span&gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: crimson"&gt;Notification&lt;/span&gt;();
   }
}&lt;/pre&gt;
&lt;p&gt;Использование &lt;span style="color: #2b91af"&gt;INETFormControllerCallback&lt;/span&gt; в качестве source интерфейса позволяет задействовать 
унифицированный механизм подписки и отписки от уведомлений COM объекта (подробнее -
&lt;a href="http://msdn.microsoft.com/en-us/library/ms690572(VS.85).aspx" target="_blank"&gt;Using IConnectionPointContainer&lt;/a&gt;). 
Кстати, &lt;a href="http://msdn.microsoft.com/en-us/library/8bwh56xe.aspx" target="_blank"&gt;RCW&lt;/a&gt; поддерживает этот интерфейс, 
если к классу прикреплен атрибут &lt;code&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.comsourceinterfacesattribute.aspx" target="_blank"&gt;
ComSourceInterfaces&lt;/a&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;На форме есть поле ввода и кнопка, для начала попытаемся показать форму и получить уведомление о том, что кнопку нажали:&lt;/p&gt;
&lt;pre class="listing"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; &lt;span style="color: blueviolet"&gt;System&lt;/span&gt;;
&lt;span style="color: blue"&gt;using&lt;/span&gt; &lt;span style="color: blueviolet"&gt;System&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: blueviolet"&gt;Runtime&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: blueviolet"&gt;InteropServices&lt;/span&gt;;
&lt;span style="color: blue"&gt;using&lt;/span&gt; &lt;span style="color: blueviolet"&gt;System&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: blueviolet"&gt;Threading&lt;/span&gt;;
&lt;span style="color: blue"&gt;using&lt;/span&gt; &lt;span style="color: blueviolet"&gt;System&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: blueviolet"&gt;Windows&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: blueviolet"&gt;Forms&lt;/span&gt;;
 
&lt;span style="color: blue"&gt;namespace&lt;/span&gt; &lt;span style="color: blueviolet"&gt;NETLibrary&lt;/span&gt;
{
   [&lt;span style="color: #2b91af"&gt;ComVisible&lt;/span&gt;(&lt;span style="color: blue"&gt;false&lt;/span&gt;)]
   [&lt;span style="color: #2b91af"&gt;ClassInterface&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ClassInterfaceType&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: navy"&gt;None&lt;/span&gt;)]
   [&lt;span style="color: #2b91af"&gt;ComSourceInterfaces&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;INETFormControllerCallback&lt;/span&gt;))]
   &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;NETFormController&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;INETFormController&lt;/span&gt;
   {
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blueviolet"&gt;NETFormController&lt;/span&gt;() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: crimson"&gt;InitializeForm&lt;/span&gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;   }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: crimson"&gt;AddCallback&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;INETFormControllerCallback&lt;/span&gt; &lt;span style="color: navy"&gt;callback&lt;/span&gt;) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: navy"&gt;Shown&lt;/span&gt; &lt;span style="color: #800040"&gt;+=&lt;/span&gt; &lt;span style="color: navy"&gt;callback&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: crimson"&gt;Shown&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: navy"&gt;ButtonClicked&lt;/span&gt; &lt;span style="color: #800040"&gt;+=&lt;/span&gt; &lt;span style="color: navy"&gt;callback&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: crimson"&gt;ButtonClicked&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: navy"&gt;Notification&lt;/span&gt; &lt;span style="color: #800040"&gt;+=&lt;/span&gt; &lt;span style="color: navy"&gt;callback&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: crimson"&gt;Notification&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;   }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: crimson"&gt;Show&lt;/span&gt;() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: navy"&gt;_netForm&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: crimson"&gt;Show&lt;/span&gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;   }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: crimson"&gt;Close&lt;/span&gt;() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: navy"&gt;_netForm&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: crimson"&gt;Close&lt;/span&gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;   }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: crimson"&gt;RequestNotification&lt;/span&gt;() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: crimson"&gt;FireNotification&lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: navy"&gt;Empty&lt;/span&gt;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;   }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;event&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Action&lt;/span&gt; &lt;span style="color: navy"&gt;Shown&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;event&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Action&lt;/span&gt; &lt;span style="color: navy"&gt;ButtonClicked&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;event&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Action&lt;/span&gt; &lt;span style="color: navy"&gt;Notification&lt;/span&gt;;
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: crimson"&gt;InitializeForm&lt;/span&gt;() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: navy"&gt;_netForm&lt;/span&gt; &lt;span style="color: #800040"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;NETForm&lt;/span&gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: navy"&gt;_netForm&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: blueviolet"&gt;Shown&lt;/span&gt; &lt;span style="color: #800040"&gt;+=&lt;/span&gt; &lt;span style="color: crimson"&gt;FireShown&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: navy"&gt;_netForm&lt;/span&gt;&lt;span style="color: #800040"&gt;.&lt;/span&gt;&lt;span style="color: navy"&gt;ButtonClicked&lt;/span&gt; &lt;span style="color: #800040"&gt;+=&lt;/span&gt; &lt;span style="color: crimson"&gt;FireButtonClicked&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;   }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: crimson"&gt;FireShown&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Object&lt;/span&gt; &lt;span style="color: navy"&gt;sender&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; &lt;span style="color: navy"&gt;args&lt;/span&gt;) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: navy"&gt;Shown&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: blue"&gt;null&lt;/span&gt;) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: navy"&gt;Shown&lt;/span&gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   }
&amp;nbsp;&amp;nbsp;&amp;nbsp;   }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: crimson"&gt;FireButtonClicked&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Object&lt;/span&gt; &lt;span style="color: navy"&gt;sender&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; &lt;span style="color: navy"&gt;args&lt;/span&gt;) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: navy"&gt;ButtonClicked&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: blue"&gt;null&lt;/span&gt;) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: navy"&gt;ButtonClicked&lt;/span&gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   }
&amp;nbsp;&amp;nbsp;&amp;nbsp;   }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: crimson"&gt;FireNotification&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Object&lt;/span&gt; &lt;span style="color: navy"&gt;sender&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; &lt;span style="color: navy"&gt;args&lt;/span&gt;) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: navy"&gt;Notification&lt;/span&gt; &lt;span style="color: #800040"&gt;!=&lt;/span&gt; &lt;span style="color: blue"&gt;null&lt;/span&gt;) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: navy"&gt;Notification&lt;/span&gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   }
&amp;nbsp;&amp;nbsp;&amp;nbsp;   }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: #2b91af"&gt;NETForm&lt;/span&gt; &lt;span style="color: navy"&gt;_netForm&lt;/span&gt;;
   }
}&lt;/pre&gt;
&lt;p&gt;Далее - C++ (код инициализации CLR я взял из (&lt;a href="http://chabster.blogspot.com/2010/09/all-in-one-code-framework.html" target="_blank"&gt;All-In-One 
Code Framework&lt;/a&gt;.zip\Visual Studio 2010\CppHostCLR):&lt;/p&gt;
&lt;pre class="listing"&gt;&lt;span style="color: orangered"&gt;#include&lt;/span&gt; &lt;span style="color: magenta"&gt;&amp;quot;stdafx.h&amp;quot;&lt;/span&gt;
 
&lt;span style="color: #8b2be3"&gt;NETLibrary&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;INETFormControllerPtr&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;g_pNETObj&lt;/span&gt;&lt;span style="color: #800040"&gt;;&lt;/span&gt;
 
&lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ATL_NO_VTABLE&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;CNETFormControllerCallback&lt;/span&gt; &lt;span style="color: #800040"&gt;:&lt;/span&gt; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;ATL&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;CComObjectRootEx&lt;/span&gt;&lt;span style="color: #800040"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;CComSingleThreadModel&lt;/span&gt;&lt;span style="color: #800040"&gt;&amp;gt;,&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #8b2be3"&gt;NETLibrary&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;INETFormControllerCallback&lt;/span&gt;
&lt;span style="color: #800040"&gt;{&lt;/span&gt;
 
&lt;span style="color: blue"&gt;protected&lt;/span&gt;&lt;span style="color: #800040"&gt;:&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;DECLARE_PROTECT_FINAL_CONSTRUCT&lt;/span&gt;&lt;span style="color: #800040"&gt;()&lt;/span&gt;
   &lt;span style="color: #8b2be3"&gt;BEGIN_COM_MAP&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;CNETFormControllerCallback&lt;/span&gt;&lt;span style="color: #800040"&gt;)&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;   &lt;span style="color: #8b2be3"&gt;COM_INTERFACE_ENTRY&lt;/span&gt;&lt;span style="color: #800040"&gt;(&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;NETLibrary&lt;/span&gt;&lt;span style="color: #800040"&gt;::&lt;/span&gt;&lt;span style="color: #8b2be3"&gt;INETFormControllerCa
