Codebase list mozc / d529665
Remove third party libraries Signed-off-by: Nobuhiro Iwamatsu <iwamatsu@debian.org> Nobuhiro Iwamatsu 7 years ago
47 changed file(s) with 0 addition(s) and 79430 deletion(s). Raw diff Collapse all Expand all
+0
-0
src/third_party/breakpad less more
(Empty file)
+0
-0
src/third_party/fontTools less more
(Empty file)
+0
-0
src/third_party/gtest less more
(Empty file)
src/third_party/guava/guava-18.0.jar less more
Binary diff not shown
src/third_party/guava/guava-testlib-18.0.jar less more
Binary diff not shown
+0
-0
src/third_party/gyp less more
(Empty file)
+0
-117
src/third_party/ipa_font/LICENSE less more
0 --------------------------------------------------
1 IPA Font License Agreement v1.0 <Japanese/English>
2 --------------------------------------------------
3
4 IPAフォントライセンスv1.0
5
6 許諾者は、この使用許諾(以下「本契約」といいます。)に定める条件の下で、許諾プログラム(1条に定義するところによります。)を提供します。受領者(1条に定義するところによります。)が、許諾プログラムを使用し、複製し、または頒布する行為、その他、本契約に定める権利の利用を行った場合、受領者は本契約に同意したものと見なします。
7
8
9 第1条 用語の定義
10
11 本契約において、次の各号に掲げる用語は、当該各号に定めるところによります。
12
13 1.「デジタル・フォント・プログラム」とは、フォントを含み、レンダリングしまたは表示するために用いられるコンピュータ・プログラムをいいます。
14 2.「許諾プログラム」とは、許諾者が本契約の下で許諾するデジタル・フォント・プログラムをいいます。
15 3.「派生プログラム」とは、許諾プログラムの一部または全部を、改変し、加除修正等し、入れ替え、その他翻案したデジタル・フォント・プログラムをいい、許諾プログラムの一部もしくは全部から文字情報を取り出し、またはデジタル・ドキュメント・ファイルからエンベッドされたフォントを取り出し、取り出された文字情報をそのまま、または改変をなして新たなデジタル・フォント・プログラムとして製作されたものを含みます。
16 4.「デジタル・コンテンツ」とは、デジタル・データ形式によってエンド・ユーザに提供される制作物のことをいい、動画・静止画等の映像コンテンツおよびテレビ番組等の放送コンテンツ、ならびに文字テキスト、画像、図形等を含んで構成された制作物を含みます。
17 5.「デジタル・ドキュメント・ファイル」とは、PDFファイルその他、各種ソフトウェア・プログラムによって製作されたデジタル・コンテンツであって、その中にフォントを表示するために許諾プログラムの全部または一部が埋め込まれた(エンベッドされた)ものをいいます。フォントが「エンベッドされた」とは、当該フォントが埋め込まれた特定の「デジタル・ドキュメント・ファイル」においてのみ表示されるために使用されている状態を指し、その特定の「デジタル・ドキュメント・ファイル」以外でフォントを表示するために使用できるデジタル・フォント・プログラムに含まれている場合と区別されます。
18 6.「コンピュータ」とは、本契約においては、サーバを含みます。
19 7.「複製その他の利用」とは、複製、譲渡、頒布、貸与、公衆送信、上映、展示、翻案その他の利用をいいます。
20 8.「受領者」とは、許諾プログラムを本契約の下で受領した人をいい、受領者から許諾プログラムを受領した人を含みます。
21
22 第2条 使用許諾の付与
23
24 許諾者は受領者に対し、本契約の条項に従い、すべての国で、許諾プログラムを使用することを許諾します。ただし、許諾プログラムに存在する一切の権利はすべて許諾者が保有しています。本契約は、本契約で明示的に定められている場合を除き、いかなる意味においても、許諾者が保有する許諾プログラムに関する一切の権利および、いかなる商標、商号、もしくはサービス・マークに関する権利をも受領者に移転するものではありません。
25
26 1.受領者は本契約に定める条件に従い、許諾プログラムを任意の数のコンピュータにインストールし、当該コンピュータで使用することができます。
27 2.受領者はコンピュータにインストールされた許諾プログラムをそのまま、または改変を行ったうえで、印刷物およびデジタル・コンテンツにおいて、文字テキスト表現等として使用することができます。
28 3.受領者は前項の定めに従い作成した印刷物およびデジタル・コンテンツにつき、その商用・非商用の別、および放送、通信、各種記録メディアなどの媒体の形式を問わず、複製その他の利用をすることができます。
29 4.受領者がデジタル・ドキュメント・ファイルからエンベッドされたフォントを取り出して派生プログラムを作成した場合には、かかる派生プログラムは本契約に定める条件に従う必要があります。
30 5.許諾プログラムのエンベッドされたフォントがデジタル・ドキュメント・ファイル内のデジタル・コンテンツをレンダリングするためにのみ使用される場合において、受領者が当該デジタル・ドキュメント・ファイルを複製その他の利用をする場合には、受領者はかかる行為に関しては本契約の下ではいかなる義務をも負いません。
31 6.受領者は、3条2項の定めに従い、商用・非商用を問わず、許諾プログラムをそのままの状態で改変することなく複製して第三者への譲渡し、公衆送信し、その他の方法で再配布することができます(以下、「再配布」といいます。)。
32 7.受領者は、上記の許諾プログラムについて定められた条件と同様の条件に従って、派生プログラムを作成し、使用し、複製し、再配布することができます。ただし、受領者が派生プログラムを再配布する場合には、3条1項の定めに従うものとします。
33
34 第3条 制限
35
36 前条により付与された使用許諾は、以下の制限に服します。
37
38 1.派生プログラムが前条4項及び7項に基づき再配布される場合には、以下の全ての条件を満たさなければなりません。
39  (1)派生プログラムを再配布する際には、下記もまた、当該派生プログラムと一緒に再配布され、オンラインで提供され、または、郵送費・媒体及び取扱手数料の合計を超えない実費と引き換えに媒体を郵送する方法により提供されなければなりません。
40   (a)派生プログラムの写し; および
41   (b)派生プログラムを作成する過程でフォント開発プログラムによって作成された追加のファイルであって派生プログラムをさらに加工するにあたって利用できるファイルが存在すれば、当該ファイル
42  (2)派生プログラムの受領者が、派生プログラムを、このライセンスの下で最初にリリースされた許諾プログラム(以下、「オリジナル・プログラム」といいます。)に置き換えることができる方法を再配布するものとします。かかる方法は、オリジナル・ファイルからの差分ファイルの提供、または、派生プログラムをオリジナル・プログラムに置き換える方法を示す指示の提供などが考えられます。
43  (3)派生プログラムを、本契約書に定められた条件の下でライセンスしなければなりません。
44  (4)派生プログラムのプログラム名、フォント名またはファイル名として、許諾プログラムが用いているのと同一の名称、またはこれを含む名称を使用してはなりません。
45  (5)本項の要件を満たすためにオンラインで提供し、または媒体を郵送する方法で提供されるものは、その提供を希望するいかなる者によっても提供が可能です。
46 2.受領者が前条6項に基づき許諾プログラムを再配布する場合には、以下の全ての条件を満たさなければなりません。
47  (1)許諾プログラムの名称を変更してはなりません。
48  (2)許諾プログラムに加工その他の改変を加えてはなりません。
49  (3)本契約の写しを許諾プログラムに添付しなければなりません。
50 3.許諾プログラムは、現状有姿で提供されており、許諾プログラムまたは派生プログラムについて、許諾者は一切の明示または黙示の保証(権利の所在、非侵害、商品性、特定目的への適合性を含むがこれに限られません)を行いません。いかなる場合にも、その原因を問わず、契約上の責任か厳格責任か過失その他の不法行為責任かにかかわらず、また事前に通知されたか否かにかかわらず、許諾者は、許諾プログラムまたは派生プログラムのインストール、使用、複製その他の利用または本契約上の権利の行使によって生じた一切の損害(直接・間接・付随的・特別・拡大・懲罰的または結果的損害)(商品またはサービスの代替品の調達、システム障害から生じた損害、現存するデータまたはプログラムの紛失または破損、逸失利益を含むがこれに限られません)について責任を負いません。
51 4.許諾プログラムまたは派生プログラムのインストール、使用、複製その他の利用に関して、許諾者は技術的な質問や問い合わせ等に対する対応その他、いかなるユーザ・サポートをも行う義務を負いません。
52
53 第4条 契約の終了
54
55 1.本契約の有効期間は、受領者が許諾プログラムを受領した時に開始し、受領者が許諾プログラムを何らかの方法で保持する限り続くものとします。
56 2.前項の定めにかかわらず、受領者が本契約に定める各条項に違反したときは、本契約は、何らの催告を要することなく、自動的に終了し、当該受領者はそれ以後、許諾プログラムおよび派生プログラムを一切使用しまたは複製その他の利用をすることができないものとします。ただし、かかる契約の終了は、当該違反した受領者から許諾プログラムまたは派生プログラムの配布を受けた受領者の権利に影響を及ぼすものではありません。
57
58 第5条 準拠法
59
60 1.IPAは、本契約の変更バージョンまたは新しいバージョンを公表することができます。その場合には、受領者は、許諾プログラムまたは派生プログラムの使用、複製その他の利用または再配布にあたり、本契約または変更後の契約のいずれかを選択することができます。その他、上記に記載されていない条項に関しては日本の著作権法および関連法規に従うものとします。
61 2.本契約は、日本法に基づき解釈されます。
62
63
64 ----------
65
66 IPA Font License Agreement v1.0
67
68 The Licensor provides the Licensed Program (as defined in Article 1 below) under the terms of this license agreement (“Agreement”). Any use, reproduction or distribution of the Licensed Program, or any exercise of rights under this Agreement by a Recipient (as defined in Article 1 below) constitutes the Recipient's acceptance of this Agreement.
69
70 Article 1 (Definitions)
71 1.“Digital Font Program” shall mean a computer program containing, or used to render or display fonts.
72 2.“Licensed Program” shall mean a Digital Font Program licensed by the Licensor under this Agreement.
73 3.“Derived Program” shall mean a Digital Font Program created as a result of a modification, addition, deletion, replacement or any other adaptation to or of a part or all of the Licensed Program, and includes a case where a Digital Font Program newly created by retrieving font information from a part or all of the Licensed Program or Embedded Fonts from a Digital Document File with or without modification of the retrieved font information.
74 4.“Digital Content” shall mean products provided to end users in the form of digital data, including video content, motion and/or still pictures, TV programs or other broadcasting content and products consisting of character text, pictures, photographic images, graphic symbols and/or the like.
75 5.“Digital Document File” shall mean a PDF file or other Digital Content created by various software programs in which a part or all of the Licensed Program becomes embedded or contained in the file for the display of the font (“Embedded Fonts”). Embedded Fonts are used only in the display of characters in the particular Digital Document File within which they are embedded, and shall be distinguished from those in any Digital Font Program, which may be used for display of characters outside that particular Digital Document File.
76 6.“Computer” shall include a server in this Agreement.
77 7.“Reproduction and Other Exploitation” shall mean reproduction, transfer, distribution, lease, public transmission, presentation, exhibition, adaptation and any other exploitation.
78 8.“Recipient” shall mean anyone who receives the Licensed Program under this Agreement, including one that receives the Licensed Program from a Recipient.
79
80 Article 2 (Grant of License)
81 The Licensor grants to the Recipient a license to use the Licensed Program in any and all countries in accordance with each of the provisions set forth in this Agreement. However, any and all rights underlying in the Licensed Program shall be held by the Licensor. In no sense is this Agreement intended to transfer any right relating to the Licensed Program held by the Licensor except as specifically set forth herein or any right relating to any trademark, trade name, or service mark to the Recipient.
82
83 1.The Recipient may install the Licensed Program on any number of Computers and use the same in accordance with the provisions set forth in this Agreement.
84 2.The Recipient may use the Licensed Program, with or without modification in printed materials or in Digital Content as an expression of character texts or the like.
85 3.The Recipient may conduct Reproduction and Other Exploitation of the printed materials and Digital Content created in accordance with the preceding Paragraph, for commercial or non-commercial purposes and in any form of media including but not limited to broadcasting, communication and various recording media.
86 4.If any Recipient extracts Embedded Fonts from a Digital Document File to create a Derived Program, such Derived Program shall be subject to the terms of this agreement.
87 5.If any Recipient performs Reproduction or Other Exploitation of a Digital Document File in which Embedded Fonts of the Licensed Program are used only for rendering the Digital Content within such Digital Document File then such Recipient shall have no further obligations under this Agreement in relation to such actions.
88 6.The Recipient may reproduce the Licensed Program as is without modification and transfer such copies, publicly transmit or otherwise redistribute the Licensed Program to a third party for commercial or non-commercial purposes (“Redistribute”), in accordance with the provisions set forth in Article 3 Paragraph 2.
89 7.The Recipient may create, use, reproduce and/or Redistribute a Derived Program under the terms stated above for the Licensed Program: provided, that the Recipient shall follow the provisions set forth in Article 3 Paragraph 1 when Redistributing the Derived Program.
90
91 Article 3 (Restriction)
92 The license granted in the preceding Article shall be subject to the following restrictions:
93
94 1.If a Derived Program is Redistributed pursuant to Paragraph 4 and 7 of the preceding Article, the following conditions must be met :
95  (1)The following must be also Redistributed together with the Derived Program, or be made available online or by means of mailing mechanisms in exchange for a cost which does not exceed the total costs of postage, storage medium and handling fees:
96   (a)a copy of the Derived Program; and
97   (b)any additional file created by the font developing program in the course of creating the Derived Program that can be used for further modification of the Derived Program, if any.
98  (2)It is required to also Redistribute means to enable recipients of the Derived Program to replace the Derived Program with the Licensed Program first released under this License (the “Original Program”). Such means may be to provide a difference file from the Original Program, or instructions setting out a method to replace the Derived Program with the Original Program.
99  (3)The Recipient must license the Derived Program under the terms and conditions of this Agreement.
100  (4)No one may use or include the name of the Licensed Program as a program name, font name or file name of the Derived Program.
101  (5)Any material to be made available online or by means of mailing a medium to satisfy the requirements of this paragraph may be provided, verbatim, by any party wishing to do so.
102 2.If the Recipient Redistributes the Licensed Program pursuant to Paragraph 6 of the preceding Article, the Recipient shall meet all of the following conditions:
103  (1)The Recipient may not change the name of the Licensed Program.
104  (2)The Recipient may not alter or otherwise modify the Licensed Program.
105  (3)The Recipient must attach a copy of this Agreement to the Licensed Program.
106 3.THIS LICENSED PROGRAM IS PROVIDED BY THE LICENSOR “AS IS” AND ANY EXPRESSED OR IMPLIED WARRANTY AS TO THE LICENSED PROGRAM OR ANY DERIVED PROGRAM, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXTENDED, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO; PROCUREMENT OF SUBSTITUTED GOODS OR SERVICE; DAMAGES ARISING FROM SYSTEM FAILURE; LOSS OR CORRUPTION OF EXISTING DATA OR PROGRAM; LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE INSTALLATION, USE, THE REPRODUCTION OR OTHER EXPLOITATION OF THE LICENSED PROGRAM OR ANY DERIVED PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
107 4.The Licensor is under no obligation to respond to any technical questions or inquiries, or provide any other user support in connection with the installation, use or the Reproduction and Other Exploitation of the Licensed Program or Derived Programs thereof.
108
109 Article 4 (Termination of Agreement)
110 1.The term of this Agreement shall begin from the time of receipt of the Licensed Program by the Recipient and shall continue as long as the Recipient retains any such Licensed Program in any way.
111 2.Notwithstanding the provision set forth in the preceding Paragraph, in the event of the breach of any of the provisions set forth in this Agreement by the Recipient, this Agreement shall automatically terminate without any notice. In the case of such termination, the Recipient may not use or conduct Reproduction and Other Exploitation of the Licensed Program or a Derived Program: provided that such termination shall not affect any rights of any other Recipient receiving the Licensed Program or the Derived Program from such Recipient who breached this Agreement.
112
113 Article 5 (Governing Law)
114 1.IPA may publish revised and/or new versions of this License. In such an event, the Recipient may select either this Agreement or any subsequent version of the Agreement in using, conducting the Reproduction and Other Exploitation of, or Redistributing the Licensed Program or a Derived Program. Other matters not specified above shall be subject to the Copyright Law of Japan and other related laws and regulations of Japan.
115 2.This Agreement shall be construed under the laws of Japan.
116
+0
-20
src/third_party/ipa_font/README.mozc less more
0 URL: http://ipafont.ipa.go.jp/ipaexfont/IPAexfont00201.php
1 Version: 002.01
2 License: IPA Open Font License v1.0
3 License File: LICENSE
4
5 Description:
6 This directory contains opensource Japanese fonts provided by
7 Information-technology Promotion Agency (IPA), Japan. These fonts are useful
8 for testing compatibility issues on advanced font rendering features such as
9 Ideographic Variation Sequence (IVS).
10
11 * ipaexg.ttf: IPAexGothic
12 * ipaexm.ttf: Mincho style
13
14 Although IPA Open Font License v1.0 is one of Open Source Initiative (OSI)
15 approved licenses, there are some special licensing conditions like
16 SIL Open Font License (OFL-1.1). See LICENSE for details.
17
18 Local Modifications:
19 No modifications.
+0
-36
src/third_party/ipa_font/Readme_IPAexfont00201.txt less more
0 IPAexフォント
1 ― はじめにお読みください ―
2
3 IPAexフォントは、JIS X 0213:2004に準拠したTrueTypeアウトラインベースのOpenTypeフォントです。
4
5 IPAexフォントの使用または利用に当たっては、添付の「IPAフォントライセンスv1.0」に定める条件に従ってください。
6 IPAexフォントを使用し、複製し、または頒布する行為、その他、「IPAフォントライセンスv1.0」に定める権利の利用を行った場合、受領者は「IPAフォントライセンスv1.0」に同意したものと見なします。
7
8
9 IPAexフォント2書体パック(IPAexゴシック、IPAex明朝) IPAexfont00201.zip
10 |--はじめにお読みください Readme_IPAexfont00201.txt
11 |--IPAフォントライセンスv1.0 IPA_Font_License_Agreement_v1.0.txt
12 |--IPAexゴシック(Ver.002.01) ipaexg.ttf
13 |--IPAex明朝(Ver.002.01) ipaexm.ttf
14
15
16 「IPAフォント」は、IPAの登録商標です。
17
18 =========================
19 IPAex Font
20 -- Readme --
21
22 IPAex Fonts are JIS X 0213:2004 compliant OpenType fonts based on TrueType outlines.
23
24 In using IPAex fonts, please comply with the terms and conditions set out in "IPA Font License Agreement v1.0" included in this package.
25 Any use, reproduction or distribution of the IPA Font or any exercise of rights under "IPA Font License Agreement v1.0" by a Recipient constitutes the Recipient's acceptance of the License Agreement.
26
27
28 IPAex Fonts 2 fonts package (IPAex Gothic、IPAex Mincho) IPAexfont00201.zip
29 |--Readme Readme_IPAexfont00201.txt
30 |--IPA Font License Agreement v1.0 IPA_Font_License_Agreement_v1.0.txt
31 |--IPAexGothic(Ver.002.01) ipaexg.ttf
32 |--IPAexMincho(Ver.002.01) ipaexm.ttf
33
34
35 "IPA Font" is a registered trademark of IPA in Japan.
src/third_party/ipa_font/ipaexg.ttf less more
Binary diff not shown
src/third_party/ipa_font/ipaexm.ttf less more
Binary diff not shown
+0
-0
src/third_party/japanese_usage_dictionary less more
(Empty file)
+0
-0
src/third_party/jsoncpp less more
(Empty file)
+0
-201
src/third_party/noto_font/LICENSE less more
0 Apache License
1 Version 2.0, January 2004
2 http://www.apache.org/licenses/
3
4 TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
5
6 1. Definitions.
7
8 "License" shall mean the terms and conditions for use, reproduction,
9 and distribution as defined by Sections 1 through 9 of this document.
10
11 "Licensor" shall mean the copyright owner or entity authorized by
12 the copyright owner that is granting the License.
13
14 "Legal Entity" shall mean the union of the acting entity and all
15 other entities that control, are controlled by, or are under common
16 control with that entity. For the purposes of this definition,
17 "control" means (i) the power, direct or indirect, to cause the
18 direction or management of such entity, whether by contract or
19 otherwise, or (ii) ownership of fifty percent (50%) or more of the
20 outstanding shares, or (iii) beneficial ownership of such entity.
21
22 "You" (or "Your") shall mean an individual or Legal Entity
23 exercising permissions granted by this License.
24
25 "Source" form shall mean the preferred form for making modifications,
26 including but not limited to software source code, documentation
27 source, and configuration files.
28
29 "Object" form shall mean any form resulting from mechanical
30 transformation or translation of a Source form, including but
31 not limited to compiled object code, generated documentation,
32 and conversions to other media types.
33
34 "Work" shall mean the work of authorship, whether in Source or
35 Object form, made available under the License, as indicated by a
36 copyright notice that is included in or attached to the work
37 (an example is provided in the Appendix below).
38
39 "Derivative Works" shall mean any work, whether in Source or Object
40 form, that is based on (or derived from) the Work and for which the
41 editorial revisions, annotations, elaborations, or other modifications
42 represent, as a whole, an original work of authorship. For the purposes
43 of this License, Derivative Works shall not include works that remain
44 separable from, or merely link (or bind by name) to the interfaces of,
45 the Work and Derivative Works thereof.
46
47 "Contribution" shall mean any work of authorship, including
48 the original version of the Work and any modifications or additions
49 to that Work or Derivative Works thereof, that is intentionally
50 submitted to Licensor for inclusion in the Work by the copyright owner
51 or by an individual or Legal Entity authorized to submit on behalf of
52 the copyright owner. For the purposes of this definition, "submitted"
53 means any form of electronic, verbal, or written communication sent
54 to the Licensor or its representatives, including but not limited to
55 communication on electronic mailing lists, source code control systems,
56 and issue tracking systems that are managed by, or on behalf of, the
57 Licensor for the purpose of discussing and improving the Work, but
58 excluding communication that is conspicuously marked or otherwise
59 designated in writing by the copyright owner as "Not a Contribution."
60
61 "Contributor" shall mean Licensor and any individual or Legal Entity
62 on behalf of whom a Contribution has been received by Licensor and
63 subsequently incorporated within the Work.
64
65 2. Grant of Copyright License. Subject to the terms and conditions of
66 this License, each Contributor hereby grants to You a perpetual,
67 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
68 copyright license to reproduce, prepare Derivative Works of,
69 publicly display, publicly perform, sublicense, and distribute the
70 Work and such Derivative Works in Source or Object form.
71
72 3. Grant of Patent License. Subject to the terms and conditions of
73 this License, each Contributor hereby grants to You a perpetual,
74 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
75 (except as stated in this section) patent license to make, have made,
76 use, offer to sell, sell, import, and otherwise transfer the Work,
77 where such license applies only to those patent claims licensable
78 by such Contributor that are necessarily infringed by their
79 Contribution(s) alone or by combination of their Contribution(s)
80 with the Work to which such Contribution(s) was submitted. If You
81 institute patent litigation against any entity (including a
82 cross-claim or counterclaim in a lawsuit) alleging that the Work
83 or a Contribution incorporated within the Work constitutes direct
84 or contributory patent infringement, then any patent licenses
85 granted to You under this License for that Work shall terminate
86 as of the date such litigation is filed.
87
88 4. Redistribution. You may reproduce and distribute copies of the
89 Work or Derivative Works thereof in any medium, with or without
90 modifications, and in Source or Object form, provided that You
91 meet the following conditions:
92
93 (a) You must give any other recipients of the Work or
94 Derivative Works a copy of this License; and
95
96 (b) You must cause any modified files to carry prominent notices
97 stating that You changed the files; and
98
99 (c) You must retain, in the Source form of any Derivative Works
100 that You distribute, all copyright, patent, trademark, and
101 attribution notices from the Source form of the Work,
102 excluding those notices that do not pertain to any part of
103 the Derivative Works; and
104
105 (d) If the Work includes a "NOTICE" text file as part of its
106 distribution, then any Derivative Works that You distribute must
107 include a readable copy of the attribution notices contained
108 within such NOTICE file, excluding those notices that do not
109 pertain to any part of the Derivative Works, in at least one
110 of the following places: within a NOTICE text file distributed
111 as part of the Derivative Works; within the Source form or
112 documentation, if provided along with the Derivative Works; or,
113 within a display generated by the Derivative Works, if and
114 wherever such third-party notices normally appear. The contents
115 of the NOTICE file are for informational purposes only and
116 do not modify the License. You may add Your own attribution
117 notices within Derivative Works that You distribute, alongside
118 or as an addendum to the NOTICE text from the Work, provided
119 that such additional attribution notices cannot be construed
120 as modifying the License.
121
122 You may add Your own copyright statement to Your modifications and
123 may provide additional or different license terms and conditions
124 for use, reproduction, or distribution of Your modifications, or
125 for any such Derivative Works as a whole, provided Your use,
126 reproduction, and distribution of the Work otherwise complies with
127 the conditions stated in this License.
128
129 5. Submission of Contributions. Unless You explicitly state otherwise,
130 any Contribution intentionally submitted for inclusion in the Work
131 by You to the Licensor shall be under the terms and conditions of
132 this License, without any additional terms or conditions.
133 Notwithstanding the above, nothing herein shall supersede or modify
134 the terms of any separate license agreement you may have executed
135 with Licensor regarding such Contributions.
136
137 6. Trademarks. This License does not grant permission to use the trade
138 names, trademarks, service marks, or product names of the Licensor,
139 except as required for reasonable and customary use in describing the
140 origin of the Work and reproducing the content of the NOTICE file.
141
142 7. Disclaimer of Warranty. Unless required by applicable law or
143 agreed to in writing, Licensor provides the Work (and each
144 Contributor provides its Contributions) on an "AS IS" BASIS,
145 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
146 implied, including, without limitation, any warranties or conditions
147 of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
148 PARTICULAR PURPOSE. You are solely responsible for determining the
149 appropriateness of using or redistributing the Work and assume any
150 risks associated with Your exercise of permissions under this License.
151
152 8. Limitation of Liability. In no event and under no legal theory,
153 whether in tort (including negligence), contract, or otherwise,
154 unless required by applicable law (such as deliberate and grossly
155 negligent acts) or agreed to in writing, shall any Contributor be
156 liable to You for damages, including any direct, indirect, special,
157 incidental, or consequential damages of any character arising as a
158 result of this License or out of the use or inability to use the
159 Work (including but not limited to damages for loss of goodwill,
160 work stoppage, computer failure or malfunction, or any and all
161 other commercial damages or losses), even if such Contributor
162 has been advised of the possibility of such damages.
163
164 9. Accepting Warranty or Additional Liability. While redistributing
165 the Work or Derivative Works thereof, You may choose to offer,
166 and charge a fee for, acceptance of support, warranty, indemnity,
167 or other liability obligations and/or rights consistent with this
168 License. However, in accepting such obligations, You may act only
169 on Your own behalf and on Your sole responsibility, not on behalf
170 of any other Contributor, and only if You agree to indemnify,
171 defend, and hold each Contributor harmless for any liability
172 incurred by, or claims asserted against, such Contributor by reason
173 of your accepting any such warranty or additional liability.
174
175 END OF TERMS AND CONDITIONS
176
177 APPENDIX: How to apply the Apache License to your work.
178
179 To apply the Apache License to your work, attach the following
180 boilerplate notice, with the fields enclosed by brackets "[]"
181 replaced with your own identifying information. (Don't include
182 the brackets!) The text should be enclosed in the appropriate
183 comment syntax for the file format. We also recommend that a
184 file or class name and description of purpose be included on the
185 same "printed page" as the copyright notice for easier
186 identification within third-party archives.
187
188 Copyright [yyyy] [name of copyright owner]
189
190 Licensed under the Apache License, Version 2.0 (the "License");
191 you may not use this file except in compliance with the License.
192 You may obtain a copy of the License at
193
194 http://www.apache.org/licenses/LICENSE-2.0
195
196 Unless required by applicable law or agreed to in writing, software
197 distributed under the License is distributed on an "AS IS" BASIS,
198 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
199 See the License for the specific language governing permissions and
200 limitations under the License.
src/third_party/noto_font/Noto-Roboto2-Regular.otf less more
Binary diff not shown
src/third_party/noto_font/NotoSansJP-Regular.otf less more
Binary diff not shown
+0
-16665
src/third_party/noto_font/NotoSansJP.cidmap less more
0 61768 61768
1 0 /.notdef
2 00001 20
3 00002 21
4 00003 22
5 00004 23
6 00005 24
7 00006 25
8 00007 26
9 00008 27
10 00009 28
11 00010 29
12 00011 2a
13 00012 2b
14 00013 2c
15 00014 2d
16 00015 2e
17 00016 2f
18 00017 30
19 00018 31
20 00019 32
21 00020 33
22 00021 34
23 00022 35
24 00023 36
25 00024 37
26 00025 38
27 00026 39
28 00027 3a
29 00028 3b
30 00029 3c
31 00030 3d
32 00031 3e
33 00032 3f
34 00033 40
35 00034 41
36 00035 42
37 00036 43
38 00037 44
39 00038 45
40 00039 46
41 00040 47
42 00041 48
43 00042 49
44 00043 4a
45 00044 4b
46 00045 4c
47 00046 4d
48 00047 4e
49 00048 4f
50 00049 50
51 00050 51
52 00051 52
53 00052 53
54 00053 54
55 00054 55
56 00055 56
57 00056 57
58 00057 58
59 00058 59
60 00059 5a
61 00060 5b
62 00061 5c
63 00062 5d
64 00063 5e
65 00064 5f
66 00065 60
67 00066 61
68 00067 62
69 00068 63
70 00069 64
71 00070 65
72 00071 66
73 00072 67
74 00073 68
75 00074 69
76 00075 6a
77 00076 6b
78 00077 6c
79 00078 6d
80 00079 6e
81 00080 6f
82 00081 70
83 00082 71
84 00083 72
85 00084 73
86 00085 74
87 00086 75
88 00087 76
89 00088 77
90 00089 78
91 00090 79
92 00091 7a
93 00092 7b
94 00093 7c
95 00094 7d
96 00095 7e
97 00096 a1
98 00097 a2
99 00098 a3
100 00099 a4
101 00100 a5
102 00101 a6
103 00102 a7
104 00103 a8
105 00104 a9
106 00105 aa
107 00106 ab
108 00107 ac
109 00108 ad
110 00109 ae
111 00110 af
112 00111 b0
113 00112 b1
114 00113 b2
115 00114 b3
116 00115 b4
117 00116 b5
118 00117 b6
119 00118 b7
120 00119 b8
121 00120 b9
122 00121 ba
123 00122 bb
124 00123 bc
125 00124 bd
126 00125 be
127 00126 bf
128 00127 c0
129 00128 c1
130 00129 c2
131 00130 c3
132 00131 c4
133 00132 c5
134 00133 c6
135 00134 c7
136 00135 c8
137 00136 c9
138 00137 ca
139 00138 cb
140 00139 cc
141 00140 cd
142 00141 ce
143 00142 cf
144 00143 d0
145 00144 d1
146 00145 d2
147 00146 d3
148 00147 d4
149 00148 d5
150 00149 d6
151 00150 d7
152 00151 d8
153 00152 d9
154 00153 da
155 00154 db
156 00155 dc
157 00156 dd
158 00157 de
159 00158 df
160 00159 e0
161 00160 e1
162 00161 e2
163 00162 e3
164 00163 e4
165 00164 e5
166 00165 e6
167 00166 e7
168 00167 e8
169 00168 e9
170 00169 ea
171 00170 eb
172 00171 ec
173 00172 ed
174 00173 ee
175 00174 ef
176 00175 f0
177 00176 f1
178 00177 f2
179 00178 f3
180 00179 f4
181 00180 f5
182 00181 f6
183 00182 f7
184 00183 f8
185 00184 f9
186 00185 fa
187 00186 fb
188 00187 fc
189 00188 fd
190 00189 fe
191 00190 ff
192 00191 100
193 00192 101
194 00193 102
195 00194 103
196 00195 110
197 00196 111
198 00197 112
199 00198 113
200 00199 11a
201 00200 11b
202 00201 128
203 00202 129
204 00203 12a
205 00204 12b
206 00205 143
207 00206 144
208 00207 147
209 00208 148
210 00209 14c
211 00210 14d
212 00211 14e
213 00212 14f
214 00213 152
215 00214 153
216 00215 168
217 00216 169
218 00217 16a
219 00218 16b
220 00219 16c
221 00220 16d
222 00221 192
223 00222 1a0
224 00223 1a1
225 00224 1af
226 00225 1b0
227 00226 1cd
228 00227 1ce
229 00228 1cf
230 00229 1d0
231 00230 1d1
232 00231 1d2
233 00232 1d3
234 00233 1d4
235 00234 1d5
236 00235 1d6
237 00236 1d7
238 00237 1d8
239 00238 1d9
240 00239 1da
241 00240 1db
242 00241 1dc
243 00242 1f8
244 00243 1f9
245 00244 251
246 00245 261
247 00246 2c7
248 00247 2c9
249 00248 2ca
250 00249 2cb
251 00250 2d9
252 00251 391
253 00252 392
254 00253 393
255 00254 394
256 00255 395
257 00256 396
258 00257 397
259 00258 398
260 00259 399
261 00260 39a
262 00261 39b
263 00262 39c
264 00263 39d
265 00264 39e
266 00265 39f
267 00266 3a0
268 00267 3a1
269 00268 3a3
270 00269 3a4
271 00270 3a5
272 00271 3a6
273 00272 3a7
274 00273 3a8
275 00274 3a9
276 00275 3b1
277 00276 3b2
278 00277 3b3
279 00278 3b4
280 00279 3b5
281 00280 3b6
282 00281 3b7
283 00282 3b8
284 00283 3b9
285 00284 3ba
286 00285 3bb
287 00286 3bc
288 00287 3bd
289 00288 3be
290 00289 3bf
291 00290 3c0
292 00291 3c1
293 00292 3c3
294 00293 3c4
295 00294 3c5
296 00295 3c6
297 00296 3c7
298 00297 3c8
299 00298 3c9
300 00299 401
301 00300 410
302 00301 411
303 00302 412
304 00303 413
305 00304 414
306 00305 415
307 00306 416
308 00307 417
309 00308 418
310 00309 419
311 00310 41a
312 00311 41b
313 00312 41c
314 00313 41d
315 00314 41e
316 00315 41f
317 00316 420
318 00317 421
319 00318 422
320 00319 423
321 00320 424
322 00321 425
323 00322 426
324 00323 427
325 00324 428
326 00325 429
327 00326 42a
328 00327 42b
329 00328 42c
330 00329 42d
331 00330 42e
332 00331 42f
333 00332 430
334 00333 431
335 00334 432
336 00335 433
337 00336 434
338 00337 435
339 00338 436
340 00339 437
341 00340 438
342 00341 439
343 00342 43a
344 00343 43b
345 00344 43c
346 00345 43d
347 00346 43e
348 00347 43f
349 00348 440
350 00349 441
351 00350 442
352 00351 443
353 00352 444
354 00353 445
355 00354 446
356 00355 447
357 00356 448
358 00357 449
359 00358 44a
360 00359 44b
361 00360 44c
362 00361 44d
363 00362 44e
364 00363 44f
365 00364 451
366 00621 1e3e
367 00622 1e3f
368 00623 1ea0
369 00624 1ea1
370 00625 1ea2
371 00626 1ea3
372 00627 1ea4
373 00628 1ea5
374 00629 1ea6
375 00630 1ea7
376 00631 1ea8
377 00632 1ea9
378 00633 1eaa
379 00634 1eab
380 00635 1eac
381 00636 1ead
382 00637 1eae
383 00638 1eaf
384 00639 1eb0
385 00640 1eb1
386 00641 1eb2
387 00642 1eb3
388 00643 1eb4
389 00644 1eb5
390 00645 1eb6
391 00646 1eb7
392 00647 1eb8
393 00648 1eb9
394 00649 1eba
395 00650 1ebb
396 00651 1ebc
397 00652 1ebd
398 00653 1ebe
399 00654 1ebf
400 00655 1ec0
401 00656 1ec1
402 00657 1ec2
403 00658 1ec3
404 00659 1ec4
405 00660 1ec5
406 00661 1ec6
407 00662 1ec7
408 00663 1ec8
409 00664 1ec9
410 00665 1eca
411 00666 1ecb
412 00667 1ecc
413 00668 1ecd
414 00669 1ece
415 00670 1ecf
416 00671 1ed0
417 00672 1ed1
418 00673 1ed2
419 00674 1ed3
420 00675 1ed4
421 00676 1ed5
422 00677 1ed6
423 00678 1ed7
424 00679 1ed8
425 00680 1ed9
426 00681 1eda
427 00682 1edb
428 00683 1edc
429 00684 1edd
430 00685 1ede
431 00686 1edf
432 00687 1ee0
433 00688 1ee1
434 00689 1ee2
435 00690 1ee3
436 00691 1ee4
437 00692 1ee5
438 00693 1ee6
439 00694 1ee7
440 00695 1ee8
441 00696 1ee9
442 00697 1eea
443 00698 1eeb
444 00699 1eec
445 00700 1eed
446 00701 1eee
447 00702 1eef
448 00703 1ef0
449 00704 1ef1
450 00705 1ef2
451 00706 1ef3
452 00707 1ef4
453 00708 1ef5
454 00709 1ef6
455 00710 1ef7
456 00711 1ef8
457 00712 1ef9
458 63039 2002
459 01389 2003
460 00713 2010
461 00014 2011
462 00714 2012
463 00714 2013
464 00715 2014
465 00716 2015
466 00717 2016
467 00718 2018
468 00719 2019
469 00720 201a
470 00721 201c
471 00722 201d
472 00723 201e
473 00724 2020
474 00725 2021
475 00726 2022
476 00727 2025
477 00728 2026
478 00729 2027
479 00730 2030
480 00731 2032
481 00732 2033
482 59055 2035
483 00733 2039
484 00734 203a
485 00735 203b
486 00736 203c
487 00737 2042
488 00738 2047
489 00739 2048
490 00740 2049
491 00741 2051
492 00742 20a9
493 00743 20ac
494 00744 20dd
495 00745 20de
496 00746 2100
497 00747 2103
498 00748 2105
499 00749 2109
500 00750 210a
501 00751 210f
502 00752 2113
503 00753 2116
504 00754 2121
505 00755 2122
506 00756 2126
507 00757 2127
508 00758 212b
509 00759 212e
510 00760 2135
511 00761 213b
512 00762 2160
513 00763 2161
514 00764 2162
515 00765 2163
516 00766 2164
517 00767 2165
518 00768 2166
519 00769 2167
520 00770 2168
521 00771 2169
522 00772 216a
523 00773 216b
524 00774 2170
525 00775 2171
526 00776 2172
527 00777 2173
528 00778 2174
529 00779 2175
530 00780 2176
531 00781 2177
532 00782 2178
533 00783 2179
534 00784 217a
535 00785 217b
536 00786 2190
537 00787 2191
538 00788 2192
539 00789 2193
540 00790 2194
541 00791 2195
542 00792 2196
543 00793 2197
544 00794 2198
545 00795 2199
546 00796 21b8
547 00797 21b9
548 00798 21c4
549 00799 21c5
550 00800 21c6
551 00801 21cb
552 00802 21cc
553 00803 21d0
554 00804 21d2
555 00805 21d4
556 00806 21e6
557 00807 21e7
558 00808 21e8
559 00809 21e9
560 00810 21f5
561 00811 2200
562 00812 2202
563 00813 2203
564 00814 2205
565 00815 2206
566 00816 2207
567 00817 2208
568 00818 2209
569 00819 220a
570 00820 220b
571 00821 220f
572 00822 2211
573 59004 2212
574 00823 2213
575 59006 2215
576 00824 221a
577 00825 221d
578 00826 221e
579 00827 221f
580 00828 2220
581 00829 2223
582 00830 2225
583 00831 2226
584 00832 2227
585 00833 2228
586 00834 2229
587 00835 222a
588 00836 222b
589 00837 222c
590 00838 222d
591 00839 222e
592 00840 2234
593 00841 2235
594 00842 2236
595 00843 2237
596 00844 223d
597 00845 2243
598 00846 2245
599 00847 2248
600 00848 224c
601 00849 2252
602 00850 2260
603 00851 2261
604 00852 2262
605 00853 2264
606 00854 2265
607 00855 2266
608 00856 2267
609 00857 226a
610 00858 226b
611 00859 226e
612 00860 226f
613 00861 2272
614 00862 2273
615 00863 2276
616 00864 2277
617 00865 2282
618 00866 2283
619 00867 2284
620 00868 2285
621 00869 2286
622 00870 2287
623 00871 228a
624 00872 228b
625 00873 2295
626 00874 2296
627 00875 2297
628 00876 2298
629 00877 2299
630 00878 22a0
631 00879 22a5
632 00880 22bf
633 00881 22da
634 00882 22db
635 00883 2305
636 00884 2306
637 00885 2307
638 00886 2312
639 00887 2318
640 01397 2329
641 01398 232a
642 00888 23b0
643 00889 23b1
644 00890 23be
645 00891 23bf
646 00892 23c0
647 00893 23c1
648 00894 23c2
649 00895 23c3
650 00896 23c4
651 00897 23c5
652 00898 23c6
653 00899 23c7
654 00900 23c8
655 00901 23c9
656 00902 23ca
657 00903 23cb
658 00904 23cc
659 00905 23ce
660 00906 23da
661 00907 23db
662 00908 2423
663 00909 2460
664 00910 2461
665 00911 2462
666 00912 2463
667 00913 2464
668 00914 2465
669 00915 2466
670 00916 2467
671 00917 2468
672 00918 2469
673 00919 246a
674 00920 246b
675 00921 246c
676 00922 246d
677 00923 246e
678 00924 246f
679 00925 2470
680 00926 2471
681 00927 2472
682 00928 2473
683 00929 2474
684 00930 2475
685 00931 2476
686 00932 2477
687 00933 2478
688 00934 2479
689 00935 247a
690 00936 247b
691 00937 247c
692 00938 247d
693 00939 247e
694 00940 247f
695 00941 2480
696 00942 2481
697 00943 2482
698 00944 2483
699 00945 2484
700 00946 2485
701 00947 2486
702 00948 2487
703 00949 2488
704 00950 2489
705 00951 248a
706 00952 248b
707 00953 248c
708 00954 248d
709 00955 248e
710 00956 248f
711 00957 2490
712 00958 2491
713 00959 2492
714 00960 2493
715 00961 2494
716 00962 2495
717 00963 2496
718 00964 2497
719 00965 2498
720 00966 2499
721 00967 249a
722 00968 249b
723 00969 249c
724 00970 249d
725 00971 249e
726 00972 249f
727 00973 24a0
728 00974 24a1
729 00975 24a2
730 00976 24a3
731 00977 24a4
732 00978 24a5
733 00979 24a6
734 00980 24a7
735 00981 24a8
736 00982 24a9
737 00983 24aa
738 00984 24ab
739 00985 24ac
740 00986 24ad
741 00987 24ae
742 00988 24af
743 00989 24b0
744 00990 24b1
745 00991 24b2
746 00992 24b3
747 00993 24b4
748 00994 24b5
749 00995 24b6
750 00996 24b7
751 00997 24b8
752 00998 24b9
753 00999 24ba
754 01000 24bb
755 01001 24bc
756 01002 24bd
757 01003 24be
758 01004 24bf
759 01005 24c0
760 01006 24c1
761 01007 24c2
762 01008 24c3
763 01009 24c4
764 01010 24c5
765 01011 24c6
766 01012 24c7
767 01013 24c8
768 01014 24c9
769 01015 24ca
770 01016 24cb
771 01017 24cc
772 01018 24cd
773 01019 24ce
774 01020 24cf
775 01021 24d0
776 01022 24d1
777 01023 24d2
778 01024 24d3
779 01025 24d4
780 01026 24d5
781 01027 24d6
782 01028 24d7
783 01029 24d8
784 01030 24d9
785 01031 24da
786 01032 24db
787 01033 24dc
788 01034 24dd
789 01035 24de
790 01036 24df
791 01037 24e0
792 01038 24e1
793 01039 24e2
794 01040 24e3
795 01041 24e4
796 01042 24e5
797 01043 24e6
798 01044 24e7
799 01045 24e8
800 01046 24e9
801 01047 24ea
802 01048 24eb
803 01049 24ec
804 01050 24ed
805 01051 24ee
806 01052 24ef
807 01053 24f0
808 01054 24f1
809 01055 24f2
810 01056 24f3
811 01057 24f4
812 01058 24f5
813 01059 24f6
814 01060 24f7
815 01061 24f8
816 01062 24f9
817 01063 24fa
818 01064 24fb
819 01065 24fc
820 01066 24fd
821 01067 24fe
822 01068 24ff
823 01069 2500
824 01070 2501
825 01071 2502
826 01072 2503
827 01073 2504
828 01074 2505
829 01075 2506
830 01076 2507
831 01077 2508
832 01078 2509
833 01079 250a
834 01080 250b
835 01081 250c
836 01082 250d
837 01083 250e
838 01084 250f
839 01085 2510
840 01086 2511
841 01087 2512
842 01088 2513
843 01089 2514
844 01090 2515
845 01091 2516
846 01092 2517
847 01093 2518
848 01094 2519
849 01095 251a
850 01096 251b
851 01097 251c
852 01098 251d
853 01099 251e
854 01100 251f
855 01101 2520
856 01102 2521
857 01103 2522
858 01104 2523
859 01105 2524
860 01106 2525
861 01107 2526
862 01108 2527
863 01109 2528
864 01110 2529
865 01111 252a
866 01112 252b
867 01113 252c
868 01114 252d
869 01115 252e
870 01116 252f
871 01117 2530
872 01118 2531
873 01119 2532
874 01120 2533
875 01121 2534
876 01122 2535
877 01123 2536
878 01124 2537
879 01125 2538
880 01126 2539
881 01127 253a
882 01128 253b
883 01129 253c
884 01130 253d
885 01131 253e
886 01132 253f
887 01133 2540
888 01134 2541
889 01135 2542
890 01136 2543
891 01137 2544
892 01138 2545
893 01139 2546
894 01140 2547
895 01141 2548
896 01142 2549
897 01143 254a
898 01144 254b
899 01145 254c
900 01146 254d
901 01147 254e
902 01148 254f
903 01149 2550
904 01150 2551
905 01151 2552
906 01152 2553
907 01153 2554
908 01154 2555
909 01155 2556
910 01156 2557
911 01157 2558
912 01158 2559
913 01159 255a
914 01160 255b
915 01161 255c
916 01162 255d
917 01163 255e
918 01164 255f
919 01165 2560
920 01166 2561
921 01167 2562
922 01168 2563
923 01169 2564
924 01170 2565
925 01171 2566
926 01172 2567
927 01173 2568
928 01174 2569
929 01175 256a
930 01176 256b
931 01177 256c
932 01178 256d
933 01179 256e
934 01180 256f
935 01181 2570
936 01182 2571
937 01183 2572
938 01184 2573
939 01185 2574
940 01186 2575
941 01187 2576
942 01188 2577
943 01189 2578
944 01190 2579
945 01191 257a
946 01192 257b
947 01193 257c
948 01194 257d
949 01195 257e
950 01196 257f
951 01197 2580
952 01198 2581
953 01199 2582
954 01200 2583
955 01201 2584
956 01202 2585
957 01203 2586
958 01204 2587
959 01205 2588
960 01206 2589
961 01207 258a
962 01208 258b
963 01209 258c
964 01210 258d
965 01211 258e
966 01212 258f
967 01213 2590
968 01214 2591
969 01215 2592
970 01216 2593
971 01217 2594
972 01218 2595
973 01219 2596
974 01220 2597
975 01221 2598
976 01222 2599
977 01223 259a
978 01224 259b
979 01225 259c
980 01226 259d
981 01227 259e
982 01228 259f
983 01229 25a0
984 01230 25a1
985 01231 25a2
986 01232 25a3
987 01233 25a4
988 01234 25a5
989 01235 25a6
990 01236 25a7
991 01237 25a8
992 01238 25a9
993 01239 25aa
994 01240 25ab
995 01241 25b1
996 01242 25b2
997 01243 25b3
998 01244 25b6
999 01245 25b7
1000 01246 25bc
1001 01247 25bd
1002 01248 25c0
1003 01249 25c1
1004 01250 25c6
1005 01251 25c7
1006 01252 25c8
1007 01253 25c9
1008 01254 25ca
1009 01255 25cb
1010 01256 25cc
1011 01257 25ce
1012 01258 25cf
1013 01259 25d0
1014 01260 25d1
1015 01261 25d2
1016 01262 25d3
1017 01263 25e2
1018 01264 25e3
1019 01265 25e4
1020 01266 25e5
1021 01267 25e6
1022 01268 25ef
1023 01269 2600
1024 01270 2601
1025 01271 2602
1026 01272 2603
1027 01273 2605
1028 01274 2606
1029 01275 2609
1030 01276 260e
1031 01277 260f
1032 01278 2616
1033 01279 2617
1034 01280 261c
1035 01281 261d
1036 01282 261e
1037 01283 261f
1038 01284 262f
1039 01285 2640
1040 01286 2641
1041 01287 2642
1042 01288 2660
1043 01289 2661
1044 01290 2662
1045 01291 2663
1046 01292 2664
1047 01293 2665
1048 01294 2666
1049 01295 2667
1050 01296 2668
1051 01297 2669
1052 01298 266a
1053 01299 266b
1054 01300 266c
1055 01301 266d
1056 01302 266e
1057 01303 266f
1058 01304 2672
1059 01305 2673
1060 01306 2674
1061 01307 2675
1062 01308 2676
1063 01309 2677
1064 01310 2678
1065 01311 2679
1066 01312 267a
1067 01313 267b
1068 01314 267c
1069 01315 267d
1070 01316 26a0
1071 01317 26bd
1072 01318 26be
1073 01319 2702
1074 01320 2713
1075 01321 271a
1076 01322 273d
1077 01323 273f
1078 01324 2740
1079 01325 2756
1080 01326 2776
1081 01327 2777
1082 01328 2778
1083 01329 2779
1084 01330 277a
1085 01331 277b
1086 01332 277c
1087 01333 277d
1088 01334 277e
1089 01335 277f
1090 01336 27a1
1091 01337 2934
1092 01338 2935
1093 01339 29bf
1094 01340 29fa
1095 01341 29fb
1096 01342 2b05
1097 01343 2b06
1098 01344 2b07
1099 01345 2b1a
1100 01346 2e3a
1101 01347 2e3b
1102 01348 2e80
1103 01349 2e81
1104 09964 2e82
1105 09962 2e83
1106 01350 2e84
1107 10116 2e85
1108 01351 2e86
1109 59555 2e87
1110 01352 2e88
1111 11532 2e89
1112 01353 2e8a
1113 02798 2e8b
1114 01354 2e8c
1115 01355 2e8d
1116 11205 2e8e
1117 16203 2e8f
1118 16202 2e90
1119 01356 2e91
1120 17083 2e92
1121 17294 2e93
1122 17710 2e94
1123 01357 2e95
1124 17906 2e96
1125 01358 2e97
1126 19036 2e98
1127 20302 2e99
1128 20606 2e9b
1129 01359 2e9c
1130 01360 2e9d
1131 23074 2e9e
1132 23265 2e9f
1133 23382 2ea0
1134 23441 2ea1
1135 01361 2ea2
1136 25250 2ea3
1137 58882 2ea4
1138 01362 2ea5
1139 09892 2ea6
1140 01363 2ea7
1141 26373 2ea8
1142 01364 2ea9
1143 01365 2eaa
1144 32249 2eab
1145 01366 2eac
1146 29211 2ead
1147 60725 2eae
1148 31157 2eaf
1149 32033 2eb0
1150 32251 2eb1
1151 32249 2eb2
1152 02652 2eb3
1153 01367 2eb4
1154 01368 2eb5
1155 01369 2eb6
1156 01370 2eb7
1157 01371 2eb8
1158 32586 2eb9
1159 32840 2eba
1160 01372 2ebb
1161 01373 2ebc
1162 60872 2ebd
1163 33931 2ebe
1164 58903 2ebf
1165 58902 2ec0
1166 36100 2ec1
1167 36999 2ec2
1168 37552 2ec3
1169 37550 2ec4
1170 37659 2ec5
1171 37677 2ec6
1172 61070 2ec7
1173 38629 2ec8
1174 39181 2ec9
1175 61126 2eca
1176 40104 2ecb
1177 58911 2ecc
1178 40212 2ecd
1179 40214 2ece
1180 01374 2ecf
1181 42700 2ed0
1182 42943 2ed1
1183 42945 2ed2
1184 42955 2ed3
1185 43126 2ed4
1186 61348 2ed5
1187 43179 2ed6
1188 01375 2ed7
1189 43756 2ed8
1190 44023 2ed9
1191 44252 2eda
1192 44389 2edb
1193 44407 2edc
1194 01376 2edd
1195 61412 2ede
1196 44411 2edf
1197 44740 2ee0
1198 61420 2ee1
1199 45161 2ee2
1200 45223 2ee3
1201 45547 2ee4
1202 46094 2ee5
1203 46721 2ee6
1204 12118 2ee7
1205 46924 2ee8
1206 46997 2ee9
1207 47118 2eea
1208 20437 2eeb
1209 47300 2eec
1210 23054 2eed
1211 47420 2eee
1212 30022 2eef
1213 47467 2ef0
1214 47471 2ef1
1215 10017 2ef2
1216 47477 2ef3
1217 09831 2f00
1218 09885 2f01
1219 09907 2f02
1220 09920 2f03
1221 09961 2f04
1222 10025 2f05
1223 10035 2f06
1224 10067 2f07
1225 10114 2f08
1226 11204 2f09
1227 11269 2f0a
1228 11282 2f0b
1229 11320 2f0c
1230 11347 2f0d
1231 11379 2f0e
1232 11484 2f0f
1233 11509 2f10
1234 11529 2f11
1235 11778 2f12
1236 11929 2f13
1237 11975 2f14
1238 11986 2f15
1239 12045 2f16
1240 12071 2f17
1241 12107 2f18
1242 12127 2f19
1243 12170 2f1a
1244 12246 2f1b
1245 12277 2f1c
1246 12321 2f1d
1247 13573 2f1e
1248 13692 2f1f
1249 14438 2f20
1250 14467 2f21
1251 14478 2f22
1252 14503 2f23
1253 14544 2f24
1254 14669 2f25
1255 15784 2f26
1256 15881 2f27
1257 16132 2f28
1258 16173 2f29
1259 16202 2f2a
1260 16236 2f2b
1261 16325 2f2c
1262 16330 2f2d
1263 17049 2f2e
1264 17064 2f2f
1265 17081 2f30
1266 17100 2f31
1267 17281 2f32
1268 17294 2f33
1269 17306 2f34
1270 17533 2f35
1271 17553 2f36
1272 17576 2f37
1273 17587 2f38
1274 17708 2f39
1275 17741 2f3a
1276 17771 2f3b
1277 17904 2f3c
1278 18914 2f3d
1279 18987 2f3e
1280 19035 2f3f
1281 20292 2f40
1282 20300 2f41
1283 20433 2f42
1284 20462 2f43
1285 20486 2f44
1286 20527 2f45
1287 20604 2f46
1288 20616 2f47
1289 21049 2f48
1290 21090 2f49
1291 21152 2f4a
1292 22912 2f4b
1293 23034 2f4c
1294 23071 2f4d
1295 23210 2f4e
1296 23260 2f4f
1297 23280 2f50
1298 23297 2f51
1299 23377 2f52
1300 23390 2f53
1301 23439 2f54
1302 25247 2f55
1303 26151 2f56
1304 26174 2f57
1305 26184 2f58
1306 26188 2f59
1307 26201 2f5a
1308 26243 2f5b
1309 26251 2f5c
1310 26372 2f5d
1311 26720 2f5e
1312 26730 2f5f
1313 27286 2f60
1314 27313 2f61
1315 27429 2f62
1316 27440 2f63
1317 27453 2f64
1318 27466 2f65
1319 27606 2f66
1320 27617 2f67
1321 28068 2f68
1322 28079 2f69
1323 28156 2f6a
1324 28179 2f6b
1325 28257 2f6c
1326 28648 2f6d
1327 28662 2f6e
1328 28694 2f6f
1329 29209 2f70
1330 29443 2f71
1331 29458 2f72
1332 29774 2f73
1333 29991 2f74
1334 30078 2f75
1335 30875 2f76
1336 31155 2f77
1337 32184 2f78
1338 32247 2f79
1339 32344 2f7a
1340 32439 2f7b
1341 32584 2f7c
1342 32604 2f7d
1343 32613 2f7e
1344 32685 2f7f
1345 32839 2f80
1346 32856 2f81
1347 33596 2f82
1348 33608 2f83
1349 33626 2f84
1350 33645 2f85
1351 33681 2f86
1352 33711 2f87
1353 33724 2f88
1354 33912 2f89
1355 33919 2f8a
1356 33929 2f8b
1357 36097 2f8c
1358 36167 2f8d
1359 36942 2f8e
1360 36964 2f8f
1361 36997 2f90
1362 37548 2f91
1363 37573 2f92
1364 37676 2f93
1365 37769 2f94
1366 38780 2f95
1367 38812 2f96
1368 38837 2f97
1369 38898 2f98
1370 38970 2f99
1371 39252 2f9a
1372 39269 2f9b
1373 39368 2f9c
1374 39782 2f9d
1375 39846 2f9e
1376 40158 2f9f
1377 40197 2fa0
1378 40211 2fa1
1379 40777 2fa2
1380 41079 2fa3
1381 41334 2fa4
1382 41341 2fa5
1383 41347 2fa6
1384 42943 2fa7
1385 42956 2fa8
1386 43178 2fa9
1387 43435 2faa
1388 43442 2fab
1389 43533 2fac
1390 43755 2fad
1391 43786 2fae
1392 43799 2faf
1393 43808 2fb0
1394 43969 2fb1
1395 44030 2fb2
1396 44040 2fb3
1397 44068 2fb4
1398 44303 2fb5
1399 44402 2fb6
1400 44408 2fb7
1401 44791 2fb8
1402 44794 2fb9
1403 44827 2fba
1404 45222 2fbb
1405 45341 2fbc
1406 45353 2fbd
1407 45501 2fbe
1408 45519 2fbf
1409 45524 2fc0
1410 45546 2fc1
1411 45620 2fc2
1412 46199 2fc3
1413 46807 2fc4
1414 46823 2fc5
1415 46922 2fc6
1416 46974 2fc7
1417 46995 2fc8
1418 47016 2fc9
1419 47025 2fca
1420 47103 2fcb
1421 47115 2fcc
1422 47154 2fcd
1423 47164 2fce
1424 47189 2fcf
1425 47256 2fd0
1426 47285 2fd1
1427 47303 2fd2
1428 47434 2fd3
1429 47470 2fd4
1430 47478 2fd5
1431 01377 2ff0
1432 01378 2ff1
1433 01379 2ff2
1434 01380 2ff3
1435 01381 2ff4
1436 01382 2ff5
1437 01383 2ff6
1438 01384 2ff7
1439 01385 2ff8
1440 01386 2ff9
1441 01387 2ffa
1442 01388 2ffb
1443 01389 3000
1444 01390 3001
1445 01391 3002
1446 01392 3003
1447 01393 3004
1448 01394 3005
1449 01395 3006
1450 01396 3007
1451 01397 3008
1452 01398 3009
1453 01399 300a
1454 01400 300b
1455 01401 300c
1456 01402 300d
1457 01403 300e
1458 01404 300f
1459 01405 3010
1460 01406 3011
1461 01407 3012
1462 01408 3013
1463 01409 3014
1464 01410 3015
1465 01411 3016
1466 01412 3017
1467 01413 3018
1468 01414 3019
1469 01415 301a
1470 01416 301b
1471 01417 301c
1472 01418 301d
1473 01419 301e
1474 01420 301f
1475 01421 3020
1476 01422 3021
1477 01423 3022
1478 01424 3023
1479 01425 3024
1480 01426 3025
1481 01427 3026
1482 01428 3027
1483 01429 3028
1484 01430 3029
1485 01431 302a
1486 01432 302b
1487 01433 302c
1488 01434 302d
1489 01435 302e
1490 01436 302f
1491 01437 3030
1492 01438 3031
1493 01439 3032
1494 01440 3033
1495 01441 3034
1496 01442 3035
1497 01443 3036
1498 01444 3037
1499 01445 3038
1500 01446 3039
1501 01447 303a
1502 01448 303b
1503 01449 303c
1504 01450 303d
1505 01451 303e
1506 01452 303f
1507 01453 3041
1508 01454 3042
1509 01455 3043
1510 01456 3044
1511 01457 3045
1512 01458 3046
1513 01459 3047
1514 01460 3048
1515 01461 3049
1516 01462 304a
1517 01463 304b
1518 01464 304c
1519 01465 304d
1520 01466 304e
1521 01467 304f
1522 01468 3050
1523 01469 3051
1524 01470 3052
1525 01471 3053
1526 01472 3054
1527 01473 3055
1528 01474 3056
1529 01475 3057
1530 01476 3058
1531 01477 3059
1532 01478 305a
1533 01479 305b
1534 01480 305c
1535 01481 305d
1536 01482 305e
1537 01483 305f
1538 01484 3060
1539 01485 3061
1540 01486 3062
1541 01487 3063
1542 01488 3064
1543 01489 3065
1544 01490 3066
1545 01491 3067
1546 01492 3068
1547 01493 3069
1548 01494 306a
1549 01495 306b
1550 01496 306c
1551 01497 306d
1552 01498 306e
1553 01499 306f
1554 01500 3070
1555 01501 3071
1556 01502 3072
1557 01503 3073
1558 01504 3074
1559 01505 3075
1560 01506 3076
1561 01507 3077
1562 01508 3078
1563 01509 3079
1564 01510 307a
1565 01511 307b
1566 01512 307c
1567 01513 307d
1568 01514 307e
1569 01515 307f
1570 01516 3080
1571 01517 3081
1572 01518 3082
1573 01519 3083
1574 01520 3084
1575 01521 3085
1576 01522 3086
1577 01523 3087
1578 01524 3088
1579 01525 3089
1580 01526 308a
1581 01527 308b
1582 01528 308c
1583 01529 308d
1584 01530 308e
1585 01531 308f
1586 01532 3090
1587 01533 3091
1588 01534 3092
1589 01535 3093
1590 01536 3094
1591 01537 3095
1592 01538 3096
1593 01539 3099
1594 01540 309a
1595 01541 309b
1596 01542 309c
1597 01543 309d
1598 01544 309e
1599 01545 309f
1600 01546 30a0
1601 01547 30a1
1602 01548 30a2
1603 01549 30a3
1604 01550 30a4
1605 01551 30a5
1606 01552 30a6
1607 01553 30a7
1608 01554 30a8
1609 01555 30a9
1610 01556 30aa
1611 01557 30ab
1612 01558 30ac
1613 01559 30ad
1614 01560 30ae
1615 01561 30af
1616 01562 30b0
1617 01563 30b1
1618 01564 30b2
1619 01565 30b3
1620 01566 30b4
1621 01567 30b5
1622 01568 30b6
1623 01569 30b7
1624 01570 30b8
1625 01571 30b9
1626 01572 30ba
1627 01573 30bb
1628 01574 30bc
1629 01575 30bd
1630 01576 30be
1631 01577 30bf
1632 01578 30c0
1633 01579 30c1
1634 01580 30c2
1635 01581 30c3
1636 01582 30c4
1637 01583 30c5
1638 01584 30c6
1639 01585 30c7
1640 01586 30c8
1641 01587 30c9
1642 01588 30ca
1643 01589 30cb
1644 01590 30cc
1645 01591 30cd
1646 01592 30ce
1647 01593 30cf
1648 01594 30d0
1649 01595 30d1
1650 01596 30d2
1651 01597 30d3
1652 01598 30d4
1653 01599 30d5
1654 01600 30d6
1655 01601 30d7
1656 01602 30d8
1657 01603 30d9
1658 01604 30da
1659 01605 30db
1660 01606 30dc
1661 01607 30dd
1662 01608 30de
1663 01609 30df
1664 01610 30e0
1665 01611 30e1
1666 01612 30e2
1667 01613 30e3
1668 01614 30e4
1669 01615 30e5
1670 01616 30e6
1671 01617 30e7
1672 01618 30e8
1673 01619 30e9
1674 01620 30ea
1675 01621 30eb
1676 01622 30ec
1677 01623 30ed
1678 01624 30ee
1679 01625 30ef
1680 01626 30f0
1681 01627 30f1
1682 01628 30f2
1683 01629 30f3
1684 01630 30f4
1685 01631 30f5
1686 01632 30f6
1687 01633 30f7
1688 01634 30f8
1689 01635 30f9
1690 01636 30fa
1691 01637 30fb
1692 01638 30fc
1693 01639 30fd
1694 01640 30fe
1695 01641 30ff
1696 01642 3105
1697 01643 3106
1698 01644 3107
1699 01645 3108
1700 01646 3109
1701 01647 310a
1702 01648 310b
1703 01649 310c
1704 01650 310d
1705 01651 310e
1706 01652 310f
1707 01653 3110
1708 01654 3111
1709 01655 3112
1710 01656 3113
1711 01657 3114
1712 01658 3115
1713 01659 3116
1714 01660 3117
1715 01661 3118
1716 01662 3119
1717 01663 311a
1718 01664 311b
1719 01665 311c
1720 01666 311d
1721 01667 311e
1722 01668 311f
1723 01669 3120
1724 01670 3121
1725 01671 3122
1726 01672 3123
1727 01673 3124
1728 01674 3125
1729 01675 3126
1730 65353 3127
1731 01677 3128
1732 01678 3129
1733 01679 312a
1734 01680 312b
1735 01681 312c
1736 01682 312d
1737 01683 3131
1738 01684 3132
1739 01685 3133
1740 01686 3134
1741 01687 3135
1742 01688 3136
1743 01689 3137
1744 01690 3138
1745 01691 3139
1746 01692 313a
1747 01693 313b
1748 01694 313c
1749 01695 313d
1750 01696 313e
1751 01697 313f
1752 01698 3140
1753 01699 3141
1754 01700 3142
1755 01701 3143
1756 01702 3144
1757 01703 3145
1758 01704 3146
1759 01705 3147
1760 01706 3148
1761 01707 3149
1762 01708 314a
1763 01709 314b
1764 01710 314c
1765 01711 314d
1766 01712 314e
1767 01713 314f
1768 01714 3150
1769 01715 3151
1770 01716 3152
1771 01717 3153
1772 01718 3154
1773 01719 3155
1774 01720 3156
1775 01721 3157
1776 01722 3158
1777 01723 3159
1778 01724 315a
1779 01725 315b
1780 01726 315c
1781 01727 315d
1782 01728 315e
1783 01729 315f
1784 01730 3160
1785 01731 3161
1786 01732 3162
1787 01733 3163
1788 01734 3165
1789 01735 3166
1790 01736 3167
1791 01737 3168
1792 01738 3169
1793 01739 316a
1794 01740 316b
1795 01741 316c
1796 01742 316d
1797 01743 316e
1798 01744 316f
1799 01745 3170
1800 01746 3171
1801 01747 3172
1802 01748 3173
1803 01749 3174
1804 01750 3175
1805 01751 3176
1806 01752 3177
1807 01753 3178
1808 01754 3179
1809 01755 317a
1810 01756 317b
1811 01757 317c
1812 01758 317d
1813 01759 317e
1814 01760 317f
1815 01761 3180
1816 01762 3181
1817 01763 3182
1818 01764 3183
1819 01765 3184
1820 01766 3185
1821 01767 3186
1822 01768 3187
1823 01769 3188
1824 01770 3189
1825 01771 318a
1826 01772 318b
1827 01773 318c
1828 01774 318d
1829 01775 318e
1830 01776 3190
1831 01777 3191
1832 01778 3192
1833 01779 3193
1834 01780 3194
1835 01781 3195
1836 01782 3196
1837 01783 3197
1838 01784 3198
1839 01785 3199
1840 01786 319a
1841 01787 319b
1842 01788 319c
1843 01789 319d
1844 01790 319e
1845 01791 319f
1846 01792 31a0
1847 01793 31a1
1848 01794 31a2
1849 01795 31a3
1850 01796 31a4
1851 01797 31a5
1852 01798 31a6
1853 01799 31a7
1854 01800 31a8
1855 01801 31a9
1856 01802 31aa
1857 01803 31ab
1858 01804 31ac
1859 01805 31ad
1860 01806 31ae
1861 01807 31af
1862 01808 31b0
1863 01809 31b1
1864 01810 31b2
1865 01811 31b3
1866 01812 31b4
1867 01813 31b5
1868 01814 31b6
1869 01815 31b7
1870 01816 31b8
1871 01817 31b9
1872 01818 31ba
1873 01819 31c0
1874 01820 31c1
1875 01821 31c2
1876 01822 31c3
1877 01823 31c4
1878 01824 31c5
1879 01825 31c6
1880 01826 31c7
1881 01827 31c8
1882 01828 31c9
1883 01829 31ca
1884 01830 31cb
1885 01831 31cc
1886 01832 31cd
1887 01833 31ce
1888 01834 31cf
1889 01835 31d0
1890 01836 31d1
1891 01837 31d2
1892 01838 31d3
1893 01839 31d4
1894 01840 31d5
1895 01841 31d6
1896 01842 31d7
1897 01843 31d8
1898 01844 31d9
1899 01845 31da
1900 01846 31db
1901 01847 31dc
1902 01848 31dd
1903 01849 31de
1904 01850 31df
1905 01851 31e0
1906 01852 31e1
1907 01853 31e2
1908 01854 31e3
1909 01855 31f0
1910 01856 31f1
1911 01857 31f2
1912 01858 31f3
1913 01859 31f4
1914 01860 31f5
1915 01861 31f6
1916 01862 31f7
1917 01863 31f8
1918 01864 31f9
1919 01865 31fa
1920 01866 31fb
1921 01867 31fc
1922 01868 31fd
1923 01869 31fe
1924 01870 31ff
1925 01871 3200
1926 01872 3201
1927 01873 3202
1928 01874 3203
1929 01875 3204
1930 01876 3205
1931 01877 3206
1932 01878 3207
1933 01879 3208
1934 01880 3209
1935 01881 320a
1936 01882 320b
1937 01883 320c
1938 01884 320d
1939 01885 320e
1940 01886 320f
1941 01887 3210
1942 01888 3211
1943 01889 3212
1944 01890 3213
1945 01891 3214
1946 01892 3215
1947 01893 3216
1948 01894 3217
1949 01895 3218
1950 01896 3219
1951 01897 321a
1952 01898 321b
1953 01899 321c
1954 01900 321d
1955 01901 321e
1956 01902 3220
1957 01903 3221
1958 01904 3222
1959 01905 3223
1960 01907 3224
1961 01908 3225
1962 01910 3226
1963 01912 3227
1964 01915 3228
1965 01916 3229
1966 01917 322a
1967 01918 322b
1968 01920 322c
1969 01921 322d
1970 01922 322e
1971 01924 322f
1972 01925 3230
1973 01926 3231
1974 01927 3232
1975 01929 3233
1976 01931 3234
1977 01932 3235
1978 01934 3236
1979 01935 3237
1980 01937 3238
1981 01938 3239
1982 01939 323a
1983 01940 323b
1984 01941 323c
1985 01943 323d
1986 01945 323e
1987 01947 323f
1988 01948 3240
1989 01950 3241
1990 01951 3242
1991 01952 3243
1992 01954 3244
1993 01955 3245
1994 01957 3246
1995 01959 3247
1996 01962 3248
1997 01963 3249
1998 01964 324a
1999 01965 324b
2000 01966 324c
2001 01967 324d
2002 01968 324e
2003 01969 324f
2004 01970 3250
2005 01971 3251
2006 01972 3252
2007 01973 3253
2008 01974 3254
2009 01975 3255
2010 01976 3256
2011 01977 3257
2012 01978 3258
2013 01979 3259
2014 01980 325a
2015 01981 325b
2016 01982 325c
2017 01983 325d
2018 01984 325e
2019 01985 325f
2020 01986 3260
2021 01987 3261
2022 01988 3262
2023 01989 3263
2024 01990 3264
2025 01991 3265
2026 01992 3266
2027 01993 3267
2028 01994 3268
2029 01995 3269
2030 01996 326a
2031 01997 326b
2032 01998 326c
2033 01999 326d
2034 02000 326e
2035 02001 326f
2036 02002 3270
2037 02003 3271
2038 02004 3272
2039 02005 3273
2040 02006 3274
2041 02007 3275
2042 02008 3276
2043 02009 3277
2044 02010 3278
2045 02011 3279
2046 02012 327a
2047 02013 327b
2048 02014 327c
2049 02015 327d
2050 02016 327e
2051 02017 327f
2052 02018 3280
2053 02019 3281
2054 02020 3282
2055 02021 3283
2056 02023 3284
2057 02024 3285
2058 02026 3286
2059 02028 3287
2060 02031 3288
2061 02032 3289
2062 02033 328a
2063 02034 328b
2064 02036 328c
2065 02037 328d
2066 02038 328e
2067 02040 328f
2068 02041 3290
2069 02042 3291
2070 02043 3292
2071 02045 3293
2072 02047 3294
2073 02048 3295
2074 02050 3296
2075 02051 3297
2076 02053 3298
2077 02054 3299
2078 02055 329a
2079 02056 329b
2080 02059 329c
2081 02062 329d
2082 02064 329e
2083 02067 329f
2084 02068 32a0
2085 02069 32a1
2086 02070 32a2
2087 02073 32a3
2088 02074 32a4
2089 02075 32a5
2090 02076 32a6
2091 02077 32a7
2092 02078 32a8
2093 02079 32a9
2094 02082 32aa
2095 02085 32ab
2096 02086 32ac
2097 02088 32ad
2098 02090 32ae
2099 02092 32af
2100 02093 32b0
2101 02096 32b1
2102 02097 32b2
2103 02098 32b3
2104 02099 32b4
2105 02100 32b5
2106 02101 32b6
2107 02102 32b7
2108 02103 32b8
2109 02104 32b9
2110 02105 32ba
2111 02106 32bb
2112 02107 32bc
2113 02108 32bd
2114 02109 32be
2115 02110 32bf
2116 02111 32c0
2117 02112 32c1
2118 02113 32c2
2119 02114 32c3
2120 02115 32c4
2121 02116 32c5
2122 02117 32c6
2123 02118 32c7
2124 02119 32c8
2125 02120 32c9
2126 02121 32ca
2127 02122 32cb
2128 02123 32cc
2129 02124 32cd
2130 02125 32ce
2131 02126 32cf
2132 02127 32d0
2133 02128 32d1
2134 02129 32d2
2135 02130 32d3
2136 02131 32d4
2137 02132 32d5
2138 02133 32d6
2139 02134 32d7
2140 02135 32d8
2141 02136 32d9
2142 02137 32da
2143 02138 32db
2144 02139 32dc
2145 02140 32dd
2146 02141 32de
2147 02142 32df
2148 02143 32e0
2149 02144 32e1
2150 02145 32e2
2151 02146 32e3
2152 02147 32e4
2153 02148 32e5
2154 02149 32e6
2155 02150 32e7
2156 02151 32e8
2157 02152 32e9
2158 02153 32ea
2159 02154 32eb
2160 02155 32ec
2161 02156 32ed
2162 02157 32ee
2163 02158 32ef
2164 02159 32f0
2165 02160 32f1
2166 02161 32f2
2167 02162 32f3
2168 02163 32f4
2169 02164 32f5
2170 02165 32f6
2171 02166 32f7
2172 02167 32f8
2173 02168 32f9
2174 02169 32fa
2175 02170 32fb
2176 02171 32fc
2177 02172 32fd
2178 02173 32fe
2179 02174 3300
2180 02175 3301
2181 02176 3302
2182 02177 3303
2183 02178 3304
2184 02179 3305
2185 02180 3306
2186 02181 3307
2187 02182 3308
2188 02183 3309
2189 02184 330a
2190 02185 330b
2191 02186 330c
2192 02187 330d
2193 02188 330e
2194 02189 330f
2195 02190 3310
2196 02191 3311
2197 02192 3312
2198 02193 3313
2199 02194 3314
2200 02195 3315
2201 02196 3316
2202 02197 3317
2203 02198 3318
2204 02199 3319
2205 02200 331a
2206 02201 331b
2207 02202 331c
2208 02203 331d
2209 02204 331e
2210 02205 331f
2211 02206 3320
2212 02207 3321
2213 02208 3322
2214 02209 3323
2215 02210 3324
2216 02211 3325
2217 02212 3326
2218 02213 3327
2219 02214 3328
2220 02215 3329
2221 02216 332a
2222 02217 332b
2223 02218 332d
2224 02219 332e
2225 02220 332f
2226 02221 3330
2227 02222 3331
2228 02223 3332
2229 02224 3333
2230 02225 3334
2231 02226 3335
2232 02227 3336
2233 02228 3337
2234 02229 3338
2235 02230 3339
2236 02231 333a
2237 02232 333b
2238 02233 333c
2239 02234 333d
2240 02235 333e
2241 02236 333f
2242 02237 3340
2243 02238 3341
2244 02239 3342
2245 02240 3343
2246 02241 3344
2247 02242 3345
2248 02243 3346
2249 02244 3347
2250 02245 3348
2251 02246 3349
2252 02247 334a
2253 02248 334b
2254 02249 334c
2255 02250 334d
2256 02251 334e
2257 02252 334f
2258 02253 3350
2259 02254 3351
2260 02255 3352
2261 02256 3353
2262 02257 3354
2263 02258 3355
2264 02259 3356
2265 02260 3357
2266 02261 3358
2267 02262 3359
2268 02263 335a
2269 02264 335b
2270 02265 335c
2271 02266 335d
2272 02267 335e
2273 02268 335f
2274 02269 3360
2275 02270 3361
2276 02271 3362
2277 02272 3363
2278 02273 3364
2279 02274 3365
2280 02275 3366
2281 02276 3367
2282 02277 3368
2283 02278 3369
2284 02279 336a
2285 02280 336b
2286 02281 336c
2287 02282 336d
2288 02283 336e
2289 02284 336f
2290 02285 3370
2291 02286 3371
2292 02287 3372
2293 02288 3373
2294 02289 3374
2295 02290 3375
2296 02291 3376
2297 02292 3377
2298 02293 3378
2299 02294 3379
2300 02295 337a
2301 02296 337b
2302 02297 337c
2303 02298 337d
2304 02299 337e
2305 02300 337f
2306 02302 3380
2307 02303 3381
2308 02304 3382
2309 02305 3383
2310 02306 3384
2311 02307 3385
2312 02308 3386
2313 02309 3387
2314 02310 3388
2315 02311 3389
2316 02312 338a
2317 02313 338b
2318 02314 338c
2319 02315 338d
2320 02316 338e
2321 02317 338f
2322 02318 3390
2323 02319 3391
2324 02320 3392
2325 02321 3393
2326 02322 3394
2327 02323 3395
2328 02324 3396
2329 02325 3397
2330 02326 3398
2331 02327 3399
2332 02328 339a
2333 02329 339b
2334 02330 339c
2335 02331 339d
2336 02332 339e
2337 02333 339f
2338 02334 33a0
2339 02335 33a1
2340 02336 33a2
2341 02337 33a3
2342 02338 33a4
2343 02339 33a5
2344 02340 33a6
2345 02341 33a7
2346 02342 33a8
2347 02343 33a9
2348 02344 33aa
2349 02345 33ab
2350 02346 33ac
2351 02347 33ad
2352 02348 33ae
2353 02349 33af
2354 02350 33b0
2355 02351 33b1
2356 02352 33b2
2357 02353 33b3
2358 02354 33b4
2359 02355 33b5
2360 02356 33b6
2361 02357 33b7
2362 02358 33b8
2363 02359 33b9
2364 02360 33ba
2365 02361 33bb
2366 02362 33bc
2367 02363 33bd
2368 02364 33be
2369 02365 33bf
2370 02366 33c0
2371 02367 33c1
2372 02368 33c2
2373 02369 33c3
2374 02370 33c4
2375 02371 33c5
2376 02372 33c6
2377 02373 33c7
2378 02374 33c8
2379 02375 33c9
2380 02376 33ca
2381 02377 33cb
2382 02378 33cc
2383 02379 33cd
2384 02380 33ce
2385 02381 33cf
2386 02382 33d0
2387 02383 33d1
2388 02384 33d2
2389 02385 33d3
2390 02386 33d4
2391 02387 33d5
2392 02388 33d6
2393 02389 33d7
2394 02390 33d8
2395 02391 33d9
2396 02392 33da
2397 02393 33db
2398 02394 33dc
2399 02395 33dd
2400 02396 33de
2401 02397 33df
2402 02398 33e0
2403 02399 33e1
2404 02400 33e2
2405 02401 33e3
2406 02402 33e4
2407 02403 33e5
2408 02404 33e6
2409 02405 33e7
2410 02406 33e8
2411 02407 33e9
2412 02408 33ea
2413 02409 33eb
2414 02410 33ec
2415 02411 33ed
2416 02412 33ee
2417 02413 33ef
2418 02414 33f0
2419 02415 33f1
2420 02416 33f2
2421 02417 33f3
2422 02418 33f4
2423 02419 33f5
2424 02420 33f6
2425 02421 33f7
2426 02422 33f8
2427 02423 33f9
2428 02424 33fa
2429 02425 33fb
2430 02426 33fc
2431 02427 33fd
2432 02428 33fe
2433 02429 33ff
2434 02432 3402
2435 02437 3405
2436 02439 3406
2437 02473 3427
2438 02480 342c
2439 02484 342e
2440 02551 3468
2441 02553 346a
2442 02586 3488
2443 02597 3492
2444 02636 34b5
2445 02645 34bc
2446 02651 34c1
2447 02660 34c7
2448 02682 34db
2449 02759 351f
2450 02798 353e
2451 02830 355d
2452 02831 355e
2453 02836 3563
2454 02848 356e
2455 02911 35a6
2456 02913 35a8
2457 02946 35c5
2458 02971 35da
2459 02976 35de
2460 03001 35f4
2461 03020 3605
2462 03037 3614
2463 03100 364a
2464 03177 3691
2465 03184 3696
2466 03187 3699
2467 03257 36cf
2468 03438 3761
2469 03440 3762
2470 03451 376b
2471 03453 376c
2472 03464 3775
2473 03488 378d
2474 03547 37c1
2475 03584 37e2
2476 03592 37e8
2477 03606 37f4
2478 03618 37fd
2479 03622 3800
2480 03679 382f
2481 03686 3836
2482 03697 3840
2483 03726 385c
2484 03733 3861
2485 03809 38a1
2486 03824 38ad
2487 03911 38fa
2488 03942 3917
2489 03946 391a
2490 04041 396f
2491 04105 39a4
2492 04128 39b8
2493 04304 3a5c
2494 04326 3a6e
2495 04332 3a73
2496 04351 3a85
2497 04421 3ac4
2498 04429 3acb
2499 04441 3ad6
2500 04442 3ad7
2501 04465 3aea
2502 04475 3af3
2503 04509 3b0e
2504 04522 3b1a
2505 04525 3b1c
2506 04533 3b22
2507 04617 3b6d
2508 04628 3b77
2509 04647 3b87
2510 04649 3b88
2511 04654 3b8d
2512 04680 3ba4
2513 04700 3bb6
2514 04718 3bc3
2515 04730 3bcd
2516 04767 3bf0
2517 04772 3bf3
2518 04803 3c0f
2519 04831 3c26
2520 05001 3cc3
2521 05016 3cd2
2522 05086 3d11
2523 05102 3d1e
2524 05123 3d31
2525 05155 3d4e
2526 05182 3d64
2527 05246 3d9a
2528 05288 3dc0
2529 05304 3dcc
2530 05316 3dd4
2531 05375 3e05
2532 05437 3e3f
2533 05439 3e40
2534 05473 3e60
2535 05481 3e66
2536 05483 3e68
2537 05512 3e83
2538 05519 3e8a
2539 05529 3e94
2540 05605 3eda
2541 05745 3f57
2542 05773 3f72
2543 05777 3f75
2544 05780 3f77
2545 05838 3fae
2546 05842 3fb1
2547 05868 3fc9
2548 05885 3fd7
2549 05892 3fdc
2550 05991 4039
2551 06025 4058
2552 06089 4093
2553 06213 4103
2554 06217 4105
2555 06290 4148
2556 06298 414f
2557 06318 4163
2558 06405 41b4
2559 06417 41bf
2560 06462 41e6
2561 06471 41ee
2562 06478 41f3
2563 06499 4207
2564 06506 420e
2565 06602 4264
2566 06657 4293
2567 06715 42c6
2568 06734 42d6
2569 06743 42dd
2570 06783 4302
2571 06831 432b
2572 06858 4343
2573 07042 43ee
2574 07044 43f0
2575 07073 4408
2576 07078 440c
2577 07090 4417
2578 07096 441c
2579 07103 4422
2580 07156 4453
2581 07165 445b
2582 07196 4476
2583 07201 447a
2584 07226 4491
2585 07267 44b3
2586 07281 44be
2587 07310 44d4
2588 07376 4508
2589 07385 450d
2590 07413 4525
2591 07453 4543
2592 07524 457a
2593 07566 459d
2594 07595 45b8
2595 07601 45be
2596 07645 45e5
2597 07650 45ea
2598 07689 460f
2599 07690 4610
2600 07744 4641
2601 07783 4665
2602 07848 46a1
2603 07864 46ae
2604 07866 46af
2605 07972 470c
2606 07995 471f
2607 08070 4764
2608 08207 47e6
2609 08231 47fd
2610 08258 4816
2611 08267 481e
2612 08307 4844
2613 08317 484e
2614 08432 48b5
2615 08718 49b0
2616 08777 49e7
2617 08797 49fa
2618 08808 4a04
2619 08849 4a29
2620 09005 4abc
2621 09139 4b38
2622 09143 4b3b
2623 09214 4b7e
2624 09289 4bc2
2625 09297 4bca
2626 09306 4bd2
2627 09330 4be8
2628 09382 4c17
2629 09392 4c20
2630 09418 4c38
2631 09573 4cc4
2632 09587 4cd1
2633 09603 4ce1
2634 09642 4d07
2635 09760 4d77
2636 09831 4e00
2637 09832 4e01
2638 09833 4e02
2639 09835 4e03
2640 09837 4e04
2641 09838 4e05
2642 09840 4e07
2643 09841 4e08
2644 09842 4e09
2645 09843 4e0a
2646 09844 4e0b
2647 09845 4e0c
2648 09846 4e0d
2649 09847 4e0e
2650 09849 4e0f
2651 09851 4e10
2652 09853 4e11
2653 09855 4e12
2654 09858 4e14
2655 09859 4e15
2656 09861 4e16
2657 09863 4e17
2658 09865 4e18
2659 09867 4e19
2660 09872 4e1e
2661 09874 4e1f
2662 09877 4e21
2663 09880 4e23
2664 09881 4e24
2665 09883 4e26
2666 09885 4e28
2667 09886 4e29
2668 09888 4e2a
2669 09890 4e2b
2670 09892 4e2c
2671 09893 4e2d
2672 09894 4e2e
2673 09896 4e2f
2674 09898 4e30
2675 09900 4e31
2676 09902 4e32
2677 09905 4e35
2678 09907 4e36
2679 09908 4e37
2680 09909 4e38
2681 09912 4e39
2682 09914 4e3b
2683 09915 4e3c
2684 09920 4e3f
2685 09921 4e40
2686 09923 4e41
2687 09925 4e42
2688 09926 4e43
2689 09928 4e44
2690 09929 4e45
2691 09931 4e47
2692 09933 4e48
2693 09938 4e4b
2694 09941 4e4d
2695 09942 4e4e
2696 09943 4e4f
2697 09946 4e51
2698 09953 4e55
2699 09955 4e56
2700 09958 4e57
2701 09959 4e58
2702 09961 4e59
2703 09962 4e5a
2704 09964 4e5b
2705 09965 4e5c
2706 09967 4e5d
2707 09969 4e5e
2708 09970 4e5f
2709 09974 4e62
2710 09976 4e63
2711 09982 4e68
2712 09984 4e69
2713 09993 4e71
2714 09995 4e73
2715 09997 4e74
2716 09999 4e75
2717 10007 4e79
2718 10012 4e7e
2719 10014 4e7f
2720 10017 4e80
2721 10020 4e82
2722 10025 4e85
2723 10026 4e86
2724 10030 4e88
2725 10031 4e89
2726 10033 4e8a
2727 10034 4e8b
2728 10035 4e8c
2729 10036 4e8d
2730 10037 4e8e
2731 10042 4e91
2732 10044 4e92
2733 10047 4e94
2734 10049 4e95
2735 10050 4e96
2736 10051 4e97
2737 10052 4e98
2738 10054 4e99
2739 10056 4e9b
2740 10058 4e9c
2741 10060 4e9d
2742 10062 4e9e
2743 10064 4e9f
2744 10067 4ea0
2745 10069 4ea1
2746 10072 4ea2
2747 10075 4ea4
2748 10077 4ea5
2749 10079 4ea6
2750 10082 4ea8
2751 10086 4eab
2752 10088 4eac
2753 10090 4ead
2754 10092 4eae
2755 10095 4eaf
2756 10097 4eb0
2757 10102 4eb3
2758 10107 4eb6
2759 10111 4eb9
2760 10114 4eba
2761 10116 4ebb
2762 10117 4ebc
2763 10122 4ec0
2764 10123 4ec1
2765 10124 4ec2
2766 10125 4ec3
2767 10126 4ec4
2768 10130 4ec6
2769 10132 4ec7
2770 10133 4ec8
2771 10137 4eca
2772 10140 4ecb
2773 10143 4ecd
2774 10145 4ece
2775 10147 4ecf
2776 10149 4ed0
2777 10154 4ed4
2778 10156 4ed5
2779 10157 4ed6
2780 10159 4ed7
2781 10160 4ed8
2782 10161 4ed9
2783 10163 4eda
2784 10165 4edb
2785 10167 4edd
2786 10169 4ede
2787 10171 4edf
2788 10172 4ee0
2789 10173 4ee1
2790 10174 4ee2
2791 10175 4ee3
2792 10176 4ee4
2793 10179 4ee5
2794 10183 4ee8
2795 10186 4eeb
2796 10189 4eed
2797 10190 4eee
2798 10192 4eef
2799 10194 4ef0
2800 10196 4ef1
2801 10199 4ef2
2802 10200 4ef3
2803 10204 4ef5
2804 10205 4ef6
2805 10206 4ef7
2806 10211 4efb
2807 10213 4efc
2808 10214 4efd
2809 10217 4efe
2810 10219 4eff
2811 10221 4f00
2812 10224 4f01
2813 10226 4f02
2814 10227 4f03
2815 10232 4f08
2816 10233 4f09
2817 10235 4f0a
2818 10236 4f0b
2819 10238 4f0c
2820 10239 4f0d
2821 10241 4f0e
2822 10243 4f0f
2823 10244 4f10
2824 10245 4f11
2825 10246 4f12
2826 10250 4f15
2827 10251 4f16
2828 10252 4f17
2829 10256 4f19
2830 10259 4f1a
2831 10262 4f1c
2832 10263 4f1d
2833 10279 4f2b
2834 10283 4f2e
2835 10285 4f2f
2836 10286 4f30
2837 10287 4f31
2838 10291 4f33
2839 10293 4f34
2840 10295 4f35
2841 10296 4f36
2842 10299 4f37
2843 10300 4f38
2844 10302 4f39
2845 10303 4f3a
2846 10304 4f3b
2847 10306 4f3c
2848 10308 4f3d
2849 10309 4f3e
2850 10312 4f40
2851 10314 4f42
2852 10315 4f43
2853 10318 4f46
2854 10319 4f47
2855 10321 4f48
2856 10322 4f49
2857 10325 4f4b
2858 10326 4f4c
2859 10328 4f4d
2860 10330 4f4e
2861 10333 4f4f
2862 10335 4f50
2863 10337 4f51
2864 10338 4f52
2865 10340 4f53
2866 10341 4f54
2867 10342 4f55
2868 10343 4f56
2869 10344 4f57
2870 10346 4f58
2871 10349 4f59
2872 10351 4f5a
2873 10352 4f5b
2874 10354 4f5c
2875 10355 4f5d
2876 10356 4f5e
2877 10359 4f5f
2878 10361 4f60
2879 10366 4f63
2880 10367 4f64
2881 10374 4f69
2882 10375 4f6a
2883 10377 4f6c
2884 10380 4f6e
2885 10382 4f6f
2886 10384 4f70
2887 10385 4f71
2888 10389 4f73
2889 10392 4f75
2890 10393 4f76
2891 10394 4f77
2892 10396 4f78
2893 10397 4f79
2894 10398 4f7a
2895 10401 4f7b
2896 10402 4f7c
2897 10404 4f7d
2898 10407 4f7e
2899 10410 4f7f
2900 10412 4f81
2901 10413 4f82
2902 10415 4f83
2903 10417 4f84
2904 10419 4f85
2905 10421 4f86
2906 10423 4f88
2907 10426 4f89
2908 10428 4f8a
2909 10429 4f8b
2910 10432 4f8c
2911 10434 4f8d
2912 10436 4f8e
2913 10437 4f8f
2914 10438 4f90
2915 10439 4f91
2916 10441 4f92
2917 10444 4f93
2918 10445 4f94
2919 10448 4f96
2920 10450 4f97
2921 10451 4f98
2922 10454 4f99
2923 10455 4f9a
2924 10456 4f9b
2925 10459 4f9d
2926 10461 4f9e
2927 10464 4f9f
2928 10466 4fa0
2929 10467 4fa1
2930 10477 4fab
2931 10481 4fad
2932 10482 4fae
2933 10484 4faf
2934 10489 4fb2
2935 10495 4fb5
2936 10497 4fb6
2937 10498 4fb7
2938 10500 4fb9
2939 10504 4fbb
2940 10507 4fbc
2941 10509 4fbd
2942 10511 4fbe
2943 10513 4fbf
2944 10514 4fc0
2945 10517 4fc1
2946 10520 4fc2
2947 10523 4fc3
2948 10524 4fc4
2949 10525 4fc5
2950 10527 4fc6
2951 10530 4fc8
2952 10532 4fc9
2953 10533 4fca
2954 10536 4fcb
2955 10537 4fcc
2956 10538 4fcd
2957 10540 4fce
2958 10541 4fcf
2959 10544 4fd0
2960 10545 4fd1
2961 10546 4fd2
2962 10548 4fd3
2963 10549 4fd4
2964 10553 4fd7
2965 10555 4fd8
2966 10558 4fda
2967 10559 4fdb
2968 10560 4fdc
2969 10562 4fdd
2970 10567 4fdf
2971 10570 4fe0
2972 10571 4fe1
2973 10573 4fe2
2974 10575 4fe3
2975 10576 4fe4
2976 10578 4fe5
2977 10579 4fe6
2978 10588 4fee
2979 10590 4fef
2980 10592 4ff0
2981 10593 4ff1
2982 10594 4ff2
2983 10596 4ff3
2984 10599 4ff5
2985 10601 4ff6
2986 10604 4ff8
2987 10607 4ffa
2988 10611 4ffc
2989 10613 4ffd
2990 10615 4ffe
2991 10617 4fff
2992 10619 5000
2993 10621 5001
2994 10622 5002
2995 10626 5004
2996 10627 5005
2997 10629 5006
2998 10631 5007
2999 10635 5009
3000 10638 500a
3001 10640 500b
3002 10641 500c
3003 10643 500d
3004 10645 500e
3005 10646 500f
3006 10649 5010
3007 10651 5011
3008 10652 5012
3009 10654 5013
3010 10656 5014
3011 10660 5016
3012 10662 5017
3013 10664 5018
3014 10666 5019
3015 10669 501a
3016 10670 501b
3017 10671 501c
3018 10674 501d
3019 10675 501e
3020 10677 501f
3021 10680 5021
3022 10681 5022
3023 10682 5023
3024 10684 5024
3025 10686 5025
3026 10689 5026
3027 10691 5027
3028 10694 5028
3029 10695 5029
3030 10698 502a
3031 10700 502b
3032 10702 502c
3033 10703 502d
3034 10706 502e
3035 10709 5030
3036 10714 5032
3037 10715 5033
3038 10717 5035
3039 10719 5036
3040 10723 5039
3041 10726 503b
3042 10733 5040
3043 10735 5041
3044 10737 5042
3045 10739 5043
3046 10743 5045
3047 10744 5046
3048 10746 5047
3049 10747 5048
3050 10750 5049
3051 10753 504a
3052 10756 504c
3053 10759 504e
3054 10761 504f
3055 10764 5050
3056 10766 5051
3057 10768 5052
3058 10769 5053
3059 10772 5055
3060 10775 5056
3061 10777 5057
3062 10780 5059
3063 10782 505a
3064 10785 505c
3065 10791 505f
3066 10792 5060
3067 10798 5062
3068 10800 5063
3069 10803 5065
3070 10805 5066
3071 10807 5067
3072 10812 506a
3073 10815 506c
3074 10817 506d
3075 10822 5070
3076 10825 5071
3077 10827 5072
3078 10830 5074
3079 10831 5075
3080 10832 5076
3081 10834 5077
3082 10837 5078
3083 10845 507d
3084 10848 5080
3085 10851 5081
3086 10856 5083
3087 10858 5084
3088 10859 5085
3089 10861 5086
3090 10864 5088
3091 10868 508a
3092 10872 508d
3093 10874 508e
3094 10876 508f
3095 10878 5090
3096 10880 5091
3097 10883 5092
3098 10886 5093
3099 10888 5094
3100 10890 5095
3101 10892 5096
3102 10896 5098
3103 10898 5099
3104 10901 509a
3105 10903 509b
3106 10905 509c
3107 10911 509e
3108 10913 509f
3109 10915 50a0
3110 10917 50a1
3111 10919 50a2
3112 10921 50a3
3113 10930 50aa
3114 10933 50ac
3115 10935 50ad
3116 10939 50af
3117 10942 50b0
3118 10944 50b1
3119 10945 50b2
3120 10948 50b3
3121 10949 50b4
3122 10952 50b5
3123 10954 50b7
3124 10956 50b9
3125 10958 50ba
3126 10961 50bb
3127 10966 50bd
3128 10968 50be
3129 10972 50c0
3130 10976 50c2
3131 10979 50c3
3132 10980 50c4
3133 10982 50c5
3134 10985 50c7
3135 10990 50c9
3136 10992 50ca
3137 10995 50cc
3138 10996 50cd
3139 10997 50ce
3140 10999 50cf
3141 11002 50d0
3142 11004 50d1
3143 11006 50d3
3144 11007 50d4
3145 11009 50d5
3146 11011 50d6
3147 11015 50d8
3148 11017 50d9
3149 11020 50da
3150 11023 50dc
3151 11025 50dd
3152 11027 50de
3153 11029 50df
3154 11034 50e1
3155 11036 50e2
3156 11038 50e3
3157 11040 50e4
3158 11041 50e5
3159 11042 50e6
3160 11044 50e7
3161 11046 50e8
3162 11047 50e9
3163 11053 50ed
3164 11056 50ee
3165 11058 50ef
3166 11061 50f0
3167 11063 50f1
3168 11066 50f2
3169 11068 50f3
3170 11070 50f4
3171 11071 50f5
3172 11072 50f6
3173 11078 50f9
3174 11079 50fa
3175 11080 50fb
3176 11085 50fe
3177 11089 5100
3178 11090 5101
3179 11092 5102
3180 11095 5103
3181 11097 5104
3182 11100 5106
3183 11102 5107
3184 11104 5108
3185 11106 5109
3186 11109 510b
3187 11112 510c
3188 11114 510d
3189 11117 510e
3190 11119 5110
3191 11122 5112
3192 11126 5114
3193 11127 5115
3194 11129 5116
3195 11131 5117
3196 11133 5118
3197 11134 5119
3198 11136 511a
3199 11139 511b
3200 11141 511c
3201 11143 511d
3202 11144 511e
3203 11145 511f
3204 11148 5121
3205 11151 5123
3206 11158 5127
3207 11159 5128
3208 11162 512a
3209 11166 512c
3210 11168 512d
3211 11173 512f
3212 11177 5131
3213 11180 5132
3214 11182 5133
3215 11185 5134
3216 11187 5135
3217 11190 5137
3218 11193 5138
3219 11195 5139
3220 11197 513a
3221 11199 513b
3222 11200 513c
3223 11204 513f
3224 11205 5140
3225 11207 5141
3226 11209 5142
3227 11211 5143
3228 11212 5144
3229 11213 5145
3230 11216 5146
3231 11217 5147
3232 11219 5148
3233 11220 5149
3234 11222 514a
3235 11224 514b
3236 11225 514c
3237 11228 514d
3238 11230 514e
3239 11232 514f
3240 11234 5150
3241 11236 5152
3242 11238 5153
3243 11240 5154
3244 11241 5155
3245 11245 5157
3246 11247 5158
3247 11250 515a
3248 11253 515c
3249 11259 515f
3250 11261 5160
3251 11264 5162
3252 11267 5164
3253 11269 5165
3254 11271 5166
3255 11273 5167
3256 11275 5168
3257 11277 5169
3258 11279 516a
3259 11282 516b
3260 11285 516c
3261 11288 516d
3262 11290 516e
3263 11295 5171
3264 11297 5173
3265 11299 5174
3266 11300 5175
3267 11302 5176
3268 11303 5177
3269 11305 5178
3270 11306 5179
3271 11309 517b
3272 11311 517c
3273 11313 517e
3274 11316 5180
3275 11320 5182
3276 11321 5183
3277 11322 5184
3278 11323 5185
3279 11324 5186
3280 11328 5189
3281 11329 518a
3282 11330 518b
3283 11331 518c
3284 11332 518d
3285 11333 518e
3286 11335 518f
3287 11338 5190
3288 11339 5191
3289 11341 5192
3290 11343 5193
3291 11346 5195
3292 11347 5196
3293 11348 5197
3294 11349 5198
3295 11350 5199
3296 11355 519d
3297 11359 51a0
3298 11360 51a1
3299 11362 51a2
3300 11365 51a3
3301 11367 51a4
3302 11369 51a5
3303 11371 51a6
3304 11373 51a8
3305 11374 51a9
3306 11376 51aa
3307 11379 51ab
3308 11380 51ac
3309 11382 51ad
3310 11386 51b0
3311 11387 51b1
3312 11389 51b2
3313 11391 51b3
3314 11392 51b4
3315 11394 51b5
3316 11396 51b6
3317 11398 51b7
3318 11401 51b8
3319 11405 51ba
3320 11408 51bc
3321 11410 51bd
3322 11413 51be
3323 11415 51bf
3324 11419 51c2
3325 11421 51c3
3326 11423 51c4
3327 11426 51c5
3328 11428 51c6
3329 11432 51c8
3330 11434 51c9
3331 11436 51ca
3332 11439 51cb
3333 11442 51cc
3334 11445 51cd
3335 11447 51cf
3336 11452 51d1
3337 11454 51d2
3338 11456 51d3
3339 11458 51d4
3340 11461 51d5
3341 11463 51d6
3342 11466 51d8
3343 11470 51db
3344 11473 51dc
3345 11476 51dd
3346 11479 51de
3347 11482 51df
3348 11484 51e0
3349 11485 51e1
3350 11486 51e2
3351 11489 51e5
3352 11490 51e6
3353 11491 51e7
3354 11493 51e9
3355 11495 51ea
3356 11497 51ec
3357 11498 51ed
3358 11500 51ee
3359 11502 51f0
3360 11503 51f1
3361 11504 51f2
3362 11506 51f3
3363 11508 51f4
3364 11509 51f5
3365 11511 51f6
3366 11513 51f7
3367 11515 51f8
3368 11517 51f9
3369 11519 51fa
3370 11524 51fd
3371 11526 51fe
3372 11529 5200
3373 11530 5201
3374 11532 5202
3375 11533 5203
3376 11536 5204
3377 11537 5205
3378 11539 5206
3379 11542 5207
3380 11544 5208
3381 11546 520a
3382 11547 520b
3383 11550 520e
3384 11553 5211
3385 11554 5212
3386 11555 5213
3387 11557 5214
3388 11558 5215
3389 11559 5216
3390 11560 5217
3391 11563 5218
3392 11569 521d
3393 11576 5222
3394 11579 5224
3395 11581 5225
3396 11582 5226
3397 11584 5227
3398 11586 5228
3399 11587 5229
3400 11589 522a
3401 11590 522b
3402 11593 522e
3403 11595 5230
3404 11597 5231
3405 11600 5232
3406 11601 5233
3407 11604 5235
3408 11606 5236
3409 11607 5237
3410 11609 5238
3411 11611 5239
3412 11613 523a
3413 11615 523b
3414 11617 523c
3415 11628 5243
3416 11630 5244
3417 11631 5245
3418 11633 5247
3419 11635 5249
3420 11636 524a
3421 11638 524b
3422 11639 524c
3423 11640 524d
3424 11644 524f
3425 11650 5254
3426 11651 5255
3427 11653 5256
3428 11655 5257
3429 11656 5258
3430 11659 525a
3431 11660 525b
3432 11662 525c
3433 11665 525d
3434 11667 525e
3435 11668 525f
3436 11669 5260
3437 11671 5261
3438 11675 5263
3439 11677 5264
3440 11679 5265
3441 11680 5266
3442 11685 5269
3443 11687 526a
3444 11691 526c
3445 11694 526e
3446 11696 526f
3447 11697 5270
3448 11698 5271
3449 11700 5272
3450 11704 5273
3451 11707 5274
3452 11708 5275
3453 11712 5277
3454 11715 5278
3455 11716 5279
3456 11723 527d
3457 11726 527f
3458 11727 5280
3459 11730 5282
3460 11732 5283
3461 11733 5284
3462 11736 5285
3463 11738 5287
3464 11741 5288
3465 11743 5289
3466 11745 528a
3467 11749 528c
3468 11750 528d
3469 11756 5291
3470 11758 5292
3471 11760 5293
3472 11761 5294
3473 11763 5295
3474 11765 5296
3475 11768 5297
3476 11771 5298
3477 11776 529a
3478 11778 529b
3479 11779 529c
3480 11782 529f
3481 11783 52a0
3482 11787 52a3
3483 11789 52a4
3484 11791 52a5
3485 11793 52a6
3486 11794 52a7
3487 11796 52a9
3488 11797 52aa
3489 11800 52ab
3490 11802 52ac
3491 11803 52ad
3492 11805 52af
3493 11806 52b0
3494 11808 52b1
3495 11812 52b4
3496 11813 52b5
3497 11815 52b6
3498 11817 52b7
3499 11819 52b8
3500 11820 52b9
3501 11822 52ba
3502 11824 52bb
3503 11826 52bc
3504 11827 52bd
3505 11829 52be
3506 11832 52c0
3507 11834 52c1
3508 11836 52c3
3509 11838 52c4
3510 11840 52c5
3511 11841 52c6
3512 11843 52c7
3513 11846 52c8
3514 11848 52c9
3515 11850 52ca
3516 11852 52cc
3517 11855 52cd
3518 11858 52cf
3519 11860 52d0
3520 11862 52d1
3521 11863 52d2
3522 11866 52d4
3523 11867 52d5
3524 11868 52d6
3525 11869 52d7
3526 11870 52d8
3527 11873 52d9
3528 11876 52db
3529 11877 52dc
3530 11879 52dd
3531 11881 52de
3532 11883 52df
3533 11885 52e0
3534 11888 52e1
3535 11890 52e2
3536 11893 52e3
3537 11894 52e4
3538 11896 52e5
3539 11898 52e6
3540 11899 52e7
3541 11901 52e8
3542 11903 52e9
3543 11904 52ea
3544 11906 52ec
3545 11911 52f0
3546 11913 52f1
3547 11915 52f2
3548 11916 52f3
3549 11918 52f4
3550 11920 52f5
3551 11922 52f6
3552 11924 52f7
3553 11926 52f8
3554 11929 52f9
3555 11930 52fa
3556 11931 52fb
3557 11935 52fe
3558 11937 52ff
3559 11938 5300
3560 11940 5301
3561 11942 5302
3562 11943 5303
3563 11946 5305
3564 11948 5306
3565 11950 5307
3566 11952 5308
3567 11955 530a
3568 11957 530b
3569 11959 530c
3570 11961 530d
3571 11964 530f
3572 11966 5310
3573 11967 5311
3574 11972 5313
3575 11975 5315
3576 11977 5316
3577 11980 5317
3578 11982 5318
3579 11984 5319
3580 11986 531a
3581 11988 531b
3582 11990 531c
3583 11993 531d
3584 11995 531e
3585 11997 531f
3586 11999 5320
3587 12001 5321
3588 12004 5323
3589 12006 5324
3590 12008 5325
3591 12011 5327
3592 12013 5328
3593 12015 5329
3594 12017 532a
3595 12020 532b
3596 12022 532c
3597 12025 532d
3598 12028 532f
3599 12030 5330
3600 12032 5331
3601 12034 5332
3602 12036 5333
3603 12040 5335
3604 12045 5338
3605 12047 5339
3606 12050 533a
3607 12052 533b
3608 12055 533c
3609 12058 533d
3610 12061 533e
3611 12065 533f
3612 12068 5340
3613 12071 5341
3614 12072 5342
3615 12074 5343
3616 12076 5345
3617 12077 5346
3618 12078 5347
3619 12079 5348
3620 12080 5349
3621 12081 534a
3622 12082 534b
3623 12083 534c
3624 12085 534d
3625 12090 5351
3626 12092 5352
3627 12094 5353
3628 12095 5354
3629 12098 5357
3630 12099 5358
3631 12100 5359
3632 12102 535a
3633 12105 535b
3634 12107 535c
3635 12109 535e
3636 12113 5360
3637 12114 5361
3638 12117 5363
3639 12118 5364
3640 12119 5365
3641 12121 5366
3642 12123 5367
3643 12127 5369
3644 12130 536c
3645 12132 536d
3646 12133 536e
3647 12135 536f
3648 12137 5370
3649 12140 5371
3650 12142 5372
3651 12143 5373
3652 12145 5374
3653 12147 5375
3654 12150 5377
3655 12152 5378
3656 12154 5379
3657 12155 537a
3658 12157 537b
3659 12162 537d
3660 12164 537e
3661 12166 537f
3662 12170 5382
3663 12171 5383
3664 12172 5384
3665 12175 5387
3666 12176 5388
3667 12177 5389
3668 12182 538e
3669 12189 5393
3670 12191 5394
3671 12194 5396
3672 12198 5398
3673 12199 5399
3674 12200 539a
3675 12205 539d
3676 12209 539f
3677 12211 53a0
3678 12212 53a1
3679 12215 53a4
3680 12216 53a5
3681 12218 53a6
3682 12221 53a8
3683 12223 53a9
3684 12225 53aa
3685 12226 53ab
3686 12231 53ad
3687 12233 53ae
3688 12235 53af
3689 12236 53b0
3690 12239 53b2
3691 12241 53b3
3692 12243 53b4
3693 12245 53b5
3694 12246 53b6
3695 12248 53b7
3696 12250 53b8
3697 12254 53ba
3698 12256 53bb
3699 12259 53bd
3700 12263 53c0
3701 12265 53c1
3702 12267 53c2
3703 12269 53c3
3704 12271 53c4
3705 12273 53c5
3706 12277 53c8
3707 12279 53c9
3708 12281 53ca
3709 12284 53cb
3710 12285 53cc
3711 12286 53cd
3712 12288 53ce
3713 12290 53cf
3714 12293 53d2
3715 12295 53d3
3716 12296 53d4
3717 12297 53d5
3718 12298 53d6
3719 12300 53d7
3720 12302 53d9
3721 12304 53da
3722 12305 53db
3723 12309 53dd
3724 12311 53de
3725 12312 53df
3726 12315 53e0
3727 12317 53e1
3728 12319 53e2
3729 12321 53e3
3730 12322 53e4
3731 12323 53e5
3732 12324 53e6
3733 12326 53e7
3734 12327 53e8
3735 12328 53e9
3736 12330 53ea
3737 12332 53eb
3738 12334 53ec
3739 12335 53ed
3740 12338 53ee
3741 12339 53ef
3742 12340 53f0
3743 12342 53f1
3744 12343 53f2
3745 12344 53f3
3746 12345 53f4
3747 12346 53f5
3748 12348 53f6
3749 12350 53f7
3750 12352 53f8
3751 12354 53fa
3752 12364 5401
3753 12365 5402
3754 12367 5403
3755 12368 5404
3756 12373 5408
3757 12375 5409
3758 12376 540a
3759 12377 540b
3760 12378 540c
3761 12379 540d
3762 12382 540e
3763 12384 540f
3764 12385 5410
3765 12386 5411
3766 12387 5412
3767 12389 5413
3768 12399 541a
3769 12400 541b
3770 12403 541d
3771 12405 541e
3772 12406 541f
3773 12409 5420
3774 12411 5421
3775 12417 5424
3776 12420 5426
3777 12421 5427
3778 12422 5428
3779 12424 5429
3780 12427 542a
3781 12429 542b
3782 12432 542c
3783 12434 542d
3784 12436 542e
3785 12438 542f
3786 12442 5431
3787 12445 5433
3788 12448 5434
3789 12449 5435
3790 12451 5436
3791 12455 5438
3792 12457 5439
3793 12460 543b
3794 12461 543c
3795 12463 543d
3796 12464 543e
3797 12465 543f
3798 12467 5440
3799 12473 5442
3800 12474 5443
3801 12475 5444
3802 12478 5446
3803 12480 5447
3804 12481 5448
3805 12485 5449
3806 12487 544a
3807 12489 544c
3808 12490 544d
3809 12492 544e
3810 12493 544f
3811 12495 5451
3812 12499 5455
3813 12510 545e
3814 12511 545f
3815 12515 5462
3816 12518 5464
3817 12522 5466
3818 12524 5467
3819 12527 5468
3820 12529 5469
3821 12531 546a
3822 12532 546b
3823 12533 546c
3824 12534 546d
3825 12536 546e
3826 12539 5470
3827 12541 5471
3828 12546 5473
3829 12547 5474
3830 12548 5475
3831 12549 5476
3832 12552 5477
3833 12557 547b
3834 12558 547c
3835 12559 547d
3836 12562 547f
3837 12564 5480
3838 12565 5481
3839 12568 5483
3840 12569 5484
3841 12571 5485
3842 12573 5486
3843 12575 5488
3844 12577 5489
3845 12578 548a
3846 12579 548b
3847 12580 548c
3848 12581 548d
3849 12583 548e
3850 12586 548f
3851 12587 5490
3852 12588 5491
3853 12589 5492
3854 12594 5495
3855 12595 5496
3856 12601 549c
3857 12605 549f
3858 12606 54a0
3859 12608 54a1
3860 12610 54a2
3861 12614 54a4
3862 12616 54a5
3863 12618 54a6
3864 12620 54a7
3865 12623 54a8
3866 12626 54a9
3867 12628 54aa
3868 12630 54ab
3869 12631 54ac
3870 12633 54ad
3871 12634 54ae
3872 12635 54af
3873 12638 54b1
3874 12639 54b2
3875 12641 54b3
3876 12647 54b7
3877 12648 54b8
3878 12649 54b9
3879 12652 54ba
3880 12653 54bb
3881 12654 54bc
3882 12656 54bd
3883 12658 54be
3884 12660 54bf
3885 12661 54c0
3886 12663 54c1
3887 12664 54c2
3888 12665 54c3
3889 12666 54c4
3890 12668 54c6
3891 12671 54c7
3892 12672 54c8
3893 12674 54c9
3894 12675 54ca
3895 12679 54cd
3896 12680 54ce
3897 12691 54d8
3898 12700 54e0
3899 12702 54e1
3900 12703 54e2
3901 12708 54e5
3902 12710 54e6
3903 12712 54e8
3904 12715 54e9
3905 12716 54ea
3906 12719 54ec
3907 12720 54ed
3908 12721 54ee
3909 12724 54ef
3910 12726 54f1
3911 12728 54f2
3912 12730 54f3
3913 12734 54f6
3914 12740 54fa
3915 12742 54fc
3916 12744 54fd
3917 12745 54fe
3918 12747 54ff
3919 12748 5500
3920 12750 5501
3921 12755 5504
3922 12756 5505
3923 12759 5506
3924 12762 5507
3925 12765 5508
3926 12766 5509
3927 12771 550c
3928 12774 550d
3929 12776 550e
3930 12777 550f
3931 12778 5510
3932 12784 5514
3933 12785 5515
3934 12786 5516
3935 12806 5527
3936 12810 552a
3937 12812 552b
3938 12817 552e
3939 12819 552f
3940 12822 5531
3941 12823 5532
3942 12825 5533
3943 12830 5535
3944 12832 5536
3945 12835 5538
3946 12838 5539
3947 12841 553b
3948 12842 553c
3949 12845 553d
3950 12847 553e
3951 12851 5540
3952 12853 5541
3953 12860 5544
3954 12863 5545
3955 12864 5546
3956 12867 5547
3957 12870 5549
3958 12871 554a
3959 12874 554c
3960 12876 554d
3961 12879 554f
3962 12880 5550
3963 12882 5551
3964 12884 5553
3965 12890 5556
3966 12893 5557
3967 12895 5558
3968 12898 555a
3969 12900 555b
3970 12902 555c
3971 12904 555d
3972 12906 555e
3973 12909 5560
3974 12911 5561
3975 12916 5563
3976 12918 5564
3977 12922 5566
3978 12944 557b
3979 12946 557c
3980 12948 557d
3981 12950 557e
3982 12952 557f
3983 12955 5580
3984 12957 5581
3985 12959 5582
3986 12961 5583
3987 12963 5584
3988 12967 5586
3989 12968 5587
3990 12969 5588
3991 12972 5589
3992 12974 558a
3993 12975 558b
3994 12981 558e
3995 12983 558f
3996 12987 5591
3997 12989 5592
3998 12992 5593
3999 12996 5594
4000 13000 5597
4001 13001 5598
4002 13002 5599
4003 13004 559a
4004 13008 559c
4005 13009 559d
4006 13012 559e
4007 13014 559f
4008 13020 55a3
4009 13021 55a4
4010 13024 55a7
4011 13026 55a8
4012 13029 55a9
4013 13032 55aa
4014 13034 55ab
4015 13037 55ac
4016 13039 55ad
4017 13042 55ae
4018 13044 55b0
4019 13048 55b2
4020 13056 55b6
4021 13069 55bf
4022 13072 55c1
4023 13077 55c3
4024 13079 55c4
4025 13081 55c5
4026 13083 55c6
4027 13086 55c7
4028 13088 55c9
4029 13091 55cb
4030 13093 55cc
4031 13096 55ce
4032 13101 55d1
4033 13103 55d2
4034 13106 55d3
4035 13108 55d4
4036 13114 55d7
4037 13117 55d8
4038 13121 55da
4039 13122 55db
4040 13124 55dc
4041 13126 55dd
4042 13128 55de
4043 13130 55df
4044 13136 55e2
4045 13138 55e3
4046 13139 55e4
4047 13149 55e9
4048 13153 55ec
4049 13156 55ee
4050 13159 55f1
4051 13167 55f6
4052 13170 55f7
4053 13173 55f8
4054 13175 55f9
4055 13182 55fd
4056 13184 55fe
4057 13187 55ff
4058 13198 5605
4059 13200 5606
4060 13203 5607
4061 13205 5608
4062 13206 5609
4063 13208 560a
4064 13213 560d
4065 13216 560e
4066 13218 560f
4067 13219 5610
4068 13222 5611
4069 13224 5612
4070 13228 5614
4071 13232 5616
4072 13233 5617
4073 13235 5618
4074 13236 5619
4075 13239 561b
4076 13249 5620
4077 13258 5628
4078 13259 5629
4079 13263 562c
4080 13270 562f
4081 13271 5630
4082 13274 5631
4083 13275 5632
4084 13277 5633
4085 13278 5634
4086 13281 5635
4087 13282 5636
4088 13284 5637
4089 13286 5638
4090 13288 5639
4091 13290 563b
4092 13291 563c
4093 13292 563d
4094 13294 563f
4095 13295 5640
4096 13297 5641
4097 13299 5642
4098 13302 5643
4099 13304 5644
4100 13308 5646
4101 13311 5647
4102 13314 5649
4103 13318 564b
4104 13320 564c
4105 13322 564d
4106 13324 564e
4107 13326 564f
4108 13329 5650
4109 13333 5653
4110 13335 5654
4111 13347 565b
4112 13351 565e
4113 13354 5660
4114 13357 5661
4115 13360 5662
4116 13363 5663
4117 13364 5664
4118 13369 5666
4119 13371 5668
4120 13373 5669
4121 13374 566a
4122 13376 566b
4123 13378 566c
4124 13380 566d
4125 13383 566f
4126 13386 5671
4127 13389 5672
4128 13393 5674
4129 13394 5675
4130 13396 5676
4131 13400 5678
4132 13403 567a
4133 13413 5680
4134 13421 5684
4135 13424 5685
4136 13426 5686
4137 13429 5687
4138 13430 5688
4139 13433 568a
4140 13434 568b
4141 13435 568c
4142 13440 568f
4143 13448 5694
4144 13450 5695
4145 13455 5699
4146 13457 569a
4147 13460 569d
4148 13463 569e
4149 13464 569f
4150 13466 56a0
4151 13469 56a2
4152 13474 56a5
4153 13476 56a6
4154 13478 56a7
4155 13480 56a8
4156 13483 56a9
4157 13486 56ab
4158 13489 56ac
4159 13491 56ad
4160 13494 56ae
4161 13499 56b1
4162 13501 56b2
4163 13503 56b3
4164 13506 56b4
4165 13510 56b6
4166 13513 56b7
4167 13520 56bc
4168 13524 56be
4169 13529 56c0
4170 13530 56c1
4171 13533 56c2
4172 13534 56c3
4173 13538 56c5
4174 13543 56c8
4175 13546 56c9
4176 13548 56ca
4177 13550 56cb
4178 13552 56cc
4179 13554 56cd
4180 13556 56ce
4181 13558 56cf
4182 13560 56d0
4183 13562 56d1
4184 13565 56d3
4185 13573 56d7
4186 13574 56d8
4187 13575 56d9
4188 13576 56da
4189 13578 56db
4190 13580 56dc
4191 13582 56dd
4192 13584 56de
4193 13585 56df
4194 13587 56e0
4195 13589 56e1
4196 13594 56e3
4197 13595 56e4
4198 13597 56e5
4199 13599 56e6
4200 13601 56e7
4201 13604 56e8
4202 13607 56eb
4203 13609 56ed
4204 13610 56ee
4205 13613 56f0
4206 13615 56f1
4207 13618 56f2
4208 13619 56f3
4209 13623 56f6
4210 13625 56f7
4211 13628 56f9
4212 13631 56fa
4213 13634 56fd
4214 13636 56ff
4215 13638 5700
4216 13641 5701
4217 13643 5702
4218 13645 5703
4219 13646 5704
4220 13649 5707
4221 13652 5708
4222 13655 5709
4223 13657 570a
4224 13660 570b
4225 13661 570c
4226 13662 570d
4227 13666 570f
4228 13669 5711
4229 13670 5712
4230 13673 5713
4231 13675 5715
4232 13676 5716
4233 13680 5718
4234 13682 571a
4235 13683 571b
4236 13685 571c
4237 13687 571d
4238 13692 571f
4239 13693 5720
4240 13694 5721
4241 13695 5722
4242 13696 5723
4243 13698 5724
4244 13700 5725
4245 13701 5726
4246 13703 5727
4247 13704 5728
4248 13705 5729
4249 13706 572a
4250 13708 572c
4251 13710 572d
4252 13711 572e
4253 13712 572f
4254 13713 5730
4255 13717 5733
4256 13718 5734
4257 13722 5737
4258 13723 5738
4259 13727 573b
4260 13730 573d
4261 13731 573e
4262 13733 573f
4263 13735 5740
4264 13737 5742
4265 13741 5745
4266 13744 5746
4267 13745 5747
4268 13750 574a
4269 13754 574c
4270 13757 574d
4271 13758 574e
4272 13760 574f
4273 13762 5750
4274 13763 5751
4275 13765 5752
4276 13774 5759
4277 13780 575f
4278 13783 5761
4279 13784 5762
4280 13787 5764
4281 13788 5765
4282 13789 5766
4283 13791 5767
4284 13792 5768
4285 13794 5769
4286 13795 576a
4287 13796 576b
4288 13798 576d
4289 13800 576e
4290 13802 576f
4291 13804 5770
4292 13805 5771
4293 13808 5773
4294 13810 5774
4295 13813 5775
4296 13816 5777
4297 13818 5779
4298 13820 577a
4299 13822 577b
4300 13825 577c
4301 13830 577e
4302 13832 577f
4303 13834 5781
4304 13835 5782
4305 13838 5783
4306 13844 5788
4307 13845 5789
4308 13847 578b
4309 13848 578c
4310 13857 5793
4311 13859 5794
4312 13862 5795
4313 13865 5797
4314 13867 5799
4315 13868 579a
4316 13871 579c
4317 13874 579d
4318 13875 579e
4319 13878 579f
4320 13879 57a0
4321 13881 57a1
4322 13882 57a2
4323 13884 57a3
4324 13886 57a4
4325 13891 57a7
4326 13892 57a8
4327 13894 57a9
4328 13895 57aa
4329 13897 57ac
4330 13899 57ae
4331 13902 57b0
4332 13905 57b3
4333 13912 57b8
4334 13920 57bd
4335 13924 57c0
4336 13928 57c3
4337 13933 57c6
4338 13935 57c7
4339 13936 57c8
4340 13941 57cb
4341 13942 57cc
4342 13945 57ce
4343 13946 57cf
4344 13953 57d2
4345 13955 57d3
4346 13957 57d4
4347 13958 57d5
4348 13960 57d6
4349 13962 57d7
4350 13968 57dc
4351 13969 57dd
4352 13972 57de
4353 13974 57df
4354 13975 57e0
4355 13976 57e1
4356 13978 57e3
4357 13980 57e4
4358 13984 57e6
4359 13987 57e7
4360 13990 57e9
4361 13996 57ed
4362 14003 57f0
4363 14009 57f4
4364 14011 57f5
4365 14014 57f6
4366 14017 57f7
4367 14019 57f8
4368 14021 57f9
4369 14023 57fa
4370 14024 57fb
4371 14026 57fc
4372 14027 57fd
4373 14029 57fe
4374 14032 57ff
4375 14033 5800
4376 14036 5802
4377 14037 5803
4378 14039 5804
4379 14041 5805
4380 14043 5806
4381 14046 5808
4382 14048 5809
4383 14051 580a
4384 14052 580b
4385 14053 580c
4386 14054 580d
4387 14065 5815
4388 14070 5819
4389 14073 581b
4390 14075 581d
4391 14077 581e
4392 14079 581f
4393 14081 5820
4394 14083 5821
4395 14089 5824
4396 14091 5826
4397 14094 5827
4398 14100 582a
4399 14106 582d
4400 14108 582f
4401 14109 5830
4402 14112 5831
4403 14114 5832
4404 14117 5834
4405 14118 5835
4406 14125 5839
4407 14126 583a
4408 14129 583d
4409 14132 583f
4410 14133 5840
4411 14135 5841
4412 14145 5849
4413 14148 584a
4414 14151 584b
4415 14153 584c
4416 14157 584d
4417 14160 584f
4418 14162 5850
4419 14164 5851
4420 14167 5852
4421 14171 5854
4422 14174 5855
4423 14178 5857
4424 14181 5858
4425 14183 5859
4426 14185 585a
4427 14192 585e
4428 14194 585f
4429 14198 5861
4430 14200 5862
4431 14203 5864
4432 14206 5867
4433 14208 5868
4434 14209 5869
4435 14212 586b
4436 14215 586d
4437 14219 5870
4438 14222 5872
4439 14226 5875
4440 14232 5878
4441 14234 5879
4442 14240 587c
4443 14242 587e
4444 14244 587f
4445 14247 5880
4446 14249 5881
4447 14254 5883
4448 14257 5885
4449 14260 5887
4450 14262 5888
4451 14265 5889
4452 14268 588a
4453 14270 588b
4454 14272 588c
4455 14274 588d
4456 14277 588f
4457 14280 5890
4458 14284 5893
4459 14286 5894
4460 14289 5896
4461 14291 5897
4462 14293 5898
4463 14298 589c
4464 14300 589d
4465 14301 589e
4466 14303 589f
4467 14306 58a0
4468 14307 58a1
4469 14309 58a2
4470 14315 58a6
4471 14318 58a8
4472 14320 58a9
4473 14322 58aa
4474 14324 58ab
4475 14329 58ae
4476 14334 58b1
4477 14336 58b2
4478 14337 58b3
4479 14344 58b8
4480 14346 58b9
4481 14347 58ba
4482 14350 58bb
4483 14351 58bc
4484 14354 58be
4485 14358 58c1
4486 14360 58c2
4487 14362 58c3
4488 14363 58c4
4489 14365 58c5
4490 14369 58c7
4491 14371 58c8
4492 14376 58ca
4493 14379 58cc
4494 14381 58cd
4495 14383 58ce
4496 14386 58d0
4497 14387 58d1
4498 14389 58d2
4499 14392 58d3
4500 14395 58d4
4501 14396 58d5
4502 14398 58d6
4503 14400 58d7
4504 14401 58d8
4505 14402 58d9
4506 14405 58da
4507 14408 58dc
4508 14411 58dd
4509 14414 58de
4510 14416 58df
4511 14419 58e0
4512 14422 58e1
4513 14424 58e2
4514 14428 58e4
4515 14430 58e5
4516 14435 58e9
4517 14438 58eb
4518 14439 58ec
4519 14442 58ee
4520 14444 58ef
4521 14446 58f0
4522 14447 58f1
4523 14448 58f2
4524 14449 58f3
4525 14451 58f4
4526 14454 58f7
4527 14456 58f9
4528 14457 58fa
4529 14458 58fb
4530 14460 58fc
4531 14461 58fd
4532 14467 5902
4533 14470 5905
4534 14472 5906
4535 14476 5909
4536 14478 590a
4537 14479 590b
4538 14481 590c
4539 14484 590d
4540 14489 590f
4541 14491 5910
4542 14494 5912
4543 14497 5913
4544 14499 5914
4545 14503 5915
4546 14505 5916
4547 14510 5918
4548 14512 5919
4549 14515 591a
4550 14518 591b
4551 14520 591c
4552 14522 591d
4553 14526 591f
4554 14530 5921
4555 14532 5922
4556 14535 5923
4557 14537 5924
4558 14540 5925
4559 14544 5927
4560 14545 5928
4561 14547 5929
4562 14549 592a
4563 14551 592b
4564 14552 592c
4565 14554 592d
4566 14555 592e
4567 14557 592f
4568 14558 5930
4569 14559 5931
4570 14560 5932
4571 14561 5933
4572 14563 5935
4573 14564 5936
4574 14566 5937
4575 14568 5938
4576 14570 5939
4577 14574 593d
4578 14576 593e
4579 14577 593f
4580 14581 5943
4581 14583 5944
4582 14586 5946
4583 14588 5947
4584 14589 5948
4585 14591 5949
4586 14598 594e
4587 14600 594f
4588 14602 5950
4589 14605 5951
4590 14608 5952
4591 14610 5953
4592 14613 5954
4593 14614 5955
4594 14618 5957
4595 14620 5958
4596 14622 5959
4597 14624 595a
4598 14627 595b
4599 14630 595d
4600 14632 595e
4601 14634 595f
4602 14636 5960
4603 14639 5961
4604 14640 5962
4605 14642 5963
4606 14644 5965
4607 14648 5967
4608 14650 5968
4609 14651 5969
4610 14653 596a
4611 14655 596b
4612 14657 596c
4613 14659 596d
4614 14660 596e
4615 14662 596f
4616 14667 5972
4617 14669 5973
4618 14672 5974
4619 14675 5975
4620 14678 5976
4621 14683 5978
4622 14686 5979
4623 14690 597b
4624 14693 597c
4625 14696 597d
4626 14705 5981
4627 14708 5982
4628 14711 5983
4629 14714 5984
4630 14724 598a
4631 14727 598b
4632 14729 598c
4633 14731 598d
4634 14734 598e
4635 14743 5992
4636 14746 5993
4637 14751 5995
4638 14753 5996
4639 14756 5997
4640 14761 5999
4641 14766 599b
4642 14769 599d
4643 14774 599f
4644 14783 59a3
4645 14786 59a4
4646 14789 59a5
4647 14794 59a7
4648 14797 59a8
4649 14803 59ac
4650 14806 59ad
4651 14808 59ae
4652 14811 59af
4653 14814 59b0
4654 14819 59b2
4655 14822 59b3
4656 14831 59b7
4657 14836 59b9
4658 14839 59ba
4659 14842 59bb
4660 14845 59bc
4661 14850 59be
4662 14857 59c1
4663 14861 59c3
4664 14864 59c4
4665 14869 59c6
4666 14874 59c8
4667 14877 59c9
4668 14880 59ca
4669 14883 59cb
4670 14888 59cd
4671 14895 59d0
4672 14898 59d1
4673 14901 59d2
4674 14904 59d3
4675 14907 59d4
4676 14916 59d9
4677 14919 59da
4678 14924 59dc
4679 14927 59dd
4680 14930 59de
4681 14933 59df
4682 14940 59e3
4683 14943 59e4
4684 14946 59e5
4685 14949 59e6
4686 14952 59e7
4687 14954 59e8
4688 14959 59ea
4689 14962 59eb
4690 14965 59ec
4691 14970 59ee
4692 14973 59ef
4693 14978 59f1
4694 14981 59f2
4695 14986 59f4
4696 14991 59f6
4697 14994 59f7
4698 14997 59f8
4699 15005 59fb
4700 15014 59ff
4701 15017 5a00
4702 15020 5a01
4703 15025 5a03
4704 15028 5a04
4705 15034 5a09
4706 15041 5a0c
4707 15044 5a0d
4708 15047 5a0e
4709 15052 5a11
4710 15055 5a12
4711 15058 5a13
4712 15066 5a17
4713 15069 5a18
4714 15075 5a1a
4715 15078 5a1b
4716 15081 5a1c
4717 15085 5a1e
4718 15088 5a1f
4719 15091 5a20
4720 15097 5a23
4721 15100 5a24
4722 15103 5a25
4723 15107 5a27
4724 15110 5a28
4725 15112 5a29
4726 15115 5a2a
4727 15122 5a2d
4728 15127 5a2f
4729 15129 5a30
4730 15136 5a35
4731 15140 5a36
4732 15151 5a3c
4733 15160 5a40
4734 15163 5a41
4735 15170 5a44
4736 15173 5a45
4737 15176 5a46
4738 15179 5a47
4739 15182 5a48
4740 15185 5a49
4741 15191 5a4c
4742 15198 5a50
4743 15209 5a55
4744 15220 5a5a
4745 15229 5a5e
4746 15238 5a62
4747 15241 5a63
4748 15246 5a65
4749 15249 5a66
4750 15252 5a67
4751 15259 5a6a
4752 15264 5a6c
4753 15267 5a6d
4754 15283 5a77
4755 15290 5a7a
4756 15293 5a7b
4757 15300 5a7e
4758 15303 5a7f
4759 15313 5a84
4760 15325 5a8b
4761 15336 5a90
4762 15341 5a92
4763 15344 5a93
4764 15352 5a96
4765 15358 5a99
4766 15361 5a9a
4767 15364 5a9b
4768 15367 5a9c
4769 15372 5a9e
4770 15375 5a9f
4771 15378 5aa0
4772 15383 5aa2
4773 15394 5aa7
4774 15404 5aac
4775 15414 5ab1
4776 15417 5ab2
4777 15420 5ab3
4778 15425 5ab5
4779 15432 5ab8
4780 15437 5aba
4781 15441 5abb
4782 15444 5abc
4783 15447 5abd
4784 15450 5abe
4785 15453 5abf
4786 15458 5ac1
4787 15461 5ac2
4788 15466 5ac4
4789 15470 5ac6
4790 15475 5ac8
4791 15478 5ac9
4792 15483 5acb
4793 15486 5acc
4794 15493 5acf
4795 15496 5ad0
4796 15506 5ad6
4797 15509 5ad7
4798 15517 5ada
4799 15523 5adc
4800 15532 5ae0
4801 15535 5ae1
4802 15541 5ae3
4803 15546 5ae5
4804 15549 5ae6
4805 15555 5ae9
4806 15558 5aea
4807 15569 5aee
4808 15574 5af0
4809 15584 5af5
4810 15587 5af6
4811 15596 5afa
4812 15599 5afb
4813 15603 5afd
4814 15610 5b00
4815 15612 5b01
4816 15626 5b08
4817 15629 5b09
4818 15633 5b0b
4819 15636 5b0c
4820 15656 5b16
4821 15659 5b17
4822 15663 5b19
4823 15668 5b1b
4824 15672 5b1d
4825 15681 5b21
4826 15684 5b22
4827 15690 5b25
4828 15701 5b2a
4829 15706 5b2c
4830 15709 5b2d
4831 15716 5b30
4832 15720 5b32
4833 15724 5b34
4834 15729 5b36
4835 15732 5b38
4836 15742 5b3e
4837 15748 5b40
4838 15751 5b41
4839 15755 5b43
4840 15760 5b45
4841 15772 5b4b
4842 15775 5b4c
4843 15784 5b50
4844 15786 5b51
4845 15788 5b52
4846 15791 5b54
4847 15793 5b55
4848 15795 5b56
4849 15797 5b57
4850 15799 5b58
4851 15802 5b5a
4852 15804 5b5b
4853 15806 5b5c
4854 15808 5b5d
4855 15811 5b5e
4856 15813 5b5f
4857 15820 5b63
4858 15823 5b64
4859 15826 5b65
4860 15829 5b66
4861 15832 5b68
4862 15834 5b69
4863 15837 5b6b
4864 15843 5b6e
4865 15846 5b6f
4866 15848 5b70
4867 15850 5b71
4868 15853 5b73
4869 15856 5b75
4870 15858 5b76
4871 15863 5b78
4872 15866 5b7a
4873 15871 5b7c
4874 15874 5b7d
4875 15877 5b7e
4876 15879 5b7f
4877 15881 5b80
4878 15883 5b81
4879 15885 5b82
4880 15887 5b83
4881 15889 5b84
4882 15891 5b85
4883 15894 5b86
4884 15896 5b87
4885 15898 5b88
4886 15900 5b89
4887 15903 5b8a
4888 15905 5b8b
4889 15907 5b8c
4890 15909 5b8d
4891 15911 5b8e
4892 15913 5b8f
4893 15915 5b90
4894 15918 5b91
4895 15921 5b93
4896 15923 5b94
4897 15925 5b95
4898 15927 5b96
4899 15929 5b97
4900 15932 5b98
4901 15934 5b99
4902 15936 5b9a
4903 15938 5b9b
4904 15941 5b9c
4905 15943 5b9d
4906 15947 5b9f
4907 15951 5ba2
4908 15953 5ba3
4909 15955 5ba4
4910 15957 5ba5
4911 15960 5ba6
4912 15963 5ba8
4913 15965 5ba9
4914 15970 5bac
4915 15973 5bad
4916 15975 5bae
4917 15977 5baf
4918 15979 5bb0
4919 15981 5bb1
4920 15983 5bb2
4921 15985 5bb3
4922 15988 5bb4
4923 15991 5bb5
4924 15994 5bb6
4925 15996 5bb7
4926 15998 5bb8
4927 16001 5bb9
4928 16003 5bba
4929 16006 5bbc
4930 16010 5bbf
4931 16012 5bc0
4932 16014 5bc1
4933 16016 5bc2
4934 16018 5bc3
4935 16020 5bc4
4936 16022 5bc5
4937 16024 5bc6
4938 16026 5bc7
4939 16029 5bc9
4940 16033 5bcc
4941 16035 5bcd
4942 16037 5bce
4943 16039 5bcf
4944 16041 5bd0
4945 16046 5bd2
4946 16048 5bd3
4947 16051 5bd4
4948 16054 5bd6
4949 16057 5bd7
4950 16059 5bd8
4951 16061 5bd9
4952 16064 5bda
4953 16066 5bdb
4954 16069 5bdd
4955 16071 5bde
4956 16074 5bdf
4957 16077 5be0
4958 16080 5be1
4959 16082 5be2
4960 16086 5be4
4961 16088 5be5
4962 16091 5be6
4963 16093 5be7
4964 16095 5be8
4965 16098 5be9
4966 16103 5beb
4967 16105 5bec
4968 16110 5bee
4969 16112 5bef
4970 16114 5bf0
4971 16116 5bf1
4972 16121 5bf3
4973 16124 5bf4
4974 16126 5bf5
4975 16129 5bf6
4976 16132 5bf8
4977 16135 5bfa
4978 16140 5bfd
4979 16142 5bfe
4980 16144 5bff
4981 16147 5c01
4982 16148 5c02
4983 16149 5c03
4984 16151 5c04
4985 16154 5c05
4986 16155 5c06
4987 16157 5c07
4988 16160 5c08
4989 16161 5c09
4990 16163 5c0a
4991 16165 5c0b
4992 16167 5c0c
4993 16168 5c0d
4994 16170 5c0e
4995 16173 5c0f
4996 16176 5c11
4997 16178 5c12
4998 16180 5c13
4999 16182 5c14
5000 16185 5c16
5001 16187 5c17
5002 16190 5c19
5003 16191 5c1a
5004 16195 5c1e
5005 16196 5c1f
5006 16198 5c20
5007 16202 5c22
5008 16203 5c23
5009 16205 5c24
5010 16207 5c26
5011 16210 5c28
5012 16212 5c29
5013 16213 5c2a
5014 16214 5c2b
5015 16215 5c2c
5016 16217 5c2d
5017 16218 5c2e
5018 16221 5c30
5019 16223 5c31
5020 16225 5c32
5021 16230 5c35
5022 16232 5c36
5023 16236 5c38
5024 16238 5c39
5025 16239 5c3a
5026 16240 5c3b
5027 16242 5c3c
5028 16244 5c3d
5029 16245 5c3e
5030 16246 5c3f
5031 16247 5c40
5032 16248 5c41
5033 16255 5c45
5034 16257 5c46
5035 16260 5c48
5036 16264 5c4a
5037 16266 5c4b
5038 16269 5c4d
5039 16272 5c4e
5040 16274 5c4f
5041 16276 5c50
5042 16277 5c51
5043 16281 5c53
5044 16284 5c55
5045 16289 5c59
5046 16290 5c5a
5047 16291 5c5b
5048 16293 5c5c
5049 16297 5c5e
5050 16299 5c5f
5051 16300 5c60
5052 16302 5c61
5053 16304 5c62
5054 16307 5c63
5055 16308 5c64
5056 16310 5c65
5057 16313 5c67
5058 16315 5c68
5059 16318 5c69
5060 16321 5c6c
5061 16323 5c6d
5062 16324 5c6e
5063 16326 5c6f
5064 16328 5c70
5065 16330 5c71
5066 16336 5c74
5067 16337 5c75
5068 16338 5c76
5069 16342 5c79
5070 16345 5c7a
5071 16348 5c7b
5072 16351 5c7c
5073 16354 5c7d
5074 16368 5c87
5075 16370 5c88
5076 16376 5c8a
5077 16380 5c8c
5078 16385 5c8f
5079 16388 5c90
5080 16391 5c91
5081 16394 5c92
5082 16399 5c94
5083 16411 5c9d
5084 16414 5c9f
5085 16417 5ca0
5086 16420 5ca1
5087 16422 5ca2
5088 16423 5ca3
5089 16431 5ca6
5090 16433 5ca7
5091 16434 5ca8
5092 16437 5ca9
5093 16438 5caa
5094 16440 5cab
5095 16443 5cac
5096 16446 5cad
5097 16455 5cb1
5098 16457 5cb2
5099 16459 5cb3
5100 16461 5cb4
5101 16463 5cb5
5102 16466 5cb6
5103 16469 5cb7
5104 16472 5cb8
5105 16474 5cba
5106 16477 5cbb
5107 16479 5cbc
5108 16482 5cbe
5109 16491 5cc5
5110 16495 5cc7
5111 16499 5cc9
5112 16502 5ccb
5113 16511 5cd0
5114 16515 5cd2
5115 16525 5cd7
5116 16530 5cd9
5117 16537 5cdd
5118 16541 5ce0
5119 16543 5ce1
5120 16550 5ce6
5121 16553 5ce8
5122 16556 5ce9
5123 16557 5cea
5124 16563 5ced
5125 16566 5cee
5126 16569 5cef
5127 16572 5cf0
5128 16575 5cf1
5129 16578 5cf2
5130 16580 5cf4
5131 16583 5cf5
5132 16586 5cf6
5133 16593 5cfa
5134 16595 5cfb
5135 16600 5cfd
5136 16607 5d01
5137 16613 5d06
5138 16616 5d07
5139 16622 5d0b
5140 16626 5d0d
5141 16629 5d0e
5142 16634 5d10
5143 16637 5d11
5144 16640 5d12
5145 16643 5d14
5146 16645 5d15
5147 16648 5d16
5148 16650 5d17
5149 16652 5d18
5150 16655 5d19
5151 16657 5d1a
5152 16660 5d1b
5153 16664 5d1d
5154 16669 5d1f
5155 16671 5d20
5156 16675 5d22
5157 16678 5d23
5158 16681 5d24
5159 16686 5d26
5160 16689 5d27
5161 16694 5d29
5162 16696 5d2b
5163 16705 5d31
5164 16710 5d34
5165 16720 5d39
5166 16728 5d3d
5167 16731 5d3f
5168 16738 5d42
5169 16739 5d43
5170 16746 5d46
5171 16748 5d47
5172 16750 5d48
5173 16755 5d4a
5174 16758 5d4b
5175 16761 5d4c
5176 16764 5d4e
5177 16768 5d50
5178 16770 5d51
5179 16773 5d52
5180 16775 5d53
5181 16778 5d55
5182 16785 5d59
5183 16789 5d5c
5184 16794 5d5f
5185 16796 5d60
5186 16798 5d61
5187 16800 5d62
5188 16805 5d64
5189 16814 5d69
5190 16816 5d6a
5191 16820 5d6c
5192 16823 5d6d
5193 16826 5d6f
5194 16829 5d70
5195 16837 5d73
5196 16842 5d76
5197 16847 5d79
5198 16850 5d7a
5199 16859 5d7e
5200 16861 5d7f
5201 16864 5d81
5202 16867 5d82
5203 16870 5d83
5204 16872 5d84
5205 16878 5d87
5206 16881 5d88
5207 16885 5d8a
5208 16887 5d8b
5209 16890 5d8c
5210 16896 5d90
5211 16898 5d92
5212 16901 5d93
5213 16904 5d94
5214 16906 5d95
5215 16910 5d97
5216 16914 5d99
5217 16918 5d9b
5218 16922 5d9d
5219 16927 5d9f
5220 16930 5da0
5221 16934 5da2
5222 16938 5da4
5223 16941 5da7
5224 16949 5dab
5225 16952 5dac
5226 16956 5dae
5227 16961 5db0
5228 16966 5db2
5229 16969 5db4
5230 16976 5db7
5231 16978 5db8
5232 16981 5db9
5233 16984 5dba
5234 16988 5dbc
5235 16991 5dbd
5236 17000 5dc3
5237 17007 5dc7
5238 17011 5dc9
5239 17015 5dcb
5240 17017 5dcc
5241 17019 5dcd
5242 17022 5dce
5243 17026 5dd0
5244 17028 5dd1
5245 17031 5dd2
5246 17033 5dd3
5247 17037 5dd6
5248 17039 5dd7
5249 17042 5dd8
5250 17045 5dd9
5251 17049 5ddb
5252 17051 5ddd
5253 17052 5dde
5254 17056 5de0
5255 17057 5de1
5256 17060 5de2
5257 17061 5de3
5258 17062 5de4
5259 17064 5de5
5260 17065 5de6
5261 17066 5de7
5262 17068 5de8
5263 17070 5de9
5264 17073 5deb
5265 17076 5dee
5266 17081 5df1
5267 17082 5df2
5268 17083 5df3
5269 17084 5df4
5270 17085 5df5
5271 17088 5df7
5272 17089 5df8
5273 17091 5df9
5274 17094 5dfb
5275 17097 5dfd
5276 17100 5dfe
5277 17101 5dff
5278 17102 5e00
5279 17104 5e02
5280 17106 5e03
5281 17109 5e06
5282 17110 5e07
5283 17116 5e0b
5284 17118 5e0c
5285 17119 5e0d
5286 17124 5e11
5287 17127 5e12
5288 17129 5e14
5289 17130 5e15
5290 17131 5e16
5291 17134 5e18
5292 17137 5e19
5293 17138 5e1a
5294 17140 5e1b
5295 17142 5e1d
5296 17145 5e1f
5297 17148 5e20
5298 17155 5e25
5299 17158 5e28
5300 17164 5e2b
5301 17166 5e2d
5302 17168 5e2e
5303 17170 5e2f
5304 17171 5e30
5305 17174 5e32
5306 17176 5e33
5307 17179 5e35
5308 17181 5e36
5309 17184 5e37
5310 17186 5e38
5311 17191 5e3d
5312 17193 5e3e
5313 17196 5e40
5314 17200 5e43
5315 17202 5e44
5316 17204 5e45
5317 17206 5e47
5318 17208 5e49
5319 17210 5e4b
5320 17213 5e4c
5321 17216 5e4e
5322 17219 5e50
5323 17221 5e51
5324 17224 5e54
5325 17226 5e55
5326 17229 5e56
5327 17230 5e57
5328 17231 5e58
5329 17235 5e5b
5330 17237 5e5c
5331 17240 5e5e
5332 17243 5e5f
5333 17247 5e61
5334 17249 5e62
5335 17251 5e63
5336 17253 5e64
5337 17259 5e68
5338 17263 5e6a
5339 17266 5e6b
5340 17267 5e6c
5341 17269 5e6d
5342 17271 5e6e
5343 17275 5e70
5344 17281 5e72
5345 17282 5e73
5346 17283 5e74
5347 17284 5e75
5348 17286 5e76
5349 17288 5e77
5350 17290 5e78
5351 17292 5e79
5352 17294 5e7a
5353 17296 5e7b
5354 17298 5e7c
5355 17300 5e7d
5356 17303 5e7e
5357 17306 5e7f
5358 17308 5e80
5359 17311 5e81
5360 17314 5e83
5361 17316 5e84
5362 17320 5e87
5363 17326 5e8a
5364 17328 5e8b
5365 17333 5e8e
5366 17335 5e8f
5367 17343 5e95
5368 17346 5e96
5369 17348 5e97
5370 17351 5e99
5371 17353 5e9a
5372 17357 5e9c
5373 17362 5ea0
5374 17365 5ea2
5375 17368 5ea4
5376 17371 5ea5
5377 17373 5ea6
5378 17375 5ea7
5379 17377 5ea8
5380 17381 5eaa
5381 17383 5eab
5382 17385 5eac
5383 17388 5ead
5384 17394 5eb1
5385 17398 5eb3
5386 17402 5eb5
5387 17405 5eb6
5388 17407 5eb7
5389 17410 5eb8
5390 17413 5eb9
5391 17418 5ebd
5392 17421 5ebe
5393 17423 5ebf
5394 17426 5ec1
5395 17428 5ec2
5396 17430 5ec3
5397 17434 5ec6
5398 17438 5ec8
5399 17441 5ec9
5400 17443 5eca
5401 17445 5ecb
5402 17448 5ecc
5403 17451 5ece
5404 17453 5ecf
5405 17455 5ed0
5406 17458 5ed1
5407 17460 5ed2
5408 17463 5ed3
5409 17465 5ed4
5410 17468 5ed5
5411 17471 5ed6
5412 17478 5ed9
5413 17480 5eda
5414 17482 5edb
5415 17485 5edc
5416 17487 5edd
5417 17489 5ede
5418 17491 5edf
5419 17493 5ee0
5420 17495 5ee1
5421 17498 5ee2
5422 17500 5ee3
5423 17504 5ee5
5424 17509 5ee8
5425 17511 5ee9
5426 17515 5eeb
5427 17517 5eec
5428 17524 5ef0
5429 17526 5ef1
5430 17530 5ef3
5431 17533 5ef4
5432 17536 5ef6
5433 17539 5ef7
5434 17541 5ef8
5435 17543 5ef9
5436 17545 5efa
5437 17547 5efb
5438 17549 5efc
5439 17551 5efd
5440 17553 5efe
5441 17554 5eff
5442 17555 5f00
5443 17556 5f01
5444 17558 5f02
5445 17560 5f03
5446 17562 5f04
5447 17565 5f06
5448 17567 5f07
5449 17569 5f08
5450 17572 5f09
5451 17574 5f0a
5452 17576 5f0b
5453 17577 5f0c
5454 17578 5f0d
5455 17580 5f0e
5456 17581 5f0f
5457 17582 5f10
5458 17583 5f11
5459 17587 5f13
5460 17589 5f14
5461 17591 5f15
5462 17593 5f16
5463 17595 5f17
5464 17597 5f18
5465 17599 5f19
5466 17603 5f1b
5467 17606 5f1c
5468 17608 5f1d
5469 17610 5f1e
5470 17612 5f1f
5471 17615 5f21
5472 17617 5f22
5473 17619 5f23
5474 17621 5f24
5475 17624 5f25
5476 17626 5f26
5477 17628 5f27
5478 17631 5f28
5479 17633 5f29
5480 17637 5f2b
5481 17639 5f2c
5482 17641 5f2d
5483 17643 5f2e
5484 17645 5f2f
5485 17647 5f30
5486 17650 5f31
5487 17654 5f34
5488 17656 5f35
5489 17658 5f36
5490 17660 5f37
5491 17662 5f38
5492 17665 5f3a
5493 17667 5f3b
5494 17669 5f3c
5495 17671 5f3d
5496 17673 5f3e
5497 17675 5f3f
5498 17677 5f40
5499 17679 5f41
5500 17684 5f44
5501 17687 5f45
5502 17691 5f47
5503 17693 5f48
5504 17697 5f4a
5505 17700 5f4c
5506 17702 5f4d
5507 17705 5f4e
5508 17708 5f50
5509 17710 5f51
5510 17714 5f53
5511 17715 5f54
5512 17719 5f56
5513 17721 5f57
5514 17724 5f58
5515 17727 5f59
5516 17730 5f5b
5517 17732 5f5c
5518 17734 5f5d
5519 17739 5f60
5520 17741 5f61
5521 17742 5f62
5522 17743 5f63
5523 17745 5f64
5524 17747 5f65
5525 17749 5f66
5526 17751 5f67
5527 17753 5f69
5528 17754 5f6a
5529 17757 5f6b
5530 17759 5f6c
5531 17760 5f6d
5532 17762 5f6f
5533 17764 5f70
5534 17766 5f71
5535 17768 5f72
5536 17771 5f73
5537 17772 5f74
5538 17773 5f75
5539 17776 5f77
5540 17778 5f78
5541 17781 5f79
5542 17783 5f7a
5543 17785 5f7c
5544 17786 5f7d
5545 17789 5f7e
5546 17792 5f7f
5547 17794 5f80
5548 17796 5f81
5549 17797 5f82
5550 17798 5f83
5551 17799 5f84
5552 17801 5f85
5553 17804 5f87
5554 17805 5f88
5555 17807 5f89
5556 17809 5f8a
5557 17810 5f8b
5558 17811 5f8c
5559 17814 5f8d
5560 17816 5f8f
5561 17818 5f90
5562 17820 5f91
5563 17821 5f92
5564 17822 5f93
5565 17825 5f96
5566 17828 5f97
5567 17829 5f98
5568 17832 5f99
5569 17836 5f9c
5570 17838 5f9d
5571 17840 5f9e
5572 17843 5fa0
5573 17844 5fa1
5574 17847 5fa2
5575 17849 5fa4
5576 17853 5fa7
5577 17856 5fa8
5578 17857 5fa9
5579 17859 5faa
5580 17862 5fab
5581 17864 5fac
5582 17866 5fad
5583 17869 5fae
5584 17872 5faf
5585 17875 5fb0
5586 17876 5fb1
5587 17879 5fb3
5588 17881 5fb4
5589 17882 5fb5
5590 17885 5fb7
5591 17887 5fb8
5592 17889 5fb9
5593 17894 5fbc
5594 17896 5fbd
5595 17904 5fc3
5596 17906 5fc4
5597 17907 5fc5
5598 17909 5fc7
5599 17910 5fc8
5600 17911 5fc9
5601 17913 5fcb
5602 17914 5fcc
5603 17916 5fcd
5604 17921 5fd0
5605 17922 5fd1
5606 17924 5fd2
5607 17926 5fd3
5608 17927 5fd4
5609 17929 5fd6
5610 17930 5fd7
5611 17932 5fd8
5612 17935 5fd9
5613 17940 5fdc
5614 17942 5fdd
5615 17944 5fde
5616 17949 5fe0
5617 17951 5fe1
5618 17952 5fe2
5619 17955 5fe4
5620 17961 5fe8
5621 17962 5fe9
5622 17964 5fea
5623 17967 5feb
5624 17969 5fec
5625 17970 5fed
5626 17973 5fee
5627 17974 5fef
5628 17976 5ff0
5629 17977 5ff1
5630 17979 5ff2
5631 17980 5ff3
5632 17984 5ff5
5633 17987 5ff6
5634 17990 5ff8
5635 17993 5ffa
5636 17995 5ffb
5637 17997 5ffc
5638 17999 5ffd
5639 18002 5fff
5640 18012 6007
5641 18016 600a
5642 18020 600d
5643 18021 600e
5644 18023 600f
5645 18025 6010
5646 18027 6012
5647 18030 6013
5648 18033 6014
5649 18034 6015
5650 18035 6016
5651 18036 6017
5652 18037 6018
5653 18038 6019
5654 18039 601a
5655 18040 601b
5656 18041 601c
5657 18044 601d
5658 18046 601f
5659 18048 6020
5660 18050 6021
5661 18052 6022
5662 18054 6024
5663 18056 6025
5664 18059 6026
5665 18061 6027
5666 18062 6028
5667 18065 6029
5668 18067 602a
5669 18068 602b
5670 18071 602d
5671 18073 602f
5672 18076 6031
5673 18079 6033
5674 18081 6035
5675 18089 603a
5676 18095 6040
5677 18098 6041
5678 18100 6042
5679 18102 6043
5680 18107 6046
5681 18108 6047
5682 18110 6048
5683 18112 6049
5684 18114 604a
5685 18115 604b
5686 18117 604c
5687 18119 604d
5688 18122 6050
5689 18125 6051
5690 18126 6052
5691 18128 6054
5692 18130 6055
5693 18133 6056
5694 18135 6057
5695 18138 6059
5696 18140 605a
5697 18144 605d
5698 18148 605f
5699 18150 6060
5700 18151 6061
5701 18153 6062
5702 18156 6063
5703 18159 6064
5704 18160 6065
5705 18163 6067
5706 18165 6068
5707 18167 6069
5708 18169 606a
5709 18171 606b
5710 18172 606c
5711 18174 606d
5712 18177 606f
5713 18179 6070
5714 18181 6071
5715 18187 6075
5716 18189 6077
5717 18196 607e
5718 18199 607f
5719 18201 6081
5720 18203 6082
5721 18205 6083
5722 18207 6084
5723 18210 6085
5724 18213 6086
5725 18217 6088
5726 18218 6089
5727 18220 608a
5728 18222 608b
5729 18224 608c
5730 18226 608d
5731 18227 608e
5732 18232 6091
5733 18233 6092
5734 18234 6093
5735 18235 6094
5736 18237 6095
5737 18238 6096
5738 18240 6097
5739 18241 6098
5740 18244 609a
5741 18245 609b
5742 18250 609d
5743 18251 609e
5744 18254 609f
5745 18255 60a0
5746 18259 60a2
5747 18261 60a3
5748 18263 60a4
5749 18266 60a5
5750 18268 60a6
5751 18270 60a7
5752 18271 60a8
5753 18274 60a9
5754 18276 60aa
5755 18283 60b0
5756 18286 60b1
5757 18288 60b2
5758 18291 60b3
5759 18293 60b4
5760 18295 60b5
5761 18297 60b6
5762 18298 60b7
5763 18301 60b8
5764 18306 60bb
5765 18308 60bc
5766 18309 60bd
5767 18312 60be
5768 18318 60c2
5769 18322 60c4
5770 18324 60c5
5771 18326 60c6
5772 18329 60c7
5773 18331 60c8
5774 18332 60c9
5775 18333 60ca
5776 18335 60cb
5777 18341 60ce
5778 18342 60cf
5779 18344 60d1
5780 18346 60d3
5781 18348 60d4
5782 18350 60d5
5783 18354 60d8
5784 18358 60d9
5785 18360 60da
5786 18362 60db
5787 18364 60dc
5788 18365 60dd
5789 18367 60de
5790 18369 60df
5791 18371 60e0
5792 18372 60e1
5793 18374 60e2
5794 18375 60e3
5795 18377 60e5
5796 18381 60e7
5797 18382 60e8
5798 18389 60ee
5799 18392 60f0
5800 18394 60f1
5801 18396 60f2
5802 18397 60f3
5803 18398 60f4
5804 18399 60f5
5805 18401 60f6
5806 18402 60f7
5807 18404 60f8
5808 18406 60f9
5809 18408 60fa
5810 18409 60fb
5811 18410 60fc
5812 18413 60fd
5813 18418 6100
5814 18420 6101
5815 18423 6102
5816 18425 6103
5817 18429 6106
5818 18430 6107
5819 18432 6108
5820 18435 6109
5821 18438 610a
5822 18440 610c
5823 18443 610d
5824 18446 610e
5825 18448 610f
5826 18450 6110
5827 18451 6111
5828 18452 6112
5829 18455 6113
5830 18456 6114
5831 18458 6115
5832 18460 6116
5833 18463 6117
5834 18465 6119
5835 18467 611a
5836 18469 611b
5837 18471 611c
5838 18475 611e
5839 18476 611f
5840 18479 6120
5841 18480 6121
5842 18481 6122
5843 18488 6127
5844 18491 6128
5845 18495 612a
5846 18496 612b
5847 18498 612c
5848 18504 6130
5849 18505 6131
5850 18510 6134
5851 18513 6135
5852 18515 6136
5853 18518 6137
5854 18521 6139
5855 18523 613a
5856 18526 613c
5857 18528 613d
5858 18530 613e
5859 18533 613f
5860 18538 6141
5861 18540 6142
5862 18542 6144
5863 18544 6145
5864 18547 6146
5865 18549 6147
5866 18552 6148
5867 18554 6149
5868 18556 614a
5869 18558 614b
5870 18561 614c
5871 18564 614d
5872 18565 614e
5873 18571 6153
5874 18575 6155
5875 18579 6158
5876 18581 6159
5877 18583 615a
5878 18588 615d
5879 18591 615e
5880 18593 615f
5881 18595 6160
5882 18599 6162
5883 18602 6163
5884 18604 6164
5885 18606 6165
5886 18611 6167
5887 18614 6168
5888 18621 616b
5889 18623 616c
5890 18625 616e
5891 18627 616f
5892 18628 6170
5893 18631 6171
5894 18632 6172
5895 18634 6173
5896 18636 6174
5897 18639 6175
5898 18642 6176
5899 18645 6177
5900 18648 6178
5901 18654 617b
5902 18656 617c
5903 18659 617d
5904 18660 617e
5905 18663 617f
5906 18664 6180
5907 18667 6181
5908 18670 6182
5909 18672 6183
5910 18674 6184
5911 18678 6187
5912 18682 618a
5913 18686 618b
5914 18691 618d
5915 18692 618e
5916 18695 6190
5917 18698 6191
5918 18699 6192
5919 18700 6193
5920 18702 6194
5921 18705 6196
5922 18708 6197
5923 18710 6198
5924 18711 6199
5925 18712 619a
5926 18714 619c
5927 18716 619d
5928 18720 619f
5929 18722 61a0
5930 18728 61a4
5931 18729 61a5
5932 18731 61a7
5933 18733 61a8
5934 18736 61a9
5935 18739 61aa
5936 18740 61ab
5937 18742 61ac
5938 18744 61ad
5939 18745 61ae
5940 18753 61b2
5941 18761 61b6
5942 18764 61b8
5943 18766 61b9
5944 18769 61ba
5945 18774 61bc
5946 18777 61be
5947 18781 61c0
5948 18783 61c1
5949 18785 61c2
5950 18787 61c3
5951 18792 61c6
5952 18794 61c7
5953 18797 61c8
5954 18799 61c9
5955 18801 61ca
5956 18804 61cb
5957 18806 61cc
5958 18809 61cd
5959 18812 61ce
5960 18813 61cf
5961 18815 61d0
5962 18822 61d5
5963 18832 61dc
5964 18834 61dd
5965 18835 61de
5966 18838 61df
5967 18840 61e1
5968 18842 61e2
5969 18845 61e3
5970 18848 61e5
5971 18850 61e6
5972 18852 61e7
5973 18854 61e8
5974 18856 61e9
5975 18861 61ec
5976 18863 61ed
5977 18868 61ef
5978 18873 61f2
5979 18877 61f4
5980 18878 61f5
5981 18880 61f6
5982 18882 61f7
5983 18884 61f8
5984 18888 61fa
5985 18891 61fc
5986 18893 61fd
5987 18896 61fe
5988 18899 61ff
5989 18902 6200
5990 18904 6201
5991 18907 6203
5992 18908 6204
5993 18912 6207
5994 18914 6208
5995 18915 6209
5996 18917 620a
5997 18919 620c
5998 18921 620d
5999 18922 620e
6000 18925 6210
6001 18926 6211
6002 18927 6212
6003 18928 6213
6004 18929 6214
6005 18930 6215
6006 18932 6216
6007 18936 621a
6008 18938 621b
6009 18939 621c
6010 18940 621d
6011 18941 621e
6012 18942 621f
6013 18943 6220
6014 18945 6221
6015 18948 6222
6016 18950 6223
6017 18956 6226
6018 18957 6227
6019 18961 6229
6020 18963 622a
6021 18965 622b
6022 18970 622e
6023 18973 622f
6024 18974 6230
6025 18975 6231
6026 18976 6232
6027 18978 6233
6028 18981 6234
6029 18984 6236
6030 18987 6238
6031 18988 6239
6032 18993 623b
6033 18996 623d
6034 18999 623e
6035 19002 623f
6036 19005 6240
6037 19007 6241
6038 19010 6242
6039 19013 6243
6040 19016 6244
6041 19019 6246
6042 19022 6247
6043 19025 6248
6044 19028 6249
6045 19035 624b
6046 19036 624c
6047 19037 624d
6048 19039 624e
6049 19041 6250
6050 19042 6251
6051 19044 6252
6052 19047 6253
6053 19048 6254
6054 19050 6255
6055 19052 6256
6056 19055 6258
6057 19057 625a
6058 19059 625b
6059 19060 625c
6060 19062 625e
6061 19065 6260
6062 19067 6261
6063 19070 6263
6064 19071 6264
6065 19077 6268
6066 19084 626d
6067 19086 626e
6068 19089 626f
6069 19092 6271
6070 19096 6273
6071 19100 6276
6072 19103 6279
6073 19106 627a
6074 19108 627b
6075 19110 627c
6076 19111 627d
6077 19114 627e
6078 19115 627f
6079 19118 6280
6080 19120 6282
6081 19121 6283
6082 19123 6284
6083 19125 6285
6084 19131 6289
6085 19134 628a
6086 19137 628d
6087 19138 628e
6088 19140 628f
6089 19141 6290
6090 19143 6291
6091 19145 6292
6092 19146 6293
6093 19149 6294
6094 19150 6295
6095 19152 6296
6096 19153 6297
6097 19155 6298
6098 19157 6299
6099 19160 629b
6100 19161 629c
6101 19163 629e
6102 19172 62a6
6103 19174 62a8
6104 19178 62ab
6105 19179 62ac
6106 19188 62b1
6107 19191 62b3
6108 19194 62b5
6109 19197 62b6
6110 19198 62b7
6111 19200 62b9
6112 19201 62ba
6113 19202 62bb
6114 19203 62bc
6115 19204 62bd
6116 19205 62be
6117 19207 62bf
6118 19211 62c2
6119 19214 62c4
6120 19216 62c5
6121 19217 62c6
6122 19220 62c7
6123 19222 62c8
6124 19223 62c9
6125 19225 62ca
6126 19227 62cc
6127 19229 62cd
6128 19230 62ce
6129 19233 62cf
6130 19236 62d0
6131 19238 62d1
6132 19239 62d2
6133 19242 62d3
6134 19243 62d4
6135 19245 62d5
6136 19247 62d6
6137 19249 62d7
6138 19251 62d8
6139 19252 62d9
6140 19254 62da
6141 19256 62db
6142 19257 62dc
6143 19259 62dd
6144 19263 62e0
6145 19265 62e1
6146 19275 62ea
6147 19277 62ec
6148 19278 62ed
6149 19279 62ee
6150 19280 62ef
6151 19284 62f1
6152 19285 62f2
6153 19286 62f3
6154 19288 62f4
6155 19291 62f5
6156 19293 62f6
6157 19296 62f7
6158 19304 62fc
6159 19305 62fd
6160 19306 62fe
6161 19308 62ff
6162 19311 6301
6163 19313 6302
6164 19314 6303
6165 19316 6304
6166 19319 6307
6167 19321 6308
6168 19324 6309
6169 19327 630a
6170 19328 630b
6171 19330 630c
6172 19331 630d
6173 19336 6310
6174 19339 6311
6175 19342 6313
6176 19347 6316
6177 19351 6318
6178 19353 6319
6179 19355 631b
6180 19360 631f
6181 19368 6327
6182 19370 6328
6183 19373 6329
6184 19376 632a
6185 19378 632b
6186 19380 632d
6187 19382 632f
6188 19387 6332
6189 19391 6335
6190 19392 6336
6191 19396 6339
6192 19397 633a
6193 19399 633b
6194 19402 633c
6195 19405 633d
6196 19406 633e
6197 19407 633f
6198 19409 6341
6199 19411 6342
6200 19413 6343
6201 19414 6344
6202 19417 6346
6203 19421 6349
6204 19422 634a
6205 19424 634b
6206 19426 634c
6207 19428 634d
6208 19429 634e
6209 19432 634f
6210 19433 6350
6211 19437 6352
6212 19438 6353
6213 19440 6354
6214 19442 6355
6215 19444 6357
6216 19446 6358
6217 19449 6359
6218 19451 635b
6219 19453 635c
6220 19462 6365
6221 19465 6366
6222 19467 6367
6223 19469 6368
6224 19471 6369
6225 19475 636b
6226 19476 636c
6227 19478 636d
6228 19480 636e
6229 19483 6371
6230 19485 6372
6231 19488 6374
6232 19490 6375
6233 19491 6376
6234 19494 6377
6235 19495 6378
6236 19499 637a
6237 19501 637b
6238 19504 637c
6239 19507 637d
6240 19510 637f
6241 19513 6380
6242 19516 6382
6243 19518 6383
6244 19520 6384
6245 19525 6387
6246 19527 6388
6247 19528 6389
6248 19529 638a
6249 19533 638c
6250 19536 638e
6251 19537 638f
6252 19539 6390
6253 19542 6392
6254 19545 6394
6255 19547 6395
6256 19549 6396
6257 19552 6398
6258 19554 6399
6259 19556 639a
6260 19558 639b
6261 19562 639e
6262 19564 639f
6263 19566 63a0
6264 19568 63a1
6265 19569 63a2
6266 19572 63a3
6267 19574 63a4
6268 19576 63a5
6269 19579 63a6
6270 19580 63a7
6271 19583 63a8
6272 19585 63a9
6273 19587 63aa
6274 19588 63ab
6275 19591 63ac
6276 19593 63ad
6277 19595 63ae
6278 19598 63af
6279 19603 63b2
6280 19605 63b4
6281 19606 63b5
6282 19613 63bb
6283 19615 63bd
6284 19617 63be
6285 19620 63c0
6286 19621 63c1
6287 19623 63c3
6288 19626 63c4
6289 19629 63c5
6290 19631 63c6
6291 19634 63c8
6292 19636 63c9
6293 19643 63ce
6294 19645 63cf
6295 19647 63d0
6296 19648 63d1
6297 19650 63d2
6298 19653 63d3
6299 19656 63d4
6300 19657 63d5
6301 19660 63d6
6302 19667 63da
6303 19668 63db
6304 19671 63dc
6305 19679 63e0
6306 19682 63e1
6307 19685 63e3
6308 19687 63e5
6309 19692 63e9
6310 19695 63ea
6311 19697 63eb
6312 19699 63ec
6313 19701 63ed
6314 19704 63ee
6315 19709 63f2
6316 19711 63f3
6317 19714 63f4
6318 19715 63f5
6319 19717 63f6
6320 19719 63f7
6321 19721 63f8
6322 19724 63f9
6323 19726 63fa
6324 19740 6406
6325 19744 6409
6326 19746 640a
6327 19750 640d
6328 19753 640f
6329 19755 6410
6330 19758 6412
6331 19760 6413
6332 19762 6414
6333 19766 6416
6334 19769 6417
6335 19771 6418
6336 19777 641c
6337 19781 641e
6338 19784 6420
6339 19788 6422
6340 19793 6424
6341 19795 6425
6342 19798 6426
6343 19802 6428
6344 19805 6429
6345 19807 642a
6346 19812 642c
6347 19815 642d
6348 19820 642f
6349 19822 6430
6350 19830 6434
6351 19832 6435
6352 19833 6436
6353 19839 643a
6354 19843 643d
6355 19846 643e
6356 19849 643f
6357 19855 6442
6358 19864 644b
6359 19869 644e
6360 19872 644f
6361 19875 6451
6362 19877 6452
6363 19879 6453
6364 19882 6454
6365 19887 6458
6366 19891 645a
6367 19892 645b
6368 19895 645c
6369 19897 645d
6370 19902 645f
6371 19905 6460
6372 19908 6461
6373 19912 6463
6374 19917 6467
6375 19920 6469
6376 19926 646d
6377 19930 646f
6378 19937 6473
6379 19940 6474
6380 19945 6476
6381 19947 6478
6382 19949 6479
6383 19951 647a
6384 19954 647b
6385 19957 647d
6386 19964 6483
6387 19967 6485
6388 19970 6487
6389 19972 6488
6390 19980 648f
6391 19982 6490
6392 19986 6491
6393 19987 6492
6394 19989 6493
6395 19991 6495
6396 19997 6498
6397 20000 6499
6398 20003 649a
6399 20006 649b
6400 20009 649d
6401 20012 649e
6402 20014 649f
6403 20016 64a1
6404 20019 64a3
6405 20020 64a4
6406 20023 64a5
6407 20025 64a6
6408 20028 64a8
6409 20030 64a9
6410 20032 64ab
6411 20034 64ac
6412 20036 64ad
6413 20038 64ae
6414 20042 64b0
6415 20046 64b2
6416 20048 64b3
6417 20056 64b9
6418 20058 64bb
6419 20061 64bc
6420 20064 64bd
6421 20066 64be
6422 20069 64bf
6423 20072 64c1
6424 20074 64c2
6425 20078 64c4
6426 20081 64c5
6427 20084 64c7
6428 20087 64c9
6429 20088 64ca
6430 20090 64cb
6431 20091 64cc
6432 20092 64cd
6433 20094 64ce
6434 20098 64d0
6435 20100 64d1
6436 20102 64d2
6437 20106 64d4
6438 20109 64d5
6439 20113 64d7
6440 20115 64d8
6441 20119 64da
6442 20128 64e0
6443 20130 64e1
6444 20132 64e2
6445 20135 64e3
6446 20136 64e4
6447 20137 64e5
6448 20140 64e6
6449 20143 64e7
6450 20148 64e9
6451 20150 64ea
6452 20155 64ec
6453 20157 64ed
6454 20161 64ef
6455 20163 64f0
6456 20165 64f1
6457 20167 64f2
6458 20171 64f4
6459 20174 64f5
6460 20176 64f6
6461 20177 64f7
6462 20181 64fa
6463 20184 64fb
6464 20188 64fd
6465 20191 64fe
6466 20193 64ff
6467 20196 6500
6468 20198 6501
6469 20204 6504
6470 20207 6505
6471 20213 6508
6472 20215 6509
6473 20218 650a
6474 20226 650f
6475 20234 6513
6476 20236 6514
6477 20239 6516
6478 20244 6518
6479 20246 6519
6480 20250 651b
6481 20253 651c
6482 20256 651d
6483 20259 651e
6484 20261 651f
6485 20268 6522
6486 20270 6523
6487 20272 6524
6488 20276 6526
6489 20281 6529
6490 20282 652a
6491 20284 652b
6492 20286 652c
6493 20290 652e
6494 20292 652f
6495 20295 6531
6496 20297 6532
6497 20300 6534
6498 20302 6535
6499 20303 6536
6500 20305 6537
6501 20307 6538
6502 20309 6539
6503 20311 653a
6504 20313 653b
6505 20314 653c
6506 20315 653d
6507 20317 653e
6508 20319 653f
6509 20323 6543
6510 20325 6544
6511 20326 6545
6512 20328 6547
6513 20329 6548
6514 20331 6549
6515 20336 654d
6516 20338 654e
6517 20340 654f
6518 20342 6550
6519 20344 6551
6520 20346 6552
6521 20348 6554
6522 20349 6555
6523 20350 6556
6524 20353 6557
6525 20354 6558
6526 20356 6559
6527 20363 655d
6528 20365 655e
6529 20367 655f
6530 20368 6560
6531 20370 6562
6532 20372 6563
6533 20377 6566
6534 20379 6567
6535 20383 656b
6536 20385 656c
6537 20391 6570
6538 20394 6572
6539 20397 6574
6540 20399 6575
6541 20402 6577
6542 20406 6578
6543 20411 657a
6544 20416 657d
6545 20420 6581
6546 20423 6582
6547 20425 6583
6548 20428 6584
6549 20430 6585
6550 20433 6587
6551 20435 6588
6552 20437 6589
6553 20439 658a
6554 20442 658c
6555 20445 658e
6556 20448 6590
6557 20451 6591
6558 20453 6592
6559 20458 6595
6560 20462 6597
6561 20463 6598
6562 20465 6599
6563 20468 659b
6564 20470 659c
6565 20472 659d
6566 20475 659f
6567 20478 65a0
6568 20480 65a1
6569 20484 65a3
6570 20486 65a4
6571 20488 65a5
6572 20491 65a6
6573 20493 65a7
6574 20498 65ab
6575 20500 65ac
6576 20502 65ad
6577 20504 65ae
6578 20506 65af
6579 20508 65b0
6580 20513 65b2
6581 20516 65b3
6582 20518 65b4
6583 20520 65b5
6584 20523 65b7
6585 20525 65b8
6586 20527 65b9
6587 20531 65bc
6588 20533 65bd
6589 20536 65be
6590 20538 65bf
6591 20541 65c1
6592 20543 65c2
6593 20545 65c3
6594 20548 65c4
6595 20550 65c5
6596 20552 65c6
6597 20555 65c8
6598 20557 65c9
6599 20561 65cb
6600 20563 65cc
6601 20567 65ce
6602 20570 65cf
6603 20573 65d0
6604 20576 65d2
6605 20581 65d4
6606 20584 65d6
6607 20586 65d7
6608 20588 65d8
6609 20590 65d9
6610 20594 65db
6611 20601 65df
6612 20604 65e0
6613 20606 65e1
6614 20608 65e2
6615 20611 65e3
6616 20616 65e5
6617 20617 65e6
6618 20618 65e7
6619 20619 65e8
6620 20621 65e9
6621 20624 65ec
6622 20625 65ed
6623 20629 65f0
6624 20630 65f1
6625 20631 65f2
6626 20635 65f4
6627 20636 65f5
6628 20641 65f9
6629 20642 65fa
6630 20643 65fb
6631 20645 65fc
6632 20649 65fe
6633 20651 65ff
6634 20652 6600
6635 20656 6602
6636 20658 6603
6637 20660 6604
6638 20664 6606
6639 20667 6607
6640 20668 6608
6641 20671 6609
6642 20673 660a
6643 20677 660c
6644 20678 660d
6645 20679 660e
6646 20681 660f
6647 20686 6611
6648 20689 6612
6649 20690 6613
6650 20691 6614
6651 20692 6615
6652 20694 6616
6653 20702 661c
6654 20703 661d
6655 20706 661e
6656 20708 661f
6657 20709 6620
6658 20711 6621
6659 20713 6622
6660 20715 6623
6661 20717 6624
6662 20720 6625
6663 20722 6626
6664 20723 6627
6665 20724 6628
6666 20725 6629
6667 20726 662a
6668 20728 662b
6669 20729 662c
6670 20731 662d
6671 20732 662e
6672 20733 662f
6673 20734 6630
6674 20735 6631
6675 20738 6633
6676 20739 6634
6677 20741 6635
6678 20743 6636
6679 20745 6637
6680 20747 6639
6681 20748 663a
6682 20749 663b
6683 20750 663c
6684 20754 663f
6685 20756 6640
6686 20757 6641
6687 20759 6642
6688 20761 6643
6689 20763 6644
6690 20764 6645
6691 20765 6646
6692 20767 6648
6693 20769 6649
6694 20771 664a
6695 20773 664b
6696 20774 664c
6697 20776 664e
6698 20777 664f
6699 20781 6651
6700 20782 6652
6701 20787 6657
6702 20790 6658
6703 20791 6659
6704 20794 665a
6705 20796 665b
6706 20797 665c
6707 20799 665d
6708 20800 665e
6709 20801 665f
6710 20802 6660
6711 20804 6661
6712 20805 6662
6713 20807 6663
6714 20809 6664
6715 20811 6665
6716 20813 6666
6717 20815 6667
6718 20816 6668
6719 20819 6669
6720 20821 666a
6721 20822 666b
6722 20823 666c
6723 20825 666d
6724 20827 666e
6725 20829 666f
6726 20831 6670
6727 20836 6673
6728 20838 6674
6729 20840 6675
6730 20842 6676
6731 20843 6677
6732 20845 6678
6733 20847 6679
6734 20848 667a
6735 20849 667b
6736 20851 667c
6737 20855 667e
6738 20857 667f
6739 20858 6680
6740 20860 6681
6741 20862 6683
6742 20864 6684
6743 20869 6687
6744 20870 6688
6745 20871 6689
6746 20873 668b
6747 20875 668c
6748 20877 668d
6749 20880 668e
6750 20883 6690
6751 20886 6691
6752 20887 6692
6753 20891 6696
6754 20892 6697
6755 20894 6698
6756 20895 6699
6757 20897 669a
6758 20900 669b
6759 20902 669c
6760 20904 669d
6761 20907 669f
6762 20909 66a0
6763 20913 66a2
6764 20915 66a4
6765 20917 66a6
6766 20925 66ab
6767 20929 66ad
6768 20931 66ae
6769 20936 66b1
6770 20939 66b2
6771 20941 66b3
6772 20944 66b4
6773 20945 66b5
6774 20949 66b8
6775 20950 66b9
6776 20954 66bb
6777 20956 66bc
6778 20960 66be
6779 20962 66bf
6780 20963 66c0
6781 20965 66c1
6782 20967 66c2
6783 20969 66c3
6784 20971 66c4
6785 20975 66c6
6786 20977 66c7
6787 20980 66c8
6788 20982 66c9
6789 20985 66cc
6790 20989 66ce
6791 20991 66cf
6792 20997 66d4
6793 20999 66d6
6794 21004 66d9
6795 21005 66da
6796 21008 66db
6797 21009 66dc
6798 21012 66dd
6799 21016 66df
6800 21018 66e0
6801 21029 66e6
6802 21032 66e8
6803 21035 66e9
6804 21039 66eb
6805 21041 66ec
6806 21045 66ee
6807 21049 66f0
6808 21052 66f2
6809 21053 66f3
6810 21055 66f4
6811 21056 66f5
6812 21058 66f7
6813 21061 66f8
6814 21062 66f9
6815 21063 66fa
6816 21064 66fb
6817 21066 66fc
6818 21068 66fd
6819 21069 66fe
6820 21071 66ff
6821 21073 6700
6822 21076 6701
6823 21081 6703
6824 21084 6705
6825 21088 6707
6826 21090 6708
6827 21091 6709
6828 21094 670b
6829 21098 670d
6830 21099 670e
6831 21102 670f
6832 21106 6712
6833 21107 6713
6834 21109 6714
6835 21112 6715
6836 21114 6716
6837 21116 6717
6838 21120 6719
6839 21124 671b
6840 21127 671c
6841 21129 671d
6842 21131 671e
6843 21133 671f
6844 21134 6720
6845 21138 6722
6846 21144 6725
6847 21146 6726
6848 21149 6727
6849 21152 6728
6850 21154 672a
6851 21155 672b
6852 21156 672c
6853 21158 672d
6854 21159 672e
6855 21163 6731
6856 21165 6733
6857 21168 6734
6858 21170 6735
6859 21173 6736
6860 21176 6737
6861 21177 6738
6862 21179 673a
6863 21184 673d
6864 21186 673e
6865 21187 673f
6866 21189 6741
6867 21192 6743
6868 21195 6745
6869 21196 6746
6870 21198 6747
6871 21200 6748
6872 21202 6749
6873 21205 674c
6874 21207 674d
6875 21209 674e
6876 21212 674f
6877 21214 6750
6878 21215 6751
6879 21218 6753
6880 21220 6754
6881 21221 6755
6882 21222 6756
6883 21226 6759
6884 21229 675c
6885 21230 675d
6886 21233 675e
6887 21234 675f
6888 21235 6760
6889 21236 6761
6890 21238 6762
6891 21240 6763
6892 21242 6764
6893 21243 6765
6894 21244 6766
6895 21249 676a
6896 21252 676c
6897 21253 676d
6898 21255 676e
6899 21256 676f
6900 21258 6770
6901 21260 6771
6902 21261 6772
6903 21263 6773
6904 21265 6774
6905 21267 6775
6906 21268 6776
6907 21270 6777
6908 21275 677b
6909 21277 677c
6910 21279 677e
6911 21282 677f
6912 21284 6780
6913 21286 6781
6914 21291 6784
6915 21293 6785
6916 21296 6787
6917 21300 6789
6918 21302 678b
6919 21304 678c
6920 21309 678e
6921 21310 678f
6922 21311 6790
6923 21313 6791
6924 21315 6792
6925 21318 6793
6926 21321 6795
6927 21323 6796
6928 21324 6797
6929 21325 6798
6930 21327 6799
6931 21328 679a
6932 21329 679b
6933 21331 679c
6934 21332 679d
6935 21336 67a0
6936 21337 67a1
6937 21338 67a2
6938 21341 67a4
6939 21344 67a6
6940 21348 67a9
6941 21355 67af
6942 21356 67b0
6943 21358 67b1
6944 21360 67b2
6945 21363 67b3
6946 21365 67b4
6947 21367 67b5
6948 21369 67b6
6949 21371 67b7
6950 21373 67b8
6951 21374 67b9
6952 21377 67bb
6953 21379 67bc
6954 21381 67bd
6955 21382 67be
6956 21385 67c0
6957 21386 67c1
6958 21388 67c2
6959 21390 67c3
6960 21393 67c4
6961 21394 67c5
6962 21396 67c6
6963 21399 67c8
6964 21401 67c9
6965 21403 67ca
6966 21409 67ce
6967 21411 67cf
6968 21412 67d0
6969 21414 67d1
6970 21415 67d2
6971 21417 67d3
6972 21419 67d4
6973 21423 67d7
6974 21426 67d8
6975 21427 67d9
6976 21428 67da
6977 21429 67db
6978 21430 67dc
6979 21432 67dd
6980 21435 67de
6981 21439 67e1
6982 21440 67e2
6983 21444 67e4
6984 21447 67e6
6985 21448 67e7
6986 21452 67e9
6987 21456 67ec
6988 21459 67ee
6989 21461 67ef
6990 21462 67f0
6991 21464 67f1
6992 21466 67f2
6993 21467 67f3
6994 21469 67f4
6995 21471 67f5
6996 21472 67f6
6997 21473 67f7
6998 21476 67f9
6999 21478 67fa
7000 21480 67fb
7001 21481 67fc
7002 21485 67fe
7003 21487 67ff
7004 21490 6801
7005 21492 6802
7006 21494 6803
7007 21496 6804
7008 21497 6805
7009 21508 6810
7010 21512 6813
7011 21515 6814
7012 21519 6816
7013 21520 6817
7014 21523 6818
7015 21526 6819
7016 21532 681d
7017 21533 681e
7018 21536 681f
7019 21540 6821
7020 21542 6822
7021 21549 6827
7022 21550 6828
7023 21553 6829
7024 21555 682a
7025 21556 682b
7026 21558 682c
7027 21560 682d
7028 21564 682f
7029 21566 6830
7030 21567 6831
7031 21568 6832
7032 21571 6833
7033 21573 6834
7034 21580 6838
7035 21582 6839
7036 21586 683b
7037 21587 683c
7038 21589 683d
7039 21591 683e
7040 21594 683f
7041 21595 6840
7042 21598 6841
7043 21599 6842
7044 21600 6843
7045 21601 6844
7046 21603 6845
7047 21604 6846
7048 21608 6848
7049 21611 6849
7050 21614 684a
7051 21617 684c
7052 21619 684d
7053 21621 684e
7054 21624 6850
7055 21625 6851
7056 21627 6852
7057 21628 6853
7058 21629 6854
7059 21630 6855
7060 21633 6857
7061 21635 6858
7062 21637 6859
7063 21640 685b
7064 21641 685c
7065 21643 685d
7066 21647 685f
7067 21651 6863
7068 21655 6867
7069 21660 686b
7070 21666 686e
7071 21667 686f
7072 21670 6870
7073 21672 6871
7074 21673 6872
7075 21676 6874
7076 21678 6875
7077 21681 6876
7078 21682 6877
7079 21685 6879
7080 21687 687a
7081 21688 687b
7082 21689 687c
7083 21692 687e
7084 21693 687f
7085 21695 6881
7086 21697 6882
7087 21698 6883
7088 21700 6884
7089 21701 6885
7090 21703 6886
7091 21707 6888
7092 21715 688d
7093 21716 688e
7094 21717 688f
7095 21719 6890
7096 21726 6893
7097 21728 6894
7098 21731 6896
7099 21733 6897
7100 21734 6898
7101 21735 6899
7102 21736 689a
7103 21737 689b
7104 21738 689c
7105 21739 689d
7106 21743 689f
7107 21746 68a0
7108 21748 68a1
7109 21750 68a2
7110 21752 68a3
7111 21757 68a5
7112 21759 68a6
7113 21762 68a7
7114 21764 68a8
7115 21766 68a9
7116 21767 68aa
7117 21769 68ab
7118 21772 68ad
7119 21775 68ae
7120 21776 68af
7121 21778 68b0
7122 21779 68b1
7123 21781 68b2
7124 21784 68b3
7125 21787 68b4
7126 21790 68b5
7127 21791 68b6
7128 21794 68b9
7129 21796 68ba
7130 21797 68bb
7131 21799 68bc
7132 21807 68c3
7133 21809 68c4
7134 21812 68c5
7135 21813 68c6
7136 21817 68c8
7137 21820 68c9
7138 21821 68ca
7139 21823 68cb
7140 21824 68cc
7141 21826 68cd
7142 21831 68cf
7143 21833 68d0
7144 21836 68d1
7145 21838 68d2
7146 21840 68d3
7147 21842 68d4
7148 21844 68d5
7149 21847 68d6
7150 21849 68d7
7151 21851 68d8
7152 21853 68d9
7153 21855 68da
7154 21857 68dc
7155 21859 68dd
7156 21861 68df
7157 21862 68e0
7158 21864 68e1
7159 21867 68e3
7160 21870 68e4
7161 21871 68e5
7162 21874 68e7
7163 21875 68e8
7164 21879 68ea
7165 21881 68eb
7166 21882 68ec
7167 21884 68ed
7168 21886 68ee
7169 21889 68ef
7170 21892 68f0
7171 21895 68f1
7172 21898 68f2
7173 21903 68f5
7174 21904 68f6
7175 21905 68f7
7176 21910 68f9
7177 21911 68fa
7178 21913 68fb
7179 21916 68fc
7180 21919 68fd
7181 21924 6900
7182 21927 6901
7183 21931 6903
7184 21934 6904
7185 21937 6905
7186 21938 6906
7187 21941 6907
7188 21942 6908
7189 21944 6909
7190 21947 690a
7191 21949 690b
7192 21951 690c
7193 21954 690d
7194 21956 690e
7195 21958 690f
7196 21959 6910
7197 21960 6911
7198 21961 6912
7199 21963 6913
7200 21969 6916
7201 21971 6917
7202 21974 6919
7203 21975 691a
7204 21976 691b
7205 21978 691c
7206 21984 6921
7207 21986 6922
7208 21987 6923
7209 21989 6925
7210 21990 6926
7211 21994 6928
7212 21997 692a
7213 22004 6930
7214 22006 6931
7215 22008 6933
7216 22010 6934
7217 22012 6935
7218 22013 6936
7219 22018 6938
7220 22021 6939
7221 22025 693b
7222 22029 693d
7223 22033 693f
7224 22038 6942
7225 22044 6945
7226 22045 6946
7227 22051 6949
7228 22053 694a
7229 22058 694e
7230 22063 6953
7231 22065 6954
7232 22068 6955
7233 22071 6957
7234 22075 6959
7235 22076 695a
7236 22078 695b
7237 22080 695c
7238 22082 695d
7239 22083 695e
7240 22086 6960
7241 22088 6961
7242 22091 6962
7243 22093 6963
7244 22094 6964
7245 22096 6965
7246 22098 6966
7247 22102 6968
7248 22103 6969
7249 22104 696a
7250 22106 696b
7251 22108 696c
7252 22111 696d
7253 22113 696e
7254 22115 696f
7255 22117 6970
7256 22119 6971
7257 22121 6972
7258 22124 6973
7259 22126 6974
7260 22128 6975
7261 22133 6977
7262 22136 6978
7263 22138 6979
7264 22140 697a
7265 22143 697b
7266 22144 697c
7267 22146 697d
7268 22148 697e
7269 22149 697f
7270 22151 6980
7271 22152 6981
7272 22154 6982
7273 22160 6986
7274 22166 698a
7275 22170 698d
7276 22173 698e
7277 22177 6991
7278 22179 6992
7279 22182 6994
7280 22184 6995
7281 22186 6996
7282 22190 6998
7283 22196 699b
7284 22199 699c
7285 22205 69a0
7286 22207 69a1
7287 22215 69a5
7288 22216 69a6
7289 22219 69a7
7290 22221 69a8
7291 22227 69ab
7292 22230 69ad
7293 22232 69ae
7294 22234 69af
7295 22237 69b0
7296 22239 69b1
7297 22241 69b2
7298 22243 69b4
7299 22248 69b7
7300 22250 69b8
7301 22253 69ba
7302 22255 69bb
7303 22258 69bc
7304 22262 69be
7305 22265 69bf
7306 22267 69c0
7307 22270 69c1
7308 22274 69c3
7309 22278 69c5
7310 22282 69c7
7311 22284 69c8
7312 22288 69ca
7313 22291 69cb
7314 22292 69cc
7315 22295 69cd
7316 22298 69ce
7317 22300 69cf
7318 22302 69d0
7319 22305 69d1
7320 22308 69d3
7321 22312 69d6
7322 22314 69d7
7323 22315 69d8
7324 22317 69d9
7325 22322 69dd
7326 22324 69de
7327 22330 69e2
7328 22333 69e3
7329 22337 69e5
7330 22343 69e7
7331 22346 69e8
7332 22348 69e9
7333 22352 69ea
7334 22355 69eb
7335 22358 69ed
7336 22359 69ee
7337 22361 69ef
7338 22364 69f1
7339 22365 69f2
7340 22367 69f3
7341 22370 69f4
7342 22373 69f5
7343 22375 69f6
7344 22380 69f9
7345 22384 69fb
7346 22388 69fd
7347 22390 69fe
7348 22392 69ff
7349 22393 6a00
7350 22395 6a01
7351 22397 6a02
7352 22400 6a03
7353 22403 6a05
7354 22410 6a0a
7355 22412 6a0b
7356 22415 6a0c
7357 22419 6a0f
7358 22422 6a11
7359 22424 6a12
7360 22426 6a13
7361 22429 6a14
7362 22430 6a15
7363 22433 6a17
7364 22437 6a19
7365 22439 6a1a
7366 22442 6a1b
7367 22446 6a1d
7368 22448 6a1e
7369 22451 6a1f
7370 22453 6a20
7371 22455 6a21
7372 22457 6a22
7373 22458 6a23
7374 22459 6a24
7375 22466 6a28
7376 22468 6a29
7377 22470 6a2a
7378 22472 6a2b
7379 22477 6a2e
7380 22480 6a30
7381 22483 6a32
7382 22484 6a33
7383 22486 6a34
7384 22488 6a35
7385 22490 6a36
7386 22492 6a37
7387 22494 6a38
7388 22496 6a39
7389 22497 6a3a
7390 22499 6a3b
7391 22501 6a3d
7392 22504 6a3e
7393 22506 6a3f
7394 22514 6a44
7395 22516 6a45
7396 22518 6a46
7397 22521 6a47
7398 22523 6a48
7399 22524 6a49
7400 22527 6a4a
7401 22528 6a4b
7402 22531 6a4e
7403 22535 6a50
7404 22537 6a51
7405 22538 6a52
7406 22544 6a54
7407 22546 6a55
7408 22548 6a56
7409 22552 6a58
7410 22555 6a59
7411 22558 6a5b
7412 22563 6a5f
7413 22568 6a61
7414 22571 6a62
7415 22575 6a64
7416 22579 6a66
7417 22581 6a67
7418 22586 6a6a
7419 22589 6a6b
7420 22597 6a71
7421 22599 6a72
7422 22601 6a73
7423 22608 6a78
7424 22610 6a7a
7425 22614 6a7e
7426 22616 6a7f
7427 22617 6a80
7428 22619 6a81
7429 22624 6a83
7430 22627 6a84
7431 22630 6a86
7432 22631 6a87
7433 22634 6a89
7434 22638 6a8b
7435 22641 6a8d
7436 22643 6a8e
7437 22648 6a90
7438 22651 6a91
7439 22658 6a94
7440 22663 6a97
7441 22669 6a9b
7442 22672 6a9c
7443 22674 6a9d
7444 22677 6a9e
7445 22679 6a9f
7446 22680 6aa0
7447 22683 6aa1
7448 22685 6aa2
7449 22687 6aa3
7450 22690 6aa5
7451 22698 6aaa
7452 22700 6aab
7453 22703 6aac
7454 22707 6aae
7455 22708 6aaf
7456 22710 6ab0
7457 22712 6ab1
7458 22715 6ab3
7459 22717 6ab4
7460 22725 6ab8
7461 22729 6abb
7462 22734 6abd
7463 22736 6abe
7464 22739 6abf
7465 22742 6ac1
7466 22744 6ac2
7467 22747 6ac3
7468 22751 6ac6
7469 22755 6ac8
7470 22756 6ac9
7471 22762 6acc
7472 22768 6ad0
7473 22770 6ad1
7474 22772 6ad3
7475 22773 6ad4
7476 22775 6ad5
7477 22776 6ad6
7478 22782 6ada
7479 22784 6adb
7480 22786 6adc
7481 22789 6add
7482 22791 6ade
7483 22793 6adf
7484 22799 6ae2
7485 22802 6ae4
7486 22806 6ae7
7487 22808 6ae8
7488 22811 6aea
7489 22815 6aec
7490 22821 6af0
7491 22823 6af1
7492 22826 6af2
7493 22828 6af3
7494 22837 6af8
7495 22842 6afa
7496 22844 6afb
7497 22847 6afc
7498 22848 6afd
7499 22854 6b02
7500 22856 6b03
7501 22859 6b04
7502 22861 6b05
7503 22864 6b06
7504 22866 6b07
7505 22870 6b09
7506 22872 6b0a
7507 22875 6b0b
7508 22880 6b0f
7509 22882 6b10
7510 22885 6b11
7511 22887 6b12
7512 22893 6b16
7513 22895 6b17
7514 22902 6b1b
7515 22905 6b1d
7516 22908 6b1e
7517 22910 6b1f
7518 22912 6b20
7519 22914 6b21
7520 22918 6b23
7521 22920 6b24
7522 22924 6b27
7523 22926 6b28
7524 22930 6b2b
7525 22932 6b2c
7526 22936 6b2f
7527 22940 6b32
7528 22944 6b35
7529 22947 6b36
7530 22949 6b37
7531 22951 6b38
7532 22953 6b39
7533 22955 6b3a
7534 22957 6b3b
7535 22961 6b3d
7536 22963 6b3e
7537 22966 6b3f
7538 22972 6b43
7539 22978 6b46
7540 22980 6b47
7541 22985 6b49
7542 22987 6b4a
7543 22991 6b4c
7544 22993 6b4d
7545 22995 6b4e
7546 22998 6b50
7547 23003 6b52
7548 23005 6b53
7549 23007 6b54
7550 23011 6b56
7551 23014 6b58
7552 23016 6b59
7553 23020 6b5b
7554 23023 6b5d
7555 23026 6b5f
7556 23029 6b60
7557 23031 6b61
7558 23034 6b62
7559 23035 6b63
7560 23036 6b64
7561 23038 6b65
7562 23040 6b66
7563 23041 6b67
7564 23044 6b69
7565 23046 6b6a
7566 23047 6b6b
7567 23049 6b6c
7568 23053 6b6e
7569 23054 6b6f
7570 23056 6b70
7571 23059 6b72
7572 23061 6b73
7573 23062 6b74
7574 23064 6b75
7575 23067 6b77
7576 23069 6b78
7577 23071 6b79
7578 23074 6b7a
7579 23076 6b7b
7580 23080 6b7d
7581 23082 6b7e
7582 23085 6b7f
7583 23088 6b80
7584 23091 6b81
7585 23094 6b82
7586 23097 6b83
7587 23100 6b84
7588 23103 6b85
7589 23105 6b86
7590 23111 6b89
7591 23114 6b8a
7592 23117 6b8b
7593 23121 6b8d
7594 23136 6b95
7595 23139 6b96
7596 23142 6b97
7597 23145 6b98
7598 23151 6b9b
7599 23156 6b9e
7600 23159 6b9f
7601 23162 6ba0
7602 23166 6ba2
7603 23169 6ba3
7604 23172 6ba4
7605 23181 6ba8
7606 23183 6ba9
7607 23185 6baa
7608 23188 6bab
7609 23191 6bac
7610 23193 6bad
7611 23196 6bae
7612 23199 6baf
7613 23202 6bb0
7614 23205 6bb1
7615 23207 6bb2
7616 23210 6bb3
7617 23212 6bb4
7618 23214 6bb5
7619 23217 6bb7
7620 23219 6bb8
7621 23221 6bb9
7622 23223 6bba
7623 23226 6bbb
7624 23228 6bbc
7625 23230 6bbd
7626 23233 6bbe
7627 23235 6bbf
7628 23237 6bc0
7629 23242 6bc3
7630 23244 6bc4
7631 23246 6bc5
7632 23248 6bc6
7633 23251 6bc7
7634 23254 6bc8
7635 23256 6bc9
7636 23260 6bcb
7637 23262 6bcc
7638 23265 6bcd
7639 23267 6bce
7640 23269 6bcf
7641 23273 6bd2
7642 23277 6bd3
7643 23280 6bd4
7644 23284 6bd6
7645 23287 6bd7
7646 23290 6bd8
7647 23294 6bda
7648 23297 6bdb
7649 23302 6bdf
7650 23305 6be1
7651 23307 6be3
7652 23312 6be6
7653 23314 6be7
7654 23318 6beb
7655 23320 6bec
7656 23323 6bee
7657 23325 6bef
7658 23328 6bf1
7659 23330 6bf3
7660 23335 6bf7
7661 23337 6bf9
7662 23349 6bff
7663 23355 6c02
7664 23358 6c04
7665 23360 6c05
7666 23364 6c08
7667 23366 6c09
7668 23368 6c0a
7669 23373 6c0d
7670 23375 6c0e
7671 23377 6c0f
7672 23379 6c10
7673 23382 6c11
7674 23384 6c12
7675 23386 6c13
7676 23390 6c14
7677 23393 6c17
7678 23395 6c19
7679 23398 6c1b
7680 23405 6c1f
7681 23411 6c23
7682 23414 6c24
7683 23416 6c26
7684 23418 6c27
7685 23420 6c28
7686 23427 6c2c
7687 23429 6c2e
7688 23438 6c33
7689 23439 6c34
7690 23441 6c35
7691 23442 6c36
7692 23444 6c37
7693 23445 6c38
7694 23447 6c3a
7695 23448 6c3b
7696 23451 6c3e
7697 23452 6c3f
7698 23453 6c40
7699 23454 6c41
7700 23455 6c42
7701 23467 6c4a
7702 23469 6c4b
7703 23472 6c4d
7704 23475 6c4e
7705 23476 6c4f
7706 23477 6c50
7707 23481 6c52
7708 23486 6c54
7709 23487 6c55
7710 23490 6c57
7711 23492 6c59
7712 23493 6c5a
7713 23495 6c5b
7714 23497 6c5c
7715 23499 6c5d
7716 23502 6c5e
7717 23504 6c5f
7718 23505 6c60
7719 23508 6c62
7720 23513 6c67
7721 23515 6c68
7722 23517 6c6a
7723 23518 6c6b
7724 23520 6c6d
7725 23524 6c6f
7726 23526 6c70
7727 23529 6c72
7728 23531 6c73
7729 23533 6c74
7730 23537 6c76
7731 23540 6c78
7732 23542 6c79
7733 23544 6c7a
7734 23546 6c7b
7735 23548 6c7d
7736 23549 6c7e
7737 23554 6c81
7738 23556 6c82
7739 23558 6c83
7740 23559 6c84
7741 23561 6c85
7742 23562 6c86
7743 23564 6c87
7744 23566 6c88
7745 23567 6c89
7746 23572 6c8c
7747 23574 6c8d
7748 23579 6c90
7749 23581 6c92
7750 23582 6c93
7751 23583 6c94
7752 23585 6c95
7753 23587 6c96
7754 23588 6c97
7755 23590 6c98
7756 23593 6c99
7757 23595 6c9a
7758 23596 6c9b
7759 23597 6c9c
7760 23601 6c9f
7761 23604 6ca1
7762 23606 6ca2
7763 23614 6caa
7764 23617 6cab
7765 23618 6cac
7766 23619 6cad
7767 23622 6cae
7768 23625 6cb0
7769 23626 6cb1
7770 23628 6cb2
7771 23630 6cb3
7772 23631 6cb4
7773 23638 6cb8
7774 23640 6cb9
7775 23641 6cba
7776 23642 6cbb
7777 23644 6cbc
7778 23645 6cbd
7779 23646 6cbe
7780 23647 6cbf
7781 23651 6cc1
7782 23652 6cc2
7783 23654 6cc4
7784 23656 6cc5
7785 23658 6cc6
7786 23661 6cc9
7787 23663 6cca
7788 23665 6ccc
7789 23667 6ccd
7790 23669 6ccf
7791 23671 6cd0
7792 23672 6cd1
7793 23674 6cd2
7794 23677 6cd3
7795 23679 6cd4
7796 23680 6cd5
7797 23682 6cd6
7798 23684 6cd7
7799 23687 6cd9
7800 23689 6cda
7801 23691 6cdb
7802 23693 6cdc
7803 23696 6cdd
7804 23701 6ce0
7805 23704 6ce1
7806 23706 6ce2
7807 23707 6ce3
7808 23710 6ce5
7809 23713 6ce7
7810 23715 6ce8
7811 23717 6ce9
7812 23718 6cea
7813 23719 6ceb
7814 23721 6cec
7815 23724 6ced
7816 23725 6cee
7817 23727 6cef
7818 23729 6cf0
7819 23731 6cf1
7820 23733 6cf2
7821 23735 6cf3
7822 23736 6cf4
7823 23743 6cfb
7824 23749 6d00
7825 23751 6d01
7826 23755 6d04
7827 23758 6d07
7828 23762 6d0a
7829 23764 6d0b
7830 23766 6d0c
7831 23770 6d0e
7832 23771 6d0f
7833 23773 6d11
7834 23774 6d12
7835 23775 6d13
7836 23780 6d17
7837 23782 6d19
7838 23783 6d1a
7839 23786 6d1b
7840 23791 6d1e
7841 23792 6d1f
7842 23798 6d24
7843 23800 6d25
7844 23801 6d26
7845 23802 6d27
7846 23804 6d28
7847 23806 6d29
7848 23807 6d2a
7849 23808 6d2b
7850 23813 6d2e
7851 23814 6d2f
7852 23819 6d31
7853 23821 6d32
7854 23823 6d33
7855 23826 6d34
7856 23828 6d35
7857 23829 6d36
7858 23832 6d38
7859 23833 6d39
7860 23838 6d3b
7861 23839 6d3c
7862 23840 6d3d
7863 23842 6d3e
7864 23844 6d3f
7865 23847 6d41
7866 23853 6d44
7867 23854 6d45
7868 23873 6d57
7869 23874 6d58
7870 23875 6d59
7871 23877 6d5a
7872 23880 6d5b
7873 23883 6d5c
7874 23886 6d5e
7875 23887 6d5f
7876 23888 6d60
7877 23889 6d61
7878 23892 6d63
7879 23894 6d64
7880 23896 6d65
7881 23897 6d66
7882 23898 6d67
7883 23902 6d69
7884 23903 6d6a
7885 23906 6d6c
7886 23908 6d6e
7887 23910 6d6f
7888 23912 6d70
7889 23917 6d74
7890 23922 6d77
7891 23924 6d78
7892 23927 6d79
7893 23931 6d7c
7894 23936 6d80
7895 23937 6d81
7896 23938 6d82
7897 23942 6d85
7898 23945 6d87
7899 23946 6d88
7900 23948 6d89
7901 23950 6d8a
7902 23953 6d8c
7903 23954 6d8d
7904 23957 6d8e
7905 23962 6d91
7906 23963 6d92
7907 23964 6d93
7908 23966 6d94
7909 23968 6d95
7910 23970 6d96
7911 23972 6d97
7912 23975 6d98
7913 23978 6d99
7914 23981 6d9b
7915 23983 6d9c
7916 23997 6daa
7917 23999 6dab
7918 24001 6dac
7919 24004 6dae
7920 24005 6daf
7921 24009 6db2
7922 24013 6db4
7923 24016 6db5
7924 24020 6db7
7925 24021 6db8
7926 24022 6db9
7927 24027 6dbc
7928 24029 6dbd
7929 24032 6dbf
7930 24035 6dc0
7931 24038 6dc2
7932 24041 6dc4
7933 24042 6dc5
7934 24044 6dc6
7935 24047 6dc7
7936 24048 6dc8
7937 24051 6dca
7938 24053 6dcb
7939 24054 6dcc
7940 24058 6dce
7941 24060 6dcf
7942 24061 6dd0
7943 24062 6dd1
7944 24063 6dd2
7945 24069 6dd5
7946 24072 6dd6
7947 24075 6dd8
7948 24077 6dd9
7949 24080 6dda
7950 24083 6ddb
7951 24085 6ddd
7952 24087 6dde
7953 24090 6ddf
7954 24091 6de0
7955 24092 6de1
7956 24094 6de2
7957 24096 6de4
7958 24098 6de5
7959 24101 6de6
7960 24104 6de8
7961 24106 6de9
7962 24109 6dea
7963 24111 6deb
7964 24114 6dec
7965 24118 6dee
7966 24120 6def
7967 24123 6df0
7968 24126 6df1
7969 24129 6df2
7970 24132 6df3
7971 24134 6df4
7972 24135 6df5
7973 24136 6df6
7974 24137 6df7
7975 24140 6df8
7976 24141 6df9
7977 24143 6dfa
7978 24144 6dfb
7979 24146 6dfc
7980 24153 6e00
7981 24158 6e04
7982 24160 6e05
7983 24164 6e07
7984 24165 6e08
7985 24167 6e09
7986 24169 6e0a
7987 24170 6e0b
7988 24178 6e13
7989 24180 6e15
7990 24182 6e17
7991 24186 6e19
7992 24189 6e1a
7993 24190 6e1b
7994 24193 6e1d
7995 24196 6e1e
7996 24197 6e1f
7997 24199 6e20
7998 24202 6e21
7999 24204 6e22
8000 24206 6e23
8001 24209 6e24
8002 24211 6e25
8003 24213 6e26
8004 24215 6e27
8005 24219 6e29
8006 24222 6e2b
8007 24224 6e2c
8008 24225 6e2d
8009 24227 6e2e
8010 24229 6e2f
8011 24233 6e32
8012 24237 6e34
8013 24242 6e36
8014 24246 6e38
8015 24248 6e39
8016 24250 6e3a
8017 24252 6e3b
8018 24254 6e3c
8019 24258 6e3e
8020 24263 6e42
8021 24265 6e43
8022 24267 6e44
8023 24268 6e45
8024 24272 6e48
8025 24273 6e49
8026 24275 6e4a
8027 24277 6e4b
8028 24280 6e4c
8029 24282 6e4d
8030 24283 6e4e
8031 24284 6e4f
8032 24286 6e51
8033 24288 6e52
8034 24290 6e53
8035 24293 6e54
8036 24297 6e56
8037 24299 6e57
8038 24301 6e58
8039 24306 6e5b
8040 24309 6e5c
8041 24310 6e5d
8042 24313 6e5e
8043 24314 6e5f
8044 24319 6e62
8045 24320 6e63
8046 24327 6e67
8047 24330 6e68
8048 24334 6e6b
8049 24338 6e6e
8050 24340 6e6f
8051 24344 6e72
8052 24346 6e73
8053 24350 6e76
8054 24356 6e7b
8055 24359 6e7d
8056 24360 6e7e
8057 24362 6e7f
8058 24363 6e80
8059 24366 6e82
8060 24373 6e89
8061 24378 6e8c
8062 24379 6e8d
8063 24383 6e8f
8064 24385 6e90
8065 24389 6e93
8066 24394 6e96
8067 24398 6e98
8068 24400 6e99
8069 24406 6e9c
8070 24408 6e9d
8071 24411 6e9f
8072 24413 6ea0
8073 24417 6ea2
8074 24421 6ea5
8075 24425 6ea7
8076 24430 6eaa
8077 24433 6eab
8078 24435 6ead
8079 24437 6eae
8080 24438 6eaf
8081 24442 6eb1
8082 24445 6eb2
8083 24449 6eb3
8084 24450 6eb4
8085 24455 6eb6
8086 24457 6eb7
8087 24460 6eba
8088 24462 6ebb
8089 24465 6ebc
8090 24467 6ebd
8091 24472 6ebf
8092 24474 6ec0
8093 24476 6ec1
8094 24478 6ec2
8095 24480 6ec3
8096 24483 6ec4
8097 24486 6ec5
8098 24489 6ec7
8099 24491 6ec8
8100 24493 6ec9
8101 24494 6eca
8102 24496 6ecb
8103 24498 6ecc
8104 24501 6ecd
8105 24503 6ece
8106 24505 6ecf
8107 24509 6ed1
8108 24513 6ed3
8109 24515 6ed4
8110 24517 6ed5
8111 24523 6ed9
8112 24525 6eda
8113 24527 6edb
8114 24530 6edd
8115 24532 6ede
8116 24542 6ee6
8117 24548 6eeb
8118 24551 6eec
8119 24554 6eed
8120 24557 6eee
8121 24560 6eef
8122 24565 6ef2
8123 24568 6ef4
8124 24574 6ef7
8125 24575 6ef8
8126 24577 6ef9
8127 24580 6efb
8128 24585 6efd
8129 24588 6efe
8130 24591 6eff
8131 24594 6f01
8132 24595 6f02
8133 24598 6f04
8134 24601 6f06
8135 24604 6f08
8136 24607 6f09
8137 24610 6f0a
8138 24614 6f0c
8139 24615 6f0d
8140 24617 6f0f
8141 24619 6f10
8142 24621 6f11
8143 24625 6f13
8144 24628 6f14
8145 24630 6f15
8146 24631 6f16
8147 24635 6f18
8148 24639 6f1a
8149 24642 6f1b
8150 24649 6f20
8151 24652 6f22
8152 24655 6f23
8153 24660 6f25
8154 24663 6f26
8155 24667 6f29
8156 24669 6f2a
8157 24671 6f2b
8158 24673 6f2c
8159 24674 6f2d
8160 24678 6f2f
8161 24680 6f30
8162 24682 6f31
8163 24684 6f32
8164 24686 6f33
8165 24690 6f35
8166 24692 6f36
8167 24695 6f38
8168 24699 6f3b
8169 24702 6f3c
8170 24705 6f3e
8171 24707 6f3f
8172 24711 6f41
8173 24718 6f45
8174 24729 6f4f
8175 24732 6f51
8176 24734 6f52
8177 24737 6f53
8178 24739 6f54
8179 24746 6f57
8180 24749 6f58
8181 24751 6f59
8182 24753 6f5a
8183 24754 6f5b
8184 24757 6f5c
8185 24760 6f5d
8186 24762 6f5e
8187 24763 6f5f
8188 24765 6f60
8189 24767 6f61
8190 24769 6f62
8191 24773 6f64
8192 24775 6f66
8193 24777 6f68
8194 24782 6f6c
8195 24783 6f6d
8196 24784 6f6e
8197 24785 6f6f
8198 24787 6f70
8199 24793 6f74
8200 24799 6f78
8201 24804 6f7a
8202 24807 6f7c
8203 24809 6f7d
8204 24810 6f7e
8205 24814 6f80
8206 24816 6f81
8207 24817 6f82
8208 24820 6f83
8209 24821 6f84
8210 24824 6f86
8211 24825 6f87
8212 24827 6f88
8213 24833 6f8b
8214 24835 6f8c
8215 24837 6f8d
8216 24839 6f8e
8217 24842 6f90
8218 24845 6f91
8219 24846 6f92
8220 24847 6f93
8221 24849 6f94
8222 24853 6f96
8223 24855 6f97
8224 24856 6f98
8225 24858 6f9a
8226 24862 6f9d
8227 24867 6f9f
8228 24870 6fa0
8229 24873 6fa1
8230 24876 6fa3
8231 24878 6fa4
8232 24880 6fa5
8233 24882 6fa6
8234 24883 6fa7
8235 24885 6fa8
8236 24888 6faa
8237 24896 6fae
8238 24898 6faf
8239 24901 6fb0
8240 24903 6fb1
8241 24907 6fb3
8242 24911 6fb5
8243 24914 6fb6
8244 24916 6fb7
8245 24920 6fb9
8246 24926 6fbc
8247 24930 6fbe
8248 24935 6fc0
8249 24937 6fc1
8250 24938 6fc2
8251 24940 6fc3
8252 24945 6fc5
8253 24947 6fc6
8254 24948 6fc7
8255 24949 6fc8
8256 24952 6fc9
8257 24954 6fca
8258 24966 6fd4
8259 24967 6fd5
8260 24971 6fd8
8261 24975 6fda
8262 24977 6fdb
8263 24982 6fde
8264 24983 6fdf
8265 24985 6fe0
8266 24987 6fe1
8267 24992 6fe4
8268 24997 6fe8
8269 24999 6fe9
8270 25003 6feb
8271 25006 6fec
8272 25010 6fee
8273 25012 6fef
8274 25015 6ff0
8275 25017 6ff1
8276 25020 6ff3
8277 25024 6ff5
8278 25026 6ff6
8279 25031 6ff9
8280 25032 6ffa
8281 25034 6ffc
8282 25037 6ffd
8283 25038 6ffe
8284 25042 7000
8285 25044 7001
8286 25051 7005
8287 25053 7006
8288 25055 7007
8289 25059 7009
8290 25061 700a
8291 25064 700b
8292 25069 700d
8293 25074 700f
8294 25077 7011
8295 25083 7015
8296 25087 7017
8297 25090 7018
8298 25094 701a
8299 25096 701b
8300 25102 701d
8301 25104 701e
8302 25107 701f
8303 25109 7020
8304 25116 7023
8305 25120 7026
8306 25123 7027
8307 25126 7028
8308 25133 702c
8309 25136 702f
8310 25139 7030
8311 25143 7032
8312 25147 7034
8313 25153 7037
8314 25157 7039
8315 25159 703a
8316 25163 703c
8317 25166 703e
8318 25174 7043
8319 25176 7044
8320 25182 7047
8321 25184 7048
8322 25186 7049
8323 25188 704a
8324 25191 704b
8325 25193 704c
8326 25197 704e
8327 25203 7051
8328 25209 7054
8329 25211 7055
8330 25217 7058
8331 25224 705d
8332 25226 705e
8333 25234 7063
8334 25236 7064
8335 25239 7065
8336 25244 7069
8337 25247 706b
8338 25250 706c
8339 25252 706e
8340 25255 706f
8341 25257 7070
8342 25266 7075
8343 25269 7076
8344 25273 7078
8345 25281 707c
8346 25284 707d
8347 25286 707e
8348 25292 7081
8349 25300 7085
8350 25303 7086
8351 25308 7089
8352 25311 708a
8353 25318 708e
8354 25326 7092
8355 25331 7094
8356 25333 7095
8357 25336 7096
8358 25339 7097
8359 25341 7098
8360 25344 7099
8361 25349 709b
8362 25354 709f
8363 25363 70a4
8364 25375 70ab
8365 25378 70ac
8366 25381 70ad
8367 25384 70ae
8368 25387 70af
8369 25389 70b0
8370 25390 70b1
8371 25394 70b3
8372 25397 70b4
8373 25402 70b7
8374 25405 70b8
8375 25407 70b9
8376 25408 70ba
8377 25409 70bb
8378 25431 70c8
8379 25435 70ca
8380 25438 70cb
8381 25446 70cf
8382 25449 70d1
8383 25453 70d3
8384 25455 70d4
8385 25457 70d5
8386 25459 70d6
8387 25463 70d8
8388 25465 70d9
8389 25471 70dc
8390 25473 70dd
8391 25477 70df
8392 25487 70e4
8393 25497 70ec
8394 25504 70f1
8395 25520 70f9
8396 25522 70fa
8397 25529 70fd
8398 25541 7103
8399 25542 7104
8400 25543 7105
8401 25546 7106
8402 25548 7107
8403 25550 7108
8404 25552 7109
8405 25556 710b
8406 25558 710c
8407 25564 710f
8408 25572 7114
8409 25579 7119
8410 25582 711a
8411 25587 711c
8412 25592 711e
8413 25597 7120
8414 25600 7121
8415 25610 7126
8416 25618 712b
8417 25623 712d
8418 25624 712e
8419 25627 712f
8420 25629 7130
8421 25632 7131
8422 25643 7136
8423 25647 7138
8424 25654 713c
8425 25661 7141
8426 25670 7145
8427 25673 7146
8428 25675 7147
8429 25678 7149
8430 25680 714a
8431 25683 714b
8432 25685 714c
8433 25689 714e
8434 25694 7150
8435 25696 7151
8436 25699 7152
8437 25702 7153
8438 25706 7155
8439 25707 7156
8440 25710 7157
8441 25714 7159
8442 25716 715a
8443 25720 715c
8444 25725 715e
8445 25730 7160
8446 25735 7162
8447 25739 7164
8448 25741 7165
8449 25744 7166
8450 25745 7167
8451 25746 7168
8452 25749 7169
8453 25755 716c
8454 25758 716e
8455 25777 7179
8456 25785 717d
8457 25791 7180
8458 25798 7184
8459 25800 7185
8460 25804 7187
8461 25807 7188
8462 25811 718a
8463 25815 718c
8464 25821 718f
8465 25827 7192
8466 25830 7194
8467 25833 7195
8468 25834 7196
8469 25841 7199
8470 25844 719a
8471 25846 719b
8472 25854 719f
8473 25856 71a0
8474 25861 71a2
8475 25874 71a8
8476 25881 71ac
8477 25886 71ae
8478 25888 71af
8479 25891 71b0
8480 25894 71b1
8481 25897 71b2
8482 25899 71b3
8483 25910 71b9
8484 25911 71ba
8485 25919 71be
8486 25922 71bf
8487 25925 71c0
8488 25927 71c1
8489 25932 71c3
8490 25935 71c4
8491 25944 71c8
8492 25947 71c9
8493 25952 71cb
8494 25955 71cc
8495 25957 71ce
8496 25961 71d0
8497 25966 71d2
8498 25968 71d3
8499 25970 71d4
8500 25973 71d5
8501 25975 71d6
8502 25978 71d7
8503 25981 71d9
8504 25983 71da
8505 25987 71dc
8506 25992 71df
8507 25995 71e0
8508 26005 71e5
8509 26007 71e6
8510 26010 71e7
8511 26019 71ec
8512 26022 71ed
8513 26024 71ee
8514 26035 71f4
8515 26038 71f5
8516 26044 71f8
8517 26046 71f9
8518 26050 71fb
8519 26052 71fc
8520 26056 71fe
8521 26057 71ff
8522 26060 7200
8523 26071 7206
8524 26074 7207
8525 26077 7208
8526 26078 7209
8527 26088 720d
8528 26095 7210
8529 26099 7213
8530 26105 7215
8531 26110 7217
8532 26115 721a
8533 26118 721b
8534 26122 721d
8535 26127 721f
8536 26137 7224
8537 26147 7228
8538 26151 722a
8539 26154 722b
8540 26156 722c
8541 26159 722d
8542 26162 722f
8543 26164 7230
8544 26167 7232
8545 26170 7234
8546 26172 7235
8547 26174 7236
8548 26177 7238
8549 26179 7239
8550 26182 723a
8551 26184 723b
8552 26185 723c
8553 26186 723d
8554 26187 723e
8555 26188 723f
8556 26190 7240
8557 26191 7241
8558 26193 7242
8559 26194 7243
8560 26197 7245
8561 26199 7246
8562 26201 7247
8563 26203 7248
8564 26210 724b
8565 26212 724c
8566 26216 724e
8567 26218 724f
8568 26221 7250
8569 26225 7252
8570 26227 7253
8571 26231 7255
8572 26234 7256
8573 26237 7257
8574 26240 7258
8575 26243 7259
8576 26247 725a
8577 26251 725b
8578 26252 725c
8579 26253 725d
8580 26255 725e
8581 26256 725f
8582 26258 7260
8583 26260 7261
8584 26261 7262
8585 26263 7263
8586 26268 7267
8587 26269 7268
8588 26271 7269
8589 26273 726b
8590 26276 726e
8591 26277 726f
8592 26279 7271
8593 26280 7272
8594 26282 7274
8595 26287 7277
8596 26290 7278
8597 26292 7279
8598 26296 727b
8599 26299 727c
8600 26300 727d
8601 26302 727e
8602 26303 727f
8603 26305 7280
8604 26307 7281
8605 26308 7282
8606 26310 7284
8607 26313 7287
8608 26315 7289
8609 26320 728d
8610 26322 728e
8611 26329 7292
8612 26331 7293
8613 26335 7296
8614 26344 729b
8615 26351 72a0
8616 26354 72a2
8617 26363 72a7
8618 26365 72a8
8619 26372 72ac
8620 26373 72ad
8621 26374 72ae
8622 26376 72af
8623 26377 72b0
8624 26378 72b1
8625 26380 72b2
8626 26382 72b4
8627 26384 72b6
8628 26387 72b9
8629 26394 72be
8630 26396 72c0
8631 26397 72c1
8632 26399 72c2
8633 26400 72c3
8634 26402 72c4
8635 26407 72c6
8636 26408 72c7
8637 26410 72c9
8638 26416 72cc
8639 26418 72ce
8640 26420 72d0
8641 26425 72d2
8642 26430 72d5
8643 26432 72d6
8644 26435 72d7
8645 26436 72d8
8646 26438 72d9
8647 26440 72db
8648 26444 72df
8649 26445 72e0
8650 26447 72e1
8651 26449 72e2
8652 26452 72e5
8653 26456 72e9
8654 26461 72ec
8655 26462 72ed
8656 26468 72f3
8657 26470 72f4
8658 26475 72f7
8659 26477 72f8
8660 26478 72f9
8661 26479 72fa
8662 26481 72fb
8663 26484 72fc
8664 26486 72fd
8665 26487 72fe
8666 26493 7302
8667 26495 7304
8668 26497 7305
8669 26500 7307
8670 26505 730a
8671 26507 730b
8672 26510 730d
8673 26517 7312
8674 26519 7313
8675 26522 7316
8676 26523 7317
8677 26524 7318
8678 26525 7319
8679 26528 731b
8680 26530 731c
8681 26533 731d
8682 26535 731e
8683 26537 731f
8684 26541 7322
8685 26545 7324
8686 26547 7325
8687 26551 7327
8688 26553 7328
8689 26555 7329
8690 26557 732a
8691 26558 732b
8692 26560 732c
8693 26563 732e
8694 26565 732f
8695 26568 7331
8696 26570 7332
8697 26573 7333
8698 26574 7334
8699 26576 7335
8700 26579 7336
8701 26581 7337
8702 26585 7339
8703 26587 733a
8704 26590 733b
8705 26595 733d
8706 26597 733e
8707 26600 733f
8708 26606 7343
8709 26608 7344
8710 26610 7345
8711 26621 734d
8712 26623 734e
8713 26626 734f
8714 26628 7350
8715 26631 7352
8716 26637 7356
8717 26638 7357
8718 26640 7358
8719 26650 735d
8720 26652 735e
8721 26654 735f
8722 26655 7360
8723 26660 7363
8724 26663 7366
8725 26666 7367
8726 26668 7368
8727 26669 7369
8728 26670 736a
8729 26672 736b
8730 26674 736c
8731 26677 736e
8732 26678 736f
8733 26679 7370
8734 26681 7371
8735 26683 7372
8736 26690 7375
8737 26695 7377
8738 26698 7378
8739 26699 7379
8740 26700 737a
8741 26702 737b
8742 26705 737c
8743 26712 7380
8744 26714 7381
8745 26718 7383
8746 26720 7384
8747 26722 7385
8748 26724 7386
8749 26726 7387
8750 26730 7389
8751 26731 738a
8752 26732 738b
8753 26735 738e
8754 26737 7390
8755 26741 7393
8756 26743 7394
8757 26744 7395
8758 26745 7396
8759 26746 7397
8760 26747 7398
8761 26751 739c
8762 26755 739e
8763 26756 739f
8764 26758 73a0
8765 26762 73a2
8766 26768 73a5
8767 26769 73a6
8768 26773 73a8
8769 26774 73a9
8770 26775 73aa
8771 26778 73ab
8772 26780 73ad
8773 26787 73b2
8774 26790 73b3
8775 26792 73b5
8776 26794 73b7
8777 26796 73b9
8778 26798 73ba
8779 26799 73bb
8780 26800 73bc
8781 26802 73bd
8782 26804 73bf
8783 26805 73c0
8784 26807 73c2
8785 26810 73c5
8786 26811 73c6
8787 26814 73c8
8788 26815 73c9
8789 26817 73ca
8790 26819 73cb
8791 26821 73cc
8792 26822 73cd
8793 26824 73ce
8794 26826 73cf
8795 26829 73d2
8796 26830 73d3
8797 26834 73d6
8798 26837 73d9
8799 26842 73dd
8800 26844 73de
8801 26847 73e0
8802 26848 73e1
8803 26852 73e3
8804 26853 73e4
8805 26856 73e5
8806 26858 73e6
8807 26859 73e7
8808 26861 73e9
8809 26862 73ea
8810 26867 73ed
8811 26870 73ee
8812 26874 73f1
8813 26878 73f4
8814 26879 73f5
8815 26883 73f7
8816 26884 73f8
8817 26885 73f9
8818 26887 73fa
8819 26888 73fb
8820 26891 73fd
8821 26893 73fe
8822 26894 73ff
8823 26895 7400
8824 26898 7401
8825 26900 7403
8826 26902 7404
8827 26904 7405
8828 26906 7406
8829 26907 7407
8830 26911 7409
8831 26914 740a
8832 26924 7411
8833 26927 7413
8834 26935 741a
8835 26936 741b
8836 26944 7421
8837 26945 7422
8838 26949 7424
8839 26952 7425
8840 26955 7426
8841 26957 7428
8842 26960 7429
8843 26961 742a
8844 26962 742b
8845 26964 742c
8846 26967 742d
8847 26970 742e
8848 26973 742f
8849 26975 7430
8850 26977 7431
8851 26980 7432
8852 26982 7433
8853 26984 7434
8854 26987 7435
8855 26990 7436
8856 26995 7439
8857 26998 743a
8858 27004 743f
8859 27005 7440
8860 27007 7441
8861 27009 7443
8862 27011 7444
8863 27014 7446
8864 27015 7447
8865 27021 744b
8866 27026 744d
8867 27036 7451
8868 27038 7452
8869 27039 7453
8870 27041 7455
8871 27043 7457
8872 27046 7459
8873 27048 745a
8874 27050 745b
8875 27052 745c
8876 27055 745d
8877 27056 745e
8878 27057 745f
8879 27059 7460
8880 27062 7462
8881 27064 7463
8882 27066 7464
8883 27071 7466
8884 27072 7467
8885 27075 7468
8886 27078 7469
8887 27080 746a
8888 27081 746b
8889 27085 746d
8890 27087 746e
8891 27089 746f
8892 27091 7470
8893 27094 7471
8894 27096 7472
8895 27099 7473
8896 27104 7476
8897 27114 747e
8898 27117 7480
8899 27119 7481
8900 27123 7483
8901 27127 7485
8902 27128 7486
8903 27131 7487
8904 27133 7488
8905 27136 7489
8906 27141 748b
8907 27147 748f
8908 27149 7490
8909 27150 7491
8910 27151 7492
8911 27158 7497
8912 27159 7498
8913 27162 7499
8914 27163 749a
8915 27166 749c
8916 27170 749e
8917 27172 749f
8918 27174 74a0
8919 27176 74a1
8920 27179 74a2
8921 27180 74a3
8922 27184 74a5
8923 27186 74a6
8924 27188 74a7
8925 27190 74a8
8926 27193 74a9
8927 27196 74aa
8928 27198 74ab
8929 27202 74ae
8930 27204 74af
8931 27206 74b0
8932 27208 74b1
8933 27210 74b2
8934 27215 74b5
8935 27223 74b9
8936 27224 74ba
8937 27227 74bb
8938 27231 74bd
8939 27233 74bf
8940 27249 74c8
8941 27251 74c9
8942 27252 74ca
8943 27256 74cc
8944 27260 74cf
8945 27263 74d0
8946 27267 74d3
8947 27269 74d4
8948 27273 74d6
8949 27277 74d8
8950 27281 74da
8951 27283 74db
8952 27286 74dc
8953 27291 74de
8954 27294 74df
8955 27297 74e0
8956 27302 74e2
8957 27305 74e3
8958 27308 74e4
8959 27313 74e6
8960 27316 74e7
8961 27318 74e8
8962 27321 74e9
8963 27324 74ea
8964 27326 74eb
8965 27331 74ee
8966 27334 74ef
8967 27336 74f0
8968 27339 74f1
8969 27341 74f2
8970 27344 74f4
8971 27348 74f6
8972 27351 74f7
8973 27354 74f8
8974 27358 74fa
8975 27360 74fb
8976 27363 74fc
8977 27369 74ff
8978 27374 7501
8979 27378 7503
8980 27381 7504
8981 27384 7505
8982 27386 7506
8983 27396 750c
8984 27399 750d
8985 27402 750e
8986 27409 7511
8987 27412 7512
8988 27415 7513
8989 27420 7515
8990 27423 7516
8991 27426 7517
8992 27429 7518
8993 27431 751a
8994 27435 751c
8995 27439 751e
8996 27440 751f
8997 27441 7520
8998 27442 7521
8999 27443 7522
9000 27445 7523
9001 27447 7524
9002 27449 7525
9003 27450 7526
9004 27451 7527
9005 27453 7528
9006 27454 7529
9007 27456 752a
9008 27458 752b
9009 27459 752c
9010 27463 752f
9011 27466 7530
9012 27467 7531
9013 27468 7532
9014 27469 7533
9015 27472 7536
9016 27473 7537
9017 27474 7538
9018 27475 7539
9019 27477 753a
9020 27479 753b
9021 27482 753c
9022 27483 753d
9023 27484 753e
9024 27485 753f
9025 27489 7540
9026 27492 7543
9027 27494 7544
9028 27496 7546
9029 27498 7547
9030 27501 7548
9031 27503 7549
9032 27504 754a
9033 27505 754b
9034 27506 754c
9035 27507 754d
9036 27509 754e
9037 27510 754f
9038 27512 7550
9039 27513 7551
9040 27515 7552
9041 27518 7554
9042 27522 7557
9043 27525 7559
9044 27527 755a
9045 27529 755b
9046 27531 755c
9047 27533 755d
9048 27535 755e
9049 27536 755f
9050 27539 7560
9051 27540 7561
9052 27542 7562
9053 27545 7564
9054 27547 7565
9055 27549 7566
9056 27550 7567
9057 27552 7569
9058 27554 756a
9059 27557 756b
9060 27558 756c
9061 27561 756d
9062 27564 756f
9063 27567 7570
9064 27568 7571
9065 27569 7572
9066 27572 7573
9067 27573 7574
9068 27575 7575
9069 27577 7576
9070 27578 7577
9071 27579 7578
9072 27580 7579
9073 27583 757a
9074 27584 757b
9075 27586 757c
9076 27587 757d
9077 27588 757e
9078 27589 757f
9079 27592 7581
9080 27594 7582
9081 27598 7585
9082 27599 7586
9083 27601 7587
9084 27603 7589
9085 27605 758a
9086 27606 758b
9087 27607 758c
9088 27609 758e
9089 27611 758f
9090 27614 7590
9091 27615 7591
9092 27617 7592
9093 27619 7593
9094 27621 7594
9095 27623 7595
9096 27629 7599
9097 27631 759a
9098 27634 759c
9099 27636 759d
9100 27642 75a2
9101 27645 75a3
9102 27647 75a4
9103 27649 75a5
9104 27658 75ab
9105 27664 75b0
9106 27666 75b1
9107 27668 75b2
9108 27670 75b3
9109 27672 75b4
9110 27674 75b5
9111 27678 75b7
9112 27680 75b8
9113 27682 75b9
9114 27684 75ba
9115 27687 75bc
9116 27689 75bd
9117 27691 75be
9118 27694 75bf
9119 27696 75c0
9120 27698 75c1
9121 27700 75c2
9122 27702 75c3
9123 27704 75c4
9124 27706 75c5
9125 27708 75c6
9126 27710 75c7
9127 27714 75ca
9128 27718 75cc
9129 27720 75cd
9130 27722 75ce
9131 27724 75cf
9132 27730 75d2
9133 27732 75d3
9134 27734 75d4
9135 27737 75d5
9136 27740 75d7
9137 27742 75d8
9138 27744 75d9
9139 27748 75db
9140 27750 75dc
9141 27753 75dd
9142 27756 75de
9143 27759 75df
9144 27762 75e0
9145 27765 75e1
9146 27767 75e2
9147 27769 75e3
9148 27771 75e4
9149 27775 75e7
9150 27778 75e9
9151 27782 75ec
9152 27785 75ee
9153 27787 75ef
9154 27789 75f0
9155 27792 75f1
9156 27795 75f2
9157 27798 75f3
9158 27800 75f4
9159 27808 75f9
9160 27810 75fa
9161 27813 75fc
9162 27816 75fe
9163 27818 75ff
9164 27821 7600
9165 27823 7601
9166 27825 7602
9167 27827 7603
9168 27830 7604
9169 27834 7607
9170 27836 7608
9171 27839 7609
9172 27842 760a
9173 27845 760b
9174 27848 760c
9175 27850 760d
9176 27853 760f
9177 27859 7612
9178 27861 7613
9179 27866 7615
9180 27868 7616
9181 27871 7618
9182 27873 7619
9183 27877 761b
9184 27880 761c
9185 27882 761d
9186 27885 761e
9187 27887 761f
9188 27890 7620
9189 27893 7621
9190 27896 7622
9191 27899 7623
9192 27902 7624
9193 27904 7625
9194 27907 7626
9195 27910 7627
9196 27913 7628
9197 27915 7629
9198 27921 762d
9199 27928 7630
9200 27932 7632
9201 27934 7633
9202 27937 7634
9203 27939 7635
9204 27944 7638
9205 27946 7639
9206 27948 763a
9207 27951 763b
9208 27954 763c
9209 27960 7640
9210 27963 7641
9211 27965 7642
9212 27967 7643
9213 27969 7644
9214 27971 7645
9215 27973 7646
9216 27976 7647
9217 27978 7648
9218 27980 7649
9219 27982 764a
9220 27984 764b
9221 27986 764c
9222 27989 764e
9223 27995 7652
9224 28001 7655
9225 28003 7656
9226 28007 7658
9227 28010 7659
9228 28016 765c
9229 28020 765f
9230 28023 7661
9231 28026 7662
9232 28030 7664
9233 28033 7665
9234 28037 7667
9235 28040 7668
9236 28042 7669
9237 28045 766a
9238 28048 766c
9239 28050 766d
9240 28053 766e
9241 28056 766f
9242 28058 7670
9243 28060 7671
9244 28062 7672
9245 28065 7674
9246 28068 7676
9247 28070 7678
9248 28074 767a
9249 28075 767b
9250 28077 767c
9251 28079 767d
9252 28080 767e
9253 28082 7680
9254 28083 7681
9255 28084 7682
9256 28087 7683
9257 28088 7684
9258 28089 7685
9259 28090 7686
9260 28093 7687
9261 28094 7688
9262 28100 768b
9263 28101 768c
9264 28102 768d
9265 28104 768e
9266 28107 7690
9267 28111 7693
9268 28113 7695
9269 28115 7696
9270 28119 7699
9271 28121 769a
9272 28123 769b
9273 28124 769c
9274 28126 769d
9275 28128 769e
9276 28129 769f
9277 28130 76a0
9278 28132 76a1
9279 28134 76a2
9280 28135 76a3
9281 28137 76a4
9282 28140 76a5
9283 28142 76a6
9284 28144 76a7
9285 28145 76a8
9286 28147 76aa
9287 28154 76ad
9288 28156 76ae
9289 28157 76af
9290 28158 76b0
9291 28162 76b4
9292 28166 76b6
9293 28168 76b7
9294 28170 76b8
9295 28171 76b9
9296 28172 76ba
9297 28176 76bd
9298 28179 76bf
9299 28181 76c1
9300 28183 76c2
9301 28184 76c3
9302 28186 76c5
9303 28188 76c6
9304 28191 76c8
9305 28193 76c9
9306 28195 76ca
9307 28197 76cb
9308 28199 76cc
9309 28200 76cd
9310 28202 76ce
9311 28208 76d2
9312 28211 76d4
9313 28215 76d6
9314 28216 76d7
9315 28218 76d9
9316 28223 76db
9317 28224 76dc
9318 28228 76de
9319 28229 76df
9320 28230 76e0
9321 28232 76e1
9322 28234 76e3
9323 28237 76e4
9324 28240 76e5
9325 28242 76e6
9326 28245 76e7
9327 28247 76e8
9328 28250 76ea
9329 28251 76eb
9330 28253 76ec
9331 28257 76ee
9332 28259 76f0
9333 28260 76f1
9334 28262 76f2
9335 28267 76f4
9336 28270 76f6
9337 28273 76f8
9338 28274 76f9
9339 28277 76fb
9340 28280 76fc
9341 28284 76fe
9342 28287 7700
9343 28288 7701
9344 28292 7704
9345 28296 7706
9346 28298 7707
9347 28300 7708
9348 28301 7709
9349 28302 770a
9350 28303 770b
9351 28304 770c
9352 28307 770e
9353 28313 7712
9354 28315 7714
9355 28317 7715
9356 28320 7717
9357 28322 7719
9358 28324 771a
9359 28325 771b
9360 28326 771c
9361 28328 771e
9362 28330 771f
9363 28332 7720
9364 28335 7722
9365 28339 7724
9366 28341 7725
9367 28343 7726
9368 28346 7728
9369 28348 7729
9370 28353 772d
9371 28354 772e
9372 28355 772f
9373 28363 7734
9374 28364 7735
9375 28366 7736
9376 28368 7737
9377 28370 7738
9378 28372 7739
9379 28375 773a
9380 28377 773c
9381 28379 773d
9382 28381 773e
9383 28384 7740
9384 28387 7742
9385 28393 7745
9386 28394 7746
9387 28396 7747
9388 28400 774a
9389 28404 774d
9390 28405 774e
9391 28406 774f
9392 28410 7752
9393 28416 7756
9394 28419 7757
9395 28420 7758
9396 28424 775a
9397 28426 775b
9398 28429 775c
9399 28432 775e
9400 28433 775f
9401 28435 7760
9402 28437 7761
9403 28440 7762
9404 28442 7763
9405 28444 7764
9406 28445 7765
9407 28447 7766
9408 28450 7767
9409 28452 7768
9410 28456 776a
9411 28458 776b
9412 28459 776c
9413 28466 7770
9414 28468 7772
9415 28469 7773
9416 28471 7774
9417 28477 7779
9418 28479 777a
9419 28481 777c
9420 28482 777d
9421 28484 777e
9422 28486 777f
9423 28489 7780
9424 28496 7784
9425 28507 778b
9426 28509 778c
9427 28511 778d
9428 28514 778e
9429 28520 7791
9430 28524 7794
9431 28525 7795
9432 28527 7796
9433 28534 779a
9434 28541 779e
9435 28543 779f
9436 28545 77a0
9437 28547 77a2
9438 28551 77a4
9439 28552 77a5
9440 28555 77a7
9441 28559 77a9
9442 28560 77aa
9443 28563 77ac
9444 28567 77ad
9445 28568 77ae
9446 28570 77af
9447 28571 77b0
9448 28573 77b1
9449 28577 77b3
9450 28581 77b5
9451 28584 77b6
9452 28585 77b7
9453 28587 77b9
9454 28590 77bb
9455 28593 77bc
9456 28595 77bd
9457 28596 77be
9458 28599 77bf
9459 28605 77c3
9460 28611 77c7
9461 28615 77c9
9462 28622 77cd
9463 28630 77d1
9464 28631 77d2
9465 28637 77d5
9466 28640 77d7
9467 28644 77d9
9468 28646 77da
9469 28648 77db
9470 28649 77dc
9471 28654 77de
9472 28657 77df
9473 28659 77e0
9474 28662 77e2
9475 28663 77e3
9476 28666 77e4
9477 28668 77e5
9478 28669 77e6
9479 28671 77e7
9480 28674 77e9
9481 28677 77ea
9482 28680 77ec
9483 28681 77ed
9484 28683 77ee
9485 28686 77ef
9486 28687 77f0
9487 28689 77f1
9488 28694 77f3
9489 28695 77f4
9490 28699 77f8
9491 28702 77fb
9492 28703 77fc
9493 28711 7802
9494 28715 7805
9495 28716 7806
9496 28719 7809
9497 28724 780c
9498 28726 780d
9499 28728 780e
9500 28735 7811
9501 28739 7812
9502 28743 7814
9503 28744 7815
9504 28748 7819
9505 28753 781d
9506 28757 7820
9507 28758 7821
9508 28759 7822
9509 28760 7823
9510 28763 7825
9511 28766 7826
9512 28769 7827
9513 28775 782c
9514 28777 782d
9515 28779 782e
9516 28783 7830
9517 28787 7832
9518 28790 7834
9519 28791 7835
9520 28793 7837
9521 28797 783a
9522 28802 783f
9523 28808 7843
9524 28809 7844
9525 28810 7845
9526 28812 7847
9527 28814 7848
9528 28818 784c
9529 28821 784e
9530 28822 784f
9531 28825 7851
9532 28827 7852
9533 28837 785c
9534 28838 785d
9535 28840 785e
9536 28843 7860
9537 28845 7861
9538 28848 7863
9539 28850 7864
9540 28855 7868
9541 28857 786a
9542 28858 786b
9543 28861 786c
9544 28864 786e
9545 28866 786f
9546 28869 7872
9547 28872 7874
9548 28880 787a
9549 28885 787c
9550 28887 787e
9551 28893 7881
9552 28899 7886
9553 28901 7887
9554 28906 788a
9555 28908 788c
9556 28911 788d
9557 28912 788e
9558 28914 788f
9559 28916 7891
9560 28919 7893
9561 28921 7894
9562 28922 7895
9563 28924 7897
9564 28927 7898
9565 28929 789a
9566 28933 789d
9567 28934 789e
9568 28935 789f
9569 28938 78a1
9570 28943 78a3
9571 28946 78a4
9572 28951 78a7
9573 28952 78a8
9574 28954 78a9
9575 28955 78aa
9576 28959 78ac
9577 28960 78ad
9578 28962 78af
9579 28964 78b0
9580 28966 78b1
9581 28968 78b2
9582 28970 78b3
9583 28975 78b5
9584 28982 78ba
9585 28984 78bb
9586 28986 78bc
9587 28987 78bd
9588 28988 78be
9589 28990 78bf
9590 28993 78c1
9591 28999 78c5
9592 29001 78c6
9593 29003 78c7
9594 29006 78c8
9595 29009 78c9
9596 29011 78ca
9597 29012 78cb
9598 29014 78cc
9599 29018 78ce
9600 29023 78d0
9601 29026 78d1
9602 29028 78d2
9603 29029 78d3
9604 29032 78d4
9605 29035 78d5
9606 29037 78d6
9607 29044 78da
9608 29045 78db
9609 29051 78df
9610 29054 78e0
9611 29056 78e1
9612 29061 78e4
9613 29064 78e6
9614 29065 78e7
9615 29066 78e8
9616 29070 78ea
9617 29073 78ec
9618 29078 78ef
9619 29085 78f2
9620 29088 78f3
9621 29090 78f4
9622 29092 78f6
9623 29094 78f7
9624 29098 78f9
9625 29099 78fa
9626 29102 78fb
9627 29107 78fd
9628 29108 78fe
9629 29109 78ff
9630 29111 7900
9631 29112 7901
9632 29118 7906
9633 29120 7907
9634 29126 790c
9635 29129 790e
9636 29132 7910
9637 29134 7911
9638 29135 7912
9639 29143 7919
9640 29145 791a
9641 29147 791b
9642 29150 791c
9643 29155 791e
9644 29158 791f
9645 29160 7920
9646 29169 7925
9647 29170 7926
9648 29173 7927
9649 29174 7928
9650 29175 7929
9651 29177 792a
9652 29179 792b
9653 29182 792c
9654 29184 792d
9655 29187 792e
9656 29191 7930
9657 29192 7931
9658 29199 7934
9659 29201 7935
9660 29209 793a
9661 29211 793b
9662 29213 793c
9663 29215 793d
9664 29217 793e
9665 29219 793f
9666 29221 7940
9667 29223 7941
9668 29225 7942
9669 29229 7944
9670 29231 7945
9671 29233 7946
9672 29235 7947
9673 29237 7948
9674 29239 7949
9675 29241 794a
9676 29243 794b
9677 29248 794f
9678 29250 7950
9679 29252 7951
9680 29255 7953
9681 29258 7954
9682 29260 7955
9683 29262 7956
9684 29264 7957
9685 29267 7958
9686 29270 795a
9687 29272 795b
9688 29274 795c
9689 29276 795d
9690 29278 795e
9691 29280 795f
9692 29282 7960
9693 29286 7962
9694 29291 7965
9695 29294 7967
9696 29296 7968
9697 29298 7969
9698 29301 796b
9699 29304 796d
9700 29311 7972
9701 29319 7977
9702 29322 7979
9703 29324 797a
9704 29326 797b
9705 29328 797c
9706 29331 797e
9707 29334 797f
9708 29337 7980
9709 29340 7981
9710 29345 7984
9711 29347 7985
9712 29353 798a
9713 29356 798b
9714 29359 798c
9715 29361 798d
9716 29364 798e
9717 29366 798f
9718 29369 7991
9719 29373 7993
9720 29375 7994
9721 29377 7995
9722 29380 7996
9723 29384 7998
9724 29389 799b
9725 29391 799c
9726 29393 799d
9727 29400 79a1
9728 29407 79a6
9729 29410 79a7
9730 29412 79a8
9731 29415 79a9
9732 29417 79aa
9733 29419 79ab
9734 29425 79ae
9735 29427 79af
9736 29429 79b0
9737 29431 79b1
9738 29435 79b3
9739 29437 79b4
9740 29443 79b8
9741 29446 79b9
9742 29449 79ba
9743 29451 79bb
9744 29455 79bd
9745 29458 79be
9746 29459 79bf
9747 29461 79c0
9748 29464 79c1
9749 29466 79c2
9750 29469 79c4
9751 29473 79c7
9752 29475 79c8
9753 29477 79c9
9754 29478 79ca
9755 29479 79cb
9756 29481 79cc
9757 29483 79cd
9758 29486 79cf
9759 29488 79d1
9760 29489 79d2
9761 29492 79d4
9762 29494 79d5
9763 29497 79d6
9764 29500 79d8
9765 29503 79da
9766 29508 79dd
9767 29509 79de
9768 29510 79df
9769 29511 79e0
9770 29513 79e1
9771 29515 79e2
9772 29518 79e3
9773 29519 79e4
9774 29521 79e5
9775 29522 79e6
9776 29525 79e7
9777 29528 79e9
9778 29529 79ea
9779 29532 79eb
9780 29535 79ec
9781 29537 79ed
9782 29541 79f0
9783 29543 79f1
9784 29551 79f8
9785 29555 79fb
9786 29558 79fc
9787 29562 7a00
9788 29565 7a02
9789 29567 7a03
9790 29571 7a05
9791 29576 7a07
9792 29578 7a08
9793 29579 7a09
9794 29580 7a0a
9795 29582 7a0b
9796 29586 7a0c
9797 29588 7a0d
9798 29591 7a0e
9799 29595 7a11
9800 29600 7a14
9801 29603 7a15
9802 29606 7a17
9803 29608 7a18
9804 29609 7a19
9805 29611 7a1a
9806 29613 7a1b
9807 29615 7a1c
9808 29619 7a1e
9809 29620 7a1f
9810 29623 7a20
9811 29626 7a21
9812 29633 7a27
9813 29641 7a2b
9814 29644 7a2d
9815 29647 7a2e
9816 29648 7a2f
9817 29651 7a30
9818 29653 7a31
9819 29655 7a32
9820 29657 7a34
9821 29659 7a35
9822 29662 7a37
9823 29665 7a38
9824 29667 7a39
9825 29669 7a3a
9826 29671 7a3b
9827 29673 7a3c
9828 29675 7a3d
9829 29679 7a3e
9830 29682 7a3f
9831 29684 7a40
9832 29687 7a42
9833 29689 7a43
9834 29691 7a44
9835 29694 7a45
9836 29697 7a46
9837 29698 7a47
9838 29700 7a48
9839 29703 7a49
9840 29709 7a4c
9841 29710 7a4d
9842 29711 7a4e
9843 29713 7a4f
9844 29714 7a50
9845 29720 7a55
9846 29722 7a56
9847 29725 7a57
9848 29727 7a59
9849 29730 7a5c
9850 29732 7a5d
9851 29735 7a5f
9852 29738 7a60
9853 29741 7a61
9854 29742 7a62
9855 29744 7a63
9856 29747 7a65
9857 29751 7a67
9858 29755 7a69
9859 29758 7a6a
9860 29759 7a6b
9861 29764 7a6d
9862 29768 7a70
9863 29774 7a74
9864 29777 7a75
9865 29780 7a76
9866 29784 7a78
9867 29787 7a79
9868 29790 7a7a
9869 29796 7a7d
9870 29799 7a7e
9871 29802 7a7f
9872 29806 7a80
9873 29809 7a81
9874 29812 7a82
9875 29814 7a83
9876 29817 7a84
9877 29820 7a85
9878 29823 7a86
9879 29828 7a88
9880 29833 7a8a
9881 29836 7a8b
9882 29845 7a90
9883 29848 7a91
9884 29851 7a92
9885 29854 7a93
9886 29857 7a94
9887 29860 7a95
9888 29863 7a96
9889 29867 7a97
9890 29870 7a98
9891 29880 7a9e
9892 29883 7a9f
9893 29886 7aa0
9894 29892 7aa3
9895 29901 7aa9
9896 29904 7aaa
9897 29909 7aac
9898 29913 7aae
9899 29916 7aaf
9900 29919 7ab0
9901 29926 7ab3
9902 29931 7ab5
9903 29934 7ab6
9904 29941 7ab9
9905 29943 7aba
9906 29946 7abb
9907 29949 7abc
9908 29952 7abd
9909 29954 7abe
9910 29957 7abf
9911 29966 7ac3
9912 29969 7ac4
9913 29973 7ac5
9914 29976 7ac6
9915 29978 7ac7
9916 29982 7ac8
9917 29985 7ac9
9918 29988 7aca
9919 29991 7acb
9920 29993 7acc
9921 29995 7acd
9922 29997 7ace
9923 29999 7acf
9924 30002 7ad1
9925 30004 7ad2
9926 30006 7ad3
9927 30009 7ad5
9928 30015 7ad9
9929 30017 7ada
9930 30019 7adb
9931 30022 7adc
9932 30024 7add
9933 30027 7adf
9934 30029 7ae0
9935 30031 7ae1
9936 30033 7ae2
9937 30036 7ae3
9938 30040 7ae5
9939 30042 7ae6
9940 30044 7ae7
9941 30046 7ae8
9942 30048 7ae9
9943 30050 7aea
9944 30052 7aeb
9945 30055 7aec
9946 30057 7aed
9947 30061 7aef
9948 30063 7af0
9949 30065 7af1
9950 30069 7af4
9951 30072 7af6
9952 30076 7af8
9953 30078 7af9
9954 30079 7afa
9955 30081 7afb
9956 30085 7afd
9957 30087 7afe
9958 30089 7aff
9959 30095 7b02
9960 30097 7b04
9961 30101 7b06
9962 30103 7b07
9963 30105 7b08
9964 30110 7b0a
9965 30113 7b0b
9966 30121 7b0f
9967 30125 7b11
9968 30127 7b12
9969 30132 7b14
9970 30137 7b18
9971 30140 7b19
9972 30144 7b1b
9973 30149 7b1e
9974 30152 7b1f
9975 30155 7b20
9976 30161 7b23
9977 30165 7b25
9978 30167 7b26
9979 30169 7b27
9980 30172 7b28
9981 30174 7b29
9982 30176 7b2a
9983 30178 7b2b
9984 30181 7b2c
9985 30184 7b2d
9986 30187 7b2e
9987 30189 7b2f
9988 30192 7b30
9989 30195 7b31
9990 30199 7b33
9991 30201 7b34
9992 30203 7b35
9993 30205 7b36
9994 30209 7b39
9995 30213 7b3b
9996 30216 7b3d
9997 30218 7b3f
9998 30219 7b40
9999 30222 7b41
10000 30229 7b45
10001 30231 7b46
10002 30233 7b47
10003 30235 7b48
10004 30237 7b49
10005 30241 7b4b
10006 30243 7b4c
10007 30246 7b4d
10008 30248 7b4e
10009 30251 7b4f
10010 30253 7b50
10011 30256 7b51
10012 30258 7b52
10013 30260 7b53
10014 30262 7b54
10015 30265 7b55
10016 30267 7b56
10017 30277 7b5d
10018 30282 7b60
10019 30291 7b64
10020 30294 7b65
10021 30297 7b66
10022 30299 7b67
10023 30302 7b69
10024 30304 7b6a
10025 30307 7b6c
10026 30309 7b6d
10027 30312 7b6e
10028 30314 7b6f
10029 30316 7b70
10030 30318 7b71
10031 30320 7b72
10032 30323 7b73
10033 30326 7b74
10034 30328 7b75
10035 30333 7b77
10036 30337 7b79
10037 30339 7b7a
10038 30347 7b7f
10039 30354 7b84
10040 30358 7b86
10041 30360 7b87
10042 30364 7b89
10043 30368 7b8b
10044 30372 7b8d
10045 30375 7b8e
10046 30378 7b8f
10047 30381 7b90
10048 30384 7b91
10049 30386 7b92
10050 30391 7b94
10051 30393 7b95
10052 30396 7b96
10053 30398 7b97
10054 30400 7b98
10055 30403 7b99
10056 30405 7b9a
10057 30407 7b9b
10058 30410 7b9c
10059 30413 7b9d
10060 30415 7b9e
10061 30417 7b9f
10062 30419 7ba0
10063 30422 7ba1
10064 30431 7ba5
10065 30436 7baa
10066 30439 7bac
10067 30441 7bad
10068 30446 7baf
10069 30448 7bb0
10070 30450 7bb1
10071 30452 7bb2
10072 30455 7bb4
10073 30457 7bb5
10074 30460 7bb6
10075 30463 7bb8
10076 30467 7bba
10077 30469 7bbb
10078 30470 7bbc
10079 30472 7bbd
10080 30477 7bc0
10081 30480 7bc1
10082 30482 7bc2
10083 30484 7bc4
10084 30486 7bc5
10085 30488 7bc6
10086 30491 7bc7
10087 30494 7bc8
10088 30496 7bc9
10089 30498 7bca
10090 30500 7bcb
10091 30503 7bcc
10092 30509 7bcf
10093 30517 7bd4
10094 30521 7bd6
10095 30523 7bd7
10096 30527 7bd9
10097 30530 7bda
10098 30533 7bdb
10099 30538 7bdd
10100 30544 7be0
10101 30554 7be4
10102 30556 7be5
10103 30559 7be6
10104 30564 7be8
10105 30567 7be9
10106 30569 7bea
10107 30576 7bed
10108 30580 7bf0
10109 30585 7bf2
10110 30588 7bf3
10111 30591 7bf4
10112 30594 7bf5
10113 30595 7bf6
10114 30597 7bf7
10115 30600 7bf8
10116 30603 7bf9
10117 30606 7bfa
10118 30610 7bfc
10119 30615 7bfe
10120 30620 7c00
10121 30622 7c01
10122 30624 7c02
10123 30626 7c03
10124 30629 7c04
10125 30633 7c06
10126 30636 7c07
10127 30640 7c09
10128 30646 7c0b
10129 30649 7c0c
10130 30652 7c0d
10131 30655 7c0e
10132 30657 7c0f
10133 30661 7c11
10134 30664 7c12
10135 30667 7c13
10136 30669 7c14
10137 30674 7c17
10138 30676 7c19
10139 30679 7c1b
10140 30686 7c1e
10141 30688 7c1f
10142 30690 7c20
10143 30693 7c21
10144 30697 7c23
10145 30700 7c25
10146 30702 7c26
10147 30704 7c27
10148 30707 7c28
10149 30711 7c2a
10150 30714 7c2b
10151 30716 7c2c
10152 30721 7c2f
10153 30724 7c31
10154 30727 7c33
10155 30730 7c34
10156 30733 7c36
10157 30735 7c37
10158 30738 7c38
10159 30740 7c39
10160 30742 7c3a
10161 30748 7c3d
10162 30751 7c3e
10163 30754 7c3f
10164 30757 7c40
10165 30761 7c42
10166 30764 7c43
10167 30769 7c45
10168 30772 7c46
10169 30780 7c4a
10170 30784 7c4c
10171 30786 7c4d
10172 30789 7c4f
10173 30791 7c50
10174 30794 7c51
10175 30797 7c52
10176 30798 7c53
10177 30800 7c54
10178 30803 7c55
10179 30805 7c56
10180 30807 7c57
10181 30810 7c58
10182 30812 7c59
10183 30815 7c5a
10184 30817 7c5b
10185 30820 7c5c
10186 30823 7c5d
10187 30826 7c5e
10188 30828 7c5f
10189 30831 7c60
10190 30834 7c61
10191 30837 7c63
10192 30840 7c64
10193 30842 7c65
10194 30847 7c67
10195 30851 7c69
10196 30858 7c6c
10197 30861 7c6d
10198 30864 7c6e
10199 30866 7c6f
10200 30869 7c70
10201 30873 7c72
10202 30875 7c73
10203 30879 7c75
10204 30885 7c79
10205 30890 7c7b
10206 30892 7c7c
10207 30895 7c7d
10208 30898 7c7e
10209 30905 7c81
10210 30907 7c82
10211 30909 7c83
10212 30916 7c86
10213 30919 7c87
10214 30923 7c89
10215 30927 7c8b
10216 30930 7c8d
10217 30934 7c8f
10218 30935 7c90
10219 30939 7c92
10220 30943 7c94
10221 30946 7c95
10222 30950 7c97
10223 30952 7c98
10224 30956 7c9b
10225 30960 7c9e
10226 30963 7c9f
10227 30965 7ca0
10228 30966 7ca1
10229 30968 7ca2
10230 30973 7ca4
10231 30975 7ca5
10232 30978 7ca6
10233 30981 7ca7
10234 30984 7ca8
10235 30988 7cab
10236 30991 7cad
10237 30993 7cae
10238 30998 7cb0
10239 31000 7cb1
10240 31002 7cb2
10241 31005 7cb3
10242 31010 7cb6
10243 31012 7cb7
10244 31015 7cb9
10245 31018 7cba
10246 31020 7cbb
10247 31023 7cbc
10248 31026 7cbd
10249 31029 7cbe
10250 31031 7cbf
10251 31033 7cc0
10252 31035 7cc2
10253 31040 7cc4
10254 31042 7cc5
10255 31046 7cc7
10256 31048 7cc8
10257 31050 7cc9
10258 31053 7cca
10259 31059 7ccd
10260 31062 7cce
10261 31064 7ccf
10262 31070 7cd2
10263 31073 7cd3
10264 31076 7cd4
10265 31079 7cd5
10266 31081 7cd6
10267 31084 7cd7
10268 31087 7cd8
10269 31089 7cd9
10270 31093 7cda
10271 31097 7cdc
10272 31100 7cdd
10273 31103 7cde
10274 31105 7cdf
10275 31107 7ce0
10276 31111 7ce2
10277 31116 7ce6
10278 31118 7ce7
10279 31122 7ce9
10280 31126 7ceb
10281 31134 7cef
10282 31140 7cf2
10283 31144 7cf4
10284 31147 7cf5
10285 31150 7cf6
10286 31155 7cf8
10287 31157 7cf9
10288 31158 7cfa
10289 31160 7cfb
10290 31165 7cfe
10291 31168 7d00
10292 31172 7d02
10293 31174 7d03
10294 31176 7d04
10295 31178 7d05
10296 31180 7d06
10297 31182 7d07
10298 31184 7d08
10299 31187 7d09
10300 31190 7d0a
10301 31192 7d0b
10302 31195 7d0d
10303 31199 7d0f
10304 31201 7d10
10305 31204 7d11
10306 31206 7d12
10307 31208 7d13
10308 31210 7d14
10309 31212 7d15
10310 31215 7d16
10311 31217 7d17
10312 31219 7d18
10313 31221 7d19
10314 31223 7d1a
10315 31226 7d1b
10316 31229 7d1c
10317 31231 7d1d
10318 31234 7d1e
10319 31238 7d20
10320 31240 7d21
10321 31242 7d22
10322 31244 7d23
10323 31248 7d26
10324 31253 7d2a
10325 31255 7d2b
10326 31258 7d2c
10327 31260 7d2d
10328 31262 7d2e
10329 31264 7d2f
10330 31266 7d30
10331 31268 7d31
10332 31271 7d32
10333 31273 7d33
10334 31276 7d35
10335 31281 7d39
10336 31283 7d3a
10337 31287 7d3c
10338 31289 7d3d
10339 31291 7d3e
10340 31293 7d3f
10341 31295 7d40
10342 31297 7d41
10343 31300 7d42
10344 31302 7d43
10345 31304 7d44
10346 31306 7d45
10347 31308 7d46
10348 31310 7d47
10349 31312 7d48
10350 31317 7d4b
10351 31319 7d4c
10352 31321 7d4d
10353 31324 7d4e
10354 31326 7d4f
10355 31328 7d50
10356 31330 7d51
10357 31334 7d53
10358 31337 7d55
10359 31339 7d56
10360 31341 7d57
10361 31345 7d59
10362 31347 7d5a
10363 31350 7d5b
10364 31353 7d5c
10365 31356 7d5d
10366 31358 7d5e
10367 31363 7d61
10368 31365 7d62
10369 31367 7d63
10370 31370 7d65
10371 31372 7d66
10372 31374 7d67
10373 31376 7d68
10374 31380 7d6a
10375 31385 7d6e
10376 31389 7d70
10377 31391 7d71
10378 31394 7d72
10379 31396 7d73
10380 31401 7d75
10381 31403 7d76
10382 31406 7d78
10383 31408 7d79
10384 31411 7d7a
10385 31413 7d7b
10386 31416 7d7d
10387 31420 7d7f
10388 31423 7d81
10389 31426 7d82
10390 31428 7d83
10391 31432 7d85
10392 31435 7d86
10393 31438 7d88
10394 31440 7d89
10395 31444 7d8b
10396 31446 7d8c
10397 31448 7d8d
10398 31452 7d8f
10399 31456 7d91
10400 31459 7d93
10401 31464 7d96
10402 31467 7d97
10403 31472 7d99
10404 31474 7d9a
10405 31476 7d9b
10406 31478 7d9c
10407 31481 7d9d
10408 31483 7d9e
10409 31486 7d9f
10410 31489 7da0
10411 31493 7da2
10412 31497 7da3
10413 31502 7da6
10414 31504 7da7
10415 31510 7daa
10416 31513 7dab
10417 31515 7dac
10418 31517 7dad
10419 31519 7dae
10420 31522 7daf
10421 31524 7db0
10422 31526 7db1
10423 31528 7db2
10424 31531 7db3
10425 31533 7db4
10426 31535 7db5
10427 31537 7db6
10428 31539 7db7
10429 31541 7db8
10430 31543 7db9
10431 31546 7dba
10432 31548 7dbb
10433 31551 7dbd
10434 31553 7dbe
10435 31556 7dbf
10436 31558 7dc0
10437 31562 7dc2
10438 31565 7dc3
10439 31567 7dc4
10440 31570 7dc5
10441 31573 7dc6
10442 31575 7dc7
10443 31580 7dca
10444 31582 7dcb
10445 31585 7dcc
10446 31588 7dcd
10447 31590 7dce
10448 31592 7dcf
10449 31595 7dd0
10450 31598 7dd1
10451 31600 7dd2
10452 31605 7dd5
10453 31607 7dd6
10454 31609 7dd7
10455 31611 7dd8
10456 31614 7dd9
10457 31616 7dda
10458 31620 7ddc
10459 31623 7ddd
10460 31626 7dde
10461 31629 7de0
10462 31631 7de1
10463 31633 7de2
10464 31635 7de3
10465 31637 7de4
10466 31640 7de5
10467 31643 7de6
10468 31647 7de8
10469 31650 7de9
10470 31652 7dea
10471 31654 7deb
10472 31656 7dec
10473 31658 7ded
10474 31662 7def
10475 31667 7df1
10476 31670 7df2
10477 31674 7df4
10478 31676 7df5
10479 31679 7df6
10480 31683 7df9
10481 31685 7dfa
10482 31688 7dfb
10483 31695 7e00
10484 31697 7e01
10485 31702 7e04
10486 31704 7e05
10487 31708 7e08
10488 31711 7e09
10489 31714 7e0a
10490 31716 7e0b
10491 31726 7e10
10492 31728 7e11
10493 31730 7e12
10494 31736 7e15
10495 31740 7e17
10496 31746 7e1b
10497 31749 7e1c
10498 31751 7e1d
10499 31753 7e1e
10500 31755 7e1f
10501 31758 7e20
10502 31760 7e21
10503 31762 7e22
10504 31764 7e23
10505 31770 7e26
10506 31772 7e27
10507 31775 7e28
10508 31781 7e2b
10509 31784 7e2c
10510 31786 7e2d
10511 31789 7e2e
10512 31791 7e2f
10513 31794 7e31
10514 31796 7e32
10515 31798 7e33
10516 31801 7e35
10517 31804 7e36
10518 31806 7e37
10519 31811 7e39
10520 31814 7e3a
10521 31817 7e3b
10522 31821 7e3d
10523 31824 7e3e
10524 31826 7e3f
10525 31829 7e41
10526 31833 7e43
10527 31835 7e44
10528 31838 7e45
10529 31840 7e46
10530 31843 7e47
10531 31846 7e48
10532 31850 7e4a
10533 31852 7e4b
10534 31856 7e4d
10535 31858 7e4e
10536 31861 7e50
10537 31864 7e52
10538 31868 7e54
10539 31870 7e55
10540 31873 7e56
10541 31879 7e58
10542 31882 7e59
10543 31885 7e5a
10544 31890 7e5d
10545 31892 7e5e
10546 31894 7e5f
10547 31897 7e61
10548 31899 7e62
10549 31903 7e65
10550 31905 7e66
10551 31907 7e67
10552 31912 7e69
10553 31916 7e6a
10554 31918 7e6b
10555 31921 7e6d
10556 31924 7e6e
10557 31926 7e6f
10558 31928 7e70
10559 31934 7e73
10560 31937 7e75
10561 31943 7e78
10562 31946 7e79
10563 31950 7e7b
10564 31953 7e7c
10565 31955 7e7d
10566 31957 7e7e
10567 31960 7e7f
10568 31965 7e81
10569 31967 7e82
10570 31970 7e83
10571 31974 7e86
10572 31976 7e87
10573 31979 7e88
10574 31981 7e89
10575 31983 7e8a
10576 31988 7e8c
10577 31990 7e8d
10578 31992 7e8e
10579 31994 7e8f
10580 31997 7e90
10581 31999 7e91
10582 32002 7e92
10583 32004 7e93
10584 32007 7e94
10585 32010 7e95
10586 32012 7e96
10587 32016 7e98
10588 32019 7e9a
10589 32022 7e9b
10590 32026 7e9c
10591 32029 7e9d
10592 32031 7e9e
10593 32033 7e9f
10594 32184 7f36
10595 32189 7f38
10596 32194 7f3a
10597 32197 7f3b
10598 32199 7f3c
10599 32201 7f3d
10600 32204 7f3e
10601 32207 7f3f
10602 32215 7f43
10603 32218 7f44
10604 32220 7f45
10605 32224 7f47
10606 32234 7f4c
10607 32236 7f4d
10608 32238 7f4e
10609 32241 7f4f
10610 32244 7f50
10611 32247 7f51
10612 32249 7f52
10613 32251 7f53
10614 32252 7f54
10615 32256 7f55
10616 32261 7f58
10617 32264 7f5b
10618 32267 7f5c
10619 32269 7f5d
10620 32271 7f5f
10621 32272 7f60
10622 32274 7f61
10623 32276 7f63
10624 32278 7f64
10625 32280 7f65
10626 32282 7f66
10627 32284 7f67
10628 32285 7f68
10629 32287 7f69
10630 32288 7f6a
10631 32291 7f6b
10632 32294 7f6d
10633 32295 7f6e
10634 32298 7f70
10635 32300 7f71
10636 32301 7f72
10637 32304 7f75
10638 32306 7f77
10639 32309 7f78
10640 32311 7f79
10641 32319 7f7d
10642 32321 7f7e
10643 32323 7f7f
10644 32325 7f80
10645 32328 7f82
10646 32330 7f83
10647 32334 7f85
10648 32336 7f86
10649 32339 7f87
10650 32340 7f88
10651 32344 7f8a
10652 32346 7f8b
10653 32348 7f8c
10654 32350 7f8d
10655 32351 7f8e
10656 32354 7f8f
10657 32356 7f90
10658 32358 7f91
10659 32363 7f94
10660 32365 7f96
10661 32367 7f97
10662 32372 7f9a
10663 32376 7f9c
10664 32378 7f9d
10665 32381 7f9e
10666 32385 7fa1
10667 32388 7fa2
10668 32390 7fa3
10669 32391 7fa4
10670 32394 7fa6
10671 32398 7fa8
10672 32399 7fa9
10673 32400 7faa
10674 32405 7fad
10675 32408 7fae
10676 32410 7faf
10677 32416 7fb2
10678 32420 7fb4
10679 32423 7fb6
10680 32426 7fb8
10681 32430 7fb9
10682 32437 7fbc
10683 32439 7fbd
10684 32441 7fbf
10685 32444 7fc0
10686 32446 7fc1
10687 32451 7fc3
10688 32454 7fc5
10689 32456 7fc6
10690 32460 7fc8
10691 32463 7fca
10692 32466 7fcc
10693 32471 7fce
10694 32474 7fcf
10695 32479 7fd2
10696 32484 7fd4
10697 32486 7fd5
10698 32495 7fdb
10699 32503 7fdf
10700 32506 7fe0
10701 32509 7fe1
10702 32514 7fe3
10703 32519 7fe5
10704 32521 7fe6
10705 32527 7fe8
10706 32530 7fe9
10707 32535 7feb
10708 32539 7fec
10709 32544 7fee
10710 32546 7fef
10711 32549 7ff0
10712 32552 7ff2
10713 32555 7ff3
10714 32565 7ff9
10715 32567 7ffa
10716 32570 7ffb
10717 32571 7ffc
10718 32575 7ffd
10719 32577 7ffe
10720 32579 7fff
10721 32581 8000
10722 32584 8001
10723 32586 8002
10724 32587 8003
10725 32589 8004
10726 32591 8005
10727 32592 8006
10728 32594 8007
10729 32595 8008
10730 32599 800a
10731 32601 800b
10732 32604 800c
10733 32605 800d
10734 32608 800e
10735 32610 800f
10736 32611 8010
10737 32612 8011
10738 32613 8012
10739 32616 8013
10740 32618 8014
10741 32621 8015
10742 32623 8016
10743 32626 8017
10744 32628 8018
10745 32631 8019
10746 32637 801c
10747 32639 801d
10748 32642 801e
10749 32644 801f
10750 32646 8020
10751 32649 8021
10752 32653 8024
10753 32657 8026
10754 32661 8028
10755 32669 802c
10756 32674 802e
10757 32679 8030
10758 32685 8033
10759 32687 8034
10760 32689 8035
10761 32691 8036
10762 32693 8037
10763 32696 8039
10764 32699 803a
10765 32701 803b
10766 32703 803c
10767 32705 803d
10768 32707 803e
10769 32710 803f
10770 32713 8040
10771 32717 8043
10772 32720 8044
10773 32723 8046
10774 32731 804a
10775 32744 8052
10776 32751 8056
10777 32755 8058
10778 32759 805a
10779 32768 805e
10780 32771 805f
10781 32772 8060
10782 32774 8061
10783 32777 8062
10784 32782 8064
10785 32786 8066
10786 32790 8068
10787 32797 806d
10788 32800 806f
10789 32803 8070
10790 32806 8071
10791 32809 8072
10792 32812 8073
10793 32814 8074
10794 32816 8075
10795 32818 8076
10796 32821 8077
10797 32826 8079
10798 32830 807b
10799 32833 807d
10800 32836 807e
10801 32839 807f
10802 32840 8080
10803 32841 8081
10804 32846 8084
10805 32848 8085
10806 32849 8086
10807 32851 8087
10808 32854 8088
10809 32856 8089
10810 32859 808b
10811 32861 808c
10812 32864 808e
10813 32873 8093
10814 32880 8096
10815 32883 8098
10816 32885 8099
10817 32887 809a
10818 32889 809b
10819 32891 809c
10820 32893 809d
10821 32895 809e
10822 32900 80a1
10823 32903 80a2
10824 32908 80a4
10825 32909 80a5
10826 32911 80a6
10827 32913 80a7
10828 32916 80a9
10829 32919 80aa
10830 32922 80ab
10831 32925 80ac
10832 32927 80ad
10833 32932 80af
10834 32935 80b1
10835 32938 80b2
10836 32942 80b4
10837 32951 80b8
10838 32954 80b9
10839 32956 80ba
10840 32970 80c3
10841 32972 80c4
10842 32974 80c5
10843 32976 80c6
10844 32980 80c8
10845 32985 80ca
10846 32988 80cc
10847 32990 80cd
10848 32993 80ce
10849 32996 80cf
10850 33002 80d2
10851 33004 80d4
10852 33006 80d5
10853 33008 80d6
10854 33011 80d7
10855 33014 80d8
10856 33017 80d9
10857 33019 80da
10858 33021 80db
10859 33025 80dd
10860 33028 80de
10861 33032 80e0
10862 33035 80e1
10863 33040 80e4
10864 33043 80e5
10865 33045 80e6
10866 33055 80ed
10867 33058 80ee
10868 33060 80ef
10869 33063 80f0
10870 33066 80f1
10871 33068 80f2
10872 33071 80f3
10873 33074 80f4
10874 33076 80f5
10875 33079 80f6
10876 33082 80f7
10877 33084 80f8
10878 33087 80f9
10879 33089 80fa
10880 33092 80fb
10881 33094 80fc
10882 33097 80fd
10883 33100 80fe
10884 33106 8102
10885 33108 8103
10886 33112 8105
10887 33114 8106
10888 33116 8107
10889 33118 8108
10890 33121 8109
10891 33123 810a
10892 33126 810b
10893 33130 810d
10894 33144 8116
10895 33147 8117
10896 33149 8118
10897 33154 811a
10898 33157 811b
10899 33159 811c
10900 33162 811e
10901 33166 8120
10902 33172 8123
10903 33175 8124
10904 33181 8127
10905 33185 8129
10906 33190 812b
10907 33193 812c
10908 33199 812f
10909 33201 8130
10910 33204 8131
10911 33207 8133
10912 33211 8135
10913 33216 8139
10914 33219 813a
10915 33223 813c
10916 33225 813d
10917 33228 813e
10918 33233 8141
10919 33241 8145
10920 33242 8146
10921 33244 8147
10922 33250 814a
10923 33252 814b
10924 33255 814c
10925 33259 814e
10926 33264 8150
10927 33266 8151
10928 33269 8152
10929 33272 8153
10930 33275 8154
10931 33278 8155
10932 33283 8157
10933 33296 815f
10934 33298 8160
10935 33301 8161
10936 33310 8165
10937 33312 8166
10938 33314 8167
10939 33317 8168
10940 33318 8169
10941 33322 816b
10942 33326 816d
10943 33329 816e
10944 33332 816f
10945 33335 8170
10946 33338 8171
10947 33343 8173
10948 33346 8174
10949 33354 8177
10950 33356 8178
10951 33358 8179
10952 33360 817a
10953 33368 817f
10954 33371 8180
10955 33374 8181
10956 33376 8182
10957 33379 8183
10958 33381 8184
10959 33385 8185
10960 33387 8186
10961 33392 8188
10962 33397 818a
10963 33399 818b
10964 33406 818e
10965 33408 818f
10966 33411 8190
10967 33415 8193
10968 33418 8195
10969 33420 8196
10970 33424 8198
10971 33428 819a
10972 33430 819b
10973 33432 819c
10974 33434 819d
10975 33437 819e
10976 33441 81a0
10977 33445 81a2
10978 33448 81a3
10979 33451 81a4
10980 33457 81a8
10981 33460 81a9
10982 33469 81ae
10983 33472 81b0
10984 33476 81b2
10985 33479 81b3
10986 33481 81b4
10987 33483 81b5
10988 33490 81b8
10989 33494 81ba
10990 33497 81bb
10991 33502 81bd
10992 33505 81be
10993 33508 81bf
10994 33511 81c0
10995 33514 81c1
10996 33517 81c2
10997 33520 81c3
10998 33525 81c5
10999 33527 81c6
11000 33532 81c8
11001 33535 81c9
11002 33538 81ca
11003 33540 81cb
11004 33544 81cd
11005 33547 81ce
11006 33549 81cf
11007 33554 81d1
11008 33558 81d3
11009 33561 81d5
11010 33564 81d6
11011 33566 81d7
11012 33569 81d8
11013 33572 81d9
11014 33574 81da
11015 33576 81db
11016 33580 81dd
11017 33584 81de
11018 33587 81df
11019 33590 81e0
11020 33592 81e1
11021 33596 81e3
11022 33598 81e4
11023 33600 81e5
11024 33603 81e7
11025 33605 81e8
11026 33608 81ea
11027 33609 81eb
11028 33610 81ec
11029 33613 81ed
11030 33617 81ef
11031 33619 81f0
11032 33621 81f1
11033 33623 81f2
11034 33626 81f3
11035 33628 81f4
11036 33631 81f5
11037 33633 81f6
11038 33636 81f8
11039 33638 81f9
11040 33640 81fa
11041 33642 81fb
11042 33645 81fc
11043 33647 81fd
11044 33649 81fe
11045 33652 81ff
11046 33655 8200
11047 33657 8201
11048 33659 8202
11049 33661 8203
11050 33663 8204
11051 33664 8205
11052 33667 8207
11053 33670 8208
11054 33672 8209
11055 33675 820a
11056 33678 820b
11057 33681 820c
11058 33682 820d
11059 33684 820e
11060 33686 820f
11061 33688 8210
11062 33693 8212
11063 33695 8213
11064 33696 8214
11065 33701 8216
11066 33703 8217
11067 33705 8218
11068 33707 8219
11069 33708 821a
11070 33711 821b
11071 33714 821c
11072 33717 821d
11073 33720 821e
11074 33724 821f
11075 33728 8221
11076 33731 8222
11077 33741 8228
11078 33744 8229
11079 33747 822a
11080 33750 822b
11081 33753 822c
11082 33758 822e
11083 33764 8232
11084 33767 8233
11085 33770 8234
11086 33773 8235
11087 33776 8236
11088 33779 8237
11089 33782 8238
11090 33785 8239
11091 33788 823a
11092 33792 823c
11093 33802 8240
11094 33808 8243
11095 33810 8244
11096 33813 8245
11097 33816 8246
11098 33818 8247
11099 33822 8249
11100 33826 824b
11101 33831 824e
11102 33834 824f
11103 33839 8251
11104 33850 8256
11105 33853 8257
11106 33856 8258
11107 33859 8259
11108 33862 825a
11109 33867 825c
11110 33870 825d
11111 33874 825f
11112 33877 8260
11113 33881 8262
11114 33884 8263
11115 33887 8264
11116 33892 8266
11117 33895 8267
11118 33897 8268
11119 33902 826a
11120 33904 826b
11121 33909 826d
11122 33912 826e
11123 33914 826f
11124 33917 8271
11125 33919 8272
11126 33922 8274
11127 33925 8276
11128 33927 8277
11129 33929 8278
11130 33931 8279
11131 33934 827b
11132 33938 827d
11133 33940 827e
11134 33942 827f
11135 33945 8280
11136 33947 8281
11137 33949 8283
11138 33951 8284
11139 33956 8287
11140 33959 8289
11141 33960 828a
11142 33962 828b
11143 33965 828d
11144 33967 828e
11145 33974 8291
11146 33976 8292
11147 33979 8293
11148 33982 8294
11149 33985 8296
11150 33987 8298
11151 33990 8299
11152 33992 829a
11153 33995 829b
11154 33998 829d
11155 34003 829f
11156 34006 82a0
11157 34009 82a1
11158 34014 82a3
11159 34016 82a4
11160 34019 82a5
11161 34022 82a6
11162 34025 82a7
11163 34027 82a8
11164 34030 82a9
11165 34033 82aa
11166 34036 82ab
11167 34038 82ac
11168 34041 82ad
11169 34043 82ae
11170 34046 82af
11171 34049 82b0
11172 34051 82b1
11173 34054 82b2
11174 34056 82b3
11175 34059 82b4
11176 34065 82b7
11177 34067 82b8
11178 34070 82b9
11179 34073 82ba
11180 34075 82bb
11181 34077 82bc
11182 34079 82bd
11183 34082 82be
11184 34084 82bf
11185 34096 82c5
11186 34097 82c6
11187 34110 82d0
11188 34113 82d1
11189 34116 82d2
11190 34118 82d3
11191 34121 82d4
11192 34124 82d5
11193 34128 82d7
11194 34132 82d9
11195 34135 82da
11196 34136 82db
11197 34138 82dc
11198 34141 82de
11199 34143 82df
11200 34145 82e0
11201 34148 82e1
11202 34151 82e2
11203 34153 82e3
11204 34156 82e4
11205 34159 82e5
11206 34161 82e6
11207 34163 82e7
11208 34166 82e8
11209 34169 82ea
11210 34172 82eb
11211 34176 82ed
11212 34181 82ef
11213 34185 82f1
11214 34189 82f3
11215 34192 82f4
11216 34196 82f6
11217 34199 82f7
11218 34203 82f9
11219 34206 82fa
11220 34209 82fb
11221 34213 82fd
11222 34216 82fe
11223 34220 8300
11224 34223 8301
11225 34226 8302
11226 34228 8303
11227 34230 8304
11228 34233 8305
11229 34235 8306
11230 34238 8307
11231 34241 8308
11232 34243 8309
11233 34245 830a
11234 34247 830b
11235 34250 830c
11236 34253 830e
11237 34262 8316
11238 34264 8317
11239 34267 8318
11240 34273 831b
11241 34276 831c
11242 34279 831d
11243 34282 831e
11244 34285 831f
11245 34288 8321
11246 34290 8322
11247 34293 8323
11248 34303 8328
11249 34310 832b
11250 34314 832c
11251 34316 832d
11252 34319 832e
11253 34321 832f
11254 34323 8330
11255 34324 8331
11256 34326 8332
11257 34329 8333
11258 34331 8334
11259 34333 8335
11260 34336 8336
11261 34339 8337
11262 34341 8338
11263 34343 8339
11264 34346 833a
11265 34350 833c
11266 34352 833d
11267 34357 8340
11268 34361 8342
11269 34364 8343
11270 34367 8344
11271 34370 8345
11272 34373 8346
11273 34374 8347
11274 34378 8349
11275 34380 834a
11276 34386 834d
11277 34389 834e
11278 34392 834f
11279 34394 8350
11280 34397 8351
11281 34400 8352
11282 34403 8353
11283 34406 8354
11284 34408 8355
11285 34409 8356
11286 34412 8357
11287 34415 8358
11288 34418 835a
11289 34426 8362
11290 34429 8363
11291 34445 8370
11292 34448 8373
11293 34453 8375
11294 34458 8377
11295 34460 8378
11296 34466 837b
11297 34468 837c
11298 34471 837d
11299 34476 837f
11300 34479 8380
11301 34483 8382
11302 34487 8384
11303 34488 8385
11304 34491 8386
11305 34493 8387
11306 34497 8389
11307 34499 838a
11308 34506 838d
11309 34509 838e
11310 34518 8392
11311 34521 8393
11312 34524 8394
11313 34527 8395
11314 34529 8396
11315 34533 8398
11316 34536 8399
11317 34538 839a
11318 34541 839b
11319 34544 839c
11320 34546 839d
11321 34548 839e
11322 34551 839f
11323 34553 83a0
11324 34557 83a2
11325 34565 83a6
11326 34568 83a7
11327 34570 83a8
11328 34573 83a9
11329 34576 83aa
11330 34578 83ab
11331 34580 83ac
11332 34583 83ad
11333 34591 83b1
11334 34595 83b5
11335 34605 83bd
11336 34608 83be
11337 34610 83bf
11338 34612 83c0
11339 34615 83c1
11340 34624 83c5
11341 34629 83c7
11342 34634 83c9
11343 34637 83ca
11344 34641 83cc
11345 34646 83ce
11346 34649 83cf
11347 34651 83d0
11348 34652 83d1
11349 34655 83d3
11350 34657 83d4
11351 34662 83d6
11352 34666 83d8
11353 34674 83dc
11354 34676 83dd
11355 34681 83df
11356 34684 83e0
11357 34686 83e1
11358 34695 83e5
11359 34701 83e8
11360 34704 83e9
11361 34707 83ea
11362 34710 83eb
11363 34719 83ef
11364 34721 83f0
11365 34724 83f1
11366 34727 83f2
11367 34732 83f4
11368 34736 83f6
11369 34739 83f7
11370 34741 83f8
11371 34744 83f9
11372 34748 83fb
11373 34750 83fc
11374 34752 83fd
11375 34759 8401
11376 34762 8403
11377 34765 8404
11378 34770 8406
11379 34772 8407
11380 34778 840a
11381 34780 840b
11382 34783 840c
11383 34785 840d
11384 34788 840e
11385 34791 840f
11386 34796 8411
11387 34801 8413
11388 34806 8415
11389 34810 8417
11390 34814 8419
11391 34823 8420
11392 34828 8422
11393 34839 8429
11394 34841 842a
11395 34844 842c
11396 34850 842f
11397 34855 8431
11398 34864 8435
11399 34871 8438
11400 34875 8439
11401 34882 843c
11402 34885 843d
11403 34900 8445
11404 34902 8446
11405 34904 8447
11406 34906 8448
11407 34909 8449
11408 34911 844a
11409 34918 844d
11410 34920 844e
11411 34922 844f
11412 34925 8451
11413 34928 8452
11414 34937 8456
11415 34940 8457
11416 34942 8458
11417 34944 8459
11418 34946 845a
11419 34949 845b
11420 34952 845c
11421 34959 845f
11422 34961 8460
11423 34964 8461
11424 34967 8462
11425 34969 8463
11426 34971 8464
11427 34974 8465
11428 34977 8466
11429 34980 8467
11430 34985 8469
11431 34987 846a
11432 34989 846b
11433 34991 846c
11434 34994 846d
11435 34996 846e
11436 34999 846f
11437 35002 8470
11438 35005 8471
11439 35010 8473
11440 35013 8474
11441 35015 8475
11442 35018 8476
11443 35021 8477
11444 35023 8478
11445 35025 8479
11446 35028 847a
11447 35031 847c
11448 35033 847d
11449 35042 8481
11450 35044 8482
11451 35048 8484
11452 35050 8485
11453 35058 848b
11454 35067 8490
11455 35072 8492
11456 35074 8493
11457 35077 8494
11458 35079 8495
11459 35082 8497
11460 35087 8499
11461 35094 849c
11462 35098 849e
11463 35101 849f
11464 35106 84a1
11465 35116 84a6
11466 35120 84a8
11467 35123 84a9
11468 35125 84aa
11469 35131 84ad
11470 35135 84af
11471 35140 84b1
11472 35142 84b2
11473 35146 84b4
11474 35153 84b8
11475 35156 84b9
11476 35159 84ba
11477 35162 84bb
11478 35165 84bc
11479 35168 84bd
11480 35171 84be
11481 35174 84bf
11482 35177 84c0
11483 35180 84c1
11484 35183 84c2
11485 35187 84c4
11486 35192 84c6
11487 35195 84c7
11488 35198 84c8
11489 35200 84c9
11490 35203 84ca
11491 35206 84cb
11492 35209 84cc
11493 35211 84cd
11494 35213 84ce
11495 35216 84cf
11496 35219 84d0
11497 35222 84d1
11498 35227 84d3
11499 35233 84d6
11500 35239 84d9
11501 35241 84da
11502 35246 84dc
11503 35263 84e7
11504 35270 84ea
11505 35275 84ec
11506 35280 84ee
11507 35283 84ef
11508 35285 84f0
11509 35288 84f1
11510 35291 84f2
11511 35296 84f4
11512 35302 84f7
11513 35309 84fa
11514 35312 84fb
11515 35315 84fc
11516 35318 84fd
11517 35322 84ff
11518 35325 8500
11519 35329 8502
11520 35332 8503
11521 35339 8506
11522 35342 8507
11523 35353 850c
11524 35358 850e
11525 35363 8510
11526 35366 8511
11527 35371 8513
11528 35373 8514
11529 35375 8515
11530 35379 8517
11531 35382 8518
11532 35387 851a
11533 35389 851b
11534 35391 851c
11535 35396 851e
11536 35399 851f
11537 35404 8521
11538 35407 8522
11539 35409 8523
11540 35412 8524
11541 35415 8525
11542 35418 8526
11543 35420 8527
11544 35427 852a
11545 35430 852b
11546 35433 852c
11547 35436 852d
11548 35441 852f
11549 35447 8532
11550 35449 8533
11551 35452 8534
11552 35455 8535
11553 35457 8536
11554 35466 853d
11555 35469 853e
11556 35471 853f
11557 35473 8540
11558 35475 8541
11559 35480 8543
11560 35486 8546
11561 35490 8548
11562 35492 8549
11563 35495 854a
11564 35498 854b
11565 35504 854e
11566 35506 854f
11567 35508 8550
11568 35510 8551
11569 35513 8552
11570 35516 8553
11571 35521 8555
11572 35524 8556
11573 35527 8557
11574 35529 8558
11575 35531 8559
11576 35533 855a
11577 35538 855c
11578 35540 855d
11579 35543 855e
11580 35546 855f
11581 35549 8560
11582 35552 8561
11583 35554 8562
11584 35556 8563
11585 35559 8564
11586 35568 8568
11587 35571 8569
11588 35573 856a
11589 35575 856b
11590 35580 856d
11591 35584 856f
11592 35598 8577
11593 35602 8579
11594 35605 857a
11595 35608 857b
11596 35613 857d
11597 35615 857e
11598 35617 857f
11599 35619 8580
11600 35621 8581
11601 35628 8584
11602 35631 8585
11603 35634 8586
11604 35636 8587
11605 35639 8588
11606 35642 8589
11607 35645 858a
11608 35647 858b
11609 35650 858c
11610 35657 858f
11611 35660 8590
11612 35663 8591
11613 35667 8593
11614 35670 8594
11615 35676 8597
11616 35679 8598
11617 35682 8599
11618 35687 859b
11619 35690 859c
11620 35693 859d
11621 35698 859f
11622 35701 85a0
11623 35705 85a2
11624 35710 85a4
11625 35713 85a5
11626 35714 85a6
11627 35717 85a7
11628 35720 85a8
11629 35723 85a9
11630 35726 85aa
11631 35729 85ab
11632 35730 85ac
11633 35731 85ad
11634 35733 85ae
11635 35735 85af
11636 35738 85b0
11637 35745 85b4
11638 35750 85b6
11639 35752 85b7
11640 35754 85b8
11641 35757 85b9
11642 35760 85ba
11643 35764 85bc
11644 35766 85bd
11645 35769 85be
11646 35771 85bf
11647 35775 85c1
11648 35778 85c2
11649 35789 85c7
11650 35794 85c9
11651 35797 85ca
11652 35799 85cb
11653 35803 85cd
11654 35806 85ce
11655 35808 85cf
11656 35811 85d0
11657 35820 85d5
11658 35827 85d8
11659 35829 85d9
11660 35832 85da
11661 35836 85dc
11662 35839 85dd
11663 35844 85df
11664 35846 85e0
11665 35848 85e1
11666 35855 85e4
11667 35858 85e5
11668 35861 85e6
11669 35865 85e8
11670 35868 85e9
11671 35870 85ea
11672 35877 85ed
11673 35890 85f3
11674 35892 85f4
11675 35895 85f6
11676 35897 85f7
11677 35902 85f9
11678 35905 85fa
11679 35908 85fb
11680 35910 85fc
11681 35916 85fe
11682 35919 85ff
11683 35922 8600
11684 35927 8602
11685 35931 8604
11686 35934 8605
11687 35937 8606
11688 35939 8607
11689 35944 860a
11690 35947 860b
11691 35952 860d
11692 35955 860e
11693 35958 8610
11694 35961 8611
11695 35964 8612
11696 35966 8613
11697 35971 8616
11698 35974 8617
11699 35977 8618
11700 35980 8619
11701 35983 861a
11702 35986 861b
11703 35992 861e
11704 35999 8621
11705 36002 8622
11706 36007 8624
11707 36014 8627
11708 36019 8629
11709 36027 862d
11710 36032 862f
11711 36034 8630
11712 36046 8636
11713 36050 8638
11714 36053 8639
11715 36056 863a
11716 36061 863c
11717 36064 863d
11718 36067 863f
11719 36070 8640
11720 36073 8641
11721 36076 8642
11722 36084 8646
11723 36097 864d
11724 36099 864e
11725 36103 8650
11726 36107 8652
11727 36110 8653
11728 36113 8654
11729 36116 8655
11730 36119 8656
11731 36121 8657
11732 36123 8658
11733 36124 8659
11734 36126 865a
11735 36127 865b
11736 36130 865c
11737 36132 865d
11738 36134 865e
11739 36137 865f
11740 36140 8660
11741 36142 8661
11742 36145 8662
11743 36148 8663
11744 36151 8664
11745 36157 8667
11746 36162 8669
11747 36167 866b
11748 36169 866c
11749 36172 866f
11750 36175 8671
11751 36180 8675
11752 36181 8676
11753 36182 8677
11754 36185 8679
11755 36186 867a
11756 36188 867b
11757 36193 867d
11758 36203 8687
11759 36204 8688
11760 36206 8689
11761 36208 868a
11762 36210 868b
11763 36212 868c
11764 36215 868d
11765 36222 8691
11766 36224 8693
11767 36227 8695
11768 36229 8696
11769 36232 8698
11770 36236 869a
11771 36239 869c
11772 36242 869d
11773 36247 86a1
11774 36251 86a3
11775 36254 86a4
11776 36258 86a6
11777 36259 86a7
11778 36261 86a8
11779 36262 86a9
11780 36264 86aa
11781 36265 86ab
11782 36267 86ad
11783 36270 86af
11784 36272 86b0
11785 36273 86b1
11786 36275 86b3
11787 36278 86b4
11788 36280 86b5
11789 36281 86b6
11790 36282 86b7
11791 36284 86b8
11792 36286 86b9
11793 36293 86bf
11794 36295 86c0
11795 36297 86c1
11796 36300 86c3
11797 36301 86c4
11798 36302 86c5
11799 36303 86c6
11800 36304 86c7
11801 36307 86c9
11802 36311 86cb
11803 36314 86cd
11804 36315 86ce
11805 36318 86d1
11806 36320 86d2
11807 36322 86d4
11808 36323 86d5
11809 36326 86d7
11810 36328 86d9
11811 36329 86da
11812 36332 86db
11813 36333 86dc
11814 36335 86de
11815 36336 86df
11816 36338 86e0
11817 36341 86e3
11818 36342 86e4
11819 36344 86e5
11820 36346 86e6
11821 36348 86e7
11822 36351 86e9
11823 36356 86ec
11824 36357 86ed
11825 36359 86ee
11826 36361 86ef
11827 36370 86f8
11828 36373 86f9
11829 36374 86fa
11830 36375 86fb
11831 36378 86fc
11832 36379 86fd
11833 36380 86fe
11834 36383 8700
11835 36385 8702
11836 36386 8703
11837 36389 8704
11838 36392 8705
11839 36393 8706
11840 36394 8707
11841 36396 8708
11842 36399 8709
11843 36401 870a
11844 36403 870b
11845 36407 870d
11846 36409 870e
11847 36411 870f
11848 36413 8710
11849 36415 8711
11850 36418 8712
11851 36421 8713
11852 36423 8714
11853 36427 8718
11854 36428 8719
11855 36431 871a
11856 36434 871c
11857 36437 871e
11858 36438 871f
11859 36441 8721
11860 36442 8722
11861 36444 8723
11862 36447 8725
11863 36452 8728
11864 36453 8729
11865 36460 872e
11866 36461 872f
11867 36465 8731
11868 36467 8732
11869 36471 8734
11870 36474 8737
11871 36477 8739
11872 36479 873a
11873 36481 873b
11874 36484 873c
11875 36486 873d
11876 36488 873e
11877 36489 873f
11878 36492 8740
11879 36496 8743
11880 36498 8745
11881 36504 8749
11882 36507 874b
11883 36508 874c
11884 36509 874d
11885 36511 874e
11886 36516 8751
11887 36519 8753
11888 36524 8755
11889 36528 8757
11890 36529 8758
11891 36532 8759
11892 36540 875d
11893 36543 875f
11894 36545 8760
11895 36546 8761
11896 36549 8763
11897 36551 8764
11898 36554 8765
11899 36555 8766
11900 36558 8768
11901 36562 876a
11902 36567 876e
11903 36570 876f
11904 36573 8771
11905 36576 8772
11906 36579 8774
11907 36583 8776
11908 36586 8778
11909 36592 877b
11910 36593 877c
11911 36597 877f
11912 36601 8782
11913 36603 8783
11914 36605 8784
11915 36606 8785
11916 36607 8786
11917 36610 8787
11918 36613 8788
11919 36614 8789
11920 36618 878b
11921 36621 878c
11922 36624 878d
11923 36626 878e
11924 36630 8790
11925 36634 8793
11926 36639 8795
11927 36643 8797
11928 36645 8798
11929 36647 8799
11930 36655 879e
11931 36656 879f
11932 36658 87a0
11933 36661 87a2
11934 36663 87a3
11935 36669 87a7
11936 36675 87ab
11937 36677 87ac
11938 36678 87ad
11939 36681 87ae
11940 36683 87af
11941 36688 87b1
11942 36693 87b3
11943 36696 87b5
11944 36703 87ba
11945 36705 87bb
11946 36709 87bd
11947 36711 87be
11948 36713 87bf
11949 36716 87c0
11950 36718 87c1
11951 36724 87c4
11952 36727 87c6
11953 36729 87c7
11954 36730 87c8
11955 36731 87c9
11956 36734 87ca
11957 36736 87cb
11958 36741 87ce
11959 36744 87d0
11960 36746 87d2
11961 36752 87d5
11962 36754 87d6
11963 36758 87d9
11964 36760 87da
11965 36762 87dc
11966 36766 87df
11967 36767 87e0
11968 36771 87e2
11969 36773 87e3
11970 36776 87e4
11971 36778 87e5
11972 36781 87e6
11973 36787 87ea
11974 36789 87eb
11975 36791 87ec
11976 36792 87ed
11977 36796 87ef
11978 36798 87f1
11979 36799 87f2
11980 36800 87f3
11981 36803 87f5
11982 36805 87f6
11983 36807 87f7
11984 36808 87f8
11985 36810 87f9
11986 36812 87fa
11987 36814 87fb
11988 36818 87fe
11989 36821 87ff
11990 36825 8801
11991 36829 8803
11992 36834 8805
11993 36837 8806
11994 36839 8807
11995 36841 8809
11996 36843 880a
11997 36845 880b
11998 36847 880d
11999 36850 880e
12000 36851 880f
12001 36853 8810
12002 36855 8811
12003 36857 8812
12004 36858 8813
12005 36861 8814
12006 36863 8815
12007 36865 8816
12008 36870 8818
12009 36872 8819
12010 36874 881a
12011 36875 881b
12012 36878 881c
12013 36881 881e
12014 36883 881f
12015 36887 8821
12016 36890 8822
12017 36892 8823
12018 36899 8827
12019 36901 8828
12020 36909 882d
12021 36912 882e
12022 36916 8830
12023 36918 8831
12024 36919 8832
12025 36924 8835
12026 36927 8836
12027 36933 8839
12028 36934 883a
12029 36935 883b
12030 36937 883c
12031 36942 8840
12032 36943 8841
12033 36946 8842
12034 36949 8843
12035 36950 8844
12036 36952 8845
12037 36954 8846
12038 36957 8848
12039 36959 8849
12040 36960 884a
12041 36962 884b
12042 36964 884c
12043 36965 884d
12044 36966 884e
12045 36969 8851
12046 36971 8852
12047 36973 8853
12048 36977 8855
12049 36978 8856
12050 36979 8857
12051 36980 8858
12052 36981 8859
12053 36983 885a
12054 36985 885b
12055 36987 885c
12056 36988 885d
12057 36989 885e
12058 36990 885f
12059 36991 8860
12060 36993 8861
12061 36995 8862
12062 36997 8863
12063 36999 8864
12064 37004 8868
12065 37006 8869
12066 37010 886b
12067 37014 886e
12068 37017 886f
12069 37020 8870
12070 37022 8871
12071 37025 8872
12072 37030 8875
12073 37033 8877
12074 37036 8879
12075 37039 887b
12076 37042 887d
12077 37045 887e
12078 37048 887f
12079 37051 8880
12080 37054 8881
12081 37056 8882
12082 37064 8888
12083 37068 888b
12084 37071 888d
12085 37077 8892
12086 37083 8896
12087 37085 8897
12088 37087 8898
12089 37090 8899
12090 37092 889a
12091 37095 889b
12092 37098 889c
12093 37102 889e
12094 37105 889f
12095 37107 88a0
12096 37110 88a2
12097 37113 88a4
12098 37118 88a8
12099 37121 88aa
12100 37123 88ab
12101 37127 88ae
12102 37130 88b0
12103 37132 88b1
12104 37136 88b4
12105 37138 88b5
12106 37143 88b7
12107 37147 88ba
12108 37150 88bc
12109 37152 88bd
12110 37155 88be
12111 37157 88bf
12112 37159 88c0
12113 37161 88c1
12114 37163 88c2
12115 37166 88c3
12116 37168 88c4
12117 37170 88c5
12118 37172 88c6
12119 37177 88ca
12120 37180 88cb
12121 37182 88cc
12122 37184 88cd
12123 37186 88ce
12124 37189 88cf
12125 37193 88d1
12126 37195 88d2
12127 37199 88d3
12128 37201 88d4
12129 37204 88d5
12130 37210 88d8
12131 37212 88d9
12132 37215 88db
12133 37217 88dc
12134 37219 88dd
12135 37221 88de
12136 37224 88df
12137 37226 88e0
12138 37228 88e1
12139 37235 88e7
12140 37238 88e8
12141 37247 88ef
12142 37251 88f0
12143 37253 88f1
12144 37255 88f2
12145 37258 88f3
12146 37260 88f4
12147 37263 88f5
12148 37268 88f7
12149 37270 88f8
12150 37272 88f9
12151 37279 88fc
12152 37281 88fd
12153 37283 88fe
12154 37287 8901
12155 37289 8902
12156 37292 8904
12157 37295 8906
12158 37297 8907
12159 37303 890a
12160 37308 890c
12161 37310 890d
12162 37312 890e
12163 37314 890f
12164 37316 8910
12165 37320 8912
12166 37323 8913
12167 37327 8915
12168 37330 8916
12169 37334 8918
12170 37337 8919
12171 37340 891a
12172 37343 891c
12173 37345 891d
12174 37347 891e
12175 37352 8920
12176 37360 8925
12177 37363 8926
12178 37366 8927
12179 37369 8928
12180 37373 892a
12181 37376 892b
12182 37385 8930
12183 37388 8931
12184 37390 8932
12185 37395 8935
12186 37398 8936
12187 37401 8937
12188 37403 8938
12189 37406 8939
12190 37408 893a
12191 37410 893b
12192 37417 893e
12193 37421 8940
12194 37423 8941
12195 37426 8942
12196 37428 8943
12197 37430 8944
12198 37432 8945
12199 37434 8946
12200 37439 8949
12201 37443 894c
12202 37445 894d
12203 37449 894f
12204 37455 8952
12205 37461 8956
12206 37464 8957
12207 37470 895a
12208 37473 895b
12209 37476 895c
12210 37480 895e
12211 37482 895f
12212 37485 8960
12213 37487 8961
12214 37489 8962
12215 37491 8963
12216 37493 8964
12217 37498 8966
12218 37504 896a
12219 37507 896b
12220 37511 896d
12221 37513 896e
12222 37515 896f
12223 37518 8970
12224 37522 8972
12225 37525 8973
12226 37527 8974
12227 37529 8975
12228 37532 8977
12229 37538 897a
12230 37541 897b
12231 37543 897c
12232 37546 897d
12233 37548 897e
12234 37550 897f
12235 37552 8980
12236 37554 8981
12237 37558 8983
12238 37563 8986
12239 37565 8987
12240 37566 8988
12241 37568 8989
12242 37570 898a
12243 37573 898b
12244 37575 898d
12245 37577 898f
12246 37579 8990
12247 37584 8993
12248 37586 8994
12249 37587 8995
12250 37588 8996
12251 37590 8997
12252 37591 8998
12253 37593 899a
12254 37594 899b
12255 37596 899c
12256 37601 899f
12257 37602 89a0
12258 37603 89a1
12259 37610 89a5
12260 37611 89a6
12261 37614 89a7
12262 37619 89a9
12263 37621 89aa
12264 37625 89ac
12265 37629 89af
12266 37630 89b0
12267 37632 89b2
12268 37633 89b3
12269 37635 89b4
12270 37637 89b5
12271 37638 89b6
12272 37640 89b7
12273 37646 89ba
12274 37649 89bc
12275 37650 89bd
12276 37654 89bf
12277 37656 89c0
12278 37659 89c1
12279 37676 89d2
12280 37680 89d4
12281 37682 89d5
12282 37684 89d6
12283 37687 89d7
12284 37689 89d8
12285 37693 89da
12286 37698 89dc
12287 37701 89dd
12288 37713 89e3
12289 37717 89e5
12290 37719 89e6
12291 37721 89e7
12292 37725 89e9
12293 37728 89eb
12294 37732 89ed
12295 37738 89f1
12296 37742 89f3
12297 37745 89f4
12298 37748 89f6
12299 37752 89f8
12300 37754 89f9
12301 37762 89fd
12302 37766 89ff
12303 37769 8a00
12304 37771 8a01
12305 37773 8a02
12306 37775 8a03
12307 37777 8a04
12308 37779 8a05
12309 37782 8a07
12310 37784 8a08
12311 37788 8a0a
12312 37791 8a0c
12313 37794 8a0e
12314 37796 8a0f
12315 37798 8a10
12316 37800 8a11
12317 37803 8a12
12318 37806 8a13
12319 37808 8a14
12320 37810 8a15
12321 37812 8a16
12322 37814 8a17
12323 37816 8a18
12324 37820 8a1b
12325 37825 8a1d
12326 37829 8a1e
12327 37831 8a1f
12328 37834 8a20
12329 37836 8a21
12330 37838 8a22
12331 37840 8a23
12332 37843 8a24
12333 37845 8a25
12334 37848 8a26
12335 37853 8a2a
12336 37855 8a2b
12337 37857 8a2c
12338 37859 8a2d
12339 37862 8a2f
12340 37865 8a31
12341 37868 8a33
12342 37870 8a34
12343 37873 8a35
12344 37875 8a36
12345 37877 8a37
12346 37882 8a3a
12347 37884 8a3b
12348 37886 8a3c
12349 37888 8a3d
12350 37890 8a3e
12351 37895 8a40
12352 37897 8a41
12353 37900 8a43
12354 37903 8a45
12355 37906 8a46
12356 37909 8a47
12357 37911 8a48
12358 37913 8a49
12359 37920 8a4d
12360 37922 8a4e
12361 37926 8a50
12362 37928 8a51
12363 37930 8a52
12364 37932 8a53
12365 37934 8a54
12366 37936 8a55
12367 37938 8a56
12368 37940 8a57
12369 37942 8a58
12370 37947 8a5b
12371 37949 8a5c
12372 37951 8a5d
12373 37953 8a5e
12374 37956 8a60
12375 37958 8a61
12376 37960 8a62
12377 37962 8a63
12378 37966 8a65
12379 37968 8a66
12380 37970 8a67
12381 37974 8a69
12382 37978 8a6b
12383 37981 8a6c
12384 37983 8a6d
12385 37985 8a6e
12386 37989 8a70
12387 37991 8a71
12388 37993 8a72
12389 37995 8a73
12390 37999 8a75
12391 38001 8a76
12392 38004 8a77
12393 38007 8a79
12394 38010 8a7a
12395 38013 8a7b
12396 38015 8a7c
12397 38019 8a7e
12398 38021 8a7f
12399 38023 8a80
12400 38026 8a82
12401 38028 8a83
12402 38031 8a84
12403 38034 8a85
12404 38036 8a86
12405 38038 8a87
12406 38041 8a89
12407 38044 8a8b
12408 38046 8a8c
12409 38048 8a8d
12410 38052 8a8f
12411 38054 8a90
12412 38056 8a91
12413 38058 8a92
12414 38061 8a93
12415 38064 8a95
12416 38067 8a96
12417 38069 8a97
12418 38071 8a98
12419 38073 8a99
12420 38075 8a9a
12421 38082 8a9e
12422 38084 8a9f
12423 38086 8aa0
12424 38088 8aa1
12425 38092 8aa3
12426 38094 8aa4
12427 38097 8aa5
12428 38100 8aa6
12429 38102 8aa7
12430 38104 8aa8
12431 38106 8aa9
12432 38108 8aaa
12433 38113 8aac
12434 38115 8aad
12435 38117 8aae
12436 38119 8aaf
12437 38121 8ab0
12438 38124 8ab2
12439 38126 8ab3
12440 38131 8ab6
12441 38133 8ab7
12442 38136 8ab9
12443 38140 8abb
12444 38142 8abc
12445 38145 8abe
12446 38147 8abf
12447 38152 8ac2
12448 38154 8ac3
12449 38156 8ac4
12450 38159 8ac6
12451 38161 8ac7
12452 38164 8ac8
12453 38167 8ac9
12454 38170 8aca
12455 38172 8acb
12456 38175 8acc
12457 38177 8acd
12458 38181 8acf
12459 38185 8ad0
12460 38187 8ad1
12461 38190 8ad2
12462 38192 8ad3
12463 38194 8ad4
12464 38196 8ad5
12465 38199 8ad6
12466 38201 8ad7
12467 38206 8ada
12468 38208 8adb
12469 38210 8adc
12470 38213 8add
12471 38216 8ade
12472 38219 8adf
12473 38221 8ae0
12474 38223 8ae1
12475 38226 8ae2
12476 38229 8ae4
12477 38232 8ae6
12478 38234 8ae7
12479 38241 8aeb
12480 38243 8aec
12481 38245 8aed
12482 38248 8aee
12483 38252 8af0
12484 38254 8af1
12485 38259 8af3
12486 38261 8af4
12487 38263 8af5
12488 38265 8af6
12489 38268 8af7
12490 38271 8af8
12491 38274 8afa
12492 38278 8afc
12493 38281 8afe
12494 38284 8aff
12495 38287 8b00
12496 38290 8b01
12497 38293 8b02
12498 38297 8b04
12499 38299 8b05
12500 38301 8b06
12501 38304 8b07
12502 38308 8b0a
12503 38311 8b0b
12504 38314 8b0c
12505 38316 8b0d
12506 38319 8b0e
12507 38322 8b0f
12508 38325 8b10
12509 38327 8b11
12510 38333 8b14
12511 38338 8b16
12512 38341 8b17
12513 38344 8b19
12514 38346 8b1a
12515 38348 8b1b
12516 38350 8b1c
12517 38352 8b1d
12518 38355 8b1e
12519 38357 8b1f
12520 38359 8b20
12521 38362 8b21
12522 38372 8b26
12523 38377 8b28
12524 38383 8b2b
12525 38385 8b2c
12526 38388 8b2d
12527 38394 8b30
12528 38400 8b33
12529 38407 8b37
12530 38411 8b39
12531 38416 8b3c
12532 38421 8b3e
12533 38427 8b41
12534 38430 8b42
12535 38432 8b43
12536 38435 8b44
12537 38437 8b45
12538 38440 8b46
12539 38443 8b48
12540 38445 8b49
12541 38449 8b4c
12542 38451 8b4d
12543 38453 8b4e
12544 38456 8b4f
12545 38461 8b51
12546 38463 8b52
12547 38466 8b53
12548 38468 8b54
12549 38473 8b56
12550 38478 8b58
12551 38480 8b59
12552 38482 8b5a
12553 38484 8b5b
12554 38486 8b5c
12555 38490 8b5e
12556 38492 8b5f
12557 38499 8b63
12558 38504 8b66
12559 38510 8b69
12560 38514 8b6b
12561 38517 8b6c
12562 38519 8b6d
12563 38523 8b6f
12564 38525 8b70
12565 38527 8b71
12566 38529 8b72
12567 38532 8b74
12568 38536 8b76
12569 38538 8b77
12570 38541 8b78
12571 38543 8b79
12572 38548 8b7c
12573 38550 8b7d
12574 38553 8b7e
12575 38556 8b7f
12576 38559 8b80
12577 38562 8b81
12578 38567 8b83
12579 38570 8b84
12580 38572 8b85
12581 38581 8b8a
12582 38583 8b8b
12583 38586 8b8c
12584 38589 8b8d
12585 38591 8b8e
12586 38593 8b8f
12587 38595 8b90
12588 38598 8b92
12589 38601 8b93
12590 38603 8b94
12591 38606 8b95
12592 38608 8b96
12593 38613 8b99
12594 38616 8b9a
12595 38620 8b9c
12596 38622 8b9d
12597 38624 8b9e
12598 38627 8b9f
12599 38629 8ba0
12600 38780 8c37
12601 38782 8c38
12602 38784 8c39
12603 38786 8c3a
12604 38791 8c3d
12605 38794 8c3e
12606 38797 8c3f
12607 38800 8c41
12608 38809 8c45
12609 38812 8c46
12610 38814 8c47
12611 38815 8c48
12612 38816 8c49
12613 38818 8c4a
12614 38820 8c4b
12615 38823 8c4c
12616 38827 8c4e
12617 38828 8c4f
12618 38830 8c50
12619 38831 8c51
12620 38834 8c53
12621 38835 8c54
12622 38837 8c55
12623 38842 8c57
12624 38844 8c58
12625 38846 8c59
12626 38848 8c5a
12627 38851 8c5b
12628 38854 8c5d
12629 38859 8c61
12630 38862 8c62
12631 38864 8c63
12632 38866 8c64
12633 38869 8c66
12634 38873 8c68
12635 38874 8c69
12636 38876 8c6a
12637 38878 8c6b
12638 38881 8c6c
12639 38884 8c6d
12640 38892 8c73
12641 38895 8c75
12642 38896 8c76
12643 38898 8c78
12644 38900 8c79
12645 38902 8c7a
12646 38904 8c7b
12647 38906 8c7c
12648 38910 8c7e
12649 38916 8c82
12650 38921 8c85
12651 38923 8c86
12652 38925 8c87
12653 38928 8c89
12654 38930 8c8a
12655 38932 8c8b
12656 38934 8c8c
12657 38936 8c8d
12658 38938 8c8e
12659 38941 8c90
12660 38945 8c92
12661 38947 8c93
12662 38950 8c94
12663 38958 8c98
12664 38961 8c99
12665 38965 8c9b
12666 38968 8c9c
12667 38970 8c9d
12668 38971 8c9e
12669 38972 8c9f
12670 38974 8ca0
12671 38975 8ca1
12672 38976 8ca2
12673 38978 8ca4
12674 38982 8ca7
12675 38984 8ca8
12676 38987 8ca9
12677 38989 8caa
12678 38992 8cab
12679 38993 8cac
12680 38994 8cad
12681 38996 8cae
12682 38997 8caf
12683 38999 8cb0
12684 39001 8cb2
12685 39003 8cb3
12686 39004 8cb4
12687 39006 8cb6
12688 39008 8cb7
12689 39009 8cb8
12690 39010 8cb9
12691 39011 8cba
12692 39012 8cbb
12693 39014 8cbc
12694 39015 8cbd
12695 39019 8cbf
12696 39021 8cc0
12697 39022 8cc1
12698 39024 8cc2
12699 39025 8cc3
12700 39027 8cc4
12701 39029 8cc5
12702 39031 8cc6
12703 39033 8cc7
12704 39036 8cc8
12705 39037 8cc9
12706 39039 8cca
12707 39041 8ccb
12708 39044 8ccd
12709 39046 8cce
12710 39048 8ccf
12711 39050 8cd1
12712 39053 8cd2
12713 39056 8cd3
12714 39059 8cd5
12715 39061 8cd6
12716 39065 8cd9
12717 39068 8cda
12718 39069 8cdb
12719 39071 8cdc
12720 39072 8cdd
12721 39075 8cde
12722 39077 8ce0
12723 39079 8ce1
12724 39081 8ce2
12725 39082 8ce3
12726 39083 8ce4
12727 39085 8ce6
12728 39088 8ce8
12729 39093 8cea
12730 39096 8cec
12731 39098 8ced
12732 39101 8cef
12733 39103 8cf0
12734 39105 8cf1
12735 39106 8cf2
12736 39109 8cf4
12737 39111 8cf5
12738 39113 8cf7
12739 39114 8cf8
12740 39117 8cfa
12741 39119 8cfb
12742 39121 8cfc
12743 39122 8cfd
12744 39124 8cfe
12745 39126 8cff
12746 39130 8d01
12747 39132 8d03
12748 39134 8d04
12749 39136 8d05
12750 39141 8d07
12751 39143 8d08
12752 39145 8d09
12753 39147 8d0a
12754 39149 8d0b
12755 39153 8d0d
12756 39156 8d0e
12757 39157 8d0f
12758 39160 8d10
12759 39162 8d12
12760 39164 8d13
12761 39166 8d14
12762 39168 8d16
12763 39170 8d17
12764 39176 8d1b
12765 39178 8d1c
12766 39181 8d1d
12767 39252 8d64
12768 39254 8d65
12769 39256 8d66
12770 39257 8d67
12771 39260 8d69
12772 39263 8d6b
12773 39264 8d6c
12774 39265 8d6d
12775 39267 8d6e
12776 39269 8d70
12777 39270 8d71
12778 39273 8d73
12779 39275 8d74
12780 39278 8d76
12781 39279 8d77
12782 39291 8d7f
12783 39294 8d81
12784 39296 8d82
12785 39299 8d84
12786 39300 8d85
12787 39303 8d88
12788 39305 8d8a
12789 39309 8d8d
12790 39314 8d90
12791 39316 8d91
12792 39324 8d95
12793 39328 8d99
12794 39336 8d9e
12795 39338 8d9f
12796 39340 8da0
12797 39343 8da3
12798 39348 8da6
12799 39352 8da8
12800 39356 8dab
12801 39357 8dac
12802 39361 8daf
12803 39366 8db2
12804 39368 8db3
12805 39371 8db5
12806 39374 8db7
12807 39376 8db9
12808 39379 8dba
12809 39380 8dbb
12810 39382 8dbc
12811 39385 8dbe
12812 39388 8dc0
12813 39390 8dc2
12814 39393 8dc5
12815 39396 8dc6
12816 39398 8dc7
12817 39400 8dc8
12818 39403 8dca
12819 39404 8dcb
12820 39406 8dcc
12821 39408 8dce
12822 39410 8dcf
12823 39413 8dd1
12824 39416 8dd4
12825 39417 8dd5
12826 39418 8dd6
12827 39419 8dd7
12828 39421 8dd9
12829 39422 8dda
12830 39424 8ddb
12831 39427 8ddd
12832 39431 8ddf
12833 39434 8de1
12834 39438 8de3
12835 39439 8de4
12836 39441 8de5
12837 39444 8de7
12838 39446 8de8
12839 39449 8dea
12840 39450 8deb
12841 39452 8dec
12842 39455 8def
12843 39456 8df0
12844 39457 8df1
12845 39459 8df2
12846 39461 8df3
12847 39462 8df4
12848 39463 8df5
12849 39472 8dfc
12850 39473 8dfd
12851 39476 8dff
12852 39478 8e01
12853 39483 8e04
12854 39485 8e05
12855 39487 8e06
12856 39491 8e08
12857 39492 8e09
12858 39494 8e0a
12859 39495 8e0b
12860 39497 8e0c
12861 39502 8e0f
12862 39503 8e10
12863 39504 8e11
12864 39508 8e14
12865 39510 8e16
12866 39522 8e1d
12867 39523 8e1e
12868 39524 8e1f
12869 39525 8e20
12870 39528 8e21
12871 39530 8e22
12872 39532 8e23
12873 39537 8e26
12874 39538 8e27
12875 39541 8e2a
12876 39550 8e30
12877 39553 8e31
12878 39556 8e33
12879 39558 8e34
12880 39561 8e35
12881 39562 8e36
12882 39563 8e37
12883 39565 8e38
12884 39568 8e39
12885 39573 8e3d
12886 39577 8e40
12887 39579 8e41
12888 39582 8e42
12889 39585 8e44
12890 39591 8e47
12891 39593 8e48
12892 39595 8e49
12893 39597 8e4a
12894 39600 8e4b
12895 39603 8e4c
12896 39606 8e4d
12897 39608 8e4e
12898 39610 8e4f
12899 39613 8e50
12900 39619 8e54
12901 39621 8e55
12902 39628 8e59
12903 39631 8e5b
12904 39633 8e5c
12905 39635 8e5d
12906 39636 8e5e
12907 39638 8e5f
12908 39639 8e60
12909 39641 8e61
12910 39644 8e62
12911 39646 8e63
12912 39648 8e64
12913 39655 8e69
12914 39660 8e6c
12915 39662 8e6d
12916 39665 8e6f
12917 39668 8e70
12918 39669 8e71
12919 39671 8e72
12920 39675 8e74
12921 39677 8e75
12922 39679 8e76
12923 39681 8e77
12924 39685 8e79
12925 39687 8e7a
12926 39688 8e7b
12927 39689 8e7c
12928 39697 8e81
12929 39699 8e82
12930 39702 8e83
12931 39704 8e84
12932 39706 8e85
12933 39709 8e87
12934 39713 8e89
12935 39715 8e8a
12936 39716 8e8b
12937 39720 8e8d
12938 39725 8e90
12939 39728 8e91
12940 39731 8e92
12941 39734 8e93
12942 39736 8e94
12943 39739 8e95
12944 39743 8e98
12945 39746 8e99
12946 39748 8e9a
12947 39751 8e9b
12948 39753 8e9d
12949 39755 8e9e
12950 39761 8ea1
12951 39764 8ea2
12952 39772 8ea7
12953 39777 8ea9
12954 39779 8eaa
12955 39782 8eab
12956 39785 8eac
12957 39788 8ead
12958 39790 8eae
12959 39792 8eaf
12960 39794 8eb0
12961 39797 8eb1
12962 39801 8eb3
12963 39804 8eb5
12964 39806 8eb6
12965 39813 8eba
12966 39815 8ebb
12967 39821 8ebe
12968 39824 8ec0
12969 39827 8ec1
12970 39831 8ec3
12971 39834 8ec4
12972 39836 8ec5
12973 39838 8ec6
12974 39840 8ec7
12975 39842 8ec8
12976 39846 8eca
12977 39847 8ecb
12978 39848 8ecc
12979 39849 8ecd
12980 39852 8ecf
12981 39854 8ed1
12982 39855 8ed2
12983 39857 8ed4
12984 39865 8edb
12985 39866 8edc
12986 39870 8edf
12987 39876 8ee2
12988 39878 8ee3
12989 39884 8ee8
12990 39889 8eeb
12991 39892 8eed
12992 39894 8eee
12993 39897 8ef0
12994 39898 8ef1
12995 39907 8ef7
12996 39909 8ef8
12997 39910 8ef9
12998 39911 8efa
12999 39912 8efb
13000 39913 8efc
13001 39914 8efd
13002 39915 8efe
13003 39917 8f00
13004 39919 8f02
13005 39920 8f03
13006 39923 8f05
13007 39925 8f07
13008 39927 8f08
13009 39929 8f09
13010 39931 8f0a
13011 39934 8f0c
13012 39939 8f0f
13013 39940 8f10
13014 39943 8f12
13015 39945 8f13
13016 39946 8f14
13017 39947 8f15
13018 39948 8f16
13019 39951 8f17
13020 39953 8f18
13021 39956 8f19
13022 39960 8f1b
13023 39962 8f1c
13024 39963 8f1d
13025 39965 8f1e
13026 39969 8f1f
13027 39970 8f20
13028 39971 8f21
13029 39974 8f23
13030 39978 8f25
13031 39981 8f26
13032 39983 8f27
13033 39985 8f28
13034 39987 8f29
13035 39989 8f2a
13036 39991 8f2b
13037 39993 8f2c
13038 39995 8f2d
13039 39997 8f2e
13040 39999 8f2f
13041 40004 8f33
13042 40006 8f34
13043 40009 8f35
13044 40012 8f36
13045 40014 8f37
13046 40016 8f38
13047 40019 8f39
13048 40021 8f3a
13049 40022 8f3b
13050 40025 8f3e
13051 40027 8f3f
13052 40029 8f40
13053 40030 8f41
13054 40032 8f42
13055 40034 8f43
13056 40037 8f44
13057 40041 8f45
13058 40043 8f46
13059 40046 8f47
13060 40050 8f49
13061 40051 8f4a
13062 40056 8f4c
13063 40058 8f4d
13064 40061 8f4e
13065 40062 8f4f
13066 40066 8f51
13067 40067 8f52
13068 40068 8f53
13069 40070 8f54
13070 40073 8f55
13071 40077 8f57
13072 40079 8f58
13073 40084 8f5c
13074 40086 8f5d
13075 40089 8f5e
13076 40091 8f5f
13077 40093 8f61
13078 40095 8f62
13079 40098 8f63
13080 40100 8f64
13081 40102 8f65
13082 40104 8f66
13083 40158 8f9b
13084 40160 8f9c
13085 40162 8f9d
13086 40164 8f9e
13087 40166 8f9f
13088 40168 8fa0
13089 40170 8fa1
13090 40172 8fa2
13091 40174 8fa3
13092 40176 8fa4
13093 40178 8fa5
13094 40180 8fa6
13095 40182 8fa7
13096 40184 8fa8
13097 40191 8fad
13098 40193 8fae
13099 40195 8faf
13100 40197 8fb0
13101 40200 8fb1
13102 40203 8fb2
13103 40208 8fb4
13104 40211 8fb5
13105 40212 8fb6
13106 40215 8fb7
13107 40218 8fb8
13108 40223 8fba
13109 40226 8fbb
13110 40229 8fbc
13111 40233 8fbe
13112 40236 8fbf
13113 40239 8fc0
13114 40241 8fc1
13115 40244 8fc2
13116 40249 8fc4
13117 40252 8fc5
13118 40255 8fc6
13119 40259 8fc8
13120 40263 8fca
13121 40266 8fcb
13122 40271 8fcd
13123 40274 8fce
13124 40279 8fd0
13125 40282 8fd1
13126 40285 8fd2
13127 40288 8fd3
13128 40292 8fd4
13129 40295 8fd5
13130 40304 8fda
13131 40312 8fe0
13132 40317 8fe2
13133 40320 8fe3
13134 40323 8fe4
13135 40326 8fe5
13136 40329 8fe6
13137 40333 8fe8
13138 40336 8fe9
13139 40338 8fea
13140 40341 8feb
13141 40346 8fed
13142 40349 8fee
13143 40352 8fef
13144 40354 8ff0
13145 40357 8ff1
13146 40362 8ff4
13147 40365 8ff5
13148 40368 8ff6
13149 40371 8ff7
13150 40374 8ff8
13151 40377 8ff9
13152 40380 8ffa
13153 40383 8ffb
13154 40388 8ffd
13155 40391 8ffe
13156 40396 9000
13157 40399 9001
13158 40402 9002
13159 40405 9003
13160 40408 9004
13161 40411 9005
13162 40414 9006
13163 40418 9008
13164 40423 900b
13165 40426 900c
13166 40429 900d
13167 40432 900e
13168 40434 900f
13169 40437 9010
13170 40440 9011
13171 40445 9013
13172 40447 9014
13173 40450 9015
13174 40453 9016
13175 40456 9017
13176 40459 9018
13177 40461 9019
13178 40464 901a
13179 40467 901b
13180 40472 901d
13181 40475 901e
13182 40478 901f
13183 40481 9020
13184 40485 9021
13185 40488 9022
13186 40492 9023
13187 40499 9027
13188 40501 9028
13189 40503 9029
13190 40505 902a
13191 40508 902c
13192 40510 902d
13193 40513 902e
13194 40516 902f
13195 40520 9031
13196 40524 9032
13197 40527 9033
13198 40530 9034
13199 40533 9035
13200 40536 9036
13201 40539 9037
13202 40542 9038
13203 40545 9039
13204 40549 903c
13205 40554 903e
13206 40557 903f
13207 40561 9041
13208 40564 9042
13209 40567 9043
13210 40569 9044
13211 40572 9045
13212 40576 9047
13213 40580 9049
13214 40583 904a
13215 40586 904b
13216 40589 904c
13217 40592 904d
13218 40595 904e
13219 40598 904f
13220 40601 9050
13221 40604 9051
13222 40608 9052
13223 40611 9053
13224 40614 9054
13225 40617 9055
13226 40621 9056
13227 40625 9058
13228 40628 9059
13229 40632 905b
13230 40635 905c
13231 40638 905d
13232 40641 905e
13233 40645 9060
13234 40648 9061
13235 40651 9062
13236 40654 9063
13237 40659 9065
13238 40661 9066
13239 40663 9067
13240 40666 9068
13241 40669 9069
13242 40676 906c
13243 40679 906d
13244 40682 906e
13245 40685 906f
13246 40688 9070
13247 40692 9072
13248 40697 9074
13249 40700 9075
13250 40703 9076
13251 40706 9077
13252 40709 9078
13253 40712 9079
13254 40715 907a
13255 40720 907c
13256 40723 907d
13257 40728 907f
13258 40731 9080
13259 40734 9081
13260 40737 9082
13261 40740 9083
13262 40743 9084
13263 40746 9085
13264 40751 9087
13265 40754 9088
13266 40757 9089
13267 40759 908a
13268 40762 908b
13269 40765 908c
13270 40769 908e
13271 40771 908f
13272 40774 9090
13273 40777 9091
13274 40782 9095
13275 40784 9097
13276 40785 9098
13277 40786 9099
13278 40791 909b
13279 40796 90a0
13280 40798 90a1
13281 40800 90a2
13282 40801 90a3
13283 40803 90a5
13284 40805 90a6
13285 40808 90a8
13286 40811 90aa
13287 40818 90af
13288 40819 90b0
13289 40821 90b1
13290 40823 90b2
13291 40824 90b3
13292 40827 90b4
13293 40829 90b5
13294 40830 90b6
13295 40834 90b8
13296 40842 90bd
13297 40843 90be
13298 40847 90c1
13299 40850 90c3
13300 40852 90c4
13301 40854 90c5
13302 40857 90c7
13303 40858 90c8
13304 40860 90c9
13305 40862 90ca
13306 40865 90cc
13307 40868 90ce
13308 40873 90d2
13309 40878 90d5
13310 40880 90d7
13311 40881 90d8
13312 40883 90d9
13313 40885 90db
13314 40887 90dc
13315 40889 90dd
13316 40890 90de
13317 40892 90df
13318 40894 90e1
13319 40895 90e2
13320 40898 90e4
13321 40900 90e5
13322 40903 90e8
13323 40910 90eb
13324 40914 90ed
13325 40917 90ef
13326 40919 90f0
13327 40923 90f2
13328 40925 90f4
13329 40926 90f5
13330 40928 90f6
13331 40930 90f7
13332 40938 90fd
13333 40939 90fe
13334 40942 90ff
13335 40944 9100
13336 40948 9102
13337 40952 9104
13338 40954 9105
13339 40956 9106
13340 40958 9108
13341 40965 910d
13342 40970 9110
13343 40974 9112
13344 40976 9114
13345 40977 9115
13346 40980 9116
13347 40981 9117
13348 40983 9118
13349 40986 9119
13350 40989 911a
13351 40993 911c
13352 40997 911e
13353 40999 9120
13354 41004 9122
13355 41006 9123
13356 41010 9125
13357 41013 9127
13358 41016 9129
13359 41022 912d
13360 41025 912e
13361 41027 912f
13362 41029 9130
13363 41033 9131
13364 41034 9132
13365 41037 9134
13366 41041 9136
13367 41043 9137
13368 41047 9139
13369 41050 913a
13370 41054 913c
13371 41056 913d
13372 41067 9143
13373 41073 9146
13374 41074 9147
13375 41076 9148
13376 41079 9149
13377 41082 914a
13378 41084 914b
13379 41087 914c
13380 41089 914d
13381 41091 914e
13382 41093 914f
13383 41098 9152
13384 41100 9153
13385 41103 9154
13386 41105 9156
13387 41107 9157
13388 41110 9158
13389 41113 9159
13390 41114 915a
13391 41117 915b
13392 41123 9161
13393 41126 9162
13394 41128 9163
13395 41130 9164
13396 41132 9165
13397 41134 9167
13398 41138 9169
13399 41141 916a
13400 41145 916c
13401 41147 916d
13402 41154 9172
13403 41157 9173
13404 41160 9174
13405 41163 9175
13406 41166 9177
13407 41168 9178
13408 41171 9179
13409 41174 917a
13410 41175 917b
13411 41183 9181
13412 41186 9182
13413 41187 9183
13414 41190 9185
13415 41193 9186
13416 41194 9187
13417 41198 9189
13418 41201 918a
13419 41202 918b
13420 41206 918d
13421 41208 918e
13422 41211 9190
13423 41213 9191
13424 41215 9192
13425 41218 9193
13426 41220 9194
13427 41221 9195
13428 41224 9197
13429 41225 9198
13430 41233 919c
13431 41238 919e
13432 41244 91a1
13433 41247 91a2
13434 41251 91a4
13435 41255 91a6
13436 41259 91a8
13437 41263 91aa
13438 41266 91ab
13439 41269 91ac
13440 41272 91ad
13441 41275 91ae
13442 41278 91af
13443 41281 91b0
13444 41284 91b1
13445 41287 91b2
13446 41290 91b3
13447 41292 91b4
13448 41294 91b5
13449 41297 91b6
13450 41301 91b8
13451 41305 91ba
13452 41307 91bb
13453 41308 91bc
13454 41310 91bd
13455 41314 91bf
13456 41316 91c0
13457 41319 91c1
13458 41322 91c2
13459 41325 91c3
13460 41328 91c4
13461 41331 91c5
13462 41334 91c6
13463 41335 91c7
13464 41336 91c8
13465 41337 91c9
13466 41339 91cb
13467 41341 91cc
13468 41342 91cd
13469 41343 91ce
13470 41344 91cf
13471 41345 91d0
13472 41347 91d1
13473 41350 91d3
13474 41352 91d4
13475 41355 91d6
13476 41357 91d7
13477 41359 91d8
13478 41361 91d9
13479 41363 91da
13480 41365 91db
13481 41367 91dc
13482 41369 91dd
13483 41371 91de
13484 41373 91df
13485 41377 91e1
13486 41380 91e3
13487 41382 91e4
13488 41384 91e5
13489 41386 91e6
13490 41388 91e7
13491 41391 91e9
13492 41393 91ea
13493 41396 91ec
13494 41398 91ed
13495 41400 91ee
13496 41402 91ef
13497 41404 91f0
13498 41406 91f1
13499 41411 91f5
13500 41413 91f6
13501 41416 91f7
13502 41420 91f9
13503 41424 91fb
13504 41426 91fc
13505 41428 91fd
13506 41432 91ff
13507 41434 9200
13508 41436 9201
13509 41440 9204
13510 41442 9205
13511 41444 9206
13512 41447 9207
13513 41450 9209
13514 41453 920a
13515 41456 920c
13516 41459 920d
13517 41461 920e
13518 41464 9210
13519 41467 9211
13520 41470 9212
13521 41473 9213
13522 41476 9214
13523 41478 9215
13524 41481 9216
13525 41484 9217
13526 41486 9218
13527 41492 921c
13528 41494 921d
13529 41496 921e
13530 41504 9223
13531 41506 9224
13532 41508 9225
13533 41511 9226
13534 41514 9228
13535 41516 9229
13536 41520 922c
13537 41524 922e
13538 41527 922f
13539 41529 9230
13540 41533 9233
13541 41535 9234
13542 41538 9235
13543 41540 9236
13544 41542 9237
13545 41544 9238
13546 41547 9239
13547 41549 923a
13548 41552 923c
13549 41555 923e
13550 41557 923f
13551 41559 9240
13552 41563 9242
13553 41565 9243
13554 41567 9244
13555 41569 9245
13556 41572 9246
13557 41574 9247
13558 41576 9248
13559 41578 9249
13560 41580 924a
13561 41582 924b
13562 41585 924d
13563 41587 924e
13564 41589 924f
13565 41591 9250
13566 41593 9251
13567 41600 9256
13568 41602 9257
13569 41604 9258
13570 41606 9259
13571 41608 925a
13572 41610 925b
13573 41613 925c
13574 41615 925d
13575 41617 925e
13576 41621 9260
13577 41624 9261
13578 41626 9262
13579 41629 9264
13580 41631 9265
13581 41634 9266
13582 41636 9267
13583 41638 9268
13584 41640 9269
13585 41646 926e
13586 41648 926f
13587 41651 9270
13588 41653 9271
13589 41658 9275
13590 41660 9276
13591 41662 9277
13592 41664 9278
13593 41666 9279
13594 41671 927b
13595 41673 927c
13596 41676 927d
13597 41678 927e
13598 41680 927f
13599 41682 9280
13600 41687 9283
13601 41691 9285
13602 41696 9288
13603 41698 9289
13604 41700 928a
13605 41706 928d
13606 41708 928e
13607 41714 9291
13608 41716 9292
13609 41718 9293
13610 41722 9295
13611 41724 9296
13612 41726 9297
13613 41728 9298
13614 41731 9299
13615 41733 929a
13616 41735 929b
13617 41737 929c
13618 41741 929f
13619 41743 92a0
13620 41750 92a4
13621 41753 92a5
13622 41756 92a7
13623 41758 92a8
13624 41765 92ab
13625 41768 92ad
13626 41772 92af
13627 41776 92b2
13628 41778 92b3
13629 41784 92b6
13630 41786 92b7
13631 41789 92b8
13632 41791 92b9
13633 41794 92ba
13634 41796 92bb
13635 41798 92bc
13636 41800 92bd
13637 41803 92bf
13638 41805 92c0
13639 41807 92c1
13640 41810 92c2
13641 41812 92c3
13642 41816 92c5
13643 41818 92c6
13644 41822 92c7
13645 41824 92c8
13646 41828 92cb
13647 41831 92cc
13648 41833 92cd
13649 41835 92ce
13650 41837 92cf
13651 41839 92d0
13652 41844 92d2
13653 41846 92d3
13654 41849 92d5
13655 41852 92d7
13656 41855 92d8
13657 41858 92d9
13658 41862 92dc
13659 41864 92dd
13660 41867 92df
13661 41870 92e0
13662 41873 92e1
13663 41877 92e3
13664 41879 92e4
13665 41881 92e5
13666 41886 92e7
13667 41888 92e8
13668 41890 92e9
13669 41893 92ea
13670 41896 92ec
13671 41899 92ed
13672 41901 92ee
13673 41904 92f0
13674 41907 92f2
13675 41909 92f3
13676 41915 92f7
13677 41918 92f8
13678 41920 92f9
13679 41922 92fa
13680 41925 92fb
13681 41927 92fc
13682 41932 92ff
13683 41934 9300
13684 41937 9302
13685 41941 9304
13686 41945 9306
13687 41949 9308
13688 41955 930d
13689 41958 930f
13690 41960 9310
13691 41962 9311
13692 41967 9314
13693 41969 9315
13694 41975 9318
13695 41978 9319
13696 41980 931a
13697 41984 931c
13698 41986 931d
13699 41989 931e
13700 41991 931f
13701 41994 9320
13702 41996 9321
13703 41998 9322
13704 42000 9323
13705 42002 9324
13706 42004 9325
13707 42007 9326
13708 42009 9327
13709 42011 9328
13710 42014 9329
13711 42016 932a
13712 42018 932b
13713 42020 932c
13714 42024 932e
13715 42026 932f
13716 42030 9332
13717 42032 9333
13718 42034 9334
13719 42037 9335
13720 42040 9336
13721 42042 9337
13722 42047 933a
13723 42049 933b
13724 42060 9344
13725 42064 9347
13726 42067 9348
13727 42070 9349
13728 42072 934a
13729 42074 934b
13730 42078 934d
13731 42082 9350
13732 42085 9351
13733 42088 9352
13734 42092 9354
13735 42094 9355
13736 42096 9356
13737 42099 9357
13738 42101 9358
13739 42104 935a
13740 42106 935b
13741 42108 935c
13742 42112 935e
13743 42115 9360
13744 42121 9364
13745 42124 9365
13746 42129 9367
13747 42132 9369
13748 42135 936a
13749 42137 936b
13750 42140 936c
13751 42143 936d
13752 42146 936e
13753 42149 936f
13754 42151 9370
13755 42153 9371
13756 42157 9373
13757 42160 9374
13758 42162 9375
13759 42164 9376
13760 42169 937a
13761 42173 937c
13762 42175 937d
13763 42178 937e
13764 42180 937f
13765 42182 9380
13766 42185 9381
13767 42188 9382
13768 42197 9388
13769 42202 938a
13770 42204 938b
13771 42206 938c
13772 42208 938d
13773 42212 938f
13774 42218 9392
13775 42222 9394
13776 42224 9395
13777 42226 9396
13778 42228 9397
13779 42231 9398
13780 42235 939a
13781 42238 939b
13782 42245 939e
13783 42252 93a1
13784 42255 93a3
13785 42258 93a4
13786 42262 93a6
13787 42264 93a7
13788 42266 93a8
13789 42268 93a9
13790 42273 93ab
13791 42275 93ac
13792 42277 93ad
13793 42280 93ae
13794 42283 93b0
13795 42289 93b4
13796 42291 93b5
13797 42293 93b6
13798 42297 93b9
13799 42299 93ba
13800 42301 93bb
13801 42308 93c1
13802 42312 93c3
13803 42315 93c4
13804 42317 93c5
13805 42319 93c6
13806 42322 93c7
13807 42324 93c8
13808 42327 93c9
13809 42329 93ca
13810 42332 93cb
13811 42335 93cc
13812 42338 93cd
13813 42344 93d0
13814 42347 93d1
13815 42350 93d3
13816 42356 93d6
13817 42360 93d7
13818 42362 93d8
13819 42365 93d9
13820 42369 93dc
13821 42371 93dd
13822 42374 93de
13823 42377 93df
13824 42382 93e1
13825 42384 93e2
13826 42388 93e4
13827 42391 93e5
13828 42393 93e6
13829 42395 93e7
13830 42397 93e8
13831 42409 93f1
13832 42414 93f5
13833 42420 93f7
13834 42423 93f8
13835 42425 93f9
13836 42428 93fa
13837 42430 93fb
13838 42435 93fd
13839 42442 9401
13840 42444 9402
13841 42446 9403
13842 42448 9404
13843 42453 9407
13844 42456 9408
13845 42458 9409
13846 42465 940d
13847 42468 940e
13848 42470 940f
13849 42473 9410
13850 42478 9413
13851 42480 9414
13852 42482 9415
13853 42485 9416
13854 42488 9417
13855 42490 9418
13856 42492 9419
13857 42494 941a
13858 42500 941f
13859 42503 9421
13860 42519 942b
13861 42524 942e
13862 42526 942f
13863 42531 9431
13864 42533 9432
13865 42535 9433
13866 42538 9434
13867 42540 9435
13868 42543 9436
13869 42547 9438
13870 42551 943a
13871 42553 943b
13872 42557 943d
13873 42561 943f
13874 42565 9441
13875 42569 9443
13876 42572 9444
13877 42574 9445
13878 42579 9448
13879 42583 944a
13880 42587 944c
13881 42594 9451
13882 42597 9452
13883 42600 9453
13884 42604 9455
13885 42609 9459
13886 42611 945a
13887 42613 945b
13888 42616 945c
13889 42620 945e
13890 42623 945f
13891 42625 9460
13892 42628 9461
13893 42630 9462
13894 42633 9463
13895 42641 9468
13896 42645 946a
13897 42648 946b
13898 42652 946d
13899 42654 946e
13900 42657 946f
13901 42659 9470
13902 42661 9471
13903 42664 9472
13904 42669 9475
13905 42674 9477
13906 42682 947c
13907 42684 947d
13908 42686 947e
13909 42688 947f
13910 42693 9481
13911 42696 9483
13912 42698 9484
13913 42700 9485
13914 42943 9577
13915 42945 9578
13916 42947 9579
13917 42953 957e
13918 42955 957f
13919 42956 9580
13920 42958 9582
13921 42959 9583
13922 42961 9584
13923 42963 9586
13924 42964 9587
13925 42966 9588
13926 42967 9589
13927 42968 958a
13928 42970 958b
13929 42971 958c
13930 42973 958d
13931 42975 958e
13932 42977 958f
13933 42979 9591
13934 42981 9592
13935 42982 9593
13936 42983 9594
13937 42986 9596
13938 42989 9598
13939 42991 9599
13940 42996 959d
13941 42998 959e
13942 43000 959f
13943 43001 95a0
13944 43002 95a1
13945 43004 95a2
13946 43006 95a3
13947 43009 95a4
13948 43012 95a5
13949 43013 95a6
13950 43015 95a7
13951 43016 95a8
13952 43018 95a9
13953 43020 95ab
13954 43022 95ac
13955 43024 95ad
13956 43029 95b1
13957 43032 95b2
13958 43034 95b4
13959 43036 95b6
13960 43041 95b9
13961 43043 95ba
13962 43045 95bb
13963 43047 95bc
13964 43050 95bd
13965 43052 95be
13966 43053 95bf
13967 43059 95c3
13968 43063 95c6
13969 43065 95c7
13970 43067 95c8
13971 43069 95c9
13972 43072 95ca
13973 43073 95cb
13974 43076 95cc
13975 43078 95cd
13976 43082 95d0
13977 43084 95d1
13978 43087 95d2
13979 43090 95d3
13980 43091 95d4
13981 43093 95d5
13982 43095 95d6
13983 43097 95d8
13984 43098 95d9
13985 43100 95da
13986 43103 95dc
13987 43105 95dd
13988 43107 95de
13989 43110 95df
13990 43113 95e0
13991 43114 95e1
13992 43115 95e2
13993 43118 95e4
13994 43120 95e5
13995 43123 95e6
13996 43125 95e8
13997 43178 961c
13998 43179 961d
13999 43180 961e
14000 43183 9621
14001 43184 9622
14002 43187 9624
14003 43189 9625
14004 43191 9626
14005 43193 9628
14006 43195 962a
14007 43198 962c
14008 43201 962e
14009 43202 962f
14010 43205 9631
14011 43207 9632
14012 43209 9633
14013 43210 9634
14014 43213 9637
14015 43214 9638
14016 43217 9639
14017 43219 963a
14018 43222 963b
14019 43223 963c
14020 43224 963d
14021 43226 963f
14022 43227 9640
14023 43229 9641
14024 43231 9642
14025 43233 9644
14026 43241 964b
14027 43243 964c
14028 43244 964d
14029 43248 964f
14030 43250 9650
14031 43253 9652
14032 43255 9654
14033 43258 9656
14034 43261 9657
14035 43263 9658
14036 43266 965b
14037 43269 965c
14038 43270 965d
14039 43272 965e
14040 43273 965f
14041 43276 9661
14042 43277 9662
14043 43279 9663
14044 43280 9664
14045 43282 9665
14046 43283 9666
14047 43288 966a
14048 43292 966c
14049 43296 966e
14050 43299 9670
14051 43304 9672
14052 43307 9673
14053 43308 9674
14054 43310 9675
14055 43313 9676
14056 43315 9677
14057 43317 9678
14058 43321 967a
14059 43323 967b
14060 43325 967c
14061 43327 967d
14062 43328 967e
14063 43330 967f
14064 43333 9681
14065 43336 9682
14066 43338 9683
14067 43341 9684
14068 43342 9685
14069 43344 9686
14070 43348 9688
14071 43350 9689
14072 43352 968a
14073 43354 968b
14074 43358 968d
14075 43361 968e
14076 43364 968f
14077 43368 9691
14078 43371 9694
14079 43373 9695
14080 43374 9696
14081 43375 9697
14082 43378 9698
14083 43380 9699
14084 43382 969a
14085 43383 969b
14086 43386 969c
14087 43388 969d
14088 43391 969f
14089 43392 96a0
14090 43396 96a3
14091 43399 96a4
14092 43400 96a5
14093 43402 96a6
14094 43404 96a7
14095 43407 96a8
14096 43410 96a9
14097 43413 96aa
14098 43418 96ae
14099 43420 96af
14100 43421 96b0
14101 43423 96b1
14102 43426 96b2
14103 43428 96b3
14104 43431 96b4
14105 43435 96b6
14106 43437 96b7
14107 43439 96b8
14108 43442 96b9
14109 43444 96ba
14110 43446 96bb
14111 43448 96bc
14112 43450 96bd
14113 43454 96c0
14114 43456 96c1
14115 43461 96c4
14116 43463 96c5
14117 43466 96c6
14118 43469 96c7
14119 43473 96c9
14120 43475 96ca
14121 43477 96cb
14122 43479 96cc
14123 43481 96cd
14124 43483 96ce
14125 43487 96d1
14126 43489 96d2
14127 43493 96d5
14128 43497 96d6
14129 43501 96d8
14130 43504 96d9
14131 43506 96da
14132 43509 96db
14133 43511 96dc
14134 43514 96dd
14135 43516 96de
14136 43518 96df
14137 43524 96e2
14138 43527 96e3
14139 43533 96e8
14140 43535 96e9
14141 43538 96ea
14142 43541 96eb
14143 43545 96ef
14144 43548 96f0
14145 43550 96f1
14146 43553 96f2
14147 43561 96f6
14148 43564 96f7
14149 43569 96f9
14150 43571 96fa
14151 43573 96fb
14152 43581 9700
14153 43584 9702
14154 43586 9703
14155 43588 9704
14156 43591 9705
14157 43594 9706
14158 43597 9707
14159 43600 9708
14160 43602 9709
14161 43605 970a
14162 43609 970d
14163 43612 970e
14164 43615 970f
14165 43620 9711
14166 43624 9713
14167 43627 9714
14168 43630 9716
14169 43635 9719
14170 43637 971a
14171 43638 971b
14172 43641 971c
14173 43643 971d
14174 43645 971e
14175 43651 9721
14176 43653 9722
14177 43656 9723
14178 43658 9724
14179 43665 9727
14180 43668 9728
14181 43672 972a
14182 43684 9730
14183 43687 9731
14184 43690 9732
14185 43692 9733
14186 43697 9736
14187 43701 9738
14188 43703 9739
14189 43708 973b
14190 43710 973d
14191 43713 973e
14192 43719 9741
14193 43721 9742
14194 43723 9743
14195 43726 9744
14196 43730 9746
14197 43733 9747
14198 43736 9748
14199 43738 9749
14200 43741 974a
14201 43748 974d
14202 43750 974e
14203 43752 974f
14204 43755 9751
14205 43756 9752
14206 43760 9755
14207 43763 9756
14208 43766 9757
14209 43769 9758
14210 43772 9759
14211 43774 975a
14212 43777 975b
14213 43780 975c
14214 43786 975e
14215 43791 9760
14216 43795 9761
14217 43799 9762
14218 43800 9763
14219 43801 9764
14220 43803 9766
14221 43804 9767
14222 43805 9768
14223 43808 9769
14224 43809 976a
14225 43810 976b
14226 43813 976d
14227 43816 976e
14228 43820 9771
14229 43823 9773
14230 43825 9774
14231 43830 9776
14232 43831 9777
14233 43833 9778
14234 43835 9779
14235 43837 977a
14236 43838 977b
14237 43839 977c
14238 43840 977d
14239 43843 977f
14240 43845 9780
14241 43846 9781
14242 43849 9784
14243 43850 9785
14244 43852 9786
14245 43855 9789
14246 43857 978b
14247 43859 978d
14248 43863 978f
14249 43865 9790
14250 43870 9795
14251 43871 9796
14252 43873 9797
14253 43875 9798
14254 43878 9799
14255 43880 979a
14256 43884 979c
14257 43886 979e
14258 43887 979f
14259 43889 97a0
14260 43892 97a2
14261 43894 97a3
14262 43898 97a6
14263 43901 97a8
14264 43906 97ab
14265 43908 97ac
14266 43910 97ad
14267 43911 97ae
14268 43914 97b1
14269 43916 97b2
14270 43918 97b3
14271 43921 97b4
14272 43924 97b5
14273 43926 97b6
14274 43930 97b8
14275 43933 97b9
14276 43935 97ba
14277 43938 97bc
14278 43940 97be
14279 43943 97bf
14280 43947 97c1
14281 43950 97c3
14282 43953 97c4
14283 43956 97c5
14284 43958 97c6
14285 43961 97c7
14286 43963 97c8
14287 43965 97c9
14288 43968 97ca
14289 43969 97cb
14290 43971 97cc
14291 43974 97cd
14292 43977 97ce
14293 43980 97d0
14294 43982 97d1
14295 43985 97d3
14296 43988 97d4
14297 43993 97d7
14298 43995 97d8
14299 43998 97d9
14300 44002 97db
14301 44004 97dc
14302 44006 97dd
14303 44008 97de
14304 44012 97e0
14305 44015 97e1
14306 44020 97e4
14307 44023 97e6
14308 44030 97ed
14309 44031 97ee
14310 44033 97ef
14311 44036 97f1
14312 44038 97f2
14313 44040 97f3
14314 44042 97f4
14315 44044 97f5
14316 44047 97f6
14317 44049 97f7
14318 44051 97f8
14319 44054 97fa
14320 44057 97fb
14321 44063 97ff
14322 44068 9801
14323 44069 9802
14324 44070 9803
14325 44072 9804
14326 44074 9805
14327 44075 9806
14328 44076 9807
14329 44077 9808
14330 44079 980a
14331 44081 980c
14332 44083 980d
14333 44084 980e
14334 44086 980f
14335 44088 9810
14336 44089 9811
14337 44091 9812
14338 44093 9813
14339 44095 9814
14340 44097 9816
14341 44099 9817
14342 44100 9818
14343 44103 9819
14344 44105 981a
14345 44109 981c
14346 44112 981e
14347 44116 9820
14348 44118 9821
14349 44120 9823
14350 44122 9824
14351 44124 9825
14352 44126 9826
14353 44132 982b
14354 44134 982c
14355 44135 982d
14356 44136 982e
14357 44137 982f
14358 44140 9830
14359 44142 9832
14360 44144 9833
14361 44145 9834
14362 44147 9835
14363 44149 9837
14364 44152 9838
14365 44153 9839
14366 44156 983b
14367 44158 983c
14368 44159 983d
14369 44161 983e
14370 44169 9844
14371 44174 9846
14372 44175 9847
14373 44181 984a
14374 44182 984b
14375 44183 984c
14376 44184 984d
14377 44186 984e
14378 44188 984f
14379 44191 9851
14380 44192 9852
14381 44194 9853
14382 44195 9854
14383 44197 9855
14384 44198 9856
14385 44200 9857
14386 44201 9858
14387 44202 9859
14388 44204 985a
14389 44205 985b
14390 44210 985e
14391 44217 9862
14392 44219 9863
14393 44221 9865
14394 44223 9866
14395 44225 9867
14396 44230 986a
14397 44232 986b
14398 44234 986c
14399 44238 986f
14400 44240 9870
14401 44242 9871
14402 44246 9873
14403 44249 9874
14404 44252 9875
14405 44303 98a8
14406 44307 98aa
14407 44309 98ab
14408 44313 98ad
14409 44315 98ae
14410 44317 98af
14411 44320 98b0
14412 44322 98b1
14413 44330 98b4
14414 44333 98b6
14415 44335 98b7
14416 44338 98b8
14417 44342 98ba
14418 44344 98bb
14419 44347 98bc
14420 44355 98bf
14421 44361 98c2
14422 44364 98c3
14423 44366 98c4
14424 44369 98c5
14425 44370 98c6
14426 44373 98c7
14427 44376 98c8
14428 44382 98cb
14429 44385 98cc
14430 44389 98ce
14431 44402 98db
14432 44404 98dc
14433 44407 98de
14434 44408 98df
14435 44411 98e0
14436 44414 98e1
14437 44417 98e2
14438 44420 98e3
14439 44424 98e5
14440 44427 98e6
14441 44430 98e7
14442 44434 98e9
14443 44437 98ea
14444 44440 98eb
14445 44445 98ed
14446 44448 98ee
14447 44450 98ef
14448 44453 98f0
14449 44455 98f1
14450 44458 98f2
14451 44461 98f3
14452 44463 98f4
14453 44468 98f6
14454 44479 98fc
14455 44482 98fd
14456 44485 98fe
14457 44492 9902
14458 44495 9903
14459 44499 9905
14460 44503 9907
14461 44506 9908
14462 44509 9909
14463 44512 990a
14464 44516 990c
14465 44523 9910
14466 44526 9911
14467 44529 9912
14468 44532 9913
14469 44535 9914
14470 44538 9915
14471 44541 9916
14472 44544 9917
14473 44547 9918
14474 44552 991a
14475 44555 991b
14476 44558 991c
14477 44561 991d
14478 44563 991e
14479 44566 991f
14480 44569 9920
14481 44571 9921
14482 44574 9922
14483 44577 9924
14484 44582 9926
14485 44584 9927
14486 44587 9928
14487 44595 992b
14488 44598 992c
14489 44603 992e
14490 44611 9931
14491 44614 9932
14492 44617 9933
14493 44620 9934
14494 44622 9935
14495 44630 9939
14496 44633 993a
14497 44636 993b
14498 44639 993c
14499 44642 993d
14500 44645 993e
14501 44650 9940
14502 44653 9941
14503 44656 9942
14504 44662 9945
14505 44665 9946
14506 44667 9947
14507 44670 9948
14508 44673 9949
14509 44678 994b
14510 44681 994c
14511 44684 994d
14512 44687 994e
14513 44691 9950
14514 44694 9951
14515 44697 9952
14516 44702 9954
14517 44705 9955
14518 44710 9957
14519 44713 9958
14520 44716 9959
14521 44720 995b
14522 44723 995c
14523 44728 995e
14524 44731 995f
14525 44734 9960
14526 44740 9963
14527 44791 9996
14528 44792 9997
14529 44793 9998
14530 44794 9999
14531 44797 999b
14532 44801 999d
14533 44802 999e
14534 44804 999f
14535 44810 99a3
14536 44814 99a5
14537 44816 99a6
14538 44820 99a8
14539 44827 99ac
14540 44828 99ad
14541 44830 99ae
14542 44833 99b0
14543 44835 99b1
14544 44836 99b2
14545 44837 99b3
14546 44839 99b4
14547 44840 99b5
14548 44844 99b9
14549 44845 99ba
14550 44848 99bc
14551 44850 99bd
14552 44852 99bf
14553 44855 99c1
14554 44859 99c3
14555 44861 99c4
14556 44862 99c5
14557 44864 99c6
14558 44867 99c8
14559 44869 99c9
14560 44878 99d0
14561 44880 99d1
14562 44883 99d2
14563 44885 99d3
14564 44888 99d4
14565 44889 99d5
14566 44893 99d8
14567 44895 99d9
14568 44896 99da
14569 44898 99db
14570 44899 99dc
14571 44901 99dd
14572 44903 99de
14573 44904 99df
14574 44906 99e1
14575 44907 99e2
14576 44913 99e7
14577 44917 99ea
14578 44918 99eb
14579 44919 99ec
14580 44921 99ed
14581 44923 99ee
14582 44926 99f0
14583 44928 99f1
14584 44930 99f2
14585 44933 99f4
14586 44934 99f5
14587 44938 99f8
14588 44940 99f9
14589 44944 99fb
14590 44945 99fc
14591 44947 99fd
14592 44949 99fe
14593 44952 99ff
14594 44956 9a01
14595 44958 9a02
14596 44960 9a03
14597 44963 9a04
14598 44966 9a05
14599 44971 9a08
14600 44975 9a0a
14601 44977 9a0b
14602 44979 9a0c
14603 44983 9a0e
14604 44984 9a0f
14605 44985 9a10
14606 44988 9a11
14607 44990 9a12
14608 44992 9a13
14609 44998 9a16
14610 45001 9a19
14611 45004 9a1a
14612 45010 9a1e
14613 45015 9a20
14614 45017 9a22
14615 45018 9a23
14616 45021 9a24
14617 45026 9a27
14618 45028 9a28
14619 45034 9a2b
14620 45038 9a2d
14621 45040 9a2e
14622 45043 9a30
14623 45045 9a31
14624 45050 9a33
14625 45053 9a35
14626 45054 9a36
14627 45055 9a37
14628 45058 9a38
14629 45068 9a3e
14630 45071 9a40
14631 45073 9a41
14632 45076 9a42
14633 45078 9a43
14634 45080 9a44
14635 45083 9a45
14636 45088 9a47
14637 45094 9a4a
14638 45097 9a4b
14639 45099 9a4c
14640 45100 9a4d
14641 45101 9a4e
14642 45108 9a51
14643 45110 9a52
14644 45112 9a54
14645 45114 9a55
14646 45115 9a56
14647 45118 9a57
14648 45120 9a58
14649 45125 9a5a
14650 45128 9a5b
14651 45132 9a5d
14652 45134 9a5f
14653 45140 9a62
14654 45143 9a64
14655 45145 9a65
14656 45154 9a69
14657 45157 9a6a
14658 45160 9a6b
14659 45161 9a6c
14660 45222 9aa8
14661 45226 9aaa
14662 45231 9aac
14663 45233 9aad
14664 45236 9aae
14665 45238 9aaf
14666 45241 9ab0
14667 45246 9ab2
14668 45251 9ab4
14669 45254 9ab5
14670 45256 9ab6
14671 45259 9ab7
14672 45262 9ab8
14673 45265 9ab9
14674 45270 9abb
14675 45273 9abc
14676 45276 9abd
14677 45279 9abe
14678 45282 9abf
14679 45285 9ac0
14680 45288 9ac1
14681 45293 9ac3
14682 45295 9ac4
14683 45298 9ac6
14684 45303 9ac8
14685 45312 9ace
14686 45314 9acf
14687 45317 9ad0
14688 45320 9ad1
14689 45323 9ad2
14690 45326 9ad3
14691 45329 9ad4
14692 45332 9ad5
14693 45335 9ad6
14694 45338 9ad7
14695 45341 9ad8
14696 45343 9ad9
14697 45346 9adb
14698 45348 9adc
14699 45351 9ade
14700 45353 9adf
14701 45355 9ae0
14702 45359 9ae2
14703 45362 9ae3
14704 45364 9ae4
14705 45366 9ae5
14706 45368 9ae6
14707 45370 9ae7
14708 45373 9ae9
14709 45375 9aea
14710 45377 9aeb
14711 45379 9aec
14712 45382 9aed
14713 45385 9aee
14714 45388 9aef
14715 45392 9af1
14716 45394 9af2
14717 45396 9af3
14718 45398 9af4
14719 45400 9af5
14720 45404 9af7
14721 45407 9af9
14722 45409 9afa
14723 45411 9afb
14724 45414 9afd
14725 45418 9aff
14726 45420 9b00
14727 45422 9b01
14728 45424 9b02
14729 45426 9b03
14730 45429 9b04
14731 45431 9b05
14732 45434 9b06
14733 45438 9b08
14734 45440 9b09
14735 45445 9b0b
14736 45449 9b0c
14737 45452 9b0d
14738 45455 9b0e
14739 45459 9b10
14740 45463 9b12
14741 45470 9b16
14742 45474 9b18
14743 45477 9b19
14744 45479 9b1a
14745 45481 9b1b
14746 45483 9b1c
14747 45485 9b1d
14748 45489 9b1f
14749 45491 9b20
14750 45494 9b22
14751 45496 9b23
14752 45501 9b25
14753 45502 9b26
14754 45503 9b27
14755 45505 9b28
14756 45506 9b29
14757 45508 9b2a
14758 45509 9b2b
14759 45512 9b2c
14760 45514 9b2d
14761 45516 9b2e
14762 45519 9b2f
14763 45522 9b31
14764 45524 9b32
14765 45526 9b33
14766 45529 9b34
14767 45531 9b35
14768 45535 9b37
14769 45539 9b39
14770 45541 9b3a
14771 45543 9b3b
14772 45546 9b3c
14773 45549 9b3d
14774 45557 9b41
14775 45560 9b42
14776 45563 9b43
14777 45566 9b44
14778 45569 9b45
14779 45575 9b48
14780 45581 9b4b
14781 45584 9b4c
14782 45587 9b4d
14783 45590 9b4e
14784 45593 9b4f
14785 45598 9b51
14786 45604 9b54
14787 45607 9b55
14788 45610 9b56
14789 45613 9b57
14790 45615 9b58
14791 45620 9b5a
14792 45621 9b5b
14793 45624 9b5e
14794 45628 9b61
14795 45631 9b63
14796 45634 9b65
14797 45636 9b66
14798 45639 9b68
14799 45642 9b6a
14800 45644 9b6b
14801 45646 9b6c
14802 45648 9b6d
14803 45649 9b6e
14804 45651 9b6f
14805 45654 9b72
14806 45656 9b73
14807 45657 9b74
14808 45659 9b75
14809 45662 9b76
14810 45664 9b77
14811 45666 9b78
14812 45667 9b79
14813 45674 9b7f
14814 45677 9b80
14815 45682 9b83
14816 45684 9b84
14817 45686 9b85
14818 45687 9b86
14819 45689 9b87
14820 45691 9b89
14821 45692 9b8a
14822 45693 9b8b
14823 45695 9b8d
14824 45696 9b8e
14825 45697 9b8f
14826 45698 9b90
14827 45700 9b91
14828 45701 9b92
14829 45702 9b93
14830 45703 9b94
14831 45706 9b96
14832 45707 9b97
14833 45710 9b9a
14834 45713 9b9d
14835 45715 9b9e
14836 45716 9b9f
14837 45719 9ba0
14838 45726 9ba6
14839 45727 9ba7
14840 45729 9ba8
14841 45731 9ba9
14842 45732 9baa
14843 45734 9bab
14844 45736 9bac
14845 45738 9bad
14846 45739 9bae
14847 45741 9bb0
14848 45742 9bb1
14849 45743 9bb2
14850 45745 9bb4
14851 45749 9bb7
14852 45751 9bb8
14853 45752 9bb9
14854 45756 9bbb
14855 45758 9bbc
14856 45761 9bbe
14857 45763 9bbf
14858 45765 9bc0
14859 45768 9bc1
14860 45773 9bc6
14861 45774 9bc7
14862 45776 9bc8
14863 45778 9bc9
14864 45779 9bca
14865 45784 9bce
14866 45786 9bcf
14867 45787 9bd0
14868 45788 9bd1
14869 45789 9bd2
14870 45792 9bd4
14871 45794 9bd6
14872 45797 9bd7
14873 45799 9bd8
14874 45804 9bdb
14875 45808 9bdd
14876 45811 9bdf
14877 45813 9be1
14878 45815 9be2
14879 45817 9be3
14880 45818 9be4
14881 45821 9be5
14882 45826 9be7
14883 45827 9be8
14884 45830 9bea
14885 45833 9beb
14886 45837 9bee
14887 45839 9bef
14888 45840 9bf0
14889 45843 9bf1
14890 45846 9bf2
14891 45848 9bf3
14892 45852 9bf5
14893 45855 9bf7
14894 45856 9bf8
14895 45858 9bf9
14896 45859 9bfa
14897 45863 9bfd
14898 45866 9bff
14899 45869 9c00
14900 45872 9c02
14901 45874 9c04
14902 45878 9c06
14903 45882 9c08
14904 45884 9c09
14905 45885 9c0a
14906 45886 9c0b
14907 45889 9c0c
14908 45891 9c0d
14909 45894 9c0f
14910 45895 9c10
14911 45897 9c11
14912 45898 9c12
14913 45900 9c13
14914 45902 9c14
14915 45903 9c15
14916 45904 9c16
14917 45907 9c18
14918 45909 9c19
14919 45910 9c1a
14920 45912 9c1b
14921 45913 9c1c
14922 45915 9c1d
14923 45917 9c1e
14924 45921 9c21
14925 45923 9c22
14926 45924 9c23
14927 45926 9c24
14928 45928 9c25
14929 45931 9c26
14930 45933 9c27
14931 45935 9c28
14932 45938 9c29
14933 45941 9c2a
14934 45946 9c2d
14935 45949 9c2e
14936 45950 9c2f
14937 45953 9c30
14938 45955 9c31
14939 45958 9c32
14940 45963 9c35
14941 45966 9c36
14942 45969 9c37
14943 45973 9c39
14944 45975 9c3a
14945 45977 9c3b
14946 45981 9c3d
14947 45982 9c3e
14948 45987 9c41
14949 45991 9c43
14950 45993 9c44
14951 45994 9c45
14952 45997 9c46
14953 45999 9c47
14954 46001 9c48
14955 46003 9c49
14956 46005 9c4a
14957 46012 9c4e
14958 46013 9c4f
14959 46015 9c50
14960 46017 9c52
14961 46020 9c53
14962 46021 9c54
14963 46025 9c56
14964 46027 9c57
14965 46030 9c58
14966 46033 9c5a
14967 46034 9c5b
14968 46036 9c5c
14969 46038 9c5d
14970 46040 9c5e
14971 46042 9c5f
14972 46044 9c60
14973 46046 9c61
14974 46050 9c63
14975 46053 9c65
14976 46056 9c67
14977 46057 9c68
14978 46059 9c69
14979 46060 9c6a
14980 46062 9c6b
14981 46064 9c6d
14982 46066 9c6e
14983 46070 9c70
14984 46074 9c72
14985 46081 9c75
14986 46083 9c76
14987 46085 9c77
14988 46086 9c78
14989 46090 9c7a
14990 46093 9c7b
14991 46094 9c7c
14992 46199 9ce5
14993 46200 9ce6
14994 46201 9ce7
14995 46203 9ce9
14996 46207 9ceb
14997 46208 9cec
14998 46213 9cf0
14999 46216 9cf2
15000 46217 9cf3
15001 46218 9cf4
15002 46220 9cf6
15003 46222 9cf7
15004 46224 9cf9
15005 46235 9d02
15006 46236 9d03
15007 46242 9d06
15008 46244 9d07
15009 46246 9d08
15010 46247 9d09
15011 46252 9d0b
15012 46257 9d0e
15013 46261 9d11
15014 46263 9d12
15015 46268 9d15
15016 46271 9d17
15017 46273 9d18
15018 46277 9d1b
15019 46279 9d1c
15020 46280 9d1d
15021 46281 9d1e
15022 46283 9d1f
15023 46289 9d23
15024 46293 9d26
15025 46297 9d28
15026 46299 9d2a
15027 46301 9d2b
15028 46302 9d2c
15029 46305 9d2f
15030 46307 9d30
15031 46310 9d32
15032 46311 9d33
15033 46314 9d34
15034 46321 9d3a
15035 46323 9d3b
15036 46324 9d3c
15037 46325 9d3d
15038 46328 9d3e
15039 46330 9d3f
15040 46334 9d41
15041 46336 9d42
15042 46337 9d43
15043 46340 9d44
15044 46342 9d45
15045 46344 9d46
15046 46345 9d47
15047 46347 9d48
15048 46351 9d4a
15049 46359 9d50
15050 46361 9d51
15051 46363 9d52
15052 46365 9d53
15053 46367 9d54
15054 46375 9d59
15055 46379 9d5c
15056 46381 9d5d
15057 46382 9d5e
15058 46383 9d5f
15059 46385 9d60
15060 46387 9d61
15061 46388 9d62
15062 46390 9d63
15063 46391 9d64
15064 46393 9d65
15065 46398 9d69
15066 46400 9d6a
15067 46402 9d6b
15068 46403 9d6c
15069 46406 9d6f
15070 46408 9d70
15071 46413 9d72
15072 46414 9d73
15073 46420 9d76
15074 46421 9d77
15075 46426 9d7a
15076 46428 9d7b
15077 46430 9d7c
15078 46434 9d7e
15079 46440 9d83
15080 46442 9d84
15081 46446 9d86
15082 46447 9d87
15083 46450 9d89
15084 46452 9d8a
15085 46457 9d8d
15086 46458 9d8e
15087 46460 9d8f
15088 46464 9d92
15089 46465 9d93
15090 46469 9d95
15091 46471 9d96
15092 46473 9d97
15093 46474 9d98
15094 46476 9d99
15095 46478 9d9a
15096 46491 9da1
15097 46497 9da4
15098 46505 9da9
15099 46506 9daa
15100 46507 9dab
15101 46508 9dac
15102 46512 9dae
15103 46514 9daf
15104 46517 9db1
15105 46519 9db2
15106 46522 9db4
15107 46524 9db5
15108 46528 9db8
15109 46530 9db9
15110 46533 9dba
15111 46536 9dbb
15112 46539 9dbc
15113 46541 9dbd
15114 46545 9dbf
15115 46548 9dc0
15116 46550 9dc1
15117 46552 9dc2
15118 46555 9dc3
15119 46558 9dc4
15120 46562 9dc6
15121 46563 9dc7
15122 46567 9dc9
15123 46570 9dca
15124 46577 9dcf
15125 46583 9dd3
15126 46585 9dd4
15127 46588 9dd5
15128 46590 9dd6
15129 46593 9dd7
15130 46597 9dd9
15131 46599 9dda
15132 46608 9dde
15133 46610 9ddf
15134 46613 9de0
15135 46617 9de3
15136 46619 9de5
15137 46622 9de6
15138 46624 9de7
15139 46627 9de9
15140 46630 9deb
15141 46633 9ded
15142 46634 9dee
15143 46636 9def
15144 46638 9df0
15145 46642 9df2
15146 46645 9df3
15147 46646 9df4
15148 46652 9df8
15149 46654 9df9
15150 46656 9dfa
15151 46659 9dfd
15152 46661 9dfe
15153 46668 9e02
15154 46675 9e07
15155 46679 9e0a
15156 46684 9e0d
15157 46685 9e0e
15158 46688 9e10
15159 46691 9e11
15160 46693 9e12
15161 46698 9e15
15162 46700 9e16
15163 46706 9e19
15164 46708 9e1a
15165 46711 9e1b
15166 46714 9e1c
15167 46716 9e1d
15168 46719 9e1e
15169 46721 9e1f
15170 46807 9e75
15171 46811 9e78
15172 46813 9e79
15173 46814 9e7a
15174 46816 9e7b
15175 46818 9e7c
15176 46820 9e7d
15177 46823 9e7f
15178 46826 9e80
15179 46829 9e81
15180 46832 9e82
15181 46835 9e83
15182 46838 9e84
15183 46841 9e85
15184 46846 9e87
15185 46849 9e88
15186 46856 9e8b
15187 46859 9e8c
15188 46864 9e8e
15189 46867 9e8f
15190 46871 9e91
15191 46874 9e92
15192 46876 9e93
15193 46881 9e95
15194 46884 9e96
15195 46887 9e97
15196 46890 9e98
15197 46897 9e9b
15198 46902 9e9d
15199 46905 9e9e
15200 46908 9e9f
15201 46919 9ea4
15202 46922 9ea5
15203 46924 9ea6
15204 46927 9ea8
15205 46930 9ea9
15206 46933 9eaa
15207 46938 9eac
15208 46941 9ead
15209 46944 9eae
15210 46947 9eaf
15211 46950 9eb0
15212 46956 9eb3
15213 46958 9eb4
15214 46961 9eb5
15215 46968 9eb8
15216 46970 9eb9
15217 46972 9eba
15218 46974 9ebb
15219 46977 9ebc
15220 46980 9ebd
15221 46983 9ebe
15222 46986 9ebf
15223 46995 9ec3
15224 46997 9ec4
15225 47001 9ec6
15226 47006 9ec8
15227 47011 9ecb
15228 47013 9ecc
15229 47016 9ecd
15230 47018 9ece
15231 47020 9ecf
15232 47022 9ed0
15233 47025 9ed1
15234 47026 9ed2
15235 47029 9ed4
15236 47032 9ed5
15237 47038 9ed8
15238 47040 9ed9
15239 47043 9edb
15240 47045 9edc
15241 47048 9edd
15242 47050 9ede
15243 47051 9edf
15244 47054 9ee0
15245 47059 9ee4
15246 47061 9ee5
15247 47066 9ee7
15248 47067 9ee8
15249 47072 9eec
15250 47073 9eed
15251 47076 9eee
15252 47079 9eef
15253 47081 9ef0
15254 47084 9ef1
15255 47086 9ef2
15256 47091 9ef4
15257 47093 9ef5
15258 47096 9ef6
15259 47099 9ef7
15260 47101 9ef8
15261 47103 9ef9
15262 47109 9efb
15263 47112 9efc
15264 47115 9efd
15265 47118 9efe
15266 47119 9eff
15267 47127 9f02
15268 47131 9f03
15269 47138 9f07
15270 47142 9f08
15271 47145 9f09
15272 47154 9f0e
15273 47156 9f0f
15274 47158 9f10
15275 47160 9f11
15276 47162 9f12
15277 47164 9f13
15278 47166 9f14
15279 47167 9f15
15280 47169 9f16
15281 47170 9f17
15282 47174 9f19
15283 47177 9f1a
15284 47179 9f1b
15285 47187 9f1f
15286 47189 9f20
15287 47192 9f21
15288 47193 9f22
15289 47202 9f26
15290 47211 9f2a
15291 47214 9f2b
15292 47217 9f2c
15293 47225 9f2f
15294 47230 9f31
15295 47233 9f32
15296 47238 9f34
15297 47245 9f37
15298 47251 9f39
15299 47254 9f3a
15300 47256 9f3b
15301 47258 9f3c
15302 47260 9f3d
15303 47262 9f3e
15304 47263 9f3f
15305 47267 9f41
15306 47270 9f43
15307 47273 9f44
15308 47276 9f45
15309 47278 9f46
15310 47279 9f47
15311 47285 9f4a
15312 47287 9f4b
15313 47294 9f4e
15314 47297 9f4f
15315 47300 9f50
15316 47303 9f52
15317 47305 9f53
15318 47308 9f54
15319 47311 9f55
15320 47314 9f56
15321 47317 9f57
15322 47320 9f58
15323 47325 9f5a
15324 47332 9f5d
15325 47335 9f5e
15326 47338 9f5f
15327 47341 9f60
15328 47344 9f61
15329 47347 9f62
15330 47350 9f63
15331 47356 9f66
15332 47359 9f67
15333 47362 9f68
15334 47364 9f69
15335 47367 9f6a
15336 47373 9f6c
15337 47376 9f6d
15338 47378 9f6e
15339 47381 9f6f
15340 47384 9f70
15341 47387 9f71
15342 47390 9f72
15343 47393 9f73
15344 47397 9f75
15345 47400 9f76
15346 47403 9f77
15347 47410 9f7a
15348 47416 9f7d
15349 47420 9f7f
15350 47434 9f8d
15351 47440 9f8f
15352 47442 9f90
15353 47445 9f91
15354 47448 9f92
15355 47453 9f94
15356 47456 9f95
15357 47459 9f96
15358 47462 9f97
15359 47467 9f99
15360 47470 9f9c
15361 47473 9f9d
15362 47475 9f9e
15363 47477 9f9f
15364 47478 9fa0
15365 47480 9fa1
15366 47482 9fa2
15367 47484 9fa3
15368 47488 9fa5
15369 47504 9fb4
15370 47513 9fbc
15371 47514 9fbd
15372 47515 9fbe
15373 47516 9fbf
15374 47517 9fc0
15375 47518 9fc1
15376 47520 9fc2
15377 47522 9fc4
15378 47525 9fc6
15379 47532 9fcc
15380 38815 f900
15381 21055 f901
15382 39846 f902
15383 39036 f903
15384 24509 f904
15385 09902 f905
15386 12323 f906
15387 62984 f907
15388 62984 f908
15389 58810 f909
15390 41347 f90a
15391 12968 f90b
15392 14589 f90c
15393 18880 f90d
15394 28042 f90e
15395 32334 f90f
15396 36067 f910
15397 36703 f911
15398 37270 f912
15399 40771 f913
15400 22397 f914
15401 23786 f915
15402 25465 f916
15403 26844 f917
15404 34885 f918
15405 41141 f919
15406 44928 f91a
15407 10020 f91b
15408 12147 f91c
15409 58811 f91d
15410 26118 f91e
15411 58812 f91f
15412 46719 f920
15413 16768 f921
15414 25003 f922
15415 35803 f923
15416 37493 f924
15417 19223 f925
15418 33569 f926
15419 36883 f927
15420 58813 f928
15421 58814 f929
15422 23903 f92a
15423 26484 f92b
15424 40868 f92c
15425 10421 f92d
15426 11398 f92e
15427 11881 f92f
15428 20078 f930
15429 22772 f931
15430 26095 f932
15431 28245 f933
15432 32584 f934
15433 35937 f935
15434 58815 f936
15435 39455 f937
15436 43690 f938
15437 45651 f939
15438 46656 f93a
15439 28908 f93b
15440 29334 f93c
15441 31489 f93d
15442 34634 f93e
15443 41941 f93f
15444 46823 f940
15445 38199 f941
15446 14416 f942
15447 17562 f943
15448 30831 f944
15449 32836 f945
15450 26261 f946
15451 29011 f947
15452 39024 f948
15453 43564 f949
15454 14401 f94a
15455 16304 f94b
15456 22426 f94c
15457 24080 f94d
15458 24617 f94e
15459 31264 f94f
15460 31806 f950
15461 43241 f951
15462 11863 f952
15463 32859 f953
15464 11473 f954
15465 11442 f955
15466 29615 f956
15467 31553 f957
15468 34724 f958
15469 43310 f959
15470 19233 f95b
15471 22397 f95c
15472 38281 f95d
15473 09912 f95e
15474 16093 f95f
15475 18027 f960
15476 26726 f961
15477 27567 f962
15478 11980 f963
15479 29102 f964
15480 10513 f965
15481 17857 f966
15482 09846 f967
15483 23665 f968
15484 20406 f969
15485 31242 f96a
15486 12269 f96b
15487 14192 f96c
15488 28288 f96d
15489 34909 f96e
15490 38108 f96f
15491 58816 f970
15492 40197 f971
15493 23566 f972
15494 19306 f973
15495 34159 f974
15496 19566 f975
15497 27547 f976
15498 10092 f977
15499 11277 f978
15500 11434 f979
15501 21695 f97a
15502 31118 f97b
15503 33914 f97c
15504 38190 f97d
15505 41344 f97e
15506 11920 f97f
15507 12473 f980
15508 14669 f981
15509 17517 f982
15510 58817 f983
15511 25038 f984
15512 29177 f985
15513 43024 f986
15514 45157 f987
15515 62965 f988
15516 47018 f989
15517 11778 f98a
15518 20975 f98b
15519 23067 f98c
15520 40095 f98d
15521 17283 f98e
15522 18695 f98f
15523 18902 f990
15524 20003 f991
15525 24655 f992
15526 25678 f993
15527 27136 f994
15528 29478 f995
15529 58896 f996
15530 32800 f997
15531 39981 f998
15532 58818 f999
15533 58819 f99a
15534 42072 f99b
15535 11560 f99c
15536 11787 f99d
15537 12656 f99e
15538 25431 f99f
15539 37163 f9a0
15540 38108 f9a1
15541 58820 f9a2
15542 17984 f9a3
15543 19501 f9a4
15544 23196 f9a5
15545 30751 f9a6
15546 26690 f9a7
15547 10176 f9a8
15548 13628 f9a9
15549 16093 f9aa
15550 16984 f9ab
15551 18041 f9ac
15552 26787 f9ad
15553 27078 f9ae
15554 32372 f9af
15555 32723 f9b0
15556 41535 f9b1
15557 43561 f9b2
15558 43736 f9b3
15559 44100 f9b4
15560 10429 f9b5
15561 29425 f9b6
15562 41292 f9b7
15563 43439 f9b8
15564 18372 f9b9
15565 10026 f9ba
15566 11020 f9bb
15567 16110 f9bc
15568 16246 f9bd
15569 20465 f9be
15570 22397 f9bf
15571 25957 f9c0
15572 27965 f9c1
15573 35315 f9c2
15574 58821 f9c3
15575 47434 f9c4
15576 20870 f9c5
15577 43201 f9c6
15578 11743 f9c7
15579 21275 f9c8
15580 21467 f9c9
15581 23847 f9ca
15582 24406 f9cb
15583 26911 f9cc
15584 27525 f9cd
15585 28858 f9ce
15586 31201 f9cf
15587 58822 f9d0
15588 11288 f9d1
15589 18970 f9d2
15590 43317 f9d3
15591 10700 f9d4
15592 16655 f9d5
15593 24109 f9d6
15594 39989 f9d7
15595 17810 f9d8
15596 18542 f9d9
15597 21520 f9da
15598 26726 f9db
15599 58823 f9dc
15600 11587 f9dd
15601 12384 f9de
15602 16310 f9df
15603 20690 f9e0
15604 21209 f9e1
15605 21764 f9e2
15606 23710 f9e3
15607 26906 f9e4
15608 27767 f9e5
15609 32311 f9e6
15610 37189 f9e7
15611 37228 f9e8
15612 41341 f9e9
15613 43524 f9ea
15614 12065 f9eb
15615 24460 f9ec
15616 12403 f9ed
15617 25961 f9ee
15618 27159 f9ef
15619 35905 f9f0
15620 62873 f9f1
15621 46027 f9f2
15622 21324 f9f4
15623 24053 f9f5
15624 33605 f9f6
15625 29991 f9f7
15626 30155 f9f8
15627 30939 f9f9
15628 26396 f9fa
15629 25344 f9fb
15630 38478 f9fc
15631 10122 f9fd
15632 34336 f9fe
15633 11613 f9ff
15634 11542 fa00
15635 17373 fa01
15636 19242 fa02
15637 58824 fa03
15638 15891 fa04
15639 23791 fa05
15640 20944 fa06
15641 40022 fa07
15642 36964 fa08
15643 62867 fa09
15644 37573 fa0a
15645 17463 fa0b
15646 58825 fa0e
15647 58826 fa0f
15648 58827 fa10
15649 58828 fa11
15650 58829 fa12
15651 58830 fa13
15652 58831 fa14
15653 58832 fa15
15654 58833 fa16
15655 58834 fa17
15656 58835 fa18
15657 58836 fa19
15658 58837 fa1a
15659 58838 fa1b
15660 58839 fa1c
15661 58840 fa1d
15662 58841 fa1e
15663 58842 fa1f
15664 58843 fa20
15665 58844 fa21
15666 58845 fa22
15667 58846 fa23
15668 58847 fa24
15669 58848 fa25
15670 58849 fa26
15671 58850 fa27
15672 58851 fa28
15673 58852 fa29
15674 58853 fa2a
15675 58854 fa2b
15676 58855 fa2c
15677 58856 fa2d
15678 40890 fa2e
15679 43437 fa2f
15680 58857 fa30
15681 58858 fa31
15682 58859 fa32
15683 58860 fa33
15684 58861 fa34
15685 58862 fa35
15686 58863 fa36
15687 58864 fa37
15688 58865 fa38
15689 58866 fa39
15690 58867 fa3a
15691 58868 fa3b
15692 58869 fa3c
15693 58870 fa3d
15694 58871 fa3e
15695 58872 fa3f
15696 58873 fa40
15697 58874 fa41
15698 58875 fa42
15699 58876 fa43
15700 58877 fa44
15701 58878 fa45
15702 58879 fa46
15703 58880 fa47
15704 58881 fa48
15705 58882 fa49
15706 58883 fa4a
15707 58884 fa4b
15708 58885 fa4c
15709 58886 fa4d
15710 58887 fa4e
15711 58888 fa4f
15712 58889 fa50
15713 58890 fa51
15714 58891 fa52
15715 58892 fa53
15716 58893 fa54
15717 58894 fa55
15718 58895 fa56
15719 58896 fa57
15720 58897 fa58
15721 58898 fa59
15722 58899 fa5a
15723 58900 fa5b
15724 58901 fa5c
15725 58902 fa5d
15726 58903 fa5e
15727 58904 fa5f
15728 58905 fa60
15729 58906 fa61
15730 58907 fa62
15731 58908 fa63
15732 58909 fa64
15733 58910 fa65
15734 58911 fa66
15735 58912 fa67
15736 58913 fa68
15737 58914 fa69
15738 58915 fa6a
15739 58916 fa6b
15740 58917 fa6c
15741 58918 fa6d
15742 58919 fb00
15743 58920 fb01
15744 58921 fb02
15745 58922 fb03
15746 58923 fb04
15747 58924 fe10
15748 58925 fe11
15749 58926 fe12
15750 58927 fe13
15751 58928 fe14
15752 58929 fe15
15753 58930 fe16
15754 58931 fe17
15755 58932 fe18
15756 58933 fe19
15757 58934 fe30
15758 58935 fe31
15759 58936 fe32
15760 58937 fe33
15761 58938 fe34
15762 58939 fe35
15763 58940 fe36
15764 58941 fe37
15765 58942 fe38
15766 58943 fe39
15767 58944 fe3a
15768 58945 fe3b
15769 58946 fe3c
15770 58947 fe3d
15771 58948 fe3e
15772 58949 fe3f
15773 58950 fe40
15774 58951 fe41
15775 58952 fe42
15776 58953 fe43
15777 58954 fe44
15778 58955 fe45
15779 58956 fe46
15780 58957 fe47
15781 58958 fe48
15782 58959 fe49
15783 58960 fe4a
15784 58961 fe4b
15785 58962 fe4c
15786 58963 fe4d
15787 58964 fe4e
15788 58965 fe4f
15789 58966 fe50
15790 58967 fe51
15791 58968 fe52
15792 58969 fe54
15793 58970 fe55
15794 58971 fe56
15795 58972 fe57
15796 58973 fe58
15797 58974 fe59
15798 58975 fe5a
15799 58976 fe5b
15800 58977 fe5c
15801 58978 fe5d
15802 58979 fe5e
15803 58980 fe5f
15804 58981 fe60
15805 58982 fe61
15806 58983 fe62
15807 58984 fe63
15808 58985 fe64
15809 58986 fe65
15810 58987 fe66
15811 58988 fe68
15812 58989 fe69
15813 58990 fe6a
15814 58991 fe6b
15815 58992 ff01
15816 58993 ff02
15817 58994 ff03
15818 58995 ff04
15819 58996 ff05
15820 58997 ff06
15821 58998 ff07
15822 58999 ff08
15823 59000 ff09
15824 59001 ff0a
15825 59002 ff0b
15826 59003 ff0c
15827 59004 ff0d
15828 59005 ff0e
15829 59006 ff0f
15830 59007 ff10
15831 59008 ff11
15832 59009 ff12
15833 59010 ff13
15834 59011 ff14
15835 59012 ff15
15836 59013 ff16
15837 59014 ff17
15838 59015 ff18
15839 59016 ff19
15840 59017 ff1a
15841 59018 ff1b
15842 59019 ff1c
15843 59020 ff1d
15844 59021 ff1e
15845 59022 ff1f
15846 59023 ff20
15847 59024 ff21
15848 59025 ff22
15849 59026 ff23
15850 59027 ff24
15851 59028 ff25
15852 59029 ff26
15853 59030 ff27
15854 59031 ff28
15855 59032 ff29
15856 59033 ff2a
15857 59034 ff2b
15858 59035 ff2c
15859 59036 ff2d
15860 59037 ff2e
15861 59038 ff2f
15862 59039 ff30
15863 59040 ff31
15864 59041 ff32
15865 59042 ff33
15866 59043 ff34
15867 59044 ff35
15868 59045 ff36
15869 59046 ff37
15870 59047 ff38
15871 59048 ff39
15872 59049 ff3a
15873 59050 ff3b
15874 59051 ff3c
15875 59052 ff3d
15876 59053 ff3e
15877 59054 ff3f
15878 59055 ff40
15879 59056 ff41
15880 59057 ff42
15881 59058 ff43
15882 59059 ff44
15883 59060 ff45
15884 59061 ff46
15885 59062 ff47
15886 59063 ff48
15887 59064 ff49
15888 59065 ff4a
15889 59066 ff4b
15890 59067 ff4c
15891 59068 ff4d
15892 59069 ff4e
15893 59070 ff4f
15894 59071 ff50
15895 59072 ff51
15896 59073 ff52
15897 59074 ff53
15898 59075 ff54
15899 59076 ff55
15900 59077 ff56
15901 59078 ff57
15902 59079 ff58
15903 59080 ff59
15904 59081 ff5a
15905 59082 ff5b
15906 59083 ff5c
15907 59084 ff5d
15908 01417 ff5e
15909 59085 ff5f
15910 59086 ff60
15911 59087 ff61
15912 59088 ff62
15913 59089 ff63
15914 59090 ff64
15915 59091 ff65
15916 59092 ff66
15917 59093 ff67
15918 59094 ff68
15919 59095 ff69
15920 59096 ff6a
15921 59097 ff6b
15922 59098 ff6c
15923 59099 ff6d
15924 59100 ff6e
15925 59101 ff6f
15926 59102 ff70
15927 59103 ff71
15928 59104 ff72
15929 59105 ff73
15930 59106 ff74
15931 59107 ff75
15932 59108 ff76
15933 59109 ff77
15934 59110 ff78
15935 59111 ff79
15936 59112 ff7a
15937 59113 ff7b
15938 59114 ff7c
15939 59115 ff7d
15940 59116 ff7e
15941 59117 ff7f
15942 59118 ff80
15943 59119 ff81
15944 59120 ff82
15945 59121 ff83
15946 59122 ff84
15947 59123 ff85
15948 59124 ff86
15949 59125 ff87
15950 59126 ff88
15951 59127 ff89
15952 59128 ff8a
15953 59129 ff8b
15954 59130 ff8c
15955 59131 ff8d
15956 59132 ff8e
15957 59133 ff8f
15958 59134 ff90
15959 59135 ff91
15960 59136 ff92
15961 59137 ff93
15962 59138 ff94
15963 59139 ff95
15964 59140 ff96
15965 59141 ff97
15966 59142 ff98
15967 59143 ff99
15968 59144 ff9a
15969 59145 ff9b
15970 59146 ff9c
15971 59147 ff9d
15972 59148 ff9e
15973 59149 ff9f
15974 63039 ffa0
15975 59150 ffa1
15976 59151 ffa2
15977 59152 ffa3
15978 59153 ffa4
15979 59154 ffa5
15980 59155 ffa6
15981 59156 ffa7
15982 59157 ffa8
15983 59158 ffa9
15984 59159 ffaa
15985 59160 ffab
15986 59161 ffac
15987 59162 ffad
15988 59163 ffae
15989 59164 ffaf
15990 59165 ffb0
15991 59166 ffb1
15992 59167 ffb2
15993 59168 ffb3
15994 59169 ffb4
15995 59170 ffb5
15996 59171 ffb6
15997 59172 ffb7
15998 59173 ffb8
15999 59174 ffb9
16000 59175 ffba
16001 59176 ffbb
16002 59177 ffbc
16003 59178 ffbd
16004 59179 ffbe
16005 59180 ffc2
16006 59181 ffc3
16007 59182 ffc4
16008 59183 ffc5
16009 59184 ffc6
16010 59185 ffc7
16011 59186 ffca
16012 59187 ffcb
16013 59188 ffcc
16014 59189 ffcd
16015 59190 ffce
16016 59191 ffcf
16017 59192 ffd2
16018 59193 ffd3
16019 59194 ffd4
16020 59195 ffd5
16021 59196 ffd6
16022 59197 ffd7
16023 59198 ffda
16024 59199 ffdb
16025 59200 ffdc
16026 59201 ffe0
16027 59202 ffe1
16028 59203 ffe2
16029 59204 ffe3
16030 59205 ffe4
16031 59206 ffe5
16032 59207 ffe6
16033 63131 ffe8
16034 59208 ffe9
16035 59209 ffea
16036 59210 ffeb
16037 59211 ffec
16038 59212 ffed
16039 59213 ffee
16040 59214 1f100
16041 59215 1f101
16042 59216 1f102
16043 59217 1f103
16044 59218 1f104
16045 59219 1f105
16046 59220 1f106
16047 59221 1f107
16048 59222 1f108
16049 59223 1f109
16050 59224 1f10a
16051 59225 1f110
16052 59226 1f111
16053 59227 1f112
16054 59228 1f113
16055 59229 1f114
16056 59230 1f115
16057 59231 1f116
16058 59232 1f117
16059 59233 1f118
16060 59234 1f119
16061 59235 1f11a
16062 59236 1f11b
16063 59237 1f11c
16064 59238 1f11d
16065 59239 1f11e
16066 59240 1f11f
16067 59241 1f120
16068 59242 1f121
16069 59243 1f122
16070 59244 1f123
16071 59245 1f124
16072 59246 1f125
16073 59247 1f126
16074 59248 1f127
16075 59249 1f128
16076 59250 1f129
16077 59251 1f12a
16078 59252 1f12b
16079 59253 1f12c
16080 59254 1f12d
16081 59255 1f12e
16082 59256 1f130
16083 59257 1f131
16084 59258 1f132
16085 59259 1f133
16086 59260 1f134
16087 59261 1f135
16088 59262 1f136
16089 59263 1f137
16090 59264 1f138
16091 59265 1f139
16092 59266 1f13a
16093 59267 1f13b
16094 59268 1f13c
16095 59269 1f13d
16096 59270 1f13e
16097 59271 1f13f
16098 59272 1f140
16099 59273 1f141
16100 59274 1f142
16101 59275 1f143
16102 59276 1f144
16103 59277 1f145
16104 59278 1f146
16105 59279 1f147
16106 59280 1f148
16107 59281 1f149
16108 59282 1f14a
16109 59283 1f14b
16110 59284 1f14c
16111 59285 1f14d
16112 59286 1f14e
16113 59287 1f14f
16114 59288 1f150
16115 59289 1f151
16116 59290 1f152
16117 59291 1f153
16118 59292 1f154
16119 59293 1f155
16120 59294 1f156
16121 59295 1f157
16122 59296 1f158
16123 59297 1f159
16124 59298 1f15a
16125 59299 1f15b
16126 59300 1f15c
16127 59301 1f15d
16128 59302 1f15e
16129 59303 1f15f
16130 59304 1f160
16131 59305 1f161
16132 59306 1f162
16133 59307 1f163
16134 59308 1f164
16135 59309 1f165
16136 59310 1f166
16137 59311 1f167
16138 59312 1f168
16139 59313 1f169
16140 59314 1f16a
16141 59315 1f16b
16142 59316 1f170
16143 59317 1f171
16144 59318 1f172
16145 59319 1f173
16146 59320 1f174
16147 59321 1f175
16148 59322 1f176
16149 59323 1f177
16150 59324 1f178
16151 59325 1f179
16152 59326 1f17a
16153 59327 1f17b
16154 59328 1f17c
16155 59329 1f17d
16156 59330 1f17e
16157 59331 1f17f
16158 59332 1f180
16159 59333 1f181
16160 59334 1f182
16161 59335 1f183
16162 59336 1f184
16163 59337 1f185
16164 59338 1f186
16165 59339 1f187
16166 59340 1f188
16167 59341 1f189
16168 59342 1f18a
16169 59343 1f18b
16170 59344 1f18c
16171 59345 1f18d
16172 59346 1f18e
16173 59347 1f18f
16174 59348 1f190
16175 59349 1f191
16176 59350 1f192
16177 59351 1f193
16178 59352 1f194
16179 59353 1f195
16180 59354 1f196
16181 59355 1f197
16182 59356 1f198
16183 59357 1f199
16184 59358 1f19a
16185 59359 1f200
16186 59360 1f201
16187 59361 1f202
16188 59362 1f210
16189 59363 1f211
16190 59365 1f212
16191 59366 1f213
16192 59367 1f214
16193 59368 1f215
16194 59369 1f216
16195 59371 1f217
16196 59373 1f218
16197 59375 1f219
16198 59377 1f21a
16199 59380 1f21b
16200 59382 1f21c
16201 59384 1f21d
16202 59387 1f21e
16203 59388 1f21f
16204 59391 1f220
16205 59393 1f221
16206 59395 1f222
16207 59396 1f223
16208 59398 1f224
16209 59399 1f225
16210 59400 1f226
16211 59402 1f227
16212 59404 1f228
16213 59405 1f229
16214 59406 1f22a
16215 59407 1f22b
16216 59410 1f22c
16217 59411 1f22d
16218 59412 1f22e
16219 59413 1f22f
16220 59415 1f230
16221 59416 1f231
16222 59417 1f232
16223 59419 1f233
16224 59422 1f234
16225 59424 1f235
16226 59427 1f236
16227 59429 1f237
16228 59430 1f238
16229 59431 1f239
16230 59434 1f23a
16231 59437 1f240
16232 59438 1f241
16233 59439 1f242
16234 59440 1f243
16235 59443 1f244
16236 59444 1f245
16237 59445 1f246
16238 59447 1f247
16239 59449 1f248
16240 59450 1f250
16241 59451 1f251
16242 59452 2000b
16243 59461 20089
16244 59462 2008a
16245 59465 200a2
16246 59466 200a4
16247 59467 200b0
16248 59474 200f5
16249 59478 20158
16250 59480 201a2
16251 59489 20213
16252 59504 2032b
16253 59509 20371
16254 59513 20381
16255 59520 203f9
16256 59525 2044a
16257 59535 20509
16258 59536 2053f
16259 59540 205b1
16260 59546 205d6
16261 59550 20611
16262 59555 20628
16263 59559 206ec
16264 59562 2074f
16265 59564 207c8
16266 59565 20807
16267 59567 2083a
16268 59569 208b9
16269 59571 2090e
16270 59576 2097c
16271 59577 20984
16272 59578 2099d
16273 59582 20a64
16274 59588 20ad3
16275 59590 20b1d
16276 59592 20b9f
16277 59596 20bb7
16278 59636 20d45
16279 59644 20d58
16280 59656 20de1
16281 59668 20e64
16282 59669 20e6d
16283 59680 20e95
16284 59704 20f5f
16285 59754 21201
16286 59756 2123d
16287 59758 21255
16288 59759 21274
16289 59760 2127b
16290 59765 212d7
16291 59767 212e4
16292 59768 212fd
16293 59774 2131b
16294 59775 21336
16295 59778 21344
16296 59785 213c4
16297 59797 2146d
16298 59798 2146e
16299 59807 215d7
16300 59813 21647
16301 59816 216b4
16302 59832 21706
16303 59839 21742
16304 59897 218bd
16305 59925 219c3
16306 59928 21a1a
16307 59938 21c56
16308 59943 21d2d
16309 59944 21d45
16310 59948 21d62
16311 59949 21d78
16312 59951 21d92
16313 59952 21d9c
16314 59953 21da1
16315 59955 21db7
16316 59959 21de0
16317 59964 21e33
16318 59965 21e34
16319 59975 21f1e
16320 59977 21f76
16321 59981 21ffa
16322 59992 2217b
16323 59997 22218
16324 59999 2231e
16325 60002 223ad
16326 60024 22609
16327 60032 226f3
16328 60048 2285b
16329 60052 228ab
16330 60062 2298f
16331 60065 22ab8
16332 60074 22b46
16333 60075 22b4f
16334 60076 22b50
16335 60078 22ba6
16336 60081 22c1d
16337 60082 22c24
16338 60111 22de1
16339 60115 22e42
16340 60124 22feb
16341 60142 231b6
16342 60143 231c3
16343 60144 231c4
16344 60148 231f5
16345 60174 23372
16346 60176 233cc
16347 60178 233d0
16348 60179 233d2
16349 60180 233d3
16350 60181 233d5
16351 60182 233da
16352 60184 233df
16353 60185 233e4
16354 60191 233fe
16355 60195 2344a
16356 60196 2344b
16357 60198 23451
16358 60199 23465
16359 60202 234e4
16360 60207 2355a
16361 60210 23594
16362 60215 235c4
16363 60224 23638
16364 60225 23639
16365 60226 2363a
16366 60229 23647
16367 60241 2370c
16368 60243 2371c
16369 60247 2373f
16370 60249 23763
16371 60250 23764
16372 60259 237e7
16373 22837 237f1
16374 60260 237ff
16375 60261 23824
16376 60263 2383d
16377 60265 23a98
16378 60273 23c7f
16379 60281 23cbe
16380 60287 23cfe
16381 60290 23d00
16382 60291 23d0e
16383 60292 23d40
16384 60305 23dd3
16385 60308 23df9
16386 60309 23dfa
16387 60337 23f7e
16388 60359 2404b
16389 60366 24096
16390 60370 24103
16391 60391 241c6
16392 60395 241fe
16393 60412 242ee
16394 60426 243bc
16395 60429 243d0
16396 60452 24629
16397 60457 246a5
16398 60464 247f1
16399 60468 24896
16400 01364 248e9
16401 60551 24a4d
16402 60590 24b56
16403 60592 24b6f
16404 60595 24c16
16405 60602 24d14
16406 60606 24e04
16407 60607 24e0e
16408 60608 24e37
16409 60611 24e6a
16410 60612 24e8b
16411 60624 24ff2
16412 60626 2504a
16413 60628 25055
16414 60630 25122
16415 60635 251a9
16416 60636 251cd
16417 60639 251e5
16418 60642 2521e
16419 60645 2524c
16420 60655 2542e
16421 60661 2548e
16422 60663 254d9
16423 60664 2550e
16424 60679 255a7
16425 60688 2567f
16426 60697 25771
16427 60699 257a9
16428 60700 257b4
16429 60708 25874
16430 60716 259c4
16431 60717 259cc
16432 60719 259d4
16433 60725 25ad7
16434 60726 25ae3
16435 60727 25ae4
16436 60729 25af1
16437 60732 25bb2
16438 60742 25c4b
16439 60743 25c64
16440 60754 25da1
16441 60757 25e2e
16442 60759 25e56
16443 60760 25e62
16444 60761 25e65
16445 60767 25ec2
16446 60770 25ed8
16447 60772 25ee8
16448 60774 25f23
16449 60776 25f5c
16450 60777 25fd4
16451 60778 25fe0
16452 60781 25ffb
16453 60782 2600c
16454 60783 26017
16455 60787 26060
16456 60793 260ed
16457 60805 26222
16458 60808 2626a
16459 60811 26270
16460 60812 26286
16461 60816 2634c
16462 60822 26402
16463 60842 2667e
16464 60844 266b0
16465 60851 2671d
16466 60866 268dd
16467 60867 268ea
16468 60872 26951
16469 60874 2696f
16470 60875 26999
16471 60878 269dd
16472 60881 26a1e
16473 60888 26a58
16474 60889 26a8c
16475 60890 26ab7
16476 60891 26aff
16477 60914 26c29
16478 60918 26c73
16479 60924 26c9e
16480 60932 26cdd
16481 60961 26e40
16482 60966 26e65
16483 60985 26f94
16484 60991 26ff6
16485 60992 26ff7
16486 60993 26ff8
16487 61004 270f4
16488 61008 2710d
16489 61012 27139
16490 61027 273da
16491 61028 273db
16492 61029 273fe
16493 61031 27410
16494 61033 27449
16495 61045 27614
16496 61046 27615
16497 61047 27631
16498 61053 27684
16499 61054 27693
16500 61056 2770e
16501 61058 27723
16502 61062 27752
16503 61070 278b2
16504 61075 27985
16505 61077 279b4
16506 61086 27a84
16507 61099 27bb3
16508 61100 27bbe
16509 61101 27bc7
16510 61105 27c3c
16511 61108 27cb8
16512 61114 27d73
16513 61119 27da0
16514 61122 27e10
16515 61126 27fb7
16516 61135 2808a
16517 61137 280bb
16518 61154 28277
16519 61156 28282
16520 61160 282f3
16521 61169 283cd
16522 61171 2840c
16523 61173 28455
16524 61181 2856b
16525 61183 285c8
16526 61184 285c9
16527 61197 286d7
16528 61200 286fa
16529 61208 28946
16530 61210 28949
16531 61215 2896b
16532 61219 28987
16533 61220 28988
16534 61226 289ba
16535 61227 289bb
16536 61243 28a1e
16537 61245 28a29
16538 61249 28a43
16539 61260 28a71
16540 61264 28a99
16541 61272 28acd
16542 61274 28add
16543 61281 28ae4
16544 61308 28bc1
16545 61321 28bef
16546 61341 28cdd
16547 61342 28d10
16548 61344 28d71
16549 61347 28dfb
16550 61348 28e0f
16551 61349 28e17
16552 61350 28e1f
16553 61351 28e36
16554 61356 28e89
16555 61364 28eeb
16556 61365 28ef6
16557 61366 28f32
16558 61368 28ff8
16559 61392 292a0
16560 61393 292b1
16561 61399 29490
16562 61408 295cf
16563 61412 2967f
16564 61414 296f0
16565 61415 29719
16566 61418 29750
16567 61420 29810
16568 61423 298c6
16569 61442 29a72
16570 61449 29d4b
16571 61454 29ddb
16572 61457 29e15
16573 61459 29e3d
16574 61460 29e49
16575 61462 29e8a
16576 61466 29ec4
16577 61467 29edb
16578 61468 29ee9
16579 61476 29fce
16580 61476 29fd7
16581 61479 2a01a
16582 61480 2a02f
16583 61481 2a082
16584 61488 2a0f9
16585 61495 2a190
16586 61507 2a2b2
16587 61516 2a38c
16588 61519 2a437
16589 61523 2a5f1
16590 61525 2a602
16591 61526 2a61a
16592 61531 2a6b2
16593 61535 2a9e6
16594 61578 2b746
16595 61579 2b751
16596 61580 2b753
16597 61581 2b75a
16598 61582 2b75c
16599 61583 2b765
16600 61584 2b776
16601 61585 2b777
16602 61586 2b77c
16603 61587 2b782
16604 61588 2b789
16605 61589 2b78b
16606 61590 2b78e
16607 61591 2b794
16608 61593 2b7ac
16609 61594 2b7af
16610 61595 2b7bd
16611 61597 2b7c9
16612 61598 2b7cf
16613 61599 2b7d2
16614 61600 2b7d8
16615 61602 2b7f0
16616 61607 2b80d
16617 61608 2b817
16618 61609 2b81a
16619 61719 2f804
16620 61720 2f80f
16621 61721 2f815
16622 11367 2f818
16623 61722 2f81a
16624 61723 2f822
16625 61725 2f828
16626 59577 2f82c
16627 61726 2f833
16628 61728 2f83f
16629 61730 2f846
16630 61731 2f852
16631 61732 2f862
16632 61733 2f86d
16633 61734 2f873
16634 16300 2f877
16635 61736 2f884
16636 61738 2f899
16637 61739 2f89a
16638 61740 2f8a6
16639 61742 2f8ac
16640 61743 2f8b2
16641 61744 2f8b6
16642 61746 2f8d3
16643 60176 2f8db
16644 21218 2f8dc
16645 61747 2f8e1
16646 61748 2f8e5
16647 61749 2f8ea
16648 22784 2f8ed
16649 61750 2f8fc
16650 61751 2f903
16651 61752 2f90b
16652 61753 2f90f
16653 61754 2f91a
16654 61755 2f920
16655 61756 2f921
16656 61757 2f945
16657 61758 2f947
16658 61759 2f96c
16659 61761 2f995
16660 61764 2f9d0
16661 61766 2f9de
16662 61767 2f9df
16663 61768 2f9f4
16664
+0
-28
src/third_party/noto_font/README.mozc less more
0 URL: https://noto.googlecode.com/git/third_party/noto_cjk/NotoSansJP-Regular.otf
1 Version: 1.001
2 License: Apache License, version 2.0
3 License File: LICENSE
4
5 URL: http://material-design.storage.googleapis.com/publish/v_1/quantumexternal/0B08MbvYZK1iNZGNoWmJqVEhQYTQ/RobotoTTF.zip
6 Version: 2.000980; 2014
7 License: Apache License, version 2.0
8 License File: LICENSE
9
10 Description:
11 Noto-Roboto2-Regular.otf is a derivative work of NotoSansJP font and Roboto2 font, where Japanese characters are covered by Noto font and ASCII characters are coverted by Roboto font.
12
13 Local Modifications:
14 Noto-Roboto2-Regular.otf is generated as follows with FontForge 20120731 and libfontforge 20120731-ML on Ubuntu 14.04.01.
15 1. Install FontForge
16 2. Open NotoSansJP-Regular.otf with FontForge
17 3. You will see the warning that indicates there is no applicable cidmap.
18 Open cidmap for NotoSansJP.cidmap, which can be found in the same directory of this README.
19 4. Open Roboto-Regular.ttf with FontForge
20 5. For Roboto, Element -> Font Info -> General.
21 Change Em Size to 1000 to adjust with NotoSansJP.otf.
22 6. For Noto, click 'CID' menu, then select 'NotoSansJP-Regular-PropotionalDigits'
23 7. Copy and paste characters "0123456789" from Roboto to Noto.
24 6. For Noto, click 'CID' menu, then select 'NotoSansJP-Regular-Propotional'
25 7. Copy and paste characters "!"#$%&'()*+,-./" from Roboto to Noto.
26 8. Copy and paste characters ":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~" from Roboto to Noto.
27 9. For Noto, click File - Generate Fonts, then save it as "Noto-Roboto2-Regular.otf" with file type: 'OpenType CID'. You may see validation errors, but please ignore them.
src/third_party/noto_font/Roboto-Regular.ttf less more
Binary diff not shown
+0
-0
src/third_party/protobuf less more
(Empty file)
+0
-2268
src/third_party/wtl/Include/atlapp.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLAPP_H__
9 #define __ATLAPP_H__
10
11 #pragma once
12
13 #ifndef __cplusplus
14 #error WTL requires C++ compilation (use a .cpp suffix)
15 #endif
16
17 #ifndef __ATLBASE_H__
18 #error atlapp.h requires atlbase.h to be included first
19 #endif
20
21 #ifndef _WIN32_WCE
22 #if (WINVER < 0x0400)
23 #error WTL requires Windows version 4.0 or higher
24 #endif
25
26 #if (_WIN32_IE < 0x0300)
27 #error WTL requires IE version 3.0 or higher
28 #endif
29 #endif
30
31 #ifdef _ATL_NO_COMMODULE
32 #error WTL requires that _ATL_NO_COMMODULE is not defined
33 #endif
34
35 #if (_ATL_VER >= 0x0900) && defined(_ATL_MIN_CRT)
36 #error _ATL_MIN_CRT is not supported with ATL 9.0 and higher
37 #endif
38
39 #if defined(_WIN32_WCE) && defined(_ATL_MIN_CRT)
40 #pragma message("Warning: WTL for Windows CE doesn't use _ATL_MIN_CRT")
41 #endif
42
43 #include <limits.h>
44 #if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE)
45 #include <process.h> // for _beginthreadex
46 #endif
47
48 #if (_ATL_VER < 0x0800) && !defined(_DEBUG)
49 #include <stdio.h>
50 #endif
51
52 #include <commctrl.h>
53 #ifndef _WIN32_WCE
54 #pragma comment(lib, "comctl32.lib")
55 #endif
56
57 #if defined(_SYSINFOAPI_H_) && defined(NOT_BUILD_WINDOWS_DEPRECATE) && (_WIN32_WINNT >= 0x0501)
58 #include <VersionHelpers.h>
59 #endif
60
61 #ifndef _WIN32_WCE
62 #include "atlres.h"
63 #else // CE specific
64 #include "atlresce.h"
65 #endif // _WIN32_WCE
66
67 // We need to disable this warning because of template class arguments
68 #pragma warning(disable: 4127)
69
70 #if (_ATL_VER >= 0x0900) && !defined(_SECURE_ATL)
71 #define _SECURE_ATL 1
72 #endif
73
74
75 ///////////////////////////////////////////////////////////////////////////////
76 // WTL version number
77
78 #define _WTL_VER 0x0910
79
80
81 ///////////////////////////////////////////////////////////////////////////////
82 // Classes in this file:
83 //
84 // CMessageFilter
85 // CIdleHandler
86 // CMessageLoop
87 //
88 // CAppModule
89 // CServerAppModule
90 //
91 // CRegKeyEx
92 //
93 // Global functions:
94 // AtlGetDefaultGuiFont()
95 // AtlCreateControlFont()
96 // AtlCreateBoldFont()
97 // AtlInitCommonControls()
98
99
100 ///////////////////////////////////////////////////////////////////////////////
101 // Global support for Windows CE
102
103 #ifdef _WIN32_WCE
104
105 #ifndef SW_SHOWDEFAULT
106 #define SW_SHOWDEFAULT SW_SHOWNORMAL
107 #endif // !SW_SHOWDEFAULT
108
109 // These get's OR-ed in a constant and will have no effect.
110 // Defining them reduces the number of #ifdefs required for CE.
111 #define LR_DEFAULTSIZE 0
112 #define LR_LOADFROMFILE 0
113
114 #ifndef SM_CXCURSOR
115 #define SM_CXCURSOR 13
116 #endif
117 #ifndef SM_CYCURSOR
118 #define SM_CYCURSOR 14
119 #endif
120
121 inline BOOL IsMenu(HMENU hMenu)
122 {
123 MENUITEMINFO mii = { sizeof(MENUITEMINFO) };
124 ::SetLastError(0);
125 BOOL bRet = ::GetMenuItemInfo(hMenu, 0, TRUE, &mii);
126 if(!bRet)
127 bRet = (::GetLastError() != ERROR_INVALID_MENU_HANDLE) ? TRUE : FALSE;
128 return bRet;
129 }
130
131 #if (_WIN32_WCE >= 410)
132 extern "C" void WINAPI ListView_SetItemSpacing(HWND hwndLV, int iHeight);
133 #endif // (_WIN32_WCE >= 410)
134
135 inline int MulDiv(IN int nNumber, IN int nNumerator, IN int nDenominator)
136 {
137 __int64 multiple = nNumber * nNumerator;
138 return static_cast<int>(multiple / nDenominator);
139 }
140
141 #if (_ATL_VER >= 0x0800)
142
143 #ifndef _WTL_KEEP_WS_OVERLAPPEDWINDOW
144 #ifdef WS_OVERLAPPEDWINDOW
145 #undef WS_OVERLAPPEDWINDOW
146 #define WS_OVERLAPPEDWINDOW 0
147 #endif // WS_OVERLAPPEDWINDOW
148 #endif // !_WTL_KEEP_WS_OVERLAPPEDWINDOW
149
150 #ifndef RDW_FRAME
151 #define RDW_FRAME 0
152 #endif // !RDW_FRAME
153
154 #ifndef WM_WINDOWPOSCHANGING
155 #define WM_WINDOWPOSCHANGING 0
156 #endif // !WM_WINDOWPOSCHANGING
157
158 #define FreeResource(x)
159 #define UnlockResource(x)
160
161 namespace ATL
162 {
163 inline HRESULT CComModule::RegisterClassObjects(DWORD /*dwClsContext*/, DWORD /*dwFlags*/) throw()
164 { return E_NOTIMPL; }
165 inline HRESULT CComModule::RevokeClassObjects() throw()
166 { return E_NOTIMPL; }
167 }; // namespace ATL
168
169 #ifndef lstrlenW
170 #define lstrlenW (int)ATL::lstrlenW
171 #endif // lstrlenW
172
173 inline int WINAPI lstrlenA(LPCSTR lpszString)
174 { return ATL::lstrlenA(lpszString); }
175
176 #ifdef lstrcpyn
177 #undef lstrcpyn
178 #define lstrcpyn ATL::lstrcpynW
179 #endif // lstrcpyn
180
181 #ifndef SetWindowLongPtrW
182 inline LONG_PTR tmp_SetWindowLongPtrW( HWND hWnd, int nIndex, LONG_PTR dwNewLong )
183 {
184 return( ::SetWindowLongW( hWnd, nIndex, LONG( dwNewLong ) ) );
185 }
186 #define SetWindowLongPtrW tmp_SetWindowLongPtrW
187 #endif
188
189 #ifndef GetWindowLongPtrW
190 inline LONG_PTR tmp_GetWindowLongPtrW( HWND hWnd, int nIndex )
191 {
192 return( ::GetWindowLongW( hWnd, nIndex ) );
193 }
194 #define GetWindowLongPtrW tmp_GetWindowLongPtrW
195 #endif
196
197 #ifndef LongToPtr
198 #define LongToPtr(x) ((void*)x)
199 #endif
200
201 #ifndef PtrToInt
202 #define PtrToInt( p ) ((INT)(INT_PTR) (p) )
203 #endif
204
205 #else // !(_ATL_VER >= 0x0800)
206
207 #ifdef lstrlenW
208 #undef lstrlenW
209 #define lstrlenW (int)::wcslen
210 #endif // lstrlenW
211
212 #define lstrlenA (int)strlen
213
214 #ifndef lstrcpyn
215 inline LPTSTR lstrcpyn(LPTSTR lpstrDest, LPCTSTR lpstrSrc, int nLength)
216 {
217 if(lpstrDest == NULL || lpstrSrc == NULL || nLength <= 0)
218 return NULL;
219 int nLen = __min(lstrlen(lpstrSrc), nLength - 1);
220 LPTSTR lpstrRet = (LPTSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(TCHAR));
221 lpstrDest[nLen] = 0;
222 return lpstrRet;
223 }
224 #endif // !lstrcpyn
225
226 #ifndef lstrcpynW
227 inline LPWSTR lstrcpynW(LPWSTR lpstrDest, LPCWSTR lpstrSrc, int nLength)
228 {
229 return lstrcpyn(lpstrDest, lpstrSrc, nLength); // WinCE is Unicode only
230 }
231 #endif // !lstrcpynW
232
233 #ifndef lstrcpynA
234 inline LPSTR lstrcpynA(LPSTR lpstrDest, LPCSTR lpstrSrc, int nLength)
235 {
236 if(lpstrDest == NULL || lpstrSrc == NULL || nLength <= 0)
237 return NULL;
238 int nLen = __min(lstrlenA(lpstrSrc), nLength - 1);
239 LPSTR lpstrRet = (LPSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(char));
240 lpstrDest[nLen] = 0;
241 return lpstrRet;
242 }
243 #endif // !lstrcpyn
244
245 #ifdef TrackPopupMenu
246 #undef TrackPopupMenu
247 #endif // TrackPopupMenu
248
249 #define DECLARE_WND_CLASS_EX(WndClassName, style, bkgnd) \
250 static CWndClassInfo& GetWndClassInfo() \
251 { \
252 static CWndClassInfo wc = \
253 { \
254 { style, StartWindowProc, \
255 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName }, \
256 NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \
257 }; \
258 return wc; \
259 }
260
261 #ifndef _MAX_FNAME
262 #define _MAX_FNAME _MAX_PATH
263 #endif // _MAX_FNAME
264
265 #if (_WIN32_WCE < 400)
266 #define MAKEINTATOM(i) (LPTSTR)((ULONG_PTR)((WORD)(i)))
267 #endif // (_WIN32_WCE < 400)
268
269 #if (_WIN32_WCE < 410)
270 #define WHEEL_PAGESCROLL (UINT_MAX)
271 #define WHEEL_DELTA 120
272 #endif // (_WIN32_WCE < 410)
273
274 #ifdef DrawIcon
275 #undef DrawIcon
276 #endif
277
278 #ifndef VARCMP_LT
279 #define VARCMP_LT 0
280 #endif
281 #ifndef VARCMP_EQ
282 #define VARCMP_EQ 1
283 #endif
284 #ifndef VARCMP_GT
285 #define VARCMP_GT 2
286 #endif
287 #ifndef VARCMP_NULL
288 #define VARCMP_NULL 3
289 #endif
290
291 #ifndef RDW_ALLCHILDREN
292 #define RDW_ALLCHILDREN 0
293 #endif
294
295 #endif // !(_ATL_VER >= 0x0800)
296
297 #endif // _WIN32_WCE
298
299
300 ///////////////////////////////////////////////////////////////////////////////
301 // Global support for using original VC++ 6.0 headers with WTL
302
303 #if (_MSC_VER < 1300) && !defined(_WIN32_WCE)
304 #ifndef REG_QWORD
305 #define REG_QWORD 11
306 #endif
307
308 #ifndef BS_PUSHBOX
309 #define BS_PUSHBOX 0x0000000AL
310 #endif
311
312 struct __declspec(uuid("000214e6-0000-0000-c000-000000000046")) IShellFolder;
313 struct __declspec(uuid("000214f9-0000-0000-c000-000000000046")) IShellLinkW;
314 struct __declspec(uuid("000214ee-0000-0000-c000-000000000046")) IShellLinkA;
315 #endif // (_MSC_VER < 1300) && !defined(_WIN32_WCE)
316
317 #ifndef _ATL_NO_OLD_HEADERS_WIN64
318 #if !defined(_WIN64) && (_ATL_VER < 0x0700)
319
320 #ifndef PSM_INSERTPAGE
321 #define PSM_INSERTPAGE (WM_USER + 119)
322 #endif // !PSM_INSERTPAGE
323
324 #ifndef GetClassLongPtr
325 #define GetClassLongPtrA GetClassLongA
326 #define GetClassLongPtrW GetClassLongW
327 #ifdef UNICODE
328 #define GetClassLongPtr GetClassLongPtrW
329 #else
330 #define GetClassLongPtr GetClassLongPtrA
331 #endif // !UNICODE
332 #endif // !GetClassLongPtr
333
334 #ifndef GCLP_HICONSM
335 #define GCLP_HICONSM (-34)
336 #endif // !GCLP_HICONSM
337
338 #ifndef GetWindowLongPtr
339 #define GetWindowLongPtrA GetWindowLongA
340 #define GetWindowLongPtrW GetWindowLongW
341 #ifdef UNICODE
342 #define GetWindowLongPtr GetWindowLongPtrW
343 #else
344 #define GetWindowLongPtr GetWindowLongPtrA
345 #endif // !UNICODE
346 #endif // !GetWindowLongPtr
347
348 #ifndef SetWindowLongPtr
349 #define SetWindowLongPtrA SetWindowLongA
350 #define SetWindowLongPtrW SetWindowLongW
351 #ifdef UNICODE
352 #define SetWindowLongPtr SetWindowLongPtrW
353 #else
354 #define SetWindowLongPtr SetWindowLongPtrA
355 #endif // !UNICODE
356 #endif // !SetWindowLongPtr
357
358 #ifndef GWLP_WNDPROC
359 #define GWLP_WNDPROC (-4)
360 #endif
361 #ifndef GWLP_HINSTANCE
362 #define GWLP_HINSTANCE (-6)
363 #endif
364 #ifndef GWLP_HWNDPARENT
365 #define GWLP_HWNDPARENT (-8)
366 #endif
367 #ifndef GWLP_USERDATA
368 #define GWLP_USERDATA (-21)
369 #endif
370 #ifndef GWLP_ID
371 #define GWLP_ID (-12)
372 #endif
373
374 #ifndef DWLP_MSGRESULT
375 #define DWLP_MSGRESULT 0
376 #endif
377
378 typedef long LONG_PTR;
379 typedef unsigned long ULONG_PTR;
380 typedef ULONG_PTR DWORD_PTR;
381
382 #ifndef HandleToUlong
383 #define HandleToUlong( h ) ((ULONG)(ULONG_PTR)(h) )
384 #endif
385 #ifndef HandleToLong
386 #define HandleToLong( h ) ((LONG)(LONG_PTR) (h) )
387 #endif
388 #ifndef LongToHandle
389 #define LongToHandle( h) ((HANDLE)(LONG_PTR) (h))
390 #endif
391 #ifndef PtrToUlong
392 #define PtrToUlong( p ) ((ULONG)(ULONG_PTR) (p) )
393 #endif
394 #ifndef PtrToLong
395 #define PtrToLong( p ) ((LONG)(LONG_PTR) (p) )
396 #endif
397 #ifndef PtrToUint
398 #define PtrToUint( p ) ((UINT)(UINT_PTR) (p) )
399 #endif
400 #ifndef PtrToInt
401 #define PtrToInt( p ) ((INT)(INT_PTR) (p) )
402 #endif
403 #ifndef PtrToUshort
404 #define PtrToUshort( p ) ((unsigned short)(ULONG_PTR)(p) )
405 #endif
406 #ifndef PtrToShort
407 #define PtrToShort( p ) ((short)(LONG_PTR)(p) )
408 #endif
409 #ifndef IntToPtr
410 #define IntToPtr( i ) ((VOID *)(INT_PTR)((int)i))
411 #endif
412 #ifndef UIntToPtr
413 #define UIntToPtr( ui ) ((VOID *)(UINT_PTR)((unsigned int)ui))
414 #endif
415 #ifndef LongToPtr
416 #define LongToPtr( l ) ((VOID *)(LONG_PTR)((long)l))
417 #endif
418 #ifndef ULongToPtr
419 #define ULongToPtr( ul ) ((VOID *)(ULONG_PTR)((unsigned long)ul))
420 #endif
421
422 #endif // !defined(_WIN64) && (_ATL_VER < 0x0700)
423 #endif // !_ATL_NO_OLD_HEADERS_WIN64
424
425
426 ///////////////////////////////////////////////////////////////////////////////
427 // Global support for using original VC++ 7.x headers with WTL
428
429 #if (_MSC_VER >= 1300) && (_MSC_VER < 1400)
430
431 #ifndef BS_PUSHBOX
432 #define BS_PUSHBOX 0x0000000AL
433 #endif
434
435 #pragma warning(disable: 4244) // conversion from 'type1' to 'type2', possible loss of data
436
437 #endif // (_MSC_VER >= 1300) && (_MSC_VER < 1400)
438
439
440 ///////////////////////////////////////////////////////////////////////////////
441 // Global support for old SDK headers
442
443 #ifndef BTNS_BUTTON
444 #define BTNS_BUTTON TBSTYLE_BUTTON
445 #endif
446
447 #ifndef BTNS_SEP
448 #define BTNS_SEP TBSTYLE_SEP
449 #endif
450
451 #ifndef BTNS_CHECK
452 #define BTNS_CHECK TBSTYLE_CHECK
453 #endif
454
455 #ifndef BTNS_GROUP
456 #define BTNS_GROUP TBSTYLE_GROUP
457 #endif
458
459 #ifndef BTNS_CHECKGROUP
460 #define BTNS_CHECKGROUP TBSTYLE_CHECKGROUP
461 #endif
462
463 #if (_WIN32_IE >= 0x0300)
464 #ifndef BTNS_DROPDOWN
465 #define BTNS_DROPDOWN TBSTYLE_DROPDOWN
466 #endif
467 #endif
468
469 #if (_WIN32_IE >= 0x0400)
470 #ifndef BTNS_AUTOSIZE
471 #define BTNS_AUTOSIZE TBSTYLE_AUTOSIZE
472 #endif
473
474 #ifndef BTNS_NOPREFIX
475 #define BTNS_NOPREFIX TBSTYLE_NOPREFIX
476 #endif
477 #endif
478
479
480 ///////////////////////////////////////////////////////////////////////////////
481 // Global support for SecureHelper functions
482
483 #ifndef _TRUNCATE
484 #define _TRUNCATE ((size_t)-1)
485 #endif
486
487 #ifndef _ERRCODE_DEFINED
488 #define _ERRCODE_DEFINED
489 typedef int errno_t;
490 #endif
491
492 #ifndef _SECURECRT_ERRCODE_VALUES_DEFINED
493 #define _SECURECRT_ERRCODE_VALUES_DEFINED
494 #define EINVAL 22
495 #define STRUNCATE 80
496 #endif
497
498 #ifndef _countof
499 #define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
500 #endif
501
502
503 ///////////////////////////////////////////////////////////////////////////////
504 // Miscellaneous global support
505
506 // define useful macros from winuser.h
507 #ifndef IS_INTRESOURCE
508 #define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0)
509 #endif // IS_INTRESOURCE
510
511 // protect template members from windowsx.h macros
512 #ifdef _INC_WINDOWSX
513 #undef SubclassWindow
514 #endif // _INC_WINDOWSX
515
516 // define useful macros from windowsx.h
517 #ifndef GET_X_LPARAM
518 #define GET_X_LPARAM(lParam) ((int)(short)LOWORD(lParam))
519 #endif
520 #ifndef GET_Y_LPARAM
521 #define GET_Y_LPARAM(lParam) ((int)(short)HIWORD(lParam))
522 #endif
523
524 // Dummy structs for compiling with /CLR
525 #if (_MSC_VER >= 1300) && defined(_MANAGED)
526 __if_not_exists(_IMAGELIST::_IMAGELIST) { struct _IMAGELIST { }; }
527 __if_not_exists(_TREEITEM::_TREEITEM) { struct _TREEITEM { }; }
528 __if_not_exists(_PSP::_PSP) { struct _PSP { }; }
529 #endif
530
531 // Define ATLVERIFY macro for ATL3
532 #if (_ATL_VER < 0x0700)
533 #ifndef ATLVERIFY
534 #ifdef _DEBUG
535 #define ATLVERIFY(expr) ATLASSERT(expr)
536 #else
537 #define ATLVERIFY(expr) (expr)
538 #endif // DEBUG
539 #endif // ATLVERIFY
540 #endif // (_ATL_VER < 0x0700)
541
542 // Forward declaration for ATL3 and ATL11 fix
543 #if (((_ATL_VER < 0x0700) && defined(_ATL_DLL)) || (_ATL_VER >= 0x0B00)) && !defined(_WIN32_WCE)
544 namespace ATL { HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor); };
545 #endif
546
547 #ifndef WM_MOUSEHWHEEL
548 #define WM_MOUSEHWHEEL 0x020E
549 #endif
550
551
552 namespace WTL
553 {
554
555 #if (_ATL_VER >= 0x0700)
556 DECLARE_TRACE_CATEGORY(atlTraceUI);
557 #ifdef _DEBUG
558 __declspec(selectany) ATL::CTraceCategory atlTraceUI(_T("atlTraceUI"));
559 #endif // _DEBUG
560 #else // !(_ATL_VER >= 0x0700)
561 enum wtlTraceFlags
562 {
563 atlTraceUI = 0x10000000
564 };
565 #endif // !(_ATL_VER >= 0x0700)
566
567 // Windows version helper
568 inline bool AtlIsOldWindows()
569 {
570 #ifdef _versionhelpers_H_INCLUDED_
571 return !::IsWindowsVersionOrGreater(4, 90, 0);
572 #else // !_versionhelpers_H_INCLUDED_
573 OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) };
574 BOOL bRet = ::GetVersionEx(&ovi);
575 return (!bRet || !((ovi.dwMajorVersion >= 5) || (ovi.dwMajorVersion == 4 && ovi.dwMinorVersion >= 90)));
576 #endif // _versionhelpers_H_INCLUDED_
577 }
578
579 // Default GUI font helper - "MS Shell Dlg" stock font
580 inline HFONT AtlGetDefaultGuiFont()
581 {
582 #ifndef _WIN32_WCE
583 return (HFONT)::GetStockObject(DEFAULT_GUI_FONT);
584 #else // CE specific
585 return (HFONT)::GetStockObject(SYSTEM_FONT);
586 #endif // _WIN32_WCE
587 }
588
589 // Control font helper - default font for controls not in a dialog
590 // (NOTE: Caller owns the font, and should destroy it when it's no longer needed)
591 inline HFONT AtlCreateControlFont()
592 {
593 #ifndef _WIN32_WCE
594 LOGFONT lf = { 0 };
595 ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE);
596 HFONT hFont = ::CreateFontIndirect(&lf);
597 ATLASSERT(hFont != NULL);
598 return hFont;
599 #else // CE specific
600 return (HFONT)::GetStockObject(SYSTEM_FONT);
601 #endif // _WIN32_WCE
602 }
603
604 // Bold font helper
605 // (NOTE: Caller owns the font, and should destroy it when it's no longer needed)
606 inline HFONT AtlCreateBoldFont(HFONT hFont = NULL)
607 {
608 LOGFONT lf = { 0 };
609 #ifndef _WIN32_WCE
610 if(hFont == NULL)
611 ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE);
612 else
613 ATLVERIFY(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT));
614 #else // CE specific
615 if(hFont == NULL)
616 hFont = (HFONT)::GetStockObject(SYSTEM_FONT);
617 ATLVERIFY(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT));
618 #endif // _WIN32_WCE
619 lf.lfWeight = FW_BOLD;
620 HFONT hFontBold = ::CreateFontIndirect(&lf);
621 ATLASSERT(hFontBold != NULL);
622 return hFontBold;
623 }
624
625 // Common Controls initialization helper
626 inline BOOL AtlInitCommonControls(DWORD dwFlags)
627 {
628 INITCOMMONCONTROLSEX iccx = { sizeof(INITCOMMONCONTROLSEX), dwFlags };
629 BOOL bRet = ::InitCommonControlsEx(&iccx);
630 ATLASSERT(bRet);
631 return bRet;
632 }
633
634
635 ///////////////////////////////////////////////////////////////////////////////
636 // RunTimeHelper - helper functions for Windows version and structure sizes
637
638 // Not for Windows CE
639 #if defined(_WIN32_WCE) && !defined(_WTL_NO_RUNTIME_STRUCT_SIZE)
640 #define _WTL_NO_RUNTIME_STRUCT_SIZE
641 #endif
642
643 #ifndef _WTL_NO_RUNTIME_STRUCT_SIZE
644
645 #ifndef _SIZEOF_STRUCT
646 #define _SIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member))
647 #endif
648
649 #if (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE)
650 #define REBARBANDINFO_V6_SIZE _SIZEOF_STRUCT(REBARBANDINFO, cxHeader)
651 #endif // (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE)
652
653 #if (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE)
654 #define LVGROUP_V5_SIZE _SIZEOF_STRUCT(LVGROUP, uAlign)
655 #endif // (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE)
656
657 #if (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE)
658 #define LVTILEINFO_V5_SIZE _SIZEOF_STRUCT(LVTILEINFO, puColumns)
659 #endif // (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE)
660
661 #if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE)
662 #define MCHITTESTINFO_V1_SIZE _SIZEOF_STRUCT(MCHITTESTINFO, st)
663 #endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE)
664
665 #if !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE)
666 #define NONCLIENTMETRICS_V1_SIZE _SIZEOF_STRUCT(NONCLIENTMETRICS, lfMessageFont)
667 #endif // !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE)
668
669 #if !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0501) && !defined(TTTOOLINFO_V2_SIZE)
670 #define TTTOOLINFO_V2_SIZE _SIZEOF_STRUCT(TTTOOLINFO, lParam)
671 #endif // !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0501) && !defined(TTTOOLINFO_V2_SIZE)
672
673 #endif // !_WTL_NO_RUNTIME_STRUCT_SIZE
674
675 namespace RunTimeHelper
676 {
677 #ifndef _WIN32_WCE
678 inline bool IsCommCtrl6()
679 {
680 DWORD dwMajor = 0, dwMinor = 0;
681 HRESULT hRet = ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor);
682 return (SUCCEEDED(hRet) && (dwMajor >= 6));
683 }
684
685 inline bool IsVista()
686 {
687 #ifdef _versionhelpers_H_INCLUDED_
688 return ::IsWindowsVistaOrGreater();
689 #else // !_versionhelpers_H_INCLUDED_
690 OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) };
691 BOOL bRet = ::GetVersionEx(&ovi);
692 return ((bRet != FALSE) && (ovi.dwMajorVersion >= 6));
693 #endif // _versionhelpers_H_INCLUDED_
694 }
695
696 inline bool IsThemeAvailable()
697 {
698 bool bRet = false;
699
700 if(IsCommCtrl6())
701 {
702 HMODULE hThemeDLL = ::LoadLibrary(_T("uxtheme.dll"));
703 if(hThemeDLL != NULL)
704 {
705 typedef BOOL (STDAPICALLTYPE *PFN_IsThemeActive)();
706 PFN_IsThemeActive pfnIsThemeActive = (PFN_IsThemeActive)::GetProcAddress(hThemeDLL, "IsThemeActive");
707 ATLASSERT(pfnIsThemeActive != NULL);
708 bRet = (pfnIsThemeActive != NULL) && (pfnIsThemeActive() != FALSE);
709 if(bRet)
710 {
711 typedef BOOL (STDAPICALLTYPE *PFN_IsAppThemed)();
712 PFN_IsAppThemed pfnIsAppThemed = (PFN_IsAppThemed)::GetProcAddress(hThemeDLL, "IsAppThemed");
713 ATLASSERT(pfnIsAppThemed != NULL);
714 bRet = (pfnIsAppThemed != NULL) && (pfnIsAppThemed() != FALSE);
715 }
716
717 ::FreeLibrary(hThemeDLL);
718 }
719 }
720
721 return bRet;
722 }
723
724 inline bool IsWin7()
725 {
726 #ifdef _versionhelpers_H_INCLUDED_
727 return ::IsWindows7OrGreater();
728 #else // !_versionhelpers_H_INCLUDED_
729 OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) };
730 BOOL bRet = ::GetVersionEx(&ovi);
731 return ((bRet != FALSE) && (ovi.dwMajorVersion == 6) && (ovi.dwMinorVersion >= 1));
732 #endif // _versionhelpers_H_INCLUDED_
733 }
734
735 inline bool IsRibbonUIAvailable()
736 {
737 static INT iRibbonUI = -1;
738
739 #if defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7)
740 if (iRibbonUI == -1)
741 {
742 HMODULE hRibbonDLL = ::LoadLibrary(_T("propsys.dll"));
743 if (hRibbonDLL != NULL)
744 {
745 const GUID CLSID_UIRibbonFramework = { 0x926749fa, 0x2615, 0x4987, { 0x88, 0x45, 0xc3, 0x3e, 0x65, 0xf2, 0xb9, 0x57 } };
746 // block - create instance
747 {
748 ATL::CComPtr<IUnknown> pIUIFramework;
749 iRibbonUI = SUCCEEDED(pIUIFramework.CoCreateInstance(CLSID_UIRibbonFramework)) ? 1 : 0;
750 }
751 ::FreeLibrary(hRibbonDLL);
752 }
753 else
754 {
755 iRibbonUI = 0;
756 }
757 }
758 #endif // defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7)
759
760 return (iRibbonUI == 1);
761 }
762
763 #endif // !_WIN32_WCE
764
765 inline UINT SizeOf_REBARBANDINFO()
766 {
767 UINT uSize = sizeof(REBARBANDINFO);
768 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
769 if(!(IsVista() && IsCommCtrl6()))
770 uSize = REBARBANDINFO_V6_SIZE;
771 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
772 return uSize;
773 }
774
775 #if (_WIN32_WINNT >= 0x501)
776 inline UINT SizeOf_LVGROUP()
777 {
778 UINT uSize = sizeof(LVGROUP);
779 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
780 if(!IsVista())
781 uSize = LVGROUP_V5_SIZE;
782 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
783 return uSize;
784 }
785
786 inline UINT SizeOf_LVTILEINFO()
787 {
788 UINT uSize = sizeof(LVTILEINFO);
789 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
790 if(!IsVista())
791 uSize = LVTILEINFO_V5_SIZE;
792 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
793 return uSize;
794 }
795 #endif // (_WIN32_WINNT >= 0x501)
796
797 inline UINT SizeOf_MCHITTESTINFO()
798 {
799 UINT uSize = sizeof(MCHITTESTINFO);
800 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
801 if(!(IsVista() && IsCommCtrl6()))
802 uSize = MCHITTESTINFO_V1_SIZE;
803 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
804 return uSize;
805 }
806
807 #ifndef _WIN32_WCE
808 inline UINT SizeOf_NONCLIENTMETRICS()
809 {
810 UINT uSize = sizeof(NONCLIENTMETRICS);
811 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600)
812 if(!IsVista())
813 uSize = NONCLIENTMETRICS_V1_SIZE;
814 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600)
815 return uSize;
816 }
817
818 inline UINT SizeOf_TOOLINFO()
819 {
820 UINT uSize = sizeof(TOOLINFO);
821 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0501)
822 if(!IsVista())
823 uSize = TTTOOLINFO_V2_SIZE;
824 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0501)
825 return uSize;
826 }
827 #endif // !_WIN32_WCE
828 };
829
830
831 ///////////////////////////////////////////////////////////////////////////////
832 // ModuleHelper - helper functions for ATL3 and ATL7 module classes
833
834 namespace ModuleHelper
835 {
836 inline HINSTANCE GetModuleInstance()
837 {
838 #if (_ATL_VER >= 0x0700)
839 return ATL::_AtlBaseModule.GetModuleInstance();
840 #else // !(_ATL_VER >= 0x0700)
841 return ATL::_pModule->GetModuleInstance();
842 #endif // !(_ATL_VER >= 0x0700)
843 }
844
845 inline HINSTANCE GetResourceInstance()
846 {
847 #if (_ATL_VER >= 0x0700)
848 return ATL::_AtlBaseModule.GetResourceInstance();
849 #else // !(_ATL_VER >= 0x0700)
850 return ATL::_pModule->GetResourceInstance();
851 #endif // !(_ATL_VER >= 0x0700)
852 }
853
854 inline void AddCreateWndData(ATL::_AtlCreateWndData* pData, void* pObject)
855 {
856 #if (_ATL_VER >= 0x0700)
857 ATL::_AtlWinModule.AddCreateWndData(pData, pObject);
858 #else // !(_ATL_VER >= 0x0700)
859 ATL::_pModule->AddCreateWndData(pData, pObject);
860 #endif // !(_ATL_VER >= 0x0700)
861 }
862
863 inline void* ExtractCreateWndData()
864 {
865 #if (_ATL_VER >= 0x0700)
866 return ATL::_AtlWinModule.ExtractCreateWndData();
867 #else // !(_ATL_VER >= 0x0700)
868 return ATL::_pModule->ExtractCreateWndData();
869 #endif // !(_ATL_VER >= 0x0700)
870 }
871 };
872
873
874 ///////////////////////////////////////////////////////////////////////////////
875 // SecureHelper - helper functions for VS2005 secure CRT
876
877 namespace SecureHelper
878 {
879 inline void strcpyA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc)
880 {
881 #if _SECURE_ATL
882 ATL::Checked::strcpy_s(lpstrDest, cchDest, lpstrSrc);
883 #else
884 if(cchDest > (size_t)lstrlenA(lpstrSrc))
885 ATLVERIFY(lstrcpyA(lpstrDest, lpstrSrc) != NULL);
886 else
887 ATLASSERT(FALSE);
888 #endif
889 }
890
891 inline void strcpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc)
892 {
893 #if _SECURE_ATL
894 ATL::Checked::wcscpy_s(lpstrDest, cchDest, lpstrSrc);
895 #else
896 if(cchDest > (size_t)lstrlenW(lpstrSrc))
897 ATLVERIFY(lstrcpyW(lpstrDest, lpstrSrc) != NULL);
898 else
899 ATLASSERT(FALSE);
900 #endif
901 }
902
903 inline void strcpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc)
904 {
905 #ifdef _UNICODE
906 strcpyW_x(lpstrDest, cchDest, lpstrSrc);
907 #else
908 strcpyA_x(lpstrDest, cchDest, lpstrSrc);
909 #endif
910 }
911
912 inline errno_t strncpyA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc, size_t cchCount)
913 {
914 #if _SECURE_ATL
915 return ATL::Checked::strncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount);
916 #else
917 errno_t nRet = 0;
918 if(lpstrDest == NULL || cchDest == 0 || lpstrSrc == NULL)
919 {
920 nRet = EINVAL;
921 }
922 else if(cchCount == _TRUNCATE)
923 {
924 cchCount = __min(cchDest - 1, size_t(lstrlenA(lpstrSrc)));
925 nRet = STRUNCATE;
926 }
927 else if(cchDest <= cchCount)
928 {
929 lpstrDest[0] = 0;
930 nRet = EINVAL;
931 }
932 if(nRet == 0 || nRet == STRUNCATE)
933 nRet = (lstrcpynA(lpstrDest, lpstrSrc, (int)cchCount + 1) != NULL) ? nRet : EINVAL;
934 ATLASSERT(nRet == 0 || nRet == STRUNCATE);
935 return nRet;
936 #endif
937 }
938
939 inline errno_t strncpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc, size_t cchCount)
940 {
941 #if _SECURE_ATL
942 return ATL::Checked::wcsncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount);
943 #else
944 errno_t nRet = 0;
945 if(lpstrDest == NULL || cchDest == 0 || lpstrSrc == NULL)
946 {
947 nRet = EINVAL;
948 }
949 else if(cchCount == _TRUNCATE)
950 {
951 cchCount = __min(cchDest - 1, size_t(lstrlenW(lpstrSrc)));
952 nRet = STRUNCATE;
953 }
954 else if(cchDest <= cchCount)
955 {
956 lpstrDest[0] = 0;
957 nRet = EINVAL;
958 }
959 if(nRet == 0 || nRet == STRUNCATE)
960 nRet = (lstrcpynW(lpstrDest, lpstrSrc, (int)cchCount + 1) != NULL) ? nRet : EINVAL;
961 ATLASSERT(nRet == 0 || nRet == STRUNCATE);
962 return nRet;
963 #endif
964 }
965
966 inline errno_t strncpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc, size_t cchCount)
967 {
968 #ifdef _UNICODE
969 return strncpyW_x(lpstrDest, cchDest, lpstrSrc, cchCount);
970 #else
971 return strncpyA_x(lpstrDest, cchDest, lpstrSrc, cchCount);
972 #endif
973 }
974
975 inline void strcatA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc)
976 {
977 #if _SECURE_ATL
978 ATL::Checked::strcat_s(lpstrDest, cchDest, lpstrSrc);
979 #else
980 if(cchDest > (size_t)lstrlenA(lpstrSrc))
981 ATLVERIFY(lstrcatA(lpstrDest, lpstrSrc) != NULL);
982 else
983 ATLASSERT(FALSE);
984 #endif
985 }
986
987 inline void strcatW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc)
988 {
989 #if _SECURE_ATL
990 ATL::Checked::wcscat_s(lpstrDest, cchDest, lpstrSrc);
991 #else
992 if(cchDest > (size_t)lstrlenW(lpstrSrc))
993 ATLVERIFY(lstrcatW(lpstrDest, lpstrSrc) != NULL);
994 else
995 ATLASSERT(FALSE);
996 #endif
997 }
998
999 inline void strcat_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc)
1000 {
1001 #ifdef _UNICODE
1002 strcatW_x(lpstrDest, cchDest, lpstrSrc);
1003 #else
1004 strcatA_x(lpstrDest, cchDest, lpstrSrc);
1005 #endif
1006 }
1007
1008 inline void memcpy_x(void* pDest, size_t cbDest, const void* pSrc, size_t cbSrc)
1009 {
1010 #if _SECURE_ATL
1011 ATL::Checked::memcpy_s(pDest, cbDest, pSrc, cbSrc);
1012 #else
1013 if(cbDest >= cbSrc)
1014 memcpy(pDest, pSrc, cbSrc);
1015 else
1016 ATLASSERT(FALSE);
1017 #endif
1018 }
1019
1020 inline void memmove_x(void* pDest, size_t cbDest, const void* pSrc, size_t cbSrc)
1021 {
1022 #if _SECURE_ATL
1023 ATL::Checked::memmove_s(pDest, cbDest, pSrc, cbSrc);
1024 #else
1025 if(cbDest >= cbSrc)
1026 memmove(pDest, pSrc, cbSrc);
1027 else
1028 ATLASSERT(FALSE);
1029 #endif
1030 }
1031
1032 inline int vsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args)
1033 {
1034 #if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE)
1035 return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args);
1036 #else
1037 cchBuff; // Avoid unused argument warning
1038 #pragma warning(push)
1039 #pragma warning(disable: 4996)
1040 return _vstprintf(lpstrBuff, lpstrFormat, args);
1041 #pragma warning(pop)
1042 #endif
1043 }
1044
1045 inline int wvsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args)
1046 {
1047 #if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE)
1048 return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args);
1049 #else
1050 cchBuff; // Avoid unused argument warning
1051 return ::wvsprintf(lpstrBuff, lpstrFormat, args);
1052 #endif
1053 }
1054
1055 inline int sprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, ...)
1056 {
1057 va_list args;
1058 va_start(args, lpstrFormat);
1059 int nRes = vsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args);
1060 va_end(args);
1061 return nRes;
1062 }
1063
1064 inline int wsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, ...)
1065 {
1066 va_list args;
1067 va_start(args, lpstrFormat);
1068 int nRes = wvsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args);
1069 va_end(args);
1070 return nRes;
1071 }
1072 }; // namespace SecureHelper
1073
1074
1075 ///////////////////////////////////////////////////////////////////////////////
1076 // MinCrtHelper - helper functions for using _ATL_MIN_CRT
1077
1078 namespace MinCrtHelper
1079 {
1080 inline int _isspace(TCHAR ch)
1081 {
1082 #ifndef _ATL_MIN_CRT
1083 return _istspace(ch);
1084 #else // _ATL_MIN_CRT
1085 WORD type = 0;
1086 ::GetStringTypeEx(::GetThreadLocale(), CT_CTYPE1, &ch, 1, &type);
1087 return (type & C1_SPACE) == C1_SPACE;
1088 #endif // _ATL_MIN_CRT
1089 }
1090
1091 inline int _isdigit(TCHAR ch)
1092 {
1093 #ifndef _ATL_MIN_CRT
1094 return _istdigit(ch);
1095 #else // _ATL_MIN_CRT
1096 WORD type = 0;
1097 ::GetStringTypeEx(::GetThreadLocale(), CT_CTYPE1, &ch, 1, &type);
1098 return (type & C1_DIGIT) == C1_DIGIT;
1099 #endif // _ATL_MIN_CRT
1100 }
1101
1102 inline int _atoi(LPCTSTR str)
1103 {
1104 #ifndef _ATL_MIN_CRT
1105 return _ttoi(str);
1106 #else // _ATL_MIN_CRT
1107 while(_isspace(*str) != 0)
1108 ++str;
1109
1110 TCHAR ch = *str++;
1111 TCHAR sign = ch; // save sign indication
1112 if(ch == _T('-') || ch == _T('+'))
1113 ch = *str++; // skip sign
1114
1115 int total = 0;
1116 while(_isdigit(ch) != 0)
1117 {
1118 total = 10 * total + (ch - '0'); // accumulate digit
1119 ch = *str++; // get next char
1120 }
1121
1122 return (sign == '-') ? -total : total; // return result, negated if necessary
1123 #endif // _ATL_MIN_CRT
1124 }
1125
1126 inline LPCTSTR _strrchr(LPCTSTR str, TCHAR ch)
1127 {
1128 #ifndef _ATL_MIN_CRT
1129 return _tcsrchr(str, ch);
1130 #else // _ATL_MIN_CRT
1131 LPCTSTR lpsz = NULL;
1132 while(*str != 0)
1133 {
1134 if(*str == ch)
1135 lpsz = str;
1136 str = ::CharNext(str);
1137 }
1138 return lpsz;
1139 #endif // _ATL_MIN_CRT
1140 }
1141
1142 inline LPTSTR _strrchr(LPTSTR str, TCHAR ch)
1143 {
1144 #ifndef _ATL_MIN_CRT
1145 return _tcsrchr(str, ch);
1146 #else // _ATL_MIN_CRT
1147 LPTSTR lpsz = NULL;
1148 while(*str != 0)
1149 {
1150 if(*str == ch)
1151 lpsz = str;
1152 str = ::CharNext(str);
1153 }
1154 return lpsz;
1155 #endif // _ATL_MIN_CRT
1156 }
1157 }; // namespace MinCrtHelper
1158
1159
1160 ///////////////////////////////////////////////////////////////////////////////
1161 // GenericWndClass - generic window class usable for subclassing
1162
1163 // Use in dialog templates to specify a placeholder to be subclassed
1164 // Specify as a custom control with class name WTL_GenericWindow
1165 // Call Rregister() before creating dialog (for example, in WinMain)
1166 namespace GenericWndClass
1167 {
1168 inline LPCTSTR GetName()
1169 {
1170 return _T("WTL_GenericWindow");
1171 }
1172
1173 inline ATOM Register()
1174 {
1175 #ifndef _WIN32_WCE
1176 WNDCLASSEX wc = { sizeof(WNDCLASSEX) };
1177 #else
1178 WNDCLASS wc = { 0 };
1179 #endif
1180 wc.lpfnWndProc = ::DefWindowProc;
1181 wc.hInstance = ModuleHelper::GetModuleInstance();
1182 wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
1183 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1184 wc.lpszClassName = GetName();
1185 #ifndef _WIN32_WCE
1186 ATOM atom = ::RegisterClassEx(&wc);
1187 #else
1188 ATOM atom = ::RegisterClass(&wc);
1189 #endif
1190 ATLASSERT(atom != 0);
1191 return atom;
1192 }
1193
1194 inline BOOL Unregister() // only needed for DLLs or tmp use
1195 {
1196 return ::UnregisterClass(GetName(), ModuleHelper::GetModuleInstance());
1197 }
1198 }; // namespace GenericWndClass
1199
1200
1201 ///////////////////////////////////////////////////////////////////////////////
1202 // CMessageFilter - Interface for message filter support
1203
1204 class CMessageFilter
1205 {
1206 public:
1207 virtual BOOL PreTranslateMessage(MSG* pMsg) = 0;
1208 };
1209
1210
1211 ///////////////////////////////////////////////////////////////////////////////
1212 // CIdleHandler - Interface for idle processing
1213
1214 class CIdleHandler
1215 {
1216 public:
1217 virtual BOOL OnIdle() = 0;
1218 };
1219
1220 #ifndef _ATL_NO_OLD_NAMES
1221 // for compatilibility with old names only
1222 typedef CIdleHandler CUpdateUIObject;
1223 #define DoUpdate OnIdle
1224 #endif // !_ATL_NO_OLD_NAMES
1225
1226
1227 ///////////////////////////////////////////////////////////////////////////////
1228 // CMessageLoop - message loop implementation
1229
1230 class CMessageLoop
1231 {
1232 public:
1233 ATL::CSimpleArray<CMessageFilter*> m_aMsgFilter;
1234 ATL::CSimpleArray<CIdleHandler*> m_aIdleHandler;
1235 MSG m_msg;
1236
1237 // Message filter operations
1238 BOOL AddMessageFilter(CMessageFilter* pMessageFilter)
1239 {
1240 return m_aMsgFilter.Add(pMessageFilter);
1241 }
1242
1243 BOOL RemoveMessageFilter(CMessageFilter* pMessageFilter)
1244 {
1245 return m_aMsgFilter.Remove(pMessageFilter);
1246 }
1247
1248 // Idle handler operations
1249 BOOL AddIdleHandler(CIdleHandler* pIdleHandler)
1250 {
1251 return m_aIdleHandler.Add(pIdleHandler);
1252 }
1253
1254 BOOL RemoveIdleHandler(CIdleHandler* pIdleHandler)
1255 {
1256 return m_aIdleHandler.Remove(pIdleHandler);
1257 }
1258
1259 #ifndef _ATL_NO_OLD_NAMES
1260 // for compatilibility with old names only
1261 BOOL AddUpdateUI(CIdleHandler* pIdleHandler)
1262 {
1263 ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIObject and AddUpdateUI are deprecated. Please change your code to use CIdleHandler and OnIdle\n"));
1264 return AddIdleHandler(pIdleHandler);
1265 }
1266
1267 BOOL RemoveUpdateUI(CIdleHandler* pIdleHandler)
1268 {
1269 ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIObject and RemoveUpdateUI are deprecated. Please change your code to use CIdleHandler and OnIdle\n"));
1270 return RemoveIdleHandler(pIdleHandler);
1271 }
1272 #endif // !_ATL_NO_OLD_NAMES
1273
1274 // message loop
1275 int Run()
1276 {
1277 BOOL bDoIdle = TRUE;
1278 int nIdleCount = 0;
1279 BOOL bRet;
1280
1281 for(;;)
1282 {
1283 while(bDoIdle && !::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE))
1284 {
1285 if(!OnIdle(nIdleCount++))
1286 bDoIdle = FALSE;
1287 }
1288
1289 bRet = ::GetMessage(&m_msg, NULL, 0, 0);
1290
1291 if(bRet == -1)
1292 {
1293 ATLTRACE2(atlTraceUI, 0, _T("::GetMessage returned -1 (error)\n"));
1294 continue; // error, don't process
1295 }
1296 else if(!bRet)
1297 {
1298 ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run - exiting\n"));
1299 break; // WM_QUIT, exit message loop
1300 }
1301
1302 if(!PreTranslateMessage(&m_msg))
1303 {
1304 ::TranslateMessage(&m_msg);
1305 ::DispatchMessage(&m_msg);
1306 }
1307
1308 if(IsIdleMessage(&m_msg))
1309 {
1310 bDoIdle = TRUE;
1311 nIdleCount = 0;
1312 }
1313 }
1314
1315 return (int)m_msg.wParam;
1316 }
1317
1318 static BOOL IsIdleMessage(MSG* pMsg)
1319 {
1320 // These messages should NOT cause idle processing
1321 switch(pMsg->message)
1322 {
1323 case WM_MOUSEMOVE:
1324 #ifndef _WIN32_WCE
1325 case WM_NCMOUSEMOVE:
1326 #endif // !_WIN32_WCE
1327 case WM_PAINT:
1328 case 0x0118: // WM_SYSTIMER (caret blink)
1329 return FALSE;
1330 }
1331
1332 return TRUE;
1333 }
1334
1335 // Overrideables
1336 // Override to change message filtering
1337 virtual BOOL PreTranslateMessage(MSG* pMsg)
1338 {
1339 // loop backwards
1340 for(int i = m_aMsgFilter.GetSize() - 1; i >= 0; i--)
1341 {
1342 CMessageFilter* pMessageFilter = m_aMsgFilter[i];
1343 if(pMessageFilter != NULL && pMessageFilter->PreTranslateMessage(pMsg))
1344 return TRUE;
1345 }
1346 return FALSE; // not translated
1347 }
1348
1349 // override to change idle processing
1350 virtual BOOL OnIdle(int /*nIdleCount*/)
1351 {
1352 for(int i = 0; i < m_aIdleHandler.GetSize(); i++)
1353 {
1354 CIdleHandler* pIdleHandler = m_aIdleHandler[i];
1355 if(pIdleHandler != NULL)
1356 pIdleHandler->OnIdle();
1357 }
1358 return FALSE; // don't continue
1359 }
1360 };
1361
1362
1363 ///////////////////////////////////////////////////////////////////////////////
1364 // CStaticDataInitCriticalSectionLock and CWindowCreateCriticalSectionLock
1365 // internal classes to manage critical sections for both ATL3 and ATL7
1366
1367 class CStaticDataInitCriticalSectionLock
1368 {
1369 public:
1370 #if (_ATL_VER >= 0x0700)
1371 ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock;
1372
1373 CStaticDataInitCriticalSectionLock() : m_cslock(ATL::_pAtlModule->m_csStaticDataInitAndTypeInfo, false)
1374 { }
1375 #endif // (_ATL_VER >= 0x0700)
1376
1377 HRESULT Lock()
1378 {
1379 #if (_ATL_VER >= 0x0700)
1380 return m_cslock.Lock();
1381 #else // !(_ATL_VER >= 0x0700)
1382 ::EnterCriticalSection(&ATL::_pModule->m_csStaticDataInit);
1383 return S_OK;
1384 #endif // !(_ATL_VER >= 0x0700)
1385 }
1386
1387 void Unlock()
1388 {
1389 #if (_ATL_VER >= 0x0700)
1390 m_cslock.Unlock();
1391 #else // !(_ATL_VER >= 0x0700)
1392 ::LeaveCriticalSection(&ATL::_pModule->m_csStaticDataInit);
1393 #endif // !(_ATL_VER >= 0x0700)
1394 }
1395 };
1396
1397
1398 class CWindowCreateCriticalSectionLock
1399 {
1400 public:
1401 #if (_ATL_VER >= 0x0700)
1402 ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock;
1403
1404 CWindowCreateCriticalSectionLock() : m_cslock(ATL::_AtlWinModule.m_csWindowCreate, false)
1405 { }
1406 #endif // (_ATL_VER >= 0x0700)
1407
1408 HRESULT Lock()
1409 {
1410 #if (_ATL_VER >= 0x0700)
1411 return m_cslock.Lock();
1412 #else // !(_ATL_VER >= 0x0700)
1413 ::EnterCriticalSection(&ATL::_pModule->m_csWindowCreate);
1414 return S_OK;
1415 #endif // !(_ATL_VER >= 0x0700)
1416 }
1417
1418 void Unlock()
1419 {
1420 #if (_ATL_VER >= 0x0700)
1421 m_cslock.Unlock();
1422 #else // !(_ATL_VER >= 0x0700)
1423 ::LeaveCriticalSection(&ATL::_pModule->m_csWindowCreate);
1424 #endif // !(_ATL_VER >= 0x0700)
1425 }
1426 };
1427
1428
1429 ///////////////////////////////////////////////////////////////////////////////
1430 // CTempBuffer - helper class for stack allocations for ATL3
1431
1432 #ifndef _WTL_STACK_ALLOC_THRESHOLD
1433 #define _WTL_STACK_ALLOC_THRESHOLD 512
1434 #endif
1435
1436 #if (_ATL_VER >= 0x0700)
1437
1438 using ATL::CTempBuffer;
1439
1440 #else // !(_ATL_VER >= 0x0700)
1441
1442 #ifndef SIZE_MAX
1443 #ifdef _WIN64
1444 #define SIZE_MAX _UI64_MAX
1445 #else
1446 #define SIZE_MAX UINT_MAX
1447 #endif
1448 #endif
1449
1450 #pragma warning(push)
1451 #pragma warning(disable: 4284) // warning for operator ->
1452
1453 template<typename T, int t_nFixedBytes = 128>
1454 class CTempBuffer
1455 {
1456 public:
1457 CTempBuffer() : m_p(NULL)
1458 {
1459 }
1460
1461 CTempBuffer(size_t nElements) : m_p(NULL)
1462 {
1463 Allocate(nElements);
1464 }
1465
1466 ~CTempBuffer()
1467 {
1468 if(m_p != reinterpret_cast<T*>(m_abFixedBuffer))
1469 free(m_p);
1470 }
1471
1472 operator T*() const
1473 {
1474 return m_p;
1475 }
1476
1477 T* operator ->() const
1478 {
1479 ATLASSERT(m_p != NULL);
1480 return m_p;
1481 }
1482
1483 T* Allocate(size_t nElements)
1484 {
1485 ATLASSERT(nElements <= (SIZE_MAX / sizeof(T)));
1486 return AllocateBytes(nElements * sizeof(T));
1487 }
1488
1489 T* AllocateBytes(size_t nBytes)
1490 {
1491 ATLASSERT(m_p == NULL);
1492 if(nBytes > t_nFixedBytes)
1493 m_p = static_cast<T*>(malloc(nBytes));
1494 else
1495 m_p = reinterpret_cast<T*>(m_abFixedBuffer);
1496
1497 return m_p;
1498 }
1499
1500 private:
1501 T* m_p;
1502 BYTE m_abFixedBuffer[t_nFixedBytes];
1503 };
1504
1505 #pragma warning(pop)
1506
1507 #endif // !(_ATL_VER >= 0x0700)
1508
1509
1510 ///////////////////////////////////////////////////////////////////////////////
1511 // CAppModule - module class for an application
1512
1513 class CAppModule : public ATL::CComModule
1514 {
1515 public:
1516 DWORD m_dwMainThreadID;
1517 ATL::CSimpleMap<DWORD, CMessageLoop*>* m_pMsgLoopMap;
1518 ATL::CSimpleArray<HWND>* m_pSettingChangeNotify;
1519
1520 // Overrides of CComModule::Init and Term
1521 HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL)
1522 {
1523 HRESULT hRet = CComModule::Init(pObjMap, hInstance, pLibID);
1524 if(FAILED(hRet))
1525 return hRet;
1526
1527 m_dwMainThreadID = ::GetCurrentThreadId();
1528 typedef ATL::CSimpleMap<DWORD, CMessageLoop*> _mapClass;
1529 m_pMsgLoopMap = NULL;
1530 ATLTRY(m_pMsgLoopMap = new _mapClass);
1531 if(m_pMsgLoopMap == NULL)
1532 return E_OUTOFMEMORY;
1533 m_pSettingChangeNotify = NULL;
1534
1535 return hRet;
1536 }
1537
1538 void Term()
1539 {
1540 TermSettingChangeNotify();
1541 delete m_pMsgLoopMap;
1542 CComModule::Term();
1543 }
1544
1545 // Message loop map methods
1546 BOOL AddMessageLoop(CMessageLoop* pMsgLoop)
1547 {
1548 CStaticDataInitCriticalSectionLock lock;
1549 if(FAILED(lock.Lock()))
1550 {
1551 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddMessageLoop.\n"));
1552 ATLASSERT(FALSE);
1553 return FALSE;
1554 }
1555
1556 ATLASSERT(pMsgLoop != NULL);
1557 ATLASSERT(m_pMsgLoopMap->Lookup(::GetCurrentThreadId()) == NULL); // not in map yet
1558
1559 BOOL bRet = m_pMsgLoopMap->Add(::GetCurrentThreadId(), pMsgLoop);
1560
1561 lock.Unlock();
1562
1563 return bRet;
1564 }
1565
1566 BOOL RemoveMessageLoop()
1567 {
1568 CStaticDataInitCriticalSectionLock lock;
1569 if(FAILED(lock.Lock()))
1570 {
1571 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveMessageLoop.\n"));
1572 ATLASSERT(FALSE);
1573 return FALSE;
1574 }
1575
1576 BOOL bRet = m_pMsgLoopMap->Remove(::GetCurrentThreadId());
1577
1578 lock.Unlock();
1579
1580 return bRet;
1581 }
1582
1583 CMessageLoop* GetMessageLoop(DWORD dwThreadID = ::GetCurrentThreadId()) const
1584 {
1585 CStaticDataInitCriticalSectionLock lock;
1586 if(FAILED(lock.Lock()))
1587 {
1588 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::GetMessageLoop.\n"));
1589 ATLASSERT(FALSE);
1590 return NULL;
1591 }
1592
1593 CMessageLoop* pLoop = m_pMsgLoopMap->Lookup(dwThreadID);
1594
1595 lock.Unlock();
1596
1597 return pLoop;
1598 }
1599
1600 // Setting change notify methods
1601 // Note: Call this from the main thread for MSDI apps
1602 BOOL InitSettingChangeNotify(DLGPROC pfnDlgProc = _SettingChangeDlgProc)
1603 {
1604 CStaticDataInitCriticalSectionLock lock;
1605 if(FAILED(lock.Lock()))
1606 {
1607 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::InitSettingChangeNotify.\n"));
1608 ATLASSERT(FALSE);
1609 return FALSE;
1610 }
1611
1612 if(m_pSettingChangeNotify == NULL)
1613 {
1614 typedef ATL::CSimpleArray<HWND> _notifyClass;
1615 ATLTRY(m_pSettingChangeNotify = new _notifyClass);
1616 ATLASSERT(m_pSettingChangeNotify != NULL);
1617 }
1618
1619 BOOL bRet = (m_pSettingChangeNotify != NULL);
1620 if(bRet && m_pSettingChangeNotify->GetSize() == 0)
1621 {
1622 // init everything
1623 _ATL_EMPTY_DLGTEMPLATE templ;
1624 HWND hNtfWnd = ::CreateDialogIndirect(GetModuleInstance(), &templ, NULL, pfnDlgProc);
1625 ATLASSERT(::IsWindow(hNtfWnd));
1626 if(::IsWindow(hNtfWnd))
1627 {
1628 // need conditional code because types don't match in winuser.h
1629 #ifdef _WIN64
1630 ::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, (LONG_PTR)this);
1631 #else
1632 ::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, PtrToLong(this));
1633 #endif
1634 bRet = m_pSettingChangeNotify->Add(hNtfWnd);
1635 }
1636 else
1637 {
1638 bRet = FALSE;
1639 }
1640 }
1641
1642 lock.Unlock();
1643
1644 return bRet;
1645 }
1646
1647 void TermSettingChangeNotify()
1648 {
1649 CStaticDataInitCriticalSectionLock lock;
1650 if(FAILED(lock.Lock()))
1651 {
1652 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::TermSettingChangeNotify.\n"));
1653 ATLASSERT(FALSE);
1654 return;
1655 }
1656
1657 if(m_pSettingChangeNotify != NULL && m_pSettingChangeNotify->GetSize() > 0)
1658 ::DestroyWindow((*m_pSettingChangeNotify)[0]);
1659 delete m_pSettingChangeNotify;
1660 m_pSettingChangeNotify = NULL;
1661
1662 lock.Unlock();
1663 }
1664
1665 BOOL AddSettingChangeNotify(HWND hWnd)
1666 {
1667 CStaticDataInitCriticalSectionLock lock;
1668 if(FAILED(lock.Lock()))
1669 {
1670 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddSettingChangeNotify.\n"));
1671 ATLASSERT(FALSE);
1672 return FALSE;
1673 }
1674
1675 ATLASSERT(::IsWindow(hWnd));
1676 BOOL bRet = FALSE;
1677 if(InitSettingChangeNotify() != FALSE)
1678 bRet = m_pSettingChangeNotify->Add(hWnd);
1679
1680 lock.Unlock();
1681
1682 return bRet;
1683 }
1684
1685 BOOL RemoveSettingChangeNotify(HWND hWnd)
1686 {
1687 CStaticDataInitCriticalSectionLock lock;
1688 if(FAILED(lock.Lock()))
1689 {
1690 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveSettingChangeNotify.\n"));
1691 ATLASSERT(FALSE);
1692 return FALSE;
1693 }
1694
1695 BOOL bRet = FALSE;
1696 if(m_pSettingChangeNotify != NULL)
1697 bRet = m_pSettingChangeNotify->Remove(hWnd);
1698
1699 lock.Unlock();
1700
1701 return bRet;
1702 }
1703
1704 // Implementation - setting change notify dialog template and dialog procedure
1705 struct _ATL_EMPTY_DLGTEMPLATE : DLGTEMPLATE
1706 {
1707 _ATL_EMPTY_DLGTEMPLATE()
1708 {
1709 memset(this, 0, sizeof(_ATL_EMPTY_DLGTEMPLATE));
1710 style = WS_POPUP;
1711 }
1712 WORD wMenu, wClass, wTitle;
1713 };
1714
1715 #ifdef _WIN64
1716 static INT_PTR CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1717 #else
1718 static BOOL CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1719 #endif
1720 {
1721 if(uMsg == WM_SETTINGCHANGE)
1722 {
1723 // need conditional code because types don't match in winuser.h
1724 #ifdef _WIN64
1725 CAppModule* pModule = (CAppModule*)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
1726 #else
1727 CAppModule* pModule = (CAppModule*)LongToPtr(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
1728 #endif
1729 ATLASSERT(pModule != NULL);
1730 ATLASSERT(pModule->m_pSettingChangeNotify != NULL);
1731 const UINT uTimeout = 1500; // ms
1732 for(int i = 1; i < pModule->m_pSettingChangeNotify->GetSize(); i++)
1733 {
1734 #if !defined(_WIN32_WCE)
1735 ::SendMessageTimeout((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam, SMTO_ABORTIFHUNG, uTimeout, NULL);
1736 #elif(_WIN32_WCE >= 400) // CE specific
1737 ::SendMessageTimeout((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam, SMTO_NORMAL, uTimeout, NULL);
1738 #else // _WIN32_WCE < 400 specific
1739 uTimeout;
1740 ::SendMessage((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam);
1741 #endif
1742 }
1743 return TRUE;
1744 }
1745 return FALSE;
1746 }
1747 };
1748
1749
1750 ///////////////////////////////////////////////////////////////////////////////
1751 // CServerAppModule - module class for a COM server application
1752
1753 class CServerAppModule : public CAppModule
1754 {
1755 public:
1756 HANDLE m_hEventShutdown;
1757 bool m_bActivity;
1758 DWORD m_dwTimeOut;
1759 DWORD m_dwPause;
1760
1761 // Override of CAppModule::Init
1762 HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL)
1763 {
1764 m_dwTimeOut = 5000;
1765 m_dwPause = 1000;
1766 return CAppModule::Init(pObjMap, hInstance, pLibID);
1767 }
1768
1769 void Term()
1770 {
1771 if(m_hEventShutdown != NULL && ::CloseHandle(m_hEventShutdown))
1772 m_hEventShutdown = NULL;
1773 CAppModule::Term();
1774 }
1775
1776 // COM Server methods
1777 #if (_MSC_VER >= 1300)
1778 LONG Unlock() throw()
1779 #else
1780 LONG Unlock()
1781 #endif
1782 {
1783 LONG lRet = CComModule::Unlock();
1784 if(lRet == 0)
1785 {
1786 m_bActivity = true;
1787 ::SetEvent(m_hEventShutdown); // tell monitor that we transitioned to zero
1788 }
1789 return lRet;
1790 }
1791
1792 void MonitorShutdown()
1793 {
1794 for(;;)
1795 {
1796 ::WaitForSingleObject(m_hEventShutdown, INFINITE);
1797 DWORD dwWait = 0;
1798 do
1799 {
1800 m_bActivity = false;
1801 dwWait = ::WaitForSingleObject(m_hEventShutdown, m_dwTimeOut);
1802 }
1803 while(dwWait == WAIT_OBJECT_0);
1804 // timed out
1805 if(!m_bActivity && m_nLockCnt == 0) // if no activity let's really bail
1806 {
1807 #if ((_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM)) && defined(_ATL_FREE_THREADED) && !defined(_WIN32_WCE)
1808 ::CoSuspendClassObjects();
1809 if(!m_bActivity && m_nLockCnt == 0)
1810 #endif
1811 break;
1812 }
1813 }
1814 // This handle should be valid now. If it isn't,
1815 // check if _Module.Term was called first (it shouldn't)
1816 if(::CloseHandle(m_hEventShutdown))
1817 m_hEventShutdown = NULL;
1818 ::PostThreadMessage(m_dwMainThreadID, WM_QUIT, 0, 0);
1819 }
1820
1821 bool StartMonitor()
1822 {
1823 m_hEventShutdown = ::CreateEvent(NULL, false, false, NULL);
1824 if(m_hEventShutdown == NULL)
1825 return false;
1826 DWORD dwThreadID = 0;
1827 #if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE)
1828 HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, (UINT (WINAPI*)(void*))MonitorProc, this, 0, (UINT*)&dwThreadID);
1829 #else
1830 HANDLE hThread = ::CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID);
1831 #endif
1832 bool bRet = (hThread != NULL);
1833 if(bRet)
1834 ::CloseHandle(hThread);
1835 return bRet;
1836 }
1837
1838 static DWORD WINAPI MonitorProc(void* pv)
1839 {
1840 CServerAppModule* p = (CServerAppModule*)pv;
1841 p->MonitorShutdown();
1842 return 0;
1843 }
1844
1845 #if (_ATL_VER < 0x0700)
1846 // search for an occurence of string p2 in string p1
1847 static LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
1848 {
1849 while(p1 != NULL && *p1 != NULL)
1850 {
1851 LPCTSTR p = p2;
1852 while(p != NULL && *p != NULL)
1853 {
1854 if(*p1 == *p)
1855 return ::CharNext(p1);
1856 p = ::CharNext(p);
1857 }
1858 p1 = ::CharNext(p1);
1859 }
1860 return NULL;
1861 }
1862 #endif // (_ATL_VER < 0x0700)
1863 };
1864
1865
1866 ///////////////////////////////////////////////////////////////////////////////
1867 // CRegKeyEx - adds type-specific methods to ATL3 CRegKey
1868
1869 #if (_ATL_VER < 0x0700)
1870
1871 class CRegKeyEx : public ATL::CRegKey
1872 {
1873 public:
1874 // Constructors and operators
1875 CRegKeyEx(HKEY hKey = NULL)
1876 {
1877 m_hKey = hKey;
1878 }
1879
1880 CRegKeyEx(CRegKeyEx& key)
1881 {
1882 Attach(key.Detach());
1883 }
1884
1885 CRegKeyEx& operator =(CRegKeyEx& key)
1886 {
1887 Close();
1888 Attach(key.Detach());
1889 return *this;
1890 }
1891
1892 // Methods
1893 LONG SetValue(LPCTSTR pszValueName, DWORD dwType, const void* pValue, ULONG nBytes)
1894 {
1895 ATLASSERT(m_hKey != NULL);
1896 return ::RegSetValueEx(m_hKey, pszValueName, NULL, dwType, static_cast<const BYTE*>(pValue), nBytes);
1897 }
1898
1899 LONG SetGUIDValue(LPCTSTR pszValueName, REFGUID guidValue)
1900 {
1901 ATLASSERT(m_hKey != NULL);
1902
1903 OLECHAR szGUID[64] = { 0 };
1904 ::StringFromGUID2(guidValue, szGUID, 64);
1905
1906 USES_CONVERSION;
1907 LPCTSTR lpstr = OLE2CT(szGUID);
1908 #ifndef _UNICODE
1909 if(lpstr == NULL)
1910 return E_OUTOFMEMORY;
1911 #endif
1912 return SetStringValue(pszValueName, lpstr);
1913 }
1914
1915 LONG SetBinaryValue(LPCTSTR pszValueName, const void* pValue, ULONG nBytes)
1916 {
1917 ATLASSERT(m_hKey != NULL);
1918 return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_BINARY, reinterpret_cast<const BYTE*>(pValue), nBytes);
1919 }
1920
1921 LONG SetDWORDValue(LPCTSTR pszValueName, DWORD dwValue)
1922 {
1923 ATLASSERT(m_hKey != NULL);
1924 return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_DWORD, reinterpret_cast<const BYTE*>(&dwValue), sizeof(DWORD));
1925 }
1926
1927 #ifndef _WIN32_WCE
1928 LONG SetQWORDValue(LPCTSTR pszValueName, ULONGLONG qwValue)
1929 {
1930 ATLASSERT(m_hKey != NULL);
1931 return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_QWORD, reinterpret_cast<const BYTE*>(&qwValue), sizeof(ULONGLONG));
1932 }
1933 #endif
1934
1935 LONG SetStringValue(LPCTSTR pszValueName, LPCTSTR pszValue, DWORD dwType = REG_SZ)
1936 {
1937 ATLASSERT(m_hKey != NULL);
1938 if(pszValue == NULL)
1939 {
1940 ATLASSERT(FALSE);
1941 return ERROR_INVALID_DATA;
1942 }
1943 ATLASSERT((dwType == REG_SZ) || (dwType == REG_EXPAND_SZ));
1944
1945 return ::RegSetValueEx(m_hKey, pszValueName, NULL, dwType, reinterpret_cast<const BYTE*>(pszValue), (lstrlen(pszValue) + 1) * sizeof(TCHAR));
1946 }
1947
1948 LONG SetMultiStringValue(LPCTSTR pszValueName, LPCTSTR pszValue)
1949 {
1950 ATLASSERT(m_hKey != NULL);
1951 if(pszValue == NULL)
1952 {
1953 ATLASSERT(FALSE);
1954 return ERROR_INVALID_DATA;
1955 }
1956
1957 ULONG nBytes = 0;
1958 ULONG nLength = 0;
1959 LPCTSTR pszTemp = pszValue;
1960 do
1961 {
1962 nLength = lstrlen(pszTemp) + 1;
1963 pszTemp += nLength;
1964 nBytes += nLength * sizeof(TCHAR);
1965 } while (nLength != 1);
1966
1967 return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_MULTI_SZ, reinterpret_cast<const BYTE*>(pszValue), nBytes);
1968 }
1969
1970 LONG QueryValue(LPCTSTR pszValueName, DWORD* pdwType, void* pData, ULONG* pnBytes)
1971 {
1972 ATLASSERT(m_hKey != NULL);
1973 return ::RegQueryValueEx(m_hKey, pszValueName, NULL, pdwType, static_cast<LPBYTE>(pData), pnBytes);
1974 }
1975
1976 LONG QueryGUIDValue(LPCTSTR pszValueName, GUID& guidValue)
1977 {
1978 ATLASSERT(m_hKey != NULL);
1979
1980 guidValue = GUID_NULL;
1981
1982 TCHAR szGUID[64] = { 0 };
1983 ULONG nCount = 64;
1984 LONG lRes = QueryStringValue(pszValueName, szGUID, &nCount);
1985
1986 if (lRes != ERROR_SUCCESS)
1987 return lRes;
1988
1989 if(szGUID[0] != _T('{'))
1990 return ERROR_INVALID_DATA;
1991
1992 USES_CONVERSION;
1993 LPOLESTR lpstr = T2OLE(szGUID);
1994 #ifndef _UNICODE
1995 if(lpstr == NULL)
1996 return E_OUTOFMEMORY;
1997 #endif
1998
1999 HRESULT hr = ::CLSIDFromString(lpstr, &guidValue);
2000 if (FAILED(hr))
2001 return ERROR_INVALID_DATA;
2002
2003 return ERROR_SUCCESS;
2004 }
2005
2006 LONG QueryBinaryValue(LPCTSTR pszValueName, void* pValue, ULONG* pnBytes)
2007 {
2008 ATLASSERT(pnBytes != NULL);
2009 ATLASSERT(m_hKey != NULL);
2010
2011 DWORD dwType = 0;
2012 LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(pValue), pnBytes);
2013 if (lRes != ERROR_SUCCESS)
2014 return lRes;
2015 if (dwType != REG_BINARY)
2016 return ERROR_INVALID_DATA;
2017
2018 return ERROR_SUCCESS;
2019 }
2020
2021 LONG QueryDWORDValue(LPCTSTR pszValueName, DWORD& dwValue)
2022 {
2023 ATLASSERT(m_hKey != NULL);
2024
2025 ULONG nBytes = sizeof(DWORD);
2026 DWORD dwType = 0;
2027 LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(&dwValue), &nBytes);
2028 if (lRes != ERROR_SUCCESS)
2029 return lRes;
2030 if (dwType != REG_DWORD)
2031 return ERROR_INVALID_DATA;
2032
2033 return ERROR_SUCCESS;
2034 }
2035
2036 #ifndef _WIN32_WCE
2037 LONG QueryQWORDValue(LPCTSTR pszValueName, ULONGLONG& qwValue)
2038 {
2039 ATLASSERT(m_hKey != NULL);
2040
2041 ULONG nBytes = sizeof(ULONGLONG);
2042 DWORD dwType = 0;
2043 LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(&qwValue), &nBytes);
2044 if (lRes != ERROR_SUCCESS)
2045 return lRes;
2046 if (dwType != REG_QWORD)
2047 return ERROR_INVALID_DATA;
2048
2049 return ERROR_SUCCESS;
2050 }
2051 #endif
2052
2053 LONG QueryStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG* pnChars)
2054 {
2055 ATLASSERT(m_hKey != NULL);
2056 ATLASSERT(pnChars != NULL);
2057
2058 ULONG nBytes = (*pnChars) * sizeof(TCHAR);
2059 DWORD dwType = 0;
2060 *pnChars = 0;
2061 LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(pszValue), &nBytes);
2062
2063 if (lRes != ERROR_SUCCESS)
2064 {
2065 return lRes;
2066 }
2067
2068 if(dwType != REG_SZ && dwType != REG_EXPAND_SZ)
2069 {
2070 return ERROR_INVALID_DATA;
2071 }
2072
2073 if (pszValue != NULL)
2074 {
2075 if(nBytes != 0)
2076 {
2077 if ((nBytes % sizeof(TCHAR) != 0) || (pszValue[nBytes / sizeof(TCHAR) -1] != 0))
2078 return ERROR_INVALID_DATA;
2079 }
2080 else
2081 {
2082 pszValue[0] = _T('\0');
2083 }
2084 }
2085
2086 *pnChars = nBytes / sizeof(TCHAR);
2087
2088 return ERROR_SUCCESS;
2089 }
2090
2091 LONG QueryMultiStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG* pnChars)
2092 {
2093 ATLASSERT(m_hKey != NULL);
2094 ATLASSERT(pnChars != NULL);
2095
2096 if (pszValue != NULL && *pnChars < 2)
2097 return ERROR_INSUFFICIENT_BUFFER;
2098
2099 ULONG nBytes = (*pnChars) * sizeof(TCHAR);
2100 DWORD dwType = 0;
2101 *pnChars = 0;
2102 LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(pszValue), &nBytes);
2103 if (lRes != ERROR_SUCCESS)
2104 return lRes;
2105 if (dwType != REG_MULTI_SZ)
2106 return ERROR_INVALID_DATA;
2107 if (pszValue != NULL && (nBytes % sizeof(TCHAR) != 0 || nBytes / sizeof(TCHAR) < 1 || pszValue[nBytes / sizeof(TCHAR) - 1] != 0 || ((nBytes / sizeof(TCHAR)) > 1 && pszValue[nBytes / sizeof(TCHAR) - 2] != 0)))
2108 return ERROR_INVALID_DATA;
2109
2110 *pnChars = nBytes / sizeof(TCHAR);
2111
2112 return ERROR_SUCCESS;
2113 }
2114 };
2115
2116 #else // !(_ATL_VER < 0x0700)
2117
2118 typedef ATL::CRegKey CRegKeyEx;
2119
2120 #endif // !(_ATL_VER < 0x0700)
2121
2122
2123 ///////////////////////////////////////////////////////////////////////////////
2124 // CString forward reference (enables CString use in atluser.h and atlgdi.h)
2125
2126 #if defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING)
2127 #define _WTL_USE_CSTRING
2128 #endif // defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING)
2129
2130 #ifdef _WTL_USE_CSTRING
2131 class CString; // forward declaration (include atlmisc.h for the whole class)
2132 #endif // _WTL_USE_CSTRING
2133
2134 // CString namespace
2135 #ifndef _CSTRING_NS
2136 #ifdef __ATLSTR_H__
2137 #define _CSTRING_NS ATL
2138 #else
2139 #define _CSTRING_NS WTL
2140 #endif
2141 #endif // _CSTRING_NS
2142
2143 // Type classes namespace
2144 #ifndef _WTYPES_NS
2145 #ifdef __ATLTYPES_H__
2146 #define _WTYPES_NS
2147 #else
2148 #define _WTYPES_NS WTL
2149 #endif
2150 #endif // _WTYPES_NS
2151
2152 }; // namespace WTL
2153
2154
2155 ///////////////////////////////////////////////////////////////////////////////
2156 // General DLL version helpers
2157 // (ATL3: excluded from atlbase.h if _ATL_DLL is defined; ATL11: removed)
2158
2159 #if (((_ATL_VER < 0x0700) && defined(_ATL_DLL)) || (_ATL_VER >= 0x0B00)) && !defined(_WIN32_WCE)
2160
2161 namespace ATL
2162 {
2163
2164 inline HRESULT AtlGetDllVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionInfo)
2165 {
2166 ATLASSERT(pDllVersionInfo != NULL);
2167 if(pDllVersionInfo == NULL)
2168 return E_INVALIDARG;
2169
2170 // We must get this function explicitly because some DLLs don't implement it.
2171 DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress(hInstDLL, "DllGetVersion");
2172 if(pfnDllGetVersion == NULL)
2173 return E_NOTIMPL;
2174
2175 return (*pfnDllGetVersion)(pDllVersionInfo);
2176 }
2177
2178 inline HRESULT AtlGetDllVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersionInfo)
2179 {
2180 HINSTANCE hInstDLL = ::LoadLibrary(lpstrDllName);
2181 if(hInstDLL == NULL)
2182 return E_FAIL;
2183 HRESULT hRet = AtlGetDllVersion(hInstDLL, pDllVersionInfo);
2184 ::FreeLibrary(hInstDLL);
2185 return hRet;
2186 }
2187
2188 // Common Control Versions:
2189 // Win95/WinNT 4.0 maj=4 min=00
2190 // IE 3.x maj=4 min=70
2191 // IE 4.0 maj=4 min=71
2192 inline HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
2193 {
2194 ATLASSERT(pdwMajor != NULL && pdwMinor != NULL);
2195 if(pdwMajor == NULL || pdwMinor == NULL)
2196 return E_INVALIDARG;
2197
2198 DLLVERSIONINFO dvi;
2199 ::ZeroMemory(&dvi, sizeof(dvi));
2200 dvi.cbSize = sizeof(dvi);
2201 HRESULT hRet = AtlGetDllVersion(_T("comctl32.dll"), &dvi);
2202
2203 if(SUCCEEDED(hRet))
2204 {
2205 *pdwMajor = dvi.dwMajorVersion;
2206 *pdwMinor = dvi.dwMinorVersion;
2207 }
2208 else if(hRet == E_NOTIMPL)
2209 {
2210 // If DllGetVersion is not there, then the DLL is a version
2211 // previous to the one shipped with IE 3.x
2212 *pdwMajor = 4;
2213 *pdwMinor = 0;
2214 hRet = S_OK;
2215 }
2216
2217 return hRet;
2218 }
2219
2220 // Shell Versions:
2221 // Win95/WinNT 4.0 maj=4 min=00
2222 // IE 3.x, IE 4.0 without Web Integrated Desktop maj=4 min=00
2223 // IE 4.0 with Web Integrated Desktop maj=4 min=71
2224 // IE 4.01 with Web Integrated Desktop maj=4 min=72
2225 inline HRESULT AtlGetShellVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
2226 {
2227 ATLASSERT(pdwMajor != NULL && pdwMinor != NULL);
2228 if(pdwMajor == NULL || pdwMinor == NULL)
2229 return E_INVALIDARG;
2230
2231 DLLVERSIONINFO dvi;
2232 ::ZeroMemory(&dvi, sizeof(dvi));
2233 dvi.cbSize = sizeof(dvi);
2234 HRESULT hRet = AtlGetDllVersion(_T("shell32.dll"), &dvi);
2235
2236 if(SUCCEEDED(hRet))
2237 {
2238 *pdwMajor = dvi.dwMajorVersion;
2239 *pdwMinor = dvi.dwMinorVersion;
2240 }
2241 else if(hRet == E_NOTIMPL)
2242 {
2243 // If DllGetVersion is not there, then the DLL is a version
2244 // previous to the one shipped with IE 4.x
2245 *pdwMajor = 4;
2246 *pdwMinor = 0;
2247 hRet = S_OK;
2248 }
2249
2250 return hRet;
2251 }
2252
2253 }; // namespace ATL
2254
2255 #endif // (_ATL_VER < 0x0700) && defined(_ATL_DLL) && !defined(_WIN32_WCE)
2256
2257
2258 // These are always included
2259 #include "atlwinx.h"
2260 #include "atluser.h"
2261 #include "atlgdi.h"
2262
2263 #ifndef _WTL_NO_AUTOMATIC_NAMESPACE
2264 using namespace WTL;
2265 #endif // !_WTL_NO_AUTOMATIC_NAMESPACE
2266
2267 #endif // __ATLAPP_H__
+0
-2395
src/third_party/wtl/Include/atlcrack.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLCRACK_H__
9 #define __ATLCRACK_H__
10
11 #pragma once
12
13 #ifndef __ATLAPP_H__
14 #error atlcrack.h requires atlapp.h to be included first
15 #endif
16
17
18 ///////////////////////////////////////////////////////////////////////////////
19 // Message map macro for cracked handlers
20
21 // Note about message maps with cracked handlers:
22 // For ATL 3.0, a message map using cracked handlers MUST use BEGIN_MSG_MAP_EX.
23 // For ATL 7.0 or higher, you can use BEGIN_MSG_MAP for CWindowImpl/CDialogImpl derived classes,
24 // but must use BEGIN_MSG_MAP_EX for classes that don't derive from CWindowImpl/CDialogImpl.
25
26 #define BEGIN_MSG_MAP_EX(theClass) \
27 public: \
28 BOOL m_bMsgHandled; \
29 /* "handled" management for cracked handlers */ \
30 BOOL IsMsgHandled() const \
31 { \
32 return m_bMsgHandled; \
33 } \
34 void SetMsgHandled(BOOL bHandled) \
35 { \
36 m_bMsgHandled = bHandled; \
37 } \
38 BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0) \
39 { \
40 BOOL bOldMsgHandled = m_bMsgHandled; \
41 BOOL bRet = _ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, dwMsgMapID); \
42 m_bMsgHandled = bOldMsgHandled; \
43 return bRet; \
44 } \
45 BOOL _ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID) \
46 { \
47 BOOL bHandled = TRUE; \
48 (hWnd); \
49 (uMsg); \
50 (wParam); \
51 (lParam); \
52 (lResult); \
53 (bHandled); \
54 switch(dwMsgMapID) \
55 { \
56 case 0:
57
58
59 ///////////////////////////////////////////////////////////////////////////////
60 // Standard Windows message macros
61
62 // int OnCreate(LPCREATESTRUCT lpCreateStruct)
63 #define MSG_WM_CREATE(func) \
64 if (uMsg == WM_CREATE) \
65 { \
66 SetMsgHandled(TRUE); \
67 lResult = (LRESULT)func((LPCREATESTRUCT)lParam); \
68 if(IsMsgHandled()) \
69 return TRUE; \
70 }
71
72 // BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam)
73 #define MSG_WM_INITDIALOG(func) \
74 if (uMsg == WM_INITDIALOG) \
75 { \
76 SetMsgHandled(TRUE); \
77 lResult = (LRESULT)func((HWND)wParam, lParam); \
78 if(IsMsgHandled()) \
79 return TRUE; \
80 }
81
82 // BOOL OnCopyData(CWindow wnd, PCOPYDATASTRUCT pCopyDataStruct)
83 #define MSG_WM_COPYDATA(func) \
84 if (uMsg == WM_COPYDATA) \
85 { \
86 SetMsgHandled(TRUE); \
87 lResult = (LRESULT)func((HWND)wParam, (PCOPYDATASTRUCT)lParam); \
88 if(IsMsgHandled()) \
89 return TRUE; \
90 }
91
92 // void OnDestroy()
93 #define MSG_WM_DESTROY(func) \
94 if (uMsg == WM_DESTROY) \
95 { \
96 SetMsgHandled(TRUE); \
97 func(); \
98 lResult = 0; \
99 if(IsMsgHandled()) \
100 return TRUE; \
101 }
102
103 // void OnMove(CPoint ptPos)
104 #define MSG_WM_MOVE(func) \
105 if (uMsg == WM_MOVE) \
106 { \
107 SetMsgHandled(TRUE); \
108 func(_WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
109 lResult = 0; \
110 if(IsMsgHandled()) \
111 return TRUE; \
112 }
113
114 // void OnSize(UINT nType, CSize size)
115 #define MSG_WM_SIZE(func) \
116 if (uMsg == WM_SIZE) \
117 { \
118 SetMsgHandled(TRUE); \
119 func((UINT)wParam, _WTYPES_NS::CSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
120 lResult = 0; \
121 if(IsMsgHandled()) \
122 return TRUE; \
123 }
124
125 // void OnActivate(UINT nState, BOOL bMinimized, CWindow wndOther)
126 #define MSG_WM_ACTIVATE(func) \
127 if (uMsg == WM_ACTIVATE) \
128 { \
129 SetMsgHandled(TRUE); \
130 func((UINT)LOWORD(wParam), (BOOL)HIWORD(wParam), (HWND)lParam); \
131 lResult = 0; \
132 if(IsMsgHandled()) \
133 return TRUE; \
134 }
135
136 // void OnSetFocus(CWindow wndOld)
137 #define MSG_WM_SETFOCUS(func) \
138 if (uMsg == WM_SETFOCUS) \
139 { \
140 SetMsgHandled(TRUE); \
141 func((HWND)wParam); \
142 lResult = 0; \
143 if(IsMsgHandled()) \
144 return TRUE; \
145 }
146
147 // void OnKillFocus(CWindow wndFocus)
148 #define MSG_WM_KILLFOCUS(func) \
149 if (uMsg == WM_KILLFOCUS) \
150 { \
151 SetMsgHandled(TRUE); \
152 func((HWND)wParam); \
153 lResult = 0; \
154 if(IsMsgHandled()) \
155 return TRUE; \
156 }
157
158 // void OnEnable(BOOL bEnable)
159 #define MSG_WM_ENABLE(func) \
160 if (uMsg == WM_ENABLE) \
161 { \
162 SetMsgHandled(TRUE); \
163 func((BOOL)wParam); \
164 lResult = 0; \
165 if(IsMsgHandled()) \
166 return TRUE; \
167 }
168
169 // void OnPaint(CDCHandle dc)
170 #define MSG_WM_PAINT(func) \
171 if (uMsg == WM_PAINT) \
172 { \
173 SetMsgHandled(TRUE); \
174 func((HDC)wParam); \
175 lResult = 0; \
176 if(IsMsgHandled()) \
177 return TRUE; \
178 }
179
180 // void OnClose()
181 #define MSG_WM_CLOSE(func) \
182 if (uMsg == WM_CLOSE) \
183 { \
184 SetMsgHandled(TRUE); \
185 func(); \
186 lResult = 0; \
187 if(IsMsgHandled()) \
188 return TRUE; \
189 }
190
191 // BOOL OnQueryEndSession(UINT nSource, UINT uLogOff)
192 #define MSG_WM_QUERYENDSESSION(func) \
193 if (uMsg == WM_QUERYENDSESSION) \
194 { \
195 SetMsgHandled(TRUE); \
196 lResult = (LRESULT)func((UINT)wParam, (UINT)lParam); \
197 if(IsMsgHandled()) \
198 return TRUE; \
199 }
200
201 // BOOL OnQueryOpen()
202 #define MSG_WM_QUERYOPEN(func) \
203 if (uMsg == WM_QUERYOPEN) \
204 { \
205 SetMsgHandled(TRUE); \
206 lResult = (LRESULT)func(); \
207 if(IsMsgHandled()) \
208 return TRUE; \
209 }
210
211 // BOOL OnEraseBkgnd(CDCHandle dc)
212 #define MSG_WM_ERASEBKGND(func) \
213 if (uMsg == WM_ERASEBKGND) \
214 { \
215 SetMsgHandled(TRUE); \
216 lResult = (LRESULT)func((HDC)wParam); \
217 if(IsMsgHandled()) \
218 return TRUE; \
219 }
220
221 // void OnSysColorChange()
222 #define MSG_WM_SYSCOLORCHANGE(func) \
223 if (uMsg == WM_SYSCOLORCHANGE) \
224 { \
225 SetMsgHandled(TRUE); \
226 func(); \
227 lResult = 0; \
228 if(IsMsgHandled()) \
229 return TRUE; \
230 }
231
232 // void OnEndSession(BOOL bEnding, UINT uLogOff)
233 #define MSG_WM_ENDSESSION(func) \
234 if (uMsg == WM_ENDSESSION) \
235 { \
236 SetMsgHandled(TRUE); \
237 func((BOOL)wParam, (UINT)lParam); \
238 lResult = 0; \
239 if(IsMsgHandled()) \
240 return TRUE; \
241 }
242
243 // void OnShowWindow(BOOL bShow, UINT nStatus)
244 #define MSG_WM_SHOWWINDOW(func) \
245 if (uMsg == WM_SHOWWINDOW) \
246 { \
247 SetMsgHandled(TRUE); \
248 func((BOOL)wParam, (int)lParam); \
249 lResult = 0; \
250 if(IsMsgHandled()) \
251 return TRUE; \
252 }
253
254 // HBRUSH OnCtlColorEdit(CDCHandle dc, CEdit edit)
255 #define MSG_WM_CTLCOLOREDIT(func) \
256 if (uMsg == WM_CTLCOLOREDIT) \
257 { \
258 SetMsgHandled(TRUE); \
259 lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \
260 if(IsMsgHandled()) \
261 return TRUE; \
262 }
263
264 // HBRUSH OnCtlColorListBox(CDCHandle dc, CListBox listBox)
265 #define MSG_WM_CTLCOLORLISTBOX(func) \
266 if (uMsg == WM_CTLCOLORLISTBOX) \
267 { \
268 SetMsgHandled(TRUE); \
269 lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \
270 if(IsMsgHandled()) \
271 return TRUE; \
272 }
273
274 // HBRUSH OnCtlColorBtn(CDCHandle dc, CButton button)
275 #define MSG_WM_CTLCOLORBTN(func) \
276 if (uMsg == WM_CTLCOLORBTN) \
277 { \
278 SetMsgHandled(TRUE); \
279 lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \
280 if(IsMsgHandled()) \
281 return TRUE; \
282 }
283
284 // HBRUSH OnCtlColorDlg(CDCHandle dc, CWindow wnd)
285 #define MSG_WM_CTLCOLORDLG(func) \
286 if (uMsg == WM_CTLCOLORDLG) \
287 { \
288 SetMsgHandled(TRUE); \
289 lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \
290 if(IsMsgHandled()) \
291 return TRUE; \
292 }
293
294 // HBRUSH OnCtlColorScrollBar(CDCHandle dc, CScrollBar scrollBar)
295 #define MSG_WM_CTLCOLORSCROLLBAR(func) \
296 if (uMsg == WM_CTLCOLORSCROLLBAR) \
297 { \
298 SetMsgHandled(TRUE); \
299 lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \
300 if(IsMsgHandled()) \
301 return TRUE; \
302 }
303
304 // HBRUSH OnCtlColorStatic(CDCHandle dc, CStatic wndStatic)
305 #define MSG_WM_CTLCOLORSTATIC(func) \
306 if (uMsg == WM_CTLCOLORSTATIC) \
307 { \
308 SetMsgHandled(TRUE); \
309 lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \
310 if(IsMsgHandled()) \
311 return TRUE; \
312 }
313
314 // void OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
315 #define MSG_WM_SETTINGCHANGE(func) \
316 if (uMsg == WM_SETTINGCHANGE) \
317 { \
318 SetMsgHandled(TRUE); \
319 func((UINT)wParam, (LPCTSTR)lParam); \
320 lResult = 0; \
321 if(IsMsgHandled()) \
322 return TRUE; \
323 }
324
325 // void OnDevModeChange(LPCTSTR lpDeviceName)
326 #define MSG_WM_DEVMODECHANGE(func) \
327 if (uMsg == WM_DEVMODECHANGE) \
328 { \
329 SetMsgHandled(TRUE); \
330 func((LPCTSTR)lParam); \
331 lResult = 0; \
332 if(IsMsgHandled()) \
333 return TRUE; \
334 }
335
336 // void OnActivateApp(BOOL bActive, DWORD dwThreadID)
337 #define MSG_WM_ACTIVATEAPP(func) \
338 if (uMsg == WM_ACTIVATEAPP) \
339 { \
340 SetMsgHandled(TRUE); \
341 func((BOOL)wParam, (DWORD)lParam); \
342 lResult = 0; \
343 if(IsMsgHandled()) \
344 return TRUE; \
345 }
346
347 // void OnFontChange()
348 #define MSG_WM_FONTCHANGE(func) \
349 if (uMsg == WM_FONTCHANGE) \
350 { \
351 SetMsgHandled(TRUE); \
352 func(); \
353 lResult = 0; \
354 if(IsMsgHandled()) \
355 return TRUE; \
356 }
357
358 // void OnTimeChange()
359 #define MSG_WM_TIMECHANGE(func) \
360 if (uMsg == WM_TIMECHANGE) \
361 { \
362 SetMsgHandled(TRUE); \
363 func(); \
364 lResult = 0; \
365 if(IsMsgHandled()) \
366 return TRUE; \
367 }
368
369 // void OnCancelMode()
370 #define MSG_WM_CANCELMODE(func) \
371 if (uMsg == WM_CANCELMODE) \
372 { \
373 SetMsgHandled(TRUE); \
374 func(); \
375 lResult = 0; \
376 if(IsMsgHandled()) \
377 return TRUE; \
378 }
379
380 // BOOL OnSetCursor(CWindow wnd, UINT nHitTest, UINT message)
381 #define MSG_WM_SETCURSOR(func) \
382 if (uMsg == WM_SETCURSOR) \
383 { \
384 SetMsgHandled(TRUE); \
385 lResult = (LRESULT)func((HWND)wParam, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); \
386 if(IsMsgHandled()) \
387 return TRUE; \
388 }
389
390 // int OnMouseActivate(CWindow wndTopLevel, UINT nHitTest, UINT message)
391 #define MSG_WM_MOUSEACTIVATE(func) \
392 if (uMsg == WM_MOUSEACTIVATE) \
393 { \
394 SetMsgHandled(TRUE); \
395 lResult = (LRESULT)func((HWND)wParam, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); \
396 if(IsMsgHandled()) \
397 return TRUE; \
398 }
399
400 // void OnChildActivate()
401 #define MSG_WM_CHILDACTIVATE(func) \
402 if (uMsg == WM_CHILDACTIVATE) \
403 { \
404 SetMsgHandled(TRUE); \
405 func(); \
406 lResult = 0; \
407 if(IsMsgHandled()) \
408 return TRUE; \
409 }
410
411 // void OnGetMinMaxInfo(LPMINMAXINFO lpMMI)
412 #define MSG_WM_GETMINMAXINFO(func) \
413 if (uMsg == WM_GETMINMAXINFO) \
414 { \
415 SetMsgHandled(TRUE); \
416 func((LPMINMAXINFO)lParam); \
417 lResult = 0; \
418 if(IsMsgHandled()) \
419 return TRUE; \
420 }
421
422 // void OnIconEraseBkgnd(CDCHandle dc)
423 #define MSG_WM_ICONERASEBKGND(func) \
424 if (uMsg == WM_ICONERASEBKGND) \
425 { \
426 SetMsgHandled(TRUE); \
427 func((HDC)wParam); \
428 lResult = 0; \
429 if(IsMsgHandled()) \
430 return TRUE; \
431 }
432
433 // void OnSpoolerStatus(UINT nStatus, UINT nJobs)
434 #define MSG_WM_SPOOLERSTATUS(func) \
435 if (uMsg == WM_SPOOLERSTATUS) \
436 { \
437 SetMsgHandled(TRUE); \
438 func((UINT)wParam, (UINT)LOWORD(lParam)); \
439 lResult = 0; \
440 if(IsMsgHandled()) \
441 return TRUE; \
442 }
443
444 // void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
445 #define MSG_WM_DRAWITEM(func) \
446 if (uMsg == WM_DRAWITEM) \
447 { \
448 SetMsgHandled(TRUE); \
449 func((UINT)wParam, (LPDRAWITEMSTRUCT)lParam); \
450 lResult = TRUE; \
451 if(IsMsgHandled()) \
452 return TRUE; \
453 }
454
455 // void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
456 #define MSG_WM_MEASUREITEM(func) \
457 if (uMsg == WM_MEASUREITEM) \
458 { \
459 SetMsgHandled(TRUE); \
460 func((UINT)wParam, (LPMEASUREITEMSTRUCT)lParam); \
461 lResult = TRUE; \
462 if(IsMsgHandled()) \
463 return TRUE; \
464 }
465
466 // void OnDeleteItem(int nIDCtl, LPDELETEITEMSTRUCT lpDeleteItemStruct)
467 #define MSG_WM_DELETEITEM(func) \
468 if (uMsg == WM_DELETEITEM) \
469 { \
470 SetMsgHandled(TRUE); \
471 func((UINT)wParam, (LPDELETEITEMSTRUCT)lParam); \
472 lResult = TRUE; \
473 if(IsMsgHandled()) \
474 return TRUE; \
475 }
476
477 //int OnCharToItem(UINT nChar, UINT nIndex, CListBox listBox)
478 #define MSG_WM_CHARTOITEM(func) \
479 if (uMsg == WM_CHARTOITEM) \
480 { \
481 SetMsgHandled(TRUE); \
482 lResult = (LRESULT)func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), (HWND)lParam); \
483 if(IsMsgHandled()) \
484 return TRUE; \
485 }
486
487 // int OnVKeyToItem(UINT nKey, UINT nIndex, CListBox listBox)
488 #define MSG_WM_VKEYTOITEM(func) \
489 if (uMsg == WM_VKEYTOITEM) \
490 { \
491 SetMsgHandled(TRUE); \
492 lResult = (LRESULT)func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), (HWND)lParam); \
493 if(IsMsgHandled()) \
494 return TRUE; \
495 }
496
497 // HCURSOR OnQueryDragIcon()
498 #define MSG_WM_QUERYDRAGICON(func) \
499 if (uMsg == WM_QUERYDRAGICON) \
500 { \
501 SetMsgHandled(TRUE); \
502 lResult = (LRESULT)func(); \
503 if(IsMsgHandled()) \
504 return TRUE; \
505 }
506
507 // int OnCompareItem(int nIDCtl, LPCOMPAREITEMSTRUCT lpCompareItemStruct)
508 #define MSG_WM_COMPAREITEM(func) \
509 if (uMsg == WM_COMPAREITEM) \
510 { \
511 SetMsgHandled(TRUE); \
512 lResult = (LRESULT)func((UINT)wParam, (LPCOMPAREITEMSTRUCT)lParam); \
513 if(IsMsgHandled()) \
514 return TRUE; \
515 }
516
517 // void OnCompacting(UINT nCpuTime)
518 #define MSG_WM_COMPACTING(func) \
519 if (uMsg == WM_COMPACTING) \
520 { \
521 SetMsgHandled(TRUE); \
522 func((UINT)wParam); \
523 lResult = 0; \
524 if(IsMsgHandled()) \
525 return TRUE; \
526 }
527
528 // BOOL OnNcCreate(LPCREATESTRUCT lpCreateStruct)
529 #define MSG_WM_NCCREATE(func) \
530 if (uMsg == WM_NCCREATE) \
531 { \
532 SetMsgHandled(TRUE); \
533 lResult = (LRESULT)func((LPCREATESTRUCT)lParam); \
534 if(IsMsgHandled()) \
535 return TRUE; \
536 }
537
538 // void OnNcDestroy()
539 #define MSG_WM_NCDESTROY(func) \
540 if (uMsg == WM_NCDESTROY) \
541 { \
542 SetMsgHandled(TRUE); \
543 func(); \
544 lResult = 0; \
545 if(IsMsgHandled()) \
546 return TRUE; \
547 }
548
549 // LRESULT OnNcCalcSize(BOOL bCalcValidRects, LPARAM lParam)
550 #define MSG_WM_NCCALCSIZE(func) \
551 if (uMsg == WM_NCCALCSIZE) \
552 { \
553 SetMsgHandled(TRUE); \
554 lResult = func((BOOL)wParam, lParam); \
555 if(IsMsgHandled()) \
556 return TRUE; \
557 }
558
559 // UINT OnNcHitTest(CPoint point)
560 #define MSG_WM_NCHITTEST(func) \
561 if (uMsg == WM_NCHITTEST) \
562 { \
563 SetMsgHandled(TRUE); \
564 lResult = (LRESULT)func(_WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
565 if(IsMsgHandled()) \
566 return TRUE; \
567 }
568
569 // void OnNcPaint(CRgnHandle rgn)
570 #define MSG_WM_NCPAINT(func) \
571 if (uMsg == WM_NCPAINT) \
572 { \
573 SetMsgHandled(TRUE); \
574 func((HRGN)wParam); \
575 lResult = 0; \
576 if(IsMsgHandled()) \
577 return TRUE; \
578 }
579
580 // BOOL OnNcActivate(BOOL bActive)
581 #define MSG_WM_NCACTIVATE(func) \
582 if (uMsg == WM_NCACTIVATE) \
583 { \
584 SetMsgHandled(TRUE); \
585 lResult = (LRESULT)func((BOOL)wParam); \
586 if(IsMsgHandled()) \
587 return TRUE; \
588 }
589
590 // UINT OnGetDlgCode(LPMSG lpMsg)
591 #define MSG_WM_GETDLGCODE(func) \
592 if (uMsg == WM_GETDLGCODE) \
593 { \
594 SetMsgHandled(TRUE); \
595 lResult = (LRESULT)func((LPMSG)lParam); \
596 if(IsMsgHandled()) \
597 return TRUE; \
598 }
599
600 // void OnNcMouseMove(UINT nHitTest, CPoint point)
601 #define MSG_WM_NCMOUSEMOVE(func) \
602 if (uMsg == WM_NCMOUSEMOVE) \
603 { \
604 SetMsgHandled(TRUE); \
605 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
606 lResult = 0; \
607 if(IsMsgHandled()) \
608 return TRUE; \
609 }
610
611 // void OnNcLButtonDown(UINT nHitTest, CPoint point)
612 #define MSG_WM_NCLBUTTONDOWN(func) \
613 if (uMsg == WM_NCLBUTTONDOWN) \
614 { \
615 SetMsgHandled(TRUE); \
616 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
617 lResult = 0; \
618 if(IsMsgHandled()) \
619 return TRUE; \
620 }
621
622 // void OnNcLButtonUp(UINT nHitTest, CPoint point)
623 #define MSG_WM_NCLBUTTONUP(func) \
624 if (uMsg == WM_NCLBUTTONUP) \
625 { \
626 SetMsgHandled(TRUE); \
627 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
628 lResult = 0; \
629 if(IsMsgHandled()) \
630 return TRUE; \
631 }
632
633 // void OnNcLButtonDblClk(UINT nHitTest, CPoint point)
634 #define MSG_WM_NCLBUTTONDBLCLK(func) \
635 if (uMsg == WM_NCLBUTTONDBLCLK) \
636 { \
637 SetMsgHandled(TRUE); \
638 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
639 lResult = 0; \
640 if(IsMsgHandled()) \
641 return TRUE; \
642 }
643
644 // void OnNcRButtonDown(UINT nHitTest, CPoint point)
645 #define MSG_WM_NCRBUTTONDOWN(func) \
646 if (uMsg == WM_NCRBUTTONDOWN) \
647 { \
648 SetMsgHandled(TRUE); \
649 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
650 lResult = 0; \
651 if(IsMsgHandled()) \
652 return TRUE; \
653 }
654
655 // void OnNcRButtonUp(UINT nHitTest, CPoint point)
656 #define MSG_WM_NCRBUTTONUP(func) \
657 if (uMsg == WM_NCRBUTTONUP) \
658 { \
659 SetMsgHandled(TRUE); \
660 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
661 lResult = 0; \
662 if(IsMsgHandled()) \
663 return TRUE; \
664 }
665
666 // void OnNcRButtonDblClk(UINT nHitTest, CPoint point)
667 #define MSG_WM_NCRBUTTONDBLCLK(func) \
668 if (uMsg == WM_NCRBUTTONDBLCLK) \
669 { \
670 SetMsgHandled(TRUE); \
671 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
672 lResult = 0; \
673 if(IsMsgHandled()) \
674 return TRUE; \
675 }
676
677 // void OnNcMButtonDown(UINT nHitTest, CPoint point)
678 #define MSG_WM_NCMBUTTONDOWN(func) \
679 if (uMsg == WM_NCMBUTTONDOWN) \
680 { \
681 SetMsgHandled(TRUE); \
682 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
683 lResult = 0; \
684 if(IsMsgHandled()) \
685 return TRUE; \
686 }
687
688 // void OnNcMButtonUp(UINT nHitTest, CPoint point)
689 #define MSG_WM_NCMBUTTONUP(func) \
690 if (uMsg == WM_NCMBUTTONUP) \
691 { \
692 SetMsgHandled(TRUE); \
693 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
694 lResult = 0; \
695 if(IsMsgHandled()) \
696 return TRUE; \
697 }
698
699 // void OnNcMButtonDblClk(UINT nHitTest, CPoint point)
700 #define MSG_WM_NCMBUTTONDBLCLK(func) \
701 if (uMsg == WM_NCMBUTTONDBLCLK) \
702 { \
703 SetMsgHandled(TRUE); \
704 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
705 lResult = 0; \
706 if(IsMsgHandled()) \
707 return TRUE; \
708 }
709
710 // void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
711 #define MSG_WM_KEYDOWN(func) \
712 if (uMsg == WM_KEYDOWN) \
713 { \
714 SetMsgHandled(TRUE); \
715 func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \
716 lResult = 0; \
717 if(IsMsgHandled()) \
718 return TRUE; \
719 }
720
721 // void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
722 #define MSG_WM_KEYUP(func) \
723 if (uMsg == WM_KEYUP) \
724 { \
725 SetMsgHandled(TRUE); \
726 func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \
727 lResult = 0; \
728 if(IsMsgHandled()) \
729 return TRUE; \
730 }
731
732 // void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
733 #define MSG_WM_CHAR(func) \
734 if (uMsg == WM_CHAR) \
735 { \
736 SetMsgHandled(TRUE); \
737 func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \
738 lResult = 0; \
739 if(IsMsgHandled()) \
740 return TRUE; \
741 }
742
743 // void OnDeadChar(UINT nChar, UINT nRepCnt, UINT nFlags)
744 #define MSG_WM_DEADCHAR(func) \
745 if (uMsg == WM_DEADCHAR) \
746 { \
747 SetMsgHandled(TRUE); \
748 func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \
749 lResult = 0; \
750 if(IsMsgHandled()) \
751 return TRUE; \
752 }
753
754 // void OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
755 #define MSG_WM_SYSKEYDOWN(func) \
756 if (uMsg == WM_SYSKEYDOWN) \
757 { \
758 SetMsgHandled(TRUE); \
759 func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \
760 lResult = 0; \
761 if(IsMsgHandled()) \
762 return TRUE; \
763 }
764
765 // void OnSysKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
766 #define MSG_WM_SYSKEYUP(func) \
767 if (uMsg == WM_SYSKEYUP) \
768 { \
769 SetMsgHandled(TRUE); \
770 func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \
771 lResult = 0; \
772 if(IsMsgHandled()) \
773 return TRUE; \
774 }
775
776 // void OnSysChar(UINT nChar, UINT nRepCnt, UINT nFlags)
777 #define MSG_WM_SYSCHAR(func) \
778 if (uMsg == WM_SYSCHAR) \
779 { \
780 SetMsgHandled(TRUE); \
781 func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \
782 lResult = 0; \
783 if(IsMsgHandled()) \
784 return TRUE; \
785 }
786
787 // void OnSysDeadChar(UINT nChar, UINT nRepCnt, UINT nFlags)
788 #define MSG_WM_SYSDEADCHAR(func) \
789 if (uMsg == WM_SYSDEADCHAR) \
790 { \
791 SetMsgHandled(TRUE); \
792 func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \
793 lResult = 0; \
794 if(IsMsgHandled()) \
795 return TRUE; \
796 }
797
798 // void OnSysCommand(UINT nID, CPoint point)
799 #define MSG_WM_SYSCOMMAND(func) \
800 if (uMsg == WM_SYSCOMMAND) \
801 { \
802 SetMsgHandled(TRUE); \
803 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
804 lResult = 0; \
805 if(IsMsgHandled()) \
806 return TRUE; \
807 }
808
809 // void OnTCard(UINT idAction, DWORD dwActionData)
810 #define MSG_WM_TCARD(func) \
811 if (uMsg == WM_TCARD) \
812 { \
813 SetMsgHandled(TRUE); \
814 func((UINT)wParam, (DWORD)lParam); \
815 lResult = 0; \
816 if(IsMsgHandled()) \
817 return TRUE; \
818 }
819
820 // void OnTimer(UINT_PTR nIDEvent)
821 #define MSG_WM_TIMER(func) \
822 if (uMsg == WM_TIMER) \
823 { \
824 SetMsgHandled(TRUE); \
825 func((UINT_PTR)wParam); \
826 lResult = 0; \
827 if(IsMsgHandled()) \
828 return TRUE; \
829 }
830
831 // void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar)
832 #define MSG_WM_HSCROLL(func) \
833 if (uMsg == WM_HSCROLL) \
834 { \
835 SetMsgHandled(TRUE); \
836 func((int)LOWORD(wParam), (short)HIWORD(wParam), (HWND)lParam); \
837 lResult = 0; \
838 if(IsMsgHandled()) \
839 return TRUE; \
840 }
841
842 // void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar)
843 #define MSG_WM_VSCROLL(func) \
844 if (uMsg == WM_VSCROLL) \
845 { \
846 SetMsgHandled(TRUE); \
847 func((int)LOWORD(wParam), (short)HIWORD(wParam), (HWND)lParam); \
848 lResult = 0; \
849 if(IsMsgHandled()) \
850 return TRUE; \
851 }
852
853 // void OnInitMenu(CMenuHandle menu)
854 #define MSG_WM_INITMENU(func) \
855 if (uMsg == WM_INITMENU) \
856 { \
857 SetMsgHandled(TRUE); \
858 func((HMENU)wParam); \
859 lResult = 0; \
860 if(IsMsgHandled()) \
861 return TRUE; \
862 }
863
864 // void OnInitMenuPopup(CMenuHandle menuPopup, UINT nIndex, BOOL bSysMenu)
865 #define MSG_WM_INITMENUPOPUP(func) \
866 if (uMsg == WM_INITMENUPOPUP) \
867 { \
868 SetMsgHandled(TRUE); \
869 func((HMENU)wParam, (UINT)LOWORD(lParam), (BOOL)HIWORD(lParam)); \
870 lResult = 0; \
871 if(IsMsgHandled()) \
872 return TRUE; \
873 }
874
875 // void OnMenuSelect(UINT nItemID, UINT nFlags, CMenuHandle menu)
876 #define MSG_WM_MENUSELECT(func) \
877 if (uMsg == WM_MENUSELECT) \
878 { \
879 SetMsgHandled(TRUE); \
880 func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), (HMENU)lParam); \
881 lResult = 0; \
882 if(IsMsgHandled()) \
883 return TRUE; \
884 }
885
886 // LRESULT OnMenuChar(UINT nChar, UINT nFlags, CMenuHandle menu)
887 #define MSG_WM_MENUCHAR(func) \
888 if (uMsg == WM_MENUCHAR) \
889 { \
890 SetMsgHandled(TRUE); \
891 lResult = func((TCHAR)LOWORD(wParam), (UINT)HIWORD(wParam), (HMENU)lParam); \
892 if(IsMsgHandled()) \
893 return TRUE; \
894 }
895
896 // LRESULT OnNotify(int idCtrl, LPNMHDR pnmh)
897 #define MSG_WM_NOTIFY(func) \
898 if (uMsg == WM_NOTIFY) \
899 { \
900 SetMsgHandled(TRUE); \
901 lResult = func((int)wParam, (LPNMHDR)lParam); \
902 if(IsMsgHandled()) \
903 return TRUE; \
904 }
905
906 // void OnEnterIdle(UINT nWhy, CWindow wndWho)
907 #define MSG_WM_ENTERIDLE(func) \
908 if (uMsg == WM_ENTERIDLE) \
909 { \
910 SetMsgHandled(TRUE); \
911 func((UINT)wParam, (HWND)lParam); \
912 lResult = 0; \
913 if(IsMsgHandled()) \
914 return TRUE; \
915 }
916
917 // void OnMouseMove(UINT nFlags, CPoint point)
918 #define MSG_WM_MOUSEMOVE(func) \
919 if (uMsg == WM_MOUSEMOVE) \
920 { \
921 SetMsgHandled(TRUE); \
922 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
923 lResult = 0; \
924 if(IsMsgHandled()) \
925 return TRUE; \
926 }
927
928 // BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
929 #define MSG_WM_MOUSEWHEEL(func) \
930 if (uMsg == WM_MOUSEWHEEL) \
931 { \
932 SetMsgHandled(TRUE); \
933 lResult = (LRESULT)func((UINT)LOWORD(wParam), (short)HIWORD(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
934 if(IsMsgHandled()) \
935 return TRUE; \
936 }
937
938 // void OnLButtonDown(UINT nFlags, CPoint point)
939 #define MSG_WM_LBUTTONDOWN(func) \
940 if (uMsg == WM_LBUTTONDOWN) \
941 { \
942 SetMsgHandled(TRUE); \
943 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
944 lResult = 0; \
945 if(IsMsgHandled()) \
946 return TRUE; \
947 }
948
949 // void OnLButtonUp(UINT nFlags, CPoint point)
950 #define MSG_WM_LBUTTONUP(func) \
951 if (uMsg == WM_LBUTTONUP) \
952 { \
953 SetMsgHandled(TRUE); \
954 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
955 lResult = 0; \
956 if(IsMsgHandled()) \
957 return TRUE; \
958 }
959
960 // void OnLButtonDblClk(UINT nFlags, CPoint point)
961 #define MSG_WM_LBUTTONDBLCLK(func) \
962 if (uMsg == WM_LBUTTONDBLCLK) \
963 { \
964 SetMsgHandled(TRUE); \
965 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
966 lResult = 0; \
967 if(IsMsgHandled()) \
968 return TRUE; \
969 }
970
971 // void OnRButtonDown(UINT nFlags, CPoint point)
972 #define MSG_WM_RBUTTONDOWN(func) \
973 if (uMsg == WM_RBUTTONDOWN) \
974 { \
975 SetMsgHandled(TRUE); \
976 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
977 lResult = 0; \
978 if(IsMsgHandled()) \
979 return TRUE; \
980 }
981
982 // void OnRButtonUp(UINT nFlags, CPoint point)
983 #define MSG_WM_RBUTTONUP(func) \
984 if (uMsg == WM_RBUTTONUP) \
985 { \
986 SetMsgHandled(TRUE); \
987 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
988 lResult = 0; \
989 if(IsMsgHandled()) \
990 return TRUE; \
991 }
992
993 // void OnRButtonDblClk(UINT nFlags, CPoint point)
994 #define MSG_WM_RBUTTONDBLCLK(func) \
995 if (uMsg == WM_RBUTTONDBLCLK) \
996 { \
997 SetMsgHandled(TRUE); \
998 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
999 lResult = 0; \
1000 if(IsMsgHandled()) \
1001 return TRUE; \
1002 }
1003
1004 // void OnMButtonDown(UINT nFlags, CPoint point)
1005 #define MSG_WM_MBUTTONDOWN(func) \
1006 if (uMsg == WM_MBUTTONDOWN) \
1007 { \
1008 SetMsgHandled(TRUE); \
1009 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
1010 lResult = 0; \
1011 if(IsMsgHandled()) \
1012 return TRUE; \
1013 }
1014
1015 // void OnMButtonUp(UINT nFlags, CPoint point)
1016 #define MSG_WM_MBUTTONUP(func) \
1017 if (uMsg == WM_MBUTTONUP) \
1018 { \
1019 SetMsgHandled(TRUE); \
1020 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
1021 lResult = 0; \
1022 if(IsMsgHandled()) \
1023 return TRUE; \
1024 }
1025
1026 // void OnMButtonDblClk(UINT nFlags, CPoint point)
1027 #define MSG_WM_MBUTTONDBLCLK(func) \
1028 if (uMsg == WM_MBUTTONDBLCLK) \
1029 { \
1030 SetMsgHandled(TRUE); \
1031 func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
1032 lResult = 0; \
1033 if(IsMsgHandled()) \
1034 return TRUE; \
1035 }
1036
1037 // void OnParentNotify(UINT message, UINT nChildID, LPARAM lParam)
1038 #define MSG_WM_PARENTNOTIFY(func) \
1039 if (uMsg == WM_PARENTNOTIFY) \
1040 { \
1041 SetMsgHandled(TRUE); \
1042 func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), lParam); \
1043 lResult = 0; \
1044 if(IsMsgHandled()) \
1045 return TRUE; \
1046 }
1047
1048 // void OnMDIActivate(CWindow wndActivate, CWindow wndDeactivate)
1049 #define MSG_WM_MDIACTIVATE(func) \
1050 if (uMsg == WM_MDIACTIVATE) \
1051 { \
1052 SetMsgHandled(TRUE); \
1053 func((HWND)wParam, (HWND)lParam); \
1054 lResult = 0; \
1055 if(IsMsgHandled()) \
1056 return TRUE; \
1057 }
1058
1059 // void OnRenderFormat(UINT nFormat)
1060 #define MSG_WM_RENDERFORMAT(func) \
1061 if (uMsg == WM_RENDERFORMAT) \
1062 { \
1063 SetMsgHandled(TRUE); \
1064 func((UINT)wParam); \
1065 lResult = 0; \
1066 if(IsMsgHandled()) \
1067 return TRUE; \
1068 }
1069
1070 // void OnRenderAllFormats()
1071 #define MSG_WM_RENDERALLFORMATS(func) \
1072 if (uMsg == WM_RENDERALLFORMATS) \
1073 { \
1074 SetMsgHandled(TRUE); \
1075 func(); \
1076 lResult = 0; \
1077 if(IsMsgHandled()) \
1078 return TRUE; \
1079 }
1080
1081 // void OnDestroyClipboard()
1082 #define MSG_WM_DESTROYCLIPBOARD(func) \
1083 if (uMsg == WM_DESTROYCLIPBOARD) \
1084 { \
1085 SetMsgHandled(TRUE); \
1086 func(); \
1087 lResult = 0; \
1088 if(IsMsgHandled()) \
1089 return TRUE; \
1090 }
1091
1092 // void OnDrawClipboard()
1093 #define MSG_WM_DRAWCLIPBOARD(func) \
1094 if (uMsg == WM_DRAWCLIPBOARD) \
1095 { \
1096 SetMsgHandled(TRUE); \
1097 func(); \
1098 lResult = 0; \
1099 if(IsMsgHandled()) \
1100 return TRUE; \
1101 }
1102
1103 // void OnPaintClipboard(CWindow wndViewer, const LPPAINTSTRUCT lpPaintStruct)
1104 #define MSG_WM_PAINTCLIPBOARD(func) \
1105 if (uMsg == WM_PAINTCLIPBOARD) \
1106 { \
1107 SetMsgHandled(TRUE); \
1108 func((HWND)wParam, (const LPPAINTSTRUCT)::GlobalLock((HGLOBAL)lParam)); \
1109 ::GlobalUnlock((HGLOBAL)lParam); \
1110 lResult = 0; \
1111 if(IsMsgHandled()) \
1112 return TRUE; \
1113 }
1114
1115 // void OnVScrollClipboard(CWindow wndViewer, UINT nSBCode, UINT nPos)
1116 #define MSG_WM_VSCROLLCLIPBOARD(func) \
1117 if (uMsg == WM_VSCROLLCLIPBOARD) \
1118 { \
1119 SetMsgHandled(TRUE); \
1120 func((HWND)wParam, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); \
1121 lResult = 0; \
1122 if(IsMsgHandled()) \
1123 return TRUE; \
1124 }
1125
1126 // void OnContextMenu(CWindow wnd, CPoint point)
1127 #define MSG_WM_CONTEXTMENU(func) \
1128 if (uMsg == WM_CONTEXTMENU) \
1129 { \
1130 SetMsgHandled(TRUE); \
1131 func((HWND)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
1132 lResult = 0; \
1133 if(IsMsgHandled()) \
1134 return TRUE; \
1135 }
1136
1137 // void OnSizeClipboard(CWindow wndViewer, const LPRECT lpRect)
1138 #define MSG_WM_SIZECLIPBOARD(func) \
1139 if (uMsg == WM_SIZECLIPBOARD) \
1140 { \
1141 SetMsgHandled(TRUE); \
1142 func((HWND)wParam, (const LPRECT)::GlobalLock((HGLOBAL)lParam)); \
1143 ::GlobalUnlock((HGLOBAL)lParam); \
1144 lResult = 0; \
1145 if(IsMsgHandled()) \
1146 return TRUE; \
1147 }
1148
1149 // void OnAskCbFormatName(UINT nMaxCount, LPTSTR lpszString)
1150 #define MSG_WM_ASKCBFORMATNAME(func) \
1151 if (uMsg == WM_ASKCBFORMATNAME) \
1152 { \
1153 SetMsgHandled(TRUE); \
1154 func((UINT)wParam, (LPTSTR)lParam); \
1155 lResult = 0; \
1156 if(IsMsgHandled()) \
1157 return TRUE; \
1158 }
1159
1160 // void OnChangeCbChain(CWindow wndRemove, CWindow wndAfter)
1161 #define MSG_WM_CHANGECBCHAIN(func) \
1162 if (uMsg == WM_CHANGECBCHAIN) \
1163 { \
1164 SetMsgHandled(TRUE); \
1165 func((HWND)wParam, (HWND)lParam); \
1166 lResult = 0; \
1167 if(IsMsgHandled()) \
1168 return TRUE; \
1169 }
1170
1171 // void OnHScrollClipboard(CWindow wndViewer, UINT nSBCode, UINT nPos)
1172 #define MSG_WM_HSCROLLCLIPBOARD(func) \
1173 if (uMsg == WM_HSCROLLCLIPBOARD) \
1174 { \
1175 SetMsgHandled(TRUE); \
1176 func((HWND)wParam, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); \
1177 lResult = 0; \
1178 if(IsMsgHandled()) \
1179 return TRUE; \
1180 }
1181
1182 // BOOL OnQueryNewPalette()
1183 #define MSG_WM_QUERYNEWPALETTE(func) \
1184 if (uMsg == WM_QUERYNEWPALETTE) \
1185 { \
1186 SetMsgHandled(TRUE); \
1187 lResult = (LRESULT)func(); \
1188 if(IsMsgHandled()) \
1189 return TRUE; \
1190 }
1191
1192 // void OnPaletteChanged(CWindow wndFocus)
1193 #define MSG_WM_PALETTECHANGED(func) \
1194 if (uMsg == WM_PALETTECHANGED) \
1195 { \
1196 SetMsgHandled(TRUE); \
1197 func((HWND)wParam); \
1198 lResult = 0; \
1199 if(IsMsgHandled()) \
1200 return TRUE; \
1201 }
1202
1203 // void OnPaletteIsChanging(CWindow wndPalChg)
1204 #define MSG_WM_PALETTEISCHANGING(func) \
1205 if (uMsg == WM_PALETTEISCHANGING) \
1206 { \
1207 SetMsgHandled(TRUE); \
1208 func((HWND)wParam); \
1209 lResult = 0; \
1210 if(IsMsgHandled()) \
1211 return TRUE; \
1212 }
1213
1214 // void OnDropFiles(HDROP hDropInfo)
1215 #define MSG_WM_DROPFILES(func) \
1216 if (uMsg == WM_DROPFILES) \
1217 { \
1218 SetMsgHandled(TRUE); \
1219 func((HDROP)wParam); \
1220 lResult = 0; \
1221 if(IsMsgHandled()) \
1222 return TRUE; \
1223 }
1224
1225 // void OnWindowPosChanging(LPWINDOWPOS lpWndPos)
1226 #define MSG_WM_WINDOWPOSCHANGING(func) \
1227 if (uMsg == WM_WINDOWPOSCHANGING) \
1228 { \
1229 SetMsgHandled(TRUE); \
1230 func((LPWINDOWPOS)lParam); \
1231 lResult = 0; \
1232 if(IsMsgHandled()) \
1233 return TRUE; \
1234 }
1235
1236 // void OnWindowPosChanged(LPWINDOWPOS lpWndPos)
1237 #define MSG_WM_WINDOWPOSCHANGED(func) \
1238 if (uMsg == WM_WINDOWPOSCHANGED) \
1239 { \
1240 SetMsgHandled(TRUE); \
1241 func((LPWINDOWPOS)lParam); \
1242 lResult = 0; \
1243 if(IsMsgHandled()) \
1244 return TRUE; \
1245 }
1246
1247 // void OnExitMenuLoop(BOOL fIsTrackPopupMenu)
1248 #define MSG_WM_EXITMENULOOP(func) \
1249 if (uMsg == WM_EXITMENULOOP) \
1250 { \
1251 SetMsgHandled(TRUE); \
1252 func((BOOL)wParam); \
1253 lResult = 0; \
1254 if(IsMsgHandled()) \
1255 return TRUE; \
1256 }
1257
1258 // void OnEnterMenuLoop(BOOL fIsTrackPopupMenu)
1259 #define MSG_WM_ENTERMENULOOP(func) \
1260 if (uMsg == WM_ENTERMENULOOP) \
1261 { \
1262 SetMsgHandled(TRUE); \
1263 func((BOOL)wParam); \
1264 lResult = 0; \
1265 if(IsMsgHandled()) \
1266 return TRUE; \
1267 }
1268
1269 // void OnStyleChanged(int nStyleType, LPSTYLESTRUCT lpStyleStruct)
1270 #define MSG_WM_STYLECHANGED(func) \
1271 if (uMsg == WM_STYLECHANGED) \
1272 { \
1273 SetMsgHandled(TRUE); \
1274 func((UINT)wParam, (LPSTYLESTRUCT)lParam); \
1275 lResult = 0; \
1276 if(IsMsgHandled()) \
1277 return TRUE; \
1278 }
1279
1280 // void OnStyleChanging(int nStyleType, LPSTYLESTRUCT lpStyleStruct)
1281 #define MSG_WM_STYLECHANGING(func) \
1282 if (uMsg == WM_STYLECHANGING) \
1283 { \
1284 SetMsgHandled(TRUE); \
1285 func((UINT)wParam, (LPSTYLESTRUCT)lParam); \
1286 lResult = 0; \
1287 if(IsMsgHandled()) \
1288 return TRUE; \
1289 }
1290
1291 // void OnSizing(UINT fwSide, LPRECT pRect)
1292 #define MSG_WM_SIZING(func) \
1293 if (uMsg == WM_SIZING) \
1294 { \
1295 SetMsgHandled(TRUE); \
1296 func((UINT)wParam, (LPRECT)lParam); \
1297 lResult = TRUE; \
1298 if(IsMsgHandled()) \
1299 return TRUE; \
1300 }
1301
1302 // void OnMoving(UINT fwSide, LPRECT pRect)
1303 #define MSG_WM_MOVING(func) \
1304 if (uMsg == WM_MOVING) \
1305 { \
1306 SetMsgHandled(TRUE); \
1307 func((UINT)wParam, (LPRECT)lParam); \
1308 lResult = TRUE; \
1309 if(IsMsgHandled()) \
1310 return TRUE; \
1311 }
1312
1313 // void OnCaptureChanged(CWindow wnd)
1314 #define MSG_WM_CAPTURECHANGED(func) \
1315 if (uMsg == WM_CAPTURECHANGED) \
1316 { \
1317 SetMsgHandled(TRUE); \
1318 func((HWND)lParam); \
1319 lResult = 0; \
1320 if(IsMsgHandled()) \
1321 return TRUE; \
1322 }
1323
1324 // BOOL OnDeviceChange(UINT nEventType, DWORD_PTR dwData)
1325 #define MSG_WM_DEVICECHANGE(func) \
1326 if (uMsg == WM_DEVICECHANGE) \
1327 { \
1328 SetMsgHandled(TRUE); \
1329 lResult = (LRESULT)func((UINT)wParam, (DWORD_PTR)lParam); \
1330 if(IsMsgHandled()) \
1331 return TRUE; \
1332 }
1333
1334 // void OnCommand(UINT uNotifyCode, int nID, CWindow wndCtl)
1335 #define MSG_WM_COMMAND(func) \
1336 if (uMsg == WM_COMMAND) \
1337 { \
1338 SetMsgHandled(TRUE); \
1339 func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \
1340 lResult = 0; \
1341 if(IsMsgHandled()) \
1342 return TRUE; \
1343 }
1344
1345 // void OnDisplayChange(UINT uBitsPerPixel, CSize sizeScreen)
1346 #define MSG_WM_DISPLAYCHANGE(func) \
1347 if (uMsg == WM_DISPLAYCHANGE) \
1348 { \
1349 SetMsgHandled(TRUE); \
1350 func((UINT)wParam, _WTYPES_NS::CSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
1351 lResult = 0; \
1352 if(IsMsgHandled()) \
1353 return TRUE; \
1354 }
1355
1356 // void OnEnterSizeMove()
1357 #define MSG_WM_ENTERSIZEMOVE(func) \
1358 if (uMsg == WM_ENTERSIZEMOVE) \
1359 { \
1360 SetMsgHandled(TRUE); \
1361 func(); \
1362 lResult = 0; \
1363 if(IsMsgHandled()) \
1364 return TRUE; \
1365 }
1366
1367 // void OnExitSizeMove()
1368 #define MSG_WM_EXITSIZEMOVE(func) \
1369 if (uMsg == WM_EXITSIZEMOVE) \
1370 { \
1371 SetMsgHandled(TRUE); \
1372 func(); \
1373 lResult = 0; \
1374 if(IsMsgHandled()) \
1375 return TRUE; \
1376 }
1377
1378 // HFONT OnGetFont()
1379 #define MSG_WM_GETFONT(func) \
1380 if (uMsg == WM_GETFONT) \
1381 { \
1382 SetMsgHandled(TRUE); \
1383 lResult = (LRESULT)func(); \
1384 if(IsMsgHandled()) \
1385 return TRUE; \
1386 }
1387
1388 // LRESULT OnGetHotKey()
1389 #define MSG_WM_GETHOTKEY(func) \
1390 if (uMsg == WM_GETHOTKEY) \
1391 { \
1392 SetMsgHandled(TRUE); \
1393 lResult = func(); \
1394 if(IsMsgHandled()) \
1395 return TRUE; \
1396 }
1397
1398 // HICON OnGetIcon()
1399 #define MSG_WM_GETICON(func) \
1400 if (uMsg == WM_GETICON) \
1401 { \
1402 SetMsgHandled(TRUE); \
1403 lResult = (LRESULT)func((UINT)wParam); \
1404 if(IsMsgHandled()) \
1405 return TRUE; \
1406 }
1407
1408 // int OnGetText(int cchTextMax, LPTSTR lpszText)
1409 #define MSG_WM_GETTEXT(func) \
1410 if (uMsg == WM_GETTEXT) \
1411 { \
1412 SetMsgHandled(TRUE); \
1413 lResult = (LRESULT)func((int)wParam, (LPTSTR)lParam); \
1414 if(IsMsgHandled()) \
1415 return TRUE; \
1416 }
1417
1418 // int OnGetTextLength()
1419 #define MSG_WM_GETTEXTLENGTH(func) \
1420 if (uMsg == WM_GETTEXTLENGTH) \
1421 { \
1422 SetMsgHandled(TRUE); \
1423 lResult = (LRESULT)func(); \
1424 if(IsMsgHandled()) \
1425 return TRUE; \
1426 }
1427
1428 // void OnHelp(LPHELPINFO lpHelpInfo)
1429 #define MSG_WM_HELP(func) \
1430 if (uMsg == WM_HELP) \
1431 { \
1432 SetMsgHandled(TRUE); \
1433 func((LPHELPINFO)lParam); \
1434 lResult = TRUE; \
1435 if(IsMsgHandled()) \
1436 return TRUE; \
1437 }
1438
1439 // void OnHotKey(int nHotKeyID, UINT uModifiers, UINT uVirtKey)
1440 #define MSG_WM_HOTKEY(func) \
1441 if (uMsg == WM_HOTKEY) \
1442 { \
1443 SetMsgHandled(TRUE); \
1444 func((int)wParam, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); \
1445 lResult = 0; \
1446 if(IsMsgHandled()) \
1447 return TRUE; \
1448 }
1449
1450 // void OnInputLangChange(DWORD dwCharSet, HKL hKbdLayout)
1451 #define MSG_WM_INPUTLANGCHANGE(func) \
1452 if (uMsg == WM_INPUTLANGCHANGE) \
1453 { \
1454 SetMsgHandled(TRUE); \
1455 func((DWORD)wParam, (HKL)lParam); \
1456 lResult = TRUE; \
1457 if(IsMsgHandled()) \
1458 return TRUE; \
1459 }
1460
1461 // void OnInputLangChangeRequest(BOOL bSysCharSet, HKL hKbdLayout)
1462 #define MSG_WM_INPUTLANGCHANGEREQUEST(func) \
1463 if (uMsg == WM_INPUTLANGCHANGEREQUEST) \
1464 { \
1465 SetMsgHandled(TRUE); \
1466 func((BOOL)wParam, (HKL)lParam); \
1467 lResult = 0; \
1468 if(IsMsgHandled()) \
1469 return TRUE; \
1470 }
1471
1472 // void OnNextDlgCtl(BOOL bHandle, WPARAM wCtlFocus)
1473 #define MSG_WM_NEXTDLGCTL(func) \
1474 if (uMsg == WM_NEXTDLGCTL) \
1475 { \
1476 SetMsgHandled(TRUE); \
1477 func((BOOL)LOWORD(lParam), wParam); \
1478 lResult = 0; \
1479 if(IsMsgHandled()) \
1480 return TRUE; \
1481 }
1482
1483 // void OnNextMenu(int nVirtKey, LPMDINEXTMENU lpMdiNextMenu)
1484 #define MSG_WM_NEXTMENU(func) \
1485 if (uMsg == WM_NEXTMENU) \
1486 { \
1487 SetMsgHandled(TRUE); \
1488 func((int)wParam, (LPMDINEXTMENU)lParam); \
1489 lResult = 0; \
1490 if(IsMsgHandled()) \
1491 return TRUE; \
1492 }
1493
1494 // int OnNotifyFormat(CWindow wndFrom, int nCommand)
1495 #define MSG_WM_NOTIFYFORMAT(func) \
1496 if (uMsg == WM_NOTIFYFORMAT) \
1497 { \
1498 SetMsgHandled(TRUE); \
1499 lResult = (LRESULT)func((HWND)wParam, (int)lParam); \
1500 if(IsMsgHandled()) \
1501 return TRUE; \
1502 }
1503
1504 // BOOL OnPowerBroadcast(DWORD dwPowerEvent, DWORD_PTR dwData)
1505 #define MSG_WM_POWERBROADCAST(func) \
1506 if (uMsg == WM_POWERBROADCAST) \
1507 { \
1508 SetMsgHandled(TRUE); \
1509 lResult = (LRESULT)func((DWORD)wParam, (DWORD_PTR)lParam); \
1510 if(IsMsgHandled()) \
1511 return TRUE; \
1512 }
1513
1514 // void OnPrint(CDCHandle dc, UINT uFlags)
1515 #define MSG_WM_PRINT(func) \
1516 if (uMsg == WM_PRINT) \
1517 { \
1518 SetMsgHandled(TRUE); \
1519 func((HDC)wParam, (UINT)lParam); \
1520 lResult = 0; \
1521 if(IsMsgHandled()) \
1522 return TRUE; \
1523 }
1524
1525 // void OnPrintClient(CDCHandle dc, UINT uFlags)
1526 #define MSG_WM_PRINTCLIENT(func) \
1527 if (uMsg == WM_PRINTCLIENT) \
1528 { \
1529 SetMsgHandled(TRUE); \
1530 func((HDC)wParam, (UINT)lParam); \
1531 lResult = 0; \
1532 if(IsMsgHandled()) \
1533 return TRUE; \
1534 }
1535
1536 // void OnRasDialEvent(RASCONNSTATE rasconnstate, DWORD dwError)
1537 #define MSG_WM_RASDIALEVENT(func) \
1538 if (uMsg == WM_RASDIALEVENT) \
1539 { \
1540 SetMsgHandled(TRUE); \
1541 func((RASCONNSTATE)wParam, (DWORD)lParam); \
1542 lResult = TRUE; \
1543 if(IsMsgHandled()) \
1544 return TRUE; \
1545 }
1546
1547 // void OnSetFont(CFontHandle font, BOOL bRedraw)
1548 #define MSG_WM_SETFONT(func) \
1549 if (uMsg == WM_SETFONT) \
1550 { \
1551 SetMsgHandled(TRUE); \
1552 func((HFONT)wParam, (BOOL)LOWORD(lParam)); \
1553 lResult = 0; \
1554 if(IsMsgHandled()) \
1555 return TRUE; \
1556 }
1557
1558 // int OnSetHotKey(int nVirtKey, UINT uFlags)
1559 #define MSG_WM_SETHOTKEY(func) \
1560 if (uMsg == WM_SETHOTKEY) \
1561 { \
1562 SetMsgHandled(TRUE); \
1563 lResult = (LRESULT)func((int)LOBYTE(LOWORD(wParam)), (UINT)HIBYTE(LOWORD(wParam))); \
1564 if(IsMsgHandled()) \
1565 return TRUE; \
1566 }
1567
1568 // HICON OnSetIcon(UINT uType, HICON hIcon)
1569 #define MSG_WM_SETICON(func) \
1570 if (uMsg == WM_SETICON) \
1571 { \
1572 SetMsgHandled(TRUE); \
1573 lResult = (LRESULT)func((UINT)wParam, (HICON)lParam); \
1574 if(IsMsgHandled()) \
1575 return TRUE; \
1576 }
1577
1578 // void OnSetRedraw(BOOL bRedraw)
1579 #define MSG_WM_SETREDRAW(func) \
1580 if (uMsg == WM_SETREDRAW) \
1581 { \
1582 SetMsgHandled(TRUE); \
1583 func((BOOL)wParam); \
1584 lResult = 0; \
1585 if(IsMsgHandled()) \
1586 return TRUE; \
1587 }
1588
1589 // int OnSetText(LPCTSTR lpstrText)
1590 #define MSG_WM_SETTEXT(func) \
1591 if (uMsg == WM_SETTEXT) \
1592 { \
1593 SetMsgHandled(TRUE); \
1594 lResult = (LRESULT)func((LPCTSTR)lParam); \
1595 if(IsMsgHandled()) \
1596 return TRUE; \
1597 }
1598
1599 // void OnUserChanged()
1600 #define MSG_WM_USERCHANGED(func) \
1601 if (uMsg == WM_USERCHANGED) \
1602 { \
1603 SetMsgHandled(TRUE); \
1604 func(); \
1605 lResult = 0; \
1606 if(IsMsgHandled()) \
1607 return TRUE; \
1608 }
1609
1610 ///////////////////////////////////////////////////////////////////////////////
1611 // New NT4 & NT5 messages
1612
1613 #if (_WIN32_WINNT >= 0x0400)
1614
1615 // void OnMouseHover(WPARAM wParam, CPoint ptPos)
1616 #define MSG_WM_MOUSEHOVER(func) \
1617 if (uMsg == WM_MOUSEHOVER) \
1618 { \
1619 SetMsgHandled(TRUE); \
1620 func(wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
1621 lResult = 0; \
1622 if(IsMsgHandled()) \
1623 return TRUE; \
1624 }
1625
1626 // void OnMouseLeave()
1627 #define MSG_WM_MOUSELEAVE(func) \
1628 if (uMsg == WM_MOUSELEAVE) \
1629 { \
1630 SetMsgHandled(TRUE); \
1631 func(); \
1632 lResult = 0; \
1633 if(IsMsgHandled()) \
1634 return TRUE; \
1635 }
1636
1637 #endif // _WIN32_WINNT >= 0x0400
1638
1639 #if (WINVER >= 0x0500)
1640
1641 // void OnMenuRButtonUp(WPARAM wParam, CMenuHandle menu)
1642 #define MSG_WM_MENURBUTTONUP(func) \
1643 if (uMsg == WM_MENURBUTTONUP) \
1644 { \
1645 SetMsgHandled(TRUE); \
1646 func(wParam, (HMENU)lParam); \
1647 lResult = 0; \
1648 if(IsMsgHandled()) \
1649 return TRUE; \
1650 }
1651
1652 // LRESULT OnMenuDrag(WPARAM wParam, CMenuHandle menu)
1653 #define MSG_WM_MENUDRAG(func) \
1654 if (uMsg == WM_MENUDRAG) \
1655 { \
1656 SetMsgHandled(TRUE); \
1657 lResult = func(wParam, (HMENU)lParam); \
1658 if(IsMsgHandled()) \
1659 return TRUE; \
1660 }
1661
1662 // LRESULT OnMenuGetObject(PMENUGETOBJECTINFO info)
1663 #define MSG_WM_MENUGETOBJECT(func) \
1664 if (uMsg == WM_MENUGETOBJECT) \
1665 { \
1666 SetMsgHandled(TRUE); \
1667 lResult = func((PMENUGETOBJECTINFO)lParam); \
1668 if(IsMsgHandled()) \
1669 return TRUE; \
1670 }
1671
1672 // void OnUnInitMenuPopup(UINT nID, CMenuHandle menu)
1673 #define MSG_WM_UNINITMENUPOPUP(func) \
1674 if (uMsg == WM_UNINITMENUPOPUP) \
1675 { \
1676 SetMsgHandled(TRUE); \
1677 func((UINT)HIWORD(lParam), (HMENU)wParam); \
1678 lResult = 0; \
1679 if(IsMsgHandled()) \
1680 return TRUE; \
1681 }
1682
1683 // void OnMenuCommand(WPARAM nIndex, CMenuHandle menu)
1684 #define MSG_WM_MENUCOMMAND(func) \
1685 if (uMsg == WM_MENUCOMMAND) \
1686 { \
1687 SetMsgHandled(TRUE); \
1688 func(wParam, (HMENU)lParam); \
1689 lResult = 0; \
1690 if(IsMsgHandled()) \
1691 return TRUE; \
1692 }
1693
1694 #endif // WINVER >= 0x0500
1695
1696 #if (_WIN32_WINNT >= 0x0500)
1697
1698 // BOOL OnAppCommand(CWindow wndFocus, short cmd, WORD uDevice, int dwKeys)
1699 #define MSG_WM_APPCOMMAND(func) \
1700 if (uMsg == WM_APPCOMMAND) \
1701 { \
1702 SetMsgHandled(TRUE); \
1703 lResult = (LRESULT)func((HWND)wParam, GET_APPCOMMAND_LPARAM(lParam), GET_DEVICE_LPARAM(lParam), GET_KEYSTATE_LPARAM(lParam)); \
1704 if(IsMsgHandled()) \
1705 return TRUE; \
1706 }
1707
1708 // void OnNCXButtonDown(int fwButton, short nHittest, CPoint ptPos)
1709 #define MSG_WM_NCXBUTTONDOWN(func) \
1710 if (uMsg == WM_NCXBUTTONDOWN) \
1711 { \
1712 SetMsgHandled(TRUE); \
1713 func(GET_XBUTTON_WPARAM(wParam), GET_NCHITTEST_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
1714 lResult = 0; \
1715 if(IsMsgHandled()) \
1716 return TRUE; \
1717 }
1718
1719 // void OnNCXButtonUp(int fwButton, short nHittest, CPoint ptPos)
1720 #define MSG_WM_NCXBUTTONUP(func) \
1721 if (uMsg == WM_NCXBUTTONUP) \
1722 { \
1723 SetMsgHandled(TRUE); \
1724 func(GET_XBUTTON_WPARAM(wParam), GET_NCHITTEST_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
1725 lResult = 0; \
1726 if(IsMsgHandled()) \
1727 return TRUE; \
1728 }
1729
1730 // void OnNCXButtonDblClk(int fwButton, short nHittest, CPoint ptPos)
1731 #define MSG_WM_NCXBUTTONDBLCLK(func) \
1732 if (uMsg == WM_NCXBUTTONDBLCLK) \
1733 { \
1734 SetMsgHandled(TRUE); \
1735 func(GET_XBUTTON_WPARAM(wParam), GET_NCHITTEST_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
1736 lResult = 0; \
1737 if(IsMsgHandled()) \
1738 return TRUE; \
1739 }
1740
1741 // void OnXButtonDown(int fwButton, int dwKeys, CPoint ptPos)
1742 #define MSG_WM_XBUTTONDOWN(func) \
1743 if (uMsg == WM_XBUTTONDOWN) \
1744 { \
1745 SetMsgHandled(TRUE); \
1746 func(GET_XBUTTON_WPARAM(wParam), GET_KEYSTATE_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
1747 lResult = 0; \
1748 if(IsMsgHandled()) \
1749 return TRUE; \
1750 }
1751
1752 // void OnXButtonUp(int fwButton, int dwKeys, CPoint ptPos)
1753 #define MSG_WM_XBUTTONUP(func) \
1754 if (uMsg == WM_XBUTTONUP) \
1755 { \
1756 SetMsgHandled(TRUE); \
1757 func(GET_XBUTTON_WPARAM(wParam), GET_KEYSTATE_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
1758 lResult = 0; \
1759 if(IsMsgHandled()) \
1760 return TRUE; \
1761 }
1762
1763 // void OnXButtonDblClk(int fwButton, int dwKeys, CPoint ptPos)
1764 #define MSG_WM_XBUTTONDBLCLK(func) \
1765 if (uMsg == WM_XBUTTONDBLCLK) \
1766 { \
1767 SetMsgHandled(TRUE); \
1768 func(GET_XBUTTON_WPARAM(wParam), GET_KEYSTATE_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
1769 lResult = 0; \
1770 if(IsMsgHandled()) \
1771 return TRUE; \
1772 }
1773
1774 // void OnChangeUIState(WORD nAction, WORD nState)
1775 #define MSG_WM_CHANGEUISTATE(func) \
1776 if (uMsg == WM_CHANGEUISTATE) \
1777 { \
1778 SetMsgHandled(TRUE); \
1779 func(LOWORD(wParam), HIWORD(wParam)); \
1780 lResult = 0; \
1781 if(IsMsgHandled()) \
1782 return TRUE; \
1783 }
1784
1785 // void OnUpdateUIState(WORD nAction, WORD nState)
1786 #define MSG_WM_UPDATEUISTATE(func) \
1787 if (uMsg == WM_UPDATEUISTATE) \
1788 { \
1789 SetMsgHandled(TRUE); \
1790 func(LOWORD(wParam), HIWORD(wParam)); \
1791 lResult = 0; \
1792 if(IsMsgHandled()) \
1793 return TRUE; \
1794 }
1795
1796 // LRESULT OnQueryUIState()
1797 #define MSG_WM_QUERYUISTATE(func) \
1798 if (uMsg == WM_QUERYUISTATE) \
1799 { \
1800 SetMsgHandled(TRUE); \
1801 lResult = func(); \
1802 if(IsMsgHandled()) \
1803 return TRUE; \
1804 }
1805
1806 #endif // (_WIN32_WINNT >= 0x0500)
1807
1808 #if(_WIN32_WINNT >= 0x0501)
1809
1810 // void OnInput(WPARAM RawInputCode, HRAWINPUT hRawInput)
1811 #define MSG_WM_INPUT(func) \
1812 if (uMsg == WM_INPUT) \
1813 { \
1814 SetMsgHandled(TRUE); \
1815 func(GET_RAWINPUT_CODE_WPARAM(wParam), (HRAWINPUT)lParam); \
1816 lResult = 0; \
1817 if(IsMsgHandled()) \
1818 return TRUE; \
1819 }
1820
1821 // void OnUniChar(TCHAR nChar, UINT nRepCnt, UINT nFlags)
1822 #define MSG_WM_UNICHAR(func) \
1823 if (uMsg == WM_UNICHAR) \
1824 { \
1825 SetMsgHandled(TRUE); \
1826 func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \
1827 if(IsMsgHandled()) \
1828 { \
1829 lResult = (wParam == UNICODE_NOCHAR) ? TRUE : FALSE; \
1830 return TRUE; \
1831 } \
1832 }
1833
1834 // void OnWTSSessionChange(WPARAM nStatusCode, PWTSSESSION_NOTIFICATION nSessionID)
1835 #define MSG_WM_WTSSESSION_CHANGE(func) \
1836 if (uMsg == WM_WTSSESSION_CHANGE) \
1837 { \
1838 SetMsgHandled(TRUE); \
1839 func(wParam, (PWTSSESSION_NOTIFICATION)lParam); \
1840 lResult = 0; \
1841 if(IsMsgHandled()) \
1842 return TRUE; \
1843 }
1844
1845 // void OnThemeChanged()
1846 #define MSG_WM_THEMECHANGED(func) \
1847 if (uMsg == WM_THEMECHANGED) \
1848 { \
1849 SetMsgHandled(TRUE); \
1850 func(); \
1851 lResult = 0; \
1852 if(IsMsgHandled()) \
1853 return TRUE; \
1854 }
1855
1856 #endif // _WIN32_WINNT >= 0x0501
1857
1858 #if (_WIN32_WINNT >= 0x0600)
1859
1860 // BOOL OnMouseHWheel(UINT nFlags, short zDelta, CPoint pt)
1861 #define MSG_WM_MOUSEHWHEEL(func) \
1862 if (uMsg == WM_MOUSEHWHEEL) \
1863 { \
1864 SetMsgHandled(TRUE); \
1865 lResult = (LRESULT)func((UINT)LOWORD(wParam), (short)HIWORD(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
1866 if(IsMsgHandled()) \
1867 return TRUE; \
1868 }
1869
1870 #endif // (_WIN32_WINNT >= 0x0600)
1871
1872 ///////////////////////////////////////////////////////////////////////////////
1873 // ATL defined messages
1874
1875 // BOOL OnForwardMsg(LPMSG Msg, DWORD nUserData)
1876 #define MSG_WM_FORWARDMSG(func) \
1877 if (uMsg == WM_FORWARDMSG) \
1878 { \
1879 SetMsgHandled(TRUE); \
1880 lResult = (LRESULT)func((LPMSG)lParam, (DWORD)wParam); \
1881 if(IsMsgHandled()) \
1882 return TRUE; \
1883 }
1884
1885 ///////////////////////////////////////////////////////////////////////////////
1886 // Dialog specific messages
1887
1888 // LRESULT OnDMGetDefID()
1889 #define MSG_DM_GETDEFID(func) \
1890 if (uMsg == DM_GETDEFID) \
1891 { \
1892 SetMsgHandled(TRUE); \
1893 lResult = func(); \
1894 if(IsMsgHandled()) \
1895 return TRUE; \
1896 }
1897
1898 // void OnDMSetDefID(UINT DefID)
1899 #define MSG_DM_SETDEFID(func) \
1900 if (uMsg == DM_SETDEFID) \
1901 { \
1902 SetMsgHandled(TRUE); \
1903 func((UINT)wParam); \
1904 lResult = TRUE; \
1905 if(IsMsgHandled()) \
1906 return TRUE; \
1907 }
1908
1909 // void OnDMReposition()
1910 #define MSG_DM_REPOSITION(func) \
1911 if (uMsg == DM_REPOSITION) \
1912 { \
1913 SetMsgHandled(TRUE); \
1914 func(); \
1915 lResult = 0; \
1916 if(IsMsgHandled()) \
1917 return TRUE; \
1918 }
1919
1920 ///////////////////////////////////////////////////////////////////////////////
1921 // Reflected messages
1922
1923 // void OnReflectedCommand(UINT uNotifyCode, int nID, CWindow wndCtl)
1924 #define MSG_OCM_COMMAND(func) \
1925 if (uMsg == OCM_COMMAND) \
1926 { \
1927 SetMsgHandled(TRUE); \
1928 func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \
1929 lResult = 0; \
1930 if(IsMsgHandled()) \
1931 return TRUE; \
1932 }
1933
1934 // LRESULT OnReflectedNotify(int idCtrl, LPNMHDR pnmh)
1935 #define MSG_OCM_NOTIFY(func) \
1936 if (uMsg == OCM_NOTIFY) \
1937 { \
1938 SetMsgHandled(TRUE); \
1939 lResult = func((int)wParam, (LPNMHDR)lParam); \
1940 if(IsMsgHandled()) \
1941 return TRUE; \
1942 }
1943
1944 // void OnReflectedParentNotify(UINT message, UINT nChildID, LPARAM lParam)
1945 #define MSG_OCM_PARENTNOTIFY(func) \
1946 if (uMsg == OCM_PARENTNOTIFY) \
1947 { \
1948 SetMsgHandled(TRUE); \
1949 func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), lParam); \
1950 lResult = 0; \
1951 if(IsMsgHandled()) \
1952 return TRUE; \
1953 }
1954
1955 // void OnReflectedDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
1956 #define MSG_OCM_DRAWITEM(func) \
1957 if (uMsg == OCM_DRAWITEM) \
1958 { \
1959 SetMsgHandled(TRUE); \
1960 func((UINT)wParam, (LPDRAWITEMSTRUCT)lParam); \
1961 lResult = TRUE; \
1962 if(IsMsgHandled()) \
1963 return TRUE; \
1964 }
1965
1966 // void OnReflectedMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
1967 #define MSG_OCM_MEASUREITEM(func) \
1968 if (uMsg == OCM_MEASUREITEM) \
1969 { \
1970 SetMsgHandled(TRUE); \
1971 func((UINT)wParam, (LPMEASUREITEMSTRUCT)lParam); \
1972 lResult = TRUE; \
1973 if(IsMsgHandled()) \
1974 return TRUE; \
1975 }
1976
1977 // int OnReflectedCompareItem(int nIDCtl, LPCOMPAREITEMSTRUCT lpCompareItemStruct)
1978 #define MSG_OCM_COMPAREITEM(func) \
1979 if (uMsg == OCM_COMPAREITEM) \
1980 { \
1981 SetMsgHandled(TRUE); \
1982 lResult = (LRESULT)func((UINT)wParam, (LPCOMPAREITEMSTRUCT)lParam); \
1983 if(IsMsgHandled()) \
1984 return TRUE; \
1985 }
1986
1987 // void OnReflectedDeleteItem(int nIDCtl, LPDELETEITEMSTRUCT lpDeleteItemStruct)
1988 #define MSG_OCM_DELETEITEM(func) \
1989 if (uMsg == OCM_DELETEITEM) \
1990 { \
1991 SetMsgHandled(TRUE); \
1992 func((UINT)wParam, (LPDELETEITEMSTRUCT)lParam); \
1993 lResult = TRUE; \
1994 if(IsMsgHandled()) \
1995 return TRUE; \
1996 }
1997
1998 // int OnReflectedVKeyToItem(UINT nKey, UINT nIndex, CListBox listBox)
1999 #define MSG_OCM_VKEYTOITEM(func) \
2000 if (uMsg == OCM_VKEYTOITEM) \
2001 { \
2002 SetMsgHandled(TRUE); \
2003 lResult = (LRESULT)func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), (HWND)lParam); \
2004 if(IsMsgHandled()) \
2005 return TRUE; \
2006 }
2007
2008 //int OnReflectedCharToItem(UINT nChar, UINT nIndex, CListBox listBox)
2009 #define MSG_OCM_CHARTOITEM(func) \
2010 if (uMsg == OCM_CHARTOITEM) \
2011 { \
2012 SetMsgHandled(TRUE); \
2013 lResult = (LRESULT)func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), (HWND)lParam); \
2014 if(IsMsgHandled()) \
2015 return TRUE; \
2016 }
2017
2018 // void OnReflectedHScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar)
2019 #define MSG_OCM_HSCROLL(func) \
2020 if (uMsg == OCM_HSCROLL) \
2021 { \
2022 SetMsgHandled(TRUE); \
2023 func((int)LOWORD(wParam), (short)HIWORD(wParam), (HWND)lParam); \
2024 lResult = 0; \
2025 if(IsMsgHandled()) \
2026 return TRUE; \
2027 }
2028
2029 // void OnReflectedVScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar)
2030 #define MSG_OCM_VSCROLL(func) \
2031 if (uMsg == OCM_VSCROLL) \
2032 { \
2033 SetMsgHandled(TRUE); \
2034 func((int)LOWORD(wParam), (short)HIWORD(wParam), (HWND)lParam); \
2035 lResult = 0; \
2036 if(IsMsgHandled()) \
2037 return TRUE; \
2038 }
2039
2040 // HBRUSH OnReflectedCtlColorEdit(CDCHandle dc, CEdit edit)
2041 #define MSG_OCM_CTLCOLOREDIT(func) \
2042 if (uMsg == OCM_CTLCOLOREDIT) \
2043 { \
2044 SetMsgHandled(TRUE); \
2045 lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \
2046 if(IsMsgHandled()) \
2047 return TRUE; \
2048 }
2049
2050 // HBRUSH OnReflectedCtlColorListBox(CDCHandle dc, CListBox listBox)
2051 #define MSG_OCM_CTLCOLORLISTBOX(func) \
2052 if (uMsg == OCM_CTLCOLORLISTBOX) \
2053 { \
2054 SetMsgHandled(TRUE); \
2055 lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \
2056 if(IsMsgHandled()) \
2057 return TRUE; \
2058 }
2059
2060 // HBRUSH OnReflectedCtlColorBtn(CDCHandle dc, CButton button)
2061 #define MSG_OCM_CTLCOLORBTN(func) \
2062 if (uMsg == OCM_CTLCOLORBTN) \
2063 { \
2064 SetMsgHandled(TRUE); \
2065 lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \
2066 if(IsMsgHandled()) \
2067 return TRUE; \
2068 }
2069
2070 // HBRUSH OnReflectedCtlColorDlg(CDCHandle dc, CWindow wnd)
2071 #define MSG_OCM_CTLCOLORDLG(func) \
2072 if (uMsg == OCM_CTLCOLORDLG) \
2073 { \
2074 SetMsgHandled(TRUE); \
2075 lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \
2076 if(IsMsgHandled()) \
2077 return TRUE; \
2078 }
2079
2080 // HBRUSH OnReflectedCtlColorScrollBar(CDCHandle dc, CScrollBar scrollBar)
2081 #define MSG_OCM_CTLCOLORSCROLLBAR(func) \
2082 if (uMsg == OCM_CTLCOLORSCROLLBAR) \
2083 { \
2084 SetMsgHandled(TRUE); \
2085 lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \
2086 if(IsMsgHandled()) \
2087 return TRUE; \
2088 }
2089
2090 // HBRUSH OnReflectedCtlColorStatic(CDCHandle dc, CStatic wndStatic)
2091 #define MSG_OCM_CTLCOLORSTATIC(func) \
2092 if (uMsg == OCM_CTLCOLORSTATIC) \
2093 { \
2094 SetMsgHandled(TRUE); \
2095 lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \
2096 if(IsMsgHandled()) \
2097 return TRUE; \
2098 }
2099
2100 ///////////////////////////////////////////////////////////////////////////////
2101 // Edit specific messages
2102
2103 // void OnClear()
2104 #define MSG_WM_CLEAR(func) \
2105 if (uMsg == WM_CLEAR) \
2106 { \
2107 SetMsgHandled(TRUE); \
2108 func(); \
2109 lResult = 0; \
2110 if(IsMsgHandled()) \
2111 return TRUE; \
2112 }
2113
2114 // void OnCopy()
2115 #define MSG_WM_COPY(func) \
2116 if (uMsg == WM_COPY) \
2117 { \
2118 SetMsgHandled(TRUE); \
2119 func(); \
2120 lResult = 0; \
2121 if(IsMsgHandled()) \
2122 return TRUE; \
2123 }
2124
2125 // void OnCut()
2126 #define MSG_WM_CUT(func) \
2127 if (uMsg == WM_CUT) \
2128 { \
2129 SetMsgHandled(TRUE); \
2130 func(); \
2131 lResult = 0; \
2132 if(IsMsgHandled()) \
2133 return TRUE; \
2134 }
2135
2136 // void OnPaste()
2137 #define MSG_WM_PASTE(func) \
2138 if (uMsg == WM_PASTE) \
2139 { \
2140 SetMsgHandled(TRUE); \
2141 func(); \
2142 lResult = 0; \
2143 if(IsMsgHandled()) \
2144 return TRUE; \
2145 }
2146
2147 // void OnUndo()
2148 #define MSG_WM_UNDO(func) \
2149 if (uMsg == WM_UNDO) \
2150 { \
2151 SetMsgHandled(TRUE); \
2152 func(); \
2153 lResult = 0; \
2154 if(IsMsgHandled()) \
2155 return TRUE; \
2156 }
2157
2158 ///////////////////////////////////////////////////////////////////////////////
2159 // Generic message handlers
2160
2161 // LRESULT OnMessageHandlerEX(UINT uMsg, WPARAM wParam, LPARAM lParam)
2162 #define MESSAGE_HANDLER_EX(msg, func) \
2163 if(uMsg == msg) \
2164 { \
2165 SetMsgHandled(TRUE); \
2166 lResult = func(uMsg, wParam, lParam); \
2167 if(IsMsgHandled()) \
2168 return TRUE; \
2169 }
2170
2171 // LRESULT OnMessageRangeHandlerEX(UINT uMsg, WPARAM wParam, LPARAM lParam)
2172 #define MESSAGE_RANGE_HANDLER_EX(msgFirst, msgLast, func) \
2173 if(uMsg >= msgFirst && uMsg <= msgLast) \
2174 { \
2175 SetMsgHandled(TRUE); \
2176 lResult = func(uMsg, wParam, lParam); \
2177 if(IsMsgHandled()) \
2178 return TRUE; \
2179 }
2180
2181 ///////////////////////////////////////////////////////////////////////////////
2182 // Commands and notifications
2183
2184 // void OnCommandHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl)
2185 #define COMMAND_HANDLER_EX(id, code, func) \
2186 if (uMsg == WM_COMMAND && code == HIWORD(wParam) && id == LOWORD(wParam)) \
2187 { \
2188 SetMsgHandled(TRUE); \
2189 func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \
2190 lResult = 0; \
2191 if(IsMsgHandled()) \
2192 return TRUE; \
2193 }
2194
2195 // void OnCommandIDHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl)
2196 #define COMMAND_ID_HANDLER_EX(id, func) \
2197 if (uMsg == WM_COMMAND && id == LOWORD(wParam)) \
2198 { \
2199 SetMsgHandled(TRUE); \
2200 func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \
2201 lResult = 0; \
2202 if(IsMsgHandled()) \
2203 return TRUE; \
2204 }
2205
2206 // void OnCommandCodeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl)
2207 #define COMMAND_CODE_HANDLER_EX(code, func) \
2208 if (uMsg == WM_COMMAND && code == HIWORD(wParam)) \
2209 { \
2210 SetMsgHandled(TRUE); \
2211 func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \
2212 lResult = 0; \
2213 if(IsMsgHandled()) \
2214 return TRUE; \
2215 }
2216
2217 // LRESULT OnNotifyHandlerEX(LPNMHDR pnmh)
2218 #define NOTIFY_HANDLER_EX(id, cd, func) \
2219 if (uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code && id == ((LPNMHDR)lParam)->idFrom) \
2220 { \
2221 SetMsgHandled(TRUE); \
2222 lResult = func((LPNMHDR)lParam); \
2223 if(IsMsgHandled()) \
2224 return TRUE; \
2225 }
2226
2227 // LRESULT OnNotifyIDHandlerEX(LPNMHDR pnmh)
2228 #define NOTIFY_ID_HANDLER_EX(id, func) \
2229 if (uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \
2230 { \
2231 SetMsgHandled(TRUE); \
2232 lResult = func((LPNMHDR)lParam); \
2233 if(IsMsgHandled()) \
2234 return TRUE; \
2235 }
2236
2237 // LRESULT OnNotifyCodeHandlerEX(LPNMHDR pnmh)
2238 #define NOTIFY_CODE_HANDLER_EX(cd, func) \
2239 if (uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \
2240 { \
2241 SetMsgHandled(TRUE); \
2242 lResult = func((LPNMHDR)lParam); \
2243 if(IsMsgHandled()) \
2244 return TRUE; \
2245 }
2246
2247 // void OnCommandRangeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl)
2248 #define COMMAND_RANGE_HANDLER_EX(idFirst, idLast, func) \
2249 if(uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
2250 { \
2251 SetMsgHandled(TRUE); \
2252 func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \
2253 lResult = 0; \
2254 if(IsMsgHandled()) \
2255 return TRUE; \
2256 }
2257
2258 // void OnCommandRangeCodeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl)
2259 #define COMMAND_RANGE_CODE_HANDLER_EX(idFirst, idLast, code, func) \
2260 if(uMsg == WM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
2261 { \
2262 SetMsgHandled(TRUE); \
2263 func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \
2264 lResult = 0; \
2265 if(IsMsgHandled()) \
2266 return TRUE; \
2267 }
2268
2269 // LRESULT OnNotifyRangeHandlerEX(LPNMHDR pnmh)
2270 #define NOTIFY_RANGE_HANDLER_EX(idFirst, idLast, func) \
2271 if(uMsg == WM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
2272 { \
2273 SetMsgHandled(TRUE); \
2274 lResult = func((LPNMHDR)lParam); \
2275 if(IsMsgHandled()) \
2276 return TRUE; \
2277 }
2278
2279 // LRESULT OnNotifyRangeCodeHandlerEX(LPNMHDR pnmh)
2280 #define NOTIFY_RANGE_CODE_HANDLER_EX(idFirst, idLast, cd, func) \
2281 if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
2282 { \
2283 SetMsgHandled(TRUE); \
2284 lResult = func((LPNMHDR)lParam); \
2285 if(IsMsgHandled()) \
2286 return TRUE; \
2287 }
2288
2289 // LRESULT OnReflectedCommandHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl)
2290 #define REFLECTED_COMMAND_HANDLER_EX(id, code, func) \
2291 if (uMsg == OCM_COMMAND && code == HIWORD(wParam) && id == LOWORD(wParam)) \
2292 { \
2293 SetMsgHandled(TRUE); \
2294 func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \
2295 lResult = 0; \
2296 if(IsMsgHandled()) \
2297 return TRUE; \
2298 }
2299
2300 // LRESULT OnReflectedCommandIDHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl)
2301 #define REFLECTED_COMMAND_ID_HANDLER_EX(id, func) \
2302 if (uMsg == OCM_COMMAND && id == LOWORD(wParam)) \
2303 { \
2304 SetMsgHandled(TRUE); \
2305 func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \
2306 lResult = 0; \
2307 if(IsMsgHandled()) \
2308 return TRUE; \
2309 }
2310
2311 // LRESULT OnReflectedCommandCodeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl)
2312 #define REFLECTED_COMMAND_CODE_HANDLER_EX(code, func) \
2313 if (uMsg == OCM_COMMAND && code == HIWORD(wParam)) \
2314 { \
2315 SetMsgHandled(TRUE); \
2316 func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \
2317 lResult = 0; \
2318 if(IsMsgHandled()) \
2319 return TRUE; \
2320 }
2321
2322 // LRESULT OnReflectedNotifyHandlerEX(LPNMHDR pnmh)
2323 #define REFLECTED_NOTIFY_HANDLER_EX(id, cd, func) \
2324 if (uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code && id == ((LPNMHDR)lParam)->idFrom) \
2325 { \
2326 SetMsgHandled(TRUE); \
2327 lResult = func((LPNMHDR)lParam); \
2328 if(IsMsgHandled()) \
2329 return TRUE; \
2330 }
2331
2332 // LRESULT OnReflectedNotifyIDHandlerEX(LPNMHDR pnmh)
2333 #define REFLECTED_NOTIFY_ID_HANDLER_EX(id, func) \
2334 if (uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \
2335 { \
2336 SetMsgHandled(TRUE); \
2337 lResult = func((LPNMHDR)lParam); \
2338 if(IsMsgHandled()) \
2339 return TRUE; \
2340 }
2341
2342 // LRESULT OnReflectedNotifyCodeHandlerEX(LPNMHDR pnmh)
2343 #define REFLECTED_NOTIFY_CODE_HANDLER_EX(cd, func) \
2344 if (uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \
2345 { \
2346 SetMsgHandled(TRUE); \
2347 lResult = func((LPNMHDR)lParam); \
2348 if(IsMsgHandled()) \
2349 return TRUE; \
2350 }
2351
2352 // void OnReflectedCommandRangeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl)
2353 #define REFLECTED_COMMAND_RANGE_HANDLER_EX(idFirst, idLast, func) \
2354 if(uMsg == OCM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
2355 { \
2356 SetMsgHandled(TRUE); \
2357 func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \
2358 lResult = 0; \
2359 if(IsMsgHandled()) \
2360 return TRUE; \
2361 }
2362
2363 // void OnReflectedCommandRangeCodeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl)
2364 #define REFLECTED_COMMAND_RANGE_CODE_HANDLER_EX(idFirst, idLast, code, func) \
2365 if(uMsg == OCM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
2366 { \
2367 SetMsgHandled(TRUE); \
2368 func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \
2369 lResult = 0; \
2370 if(IsMsgHandled()) \
2371 return TRUE; \
2372 }
2373
2374 // LRESULT OnReflectedNotifyRangeHandlerEX(LPNMHDR pnmh)
2375 #define REFLECTED_NOTIFY_RANGE_HANDLER_EX(idFirst, idLast, func) \
2376 if(uMsg == OCM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
2377 { \
2378 SetMsgHandled(TRUE); \
2379 lResult = func((LPNMHDR)lParam); \
2380 if(IsMsgHandled()) \
2381 return TRUE; \
2382 }
2383
2384 // LRESULT OnReflectedNotifyRangeCodeHandlerEX(LPNMHDR pnmh)
2385 #define REFLECTED_NOTIFY_RANGE_CODE_HANDLER_EX(idFirst, idLast, cd, func) \
2386 if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
2387 { \
2388 SetMsgHandled(TRUE); \
2389 lResult = func((LPNMHDR)lParam); \
2390 if(IsMsgHandled()) \
2391 return TRUE; \
2392 }
2393
2394 #endif // __ATLCRACK_H__
+0
-10252
src/third_party/wtl/Include/atlctrls.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLCTRLS_H__
9 #define __ATLCTRLS_H__
10
11 #pragma once
12
13 #ifndef __ATLAPP_H__
14 #error atlctrls.h requires atlapp.h to be included first
15 #endif
16
17 #ifndef __ATLWIN_H__
18 #error atlctrls.h requires atlwin.h to be included first
19 #endif
20
21 #ifndef _WIN32_WCE
22 #include <richedit.h>
23 #include <richole.h>
24 #elif defined(WIN32_PLATFORM_WFSP) && !defined(_WINUSERM_H_)
25 #include <winuserm.h>
26 #endif // !_WIN32_WCE
27
28 // protect template members from windowsx.h macros
29 #ifdef _INC_WINDOWSX
30 #undef GetNextSibling
31 #undef GetPrevSibling
32 #endif // _INC_WINDOWSX
33
34
35 ///////////////////////////////////////////////////////////////////////////////
36 // Classes in this file:
37 //
38 // CStaticT<TBase> - CStatic
39 // CButtonT<TBase> - CButton
40 // CListBoxT<TBase> - CListBox
41 // CComboBoxT<TBase> - CComboBox
42 // CEditT<TBase> - CEdit
43 // CEditCommands<T>
44 // CScrollBarT<TBase> - CScrollBar
45 //
46 // CImageListT<t_bManaged> - CImageList, CImageListManaged
47 // CListViewCtrlT<TBase> - CListViewCtrl
48 // CTreeViewCtrlT<TBase> - CTreeViewCtrl
49 // CTreeItemT<TBase> - CTreeItem
50 // CTreeViewCtrlExT<TBase> - CTreeViewCtrlEx
51 // CHeaderCtrlT<TBase> - CHeaderCtrl
52 // CToolBarCtrlT<TBase> - CToolBarCtrl
53 // CStatusBarCtrlT<TBase> - CStatusBarCtrl
54 // CTabCtrlT<TBase> - CTabCtrl
55 // CToolInfo
56 // CToolTipCtrlT<TBase> - CToolTipCtrl
57 // CTrackBarCtrlT<TBase> - CTrackBarCtrl
58 // CUpDownCtrlT<TBase> - CUpDownCtrl
59 // CProgressBarCtrlT<TBase> - CProgressBarCtrl
60 // CHotKeyCtrlT<TBase> - CHotKeyCtrl
61 // CAnimateCtrlT<TBase> - CAnimateCtrl
62 // CRichEditCtrlT<TBase> - CRichEditCtrl
63 // CRichEditCommands<T>
64 // CDragListBoxT<TBase> - CDragListBox
65 // CDragListNotifyImpl<T>
66 // CReBarCtrlT<TBase> - CReBarCtrl
67 // CComboBoxExT<TBase> - CComboBoxEx
68 // CDateTimePickerCtrlT<TBase> - CDateTimePickerCtrl
69 // CMonthCalendarCtrlT<TBase> - CMonthCalendarCtrl
70 // CFlatScrollBarImpl<T>
71 // CFlatScrollBarT<TBase> - CFlatScrollBar
72 // CIPAddressCtrlT<TBase> - CIPAddressCtrl
73 // CPagerCtrlT<TBase> - CPagerCtrl
74 // CLinkCtrlT<TBase> - CLinkCtrl
75 //
76 // CCustomDraw<T>
77 //
78 // CCECommandBarCtrlT<TBase> - CCECommandBarCtrl
79 // CCECommandBandsCtrlT<TBase> - CCECommandBandsCtrl
80
81
82 namespace WTL
83 {
84
85 // These are wrapper classes for Windows standard and common controls.
86 // To implement a window based on a control, use following:
87 // Example: Implementing a window based on a list box
88 //
89 // class CMyListBox : CWindowImpl<CMyListBox, CListBox>
90 // {
91 // public:
92 // BEGIN_MSG_MAP(CMyListBox)
93 // // put your message handler entries here
94 // END_MSG_MAP()
95 // };
96
97
98
99 // --- Standard Windows controls ---
100
101 ///////////////////////////////////////////////////////////////////////////////
102 // CStatic - client side for a Windows STATIC control
103
104 template <class TBase>
105 class CStaticT : public TBase
106 {
107 public:
108 // Constructors
109 CStaticT(HWND hWnd = NULL) : TBase(hWnd)
110 { }
111
112 CStaticT< TBase >& operator =(HWND hWnd)
113 {
114 m_hWnd = hWnd;
115 return *this;
116 }
117
118 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
119 DWORD dwStyle = 0, DWORD dwExStyle = 0,
120 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
121 {
122 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
123 }
124
125 // Attributes
126 static LPCTSTR GetWndClassName()
127 {
128 return _T("STATIC");
129 }
130
131 #ifndef _WIN32_WCE
132 HICON GetIcon() const
133 {
134 ATLASSERT(::IsWindow(m_hWnd));
135 return (HICON)::SendMessage(m_hWnd, STM_GETICON, 0, 0L);
136 }
137
138 HICON SetIcon(HICON hIcon)
139 {
140 ATLASSERT(::IsWindow(m_hWnd));
141 return (HICON)::SendMessage(m_hWnd, STM_SETICON, (WPARAM)hIcon, 0L);
142 }
143
144 HENHMETAFILE GetEnhMetaFile() const
145 {
146 ATLASSERT(::IsWindow(m_hWnd));
147 return (HENHMETAFILE)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_ENHMETAFILE, 0L);
148 }
149
150 HENHMETAFILE SetEnhMetaFile(HENHMETAFILE hMetaFile)
151 {
152 ATLASSERT(::IsWindow(m_hWnd));
153 return (HENHMETAFILE)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_ENHMETAFILE, (LPARAM)hMetaFile);
154 }
155 #else // CE specific
156 HICON GetIcon() const
157 {
158 ATLASSERT(::IsWindow(m_hWnd));
159 return (HICON)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_ICON, 0L);
160 }
161
162 HICON SetIcon(HICON hIcon)
163 {
164 ATLASSERT(::IsWindow(m_hWnd));
165 return (HICON)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
166 }
167 #endif // _WIN32_WCE
168
169 CBitmapHandle GetBitmap() const
170 {
171 ATLASSERT(::IsWindow(m_hWnd));
172 return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_BITMAP, 0L));
173 }
174
175 CBitmapHandle SetBitmap(HBITMAP hBitmap)
176 {
177 ATLASSERT(::IsWindow(m_hWnd));
178 return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap));
179 }
180
181 HCURSOR GetCursor() const
182 {
183 ATLASSERT(::IsWindow(m_hWnd));
184 return (HCURSOR)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_CURSOR, 0L);
185 }
186
187 HCURSOR SetCursor(HCURSOR hCursor)
188 {
189 ATLASSERT(::IsWindow(m_hWnd));
190 return (HCURSOR)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_CURSOR, (LPARAM)hCursor);
191 }
192 };
193
194 typedef CStaticT<ATL::CWindow> CStatic;
195
196
197 ///////////////////////////////////////////////////////////////////////////////
198 // CButton - client side for a Windows BUTTON control
199
200 template <class TBase>
201 class CButtonT : public TBase
202 {
203 public:
204 // Constructors
205 CButtonT(HWND hWnd = NULL) : TBase(hWnd)
206 { }
207
208 CButtonT< TBase >& operator =(HWND hWnd)
209 {
210 m_hWnd = hWnd;
211 return *this;
212 }
213
214 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
215 DWORD dwStyle = 0, DWORD dwExStyle = 0,
216 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
217 {
218 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
219 }
220
221 // Attributes
222 static LPCTSTR GetWndClassName()
223 {
224 return _T("BUTTON");
225 }
226
227 UINT GetState() const
228 {
229 ATLASSERT(::IsWindow(m_hWnd));
230 return (UINT)::SendMessage(m_hWnd, BM_GETSTATE, 0, 0L);
231 }
232
233 void SetState(BOOL bHighlight)
234 {
235 ATLASSERT(::IsWindow(m_hWnd));
236 ::SendMessage(m_hWnd, BM_SETSTATE, bHighlight, 0L);
237 }
238
239 int GetCheck() const
240 {
241 ATLASSERT(::IsWindow(m_hWnd));
242 return (int)::SendMessage(m_hWnd, BM_GETCHECK, 0, 0L);
243 }
244
245 void SetCheck(int nCheck)
246 {
247 ATLASSERT(::IsWindow(m_hWnd));
248 ::SendMessage(m_hWnd, BM_SETCHECK, nCheck, 0L);
249 }
250
251 UINT GetButtonStyle() const
252 {
253 ATLASSERT(::IsWindow(m_hWnd));
254 return (UINT)::GetWindowLong(m_hWnd, GWL_STYLE) & 0xFFFF;
255 }
256
257 void SetButtonStyle(UINT nStyle, BOOL bRedraw = TRUE)
258 {
259 ATLASSERT(::IsWindow(m_hWnd));
260 ::SendMessage(m_hWnd, BM_SETSTYLE, nStyle, (LPARAM)bRedraw);
261 }
262
263 #ifndef _WIN32_WCE
264 HICON GetIcon() const
265 {
266 ATLASSERT(::IsWindow(m_hWnd));
267 return (HICON)::SendMessage(m_hWnd, BM_GETIMAGE, IMAGE_ICON, 0L);
268 }
269
270 HICON SetIcon(HICON hIcon)
271 {
272 ATLASSERT(::IsWindow(m_hWnd));
273 return (HICON)::SendMessage(m_hWnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
274 }
275
276 CBitmapHandle GetBitmap() const
277 {
278 ATLASSERT(::IsWindow(m_hWnd));
279 return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, BM_GETIMAGE, IMAGE_BITMAP, 0L));
280 }
281
282 CBitmapHandle SetBitmap(HBITMAP hBitmap)
283 {
284 ATLASSERT(::IsWindow(m_hWnd));
285 return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap));
286 }
287 #endif // !_WIN32_WCE
288
289 #if (_WIN32_WINNT >= 0x0501)
290 BOOL GetIdealSize(LPSIZE lpSize) const
291 {
292 ATLASSERT(::IsWindow(m_hWnd));
293 return (BOOL)::SendMessage(m_hWnd, BCM_GETIDEALSIZE, 0, (LPARAM)lpSize);
294 }
295
296 BOOL GetImageList(PBUTTON_IMAGELIST pButtonImagelist) const
297 {
298 ATLASSERT(::IsWindow(m_hWnd));
299 return (BOOL)::SendMessage(m_hWnd, BCM_GETIMAGELIST, 0, (LPARAM)pButtonImagelist);
300 }
301
302 BOOL SetImageList(PBUTTON_IMAGELIST pButtonImagelist)
303 {
304 ATLASSERT(::IsWindow(m_hWnd));
305 return (BOOL)::SendMessage(m_hWnd, BCM_SETIMAGELIST, 0, (LPARAM)pButtonImagelist);
306 }
307
308 BOOL GetTextMargin(LPRECT lpRect) const
309 {
310 ATLASSERT(::IsWindow(m_hWnd));
311 return (BOOL)::SendMessage(m_hWnd, BCM_GETTEXTMARGIN, 0, (LPARAM)lpRect);
312 }
313
314 BOOL SetTextMargin(LPRECT lpRect)
315 {
316 ATLASSERT(::IsWindow(m_hWnd));
317 return (BOOL)::SendMessage(m_hWnd, BCM_SETTEXTMARGIN, 0, (LPARAM)lpRect);
318 }
319 #endif // (_WIN32_WINNT >= 0x0501)
320
321 #if (WINVER >= 0x0600)
322 void SetDontClick(BOOL bDontClick)
323 {
324 ATLASSERT(::IsWindow(m_hWnd));
325 ::SendMessage(m_hWnd, BM_SETDONTCLICK, (WPARAM)bDontClick, 0L);
326 }
327 #endif // (WINVER >= 0x0600)
328
329 #if (_WIN32_WINNT >= 0x0600)
330 BOOL SetDropDownState(BOOL bDropDown)
331 {
332 ATLASSERT(::IsWindow(m_hWnd));
333 ATLASSERT((GetStyle() & (BS_SPLITBUTTON | BS_DEFSPLITBUTTON)) != 0);
334 return (BOOL)::SendMessage(m_hWnd, BCM_SETDROPDOWNSTATE, (WPARAM)bDropDown, 0L);
335 }
336
337 BOOL GetSplitInfo(PBUTTON_SPLITINFO pSplitInfo) const
338 {
339 ATLASSERT(::IsWindow(m_hWnd));
340 ATLASSERT((GetStyle() & (BS_SPLITBUTTON | BS_DEFSPLITBUTTON)) != 0);
341 return (BOOL)::SendMessage(m_hWnd, BCM_GETSPLITINFO, 0, (LPARAM)pSplitInfo);
342 }
343
344 BOOL SetSplitInfo(PBUTTON_SPLITINFO pSplitInfo)
345 {
346 ATLASSERT(::IsWindow(m_hWnd));
347 ATLASSERT((GetStyle() & (BS_SPLITBUTTON | BS_DEFSPLITBUTTON)) != 0);
348 return (BOOL)::SendMessage(m_hWnd, BCM_SETSPLITINFO, 0, (LPARAM)pSplitInfo);
349 }
350
351 int GetNoteLength() const
352 {
353 ATLASSERT(::IsWindow(m_hWnd));
354 ATLASSERT((GetStyle() & (BS_COMMANDLINK | BS_DEFCOMMANDLINK)) != 0);
355 return (int)::SendMessage(m_hWnd, BCM_GETNOTELENGTH, 0, 0L);
356 }
357
358 BOOL GetNote(LPWSTR lpstrNoteText, int cchNoteText) const
359 {
360 ATLASSERT(::IsWindow(m_hWnd));
361 ATLASSERT((GetStyle() & (BS_COMMANDLINK | BS_DEFCOMMANDLINK)) != 0);
362 return (BOOL)::SendMessage(m_hWnd, BCM_GETNOTE, cchNoteText, (LPARAM)lpstrNoteText);
363 }
364
365 BOOL SetNote(LPCWSTR lpstrNoteText)
366 {
367 ATLASSERT(::IsWindow(m_hWnd));
368 ATLASSERT((GetStyle() & (BS_COMMANDLINK | BS_DEFCOMMANDLINK)) != 0);
369 return (BOOL)::SendMessage(m_hWnd, BCM_SETNOTE, 0, (LPARAM)lpstrNoteText);
370 }
371
372 LRESULT SetElevationRequiredState(BOOL bSet)
373 {
374 ATLASSERT(::IsWindow(m_hWnd));
375 return ::SendMessage(m_hWnd, BCM_SETSHIELD, 0, (LPARAM)bSet);
376 }
377 #endif // (_WIN32_WINNT >= 0x0600)
378
379 // Operations
380 void Click()
381 {
382 ATLASSERT(::IsWindow(m_hWnd));
383 ::SendMessage(m_hWnd, BM_CLICK, 0, 0L);
384 }
385 };
386
387 typedef CButtonT<ATL::CWindow> CButton;
388
389
390 ///////////////////////////////////////////////////////////////////////////////
391 // CListBox - client side for a Windows LISTBOX control
392
393 template <class TBase>
394 class CListBoxT : public TBase
395 {
396 public:
397 // Constructors
398 CListBoxT(HWND hWnd = NULL) : TBase(hWnd)
399 { }
400
401 CListBoxT< TBase >& operator =(HWND hWnd)
402 {
403 m_hWnd = hWnd;
404 return *this;
405 }
406
407 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
408 DWORD dwStyle = 0, DWORD dwExStyle = 0,
409 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
410 {
411 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
412 }
413
414 // Attributes
415 static LPCTSTR GetWndClassName()
416 {
417 return _T("LISTBOX");
418 }
419
420 // for entire listbox
421 int GetCount() const
422 {
423 ATLASSERT(::IsWindow(m_hWnd));
424 return (int)::SendMessage(m_hWnd, LB_GETCOUNT, 0, 0L);
425 }
426
427 #ifndef _WIN32_WCE
428 int SetCount(int cItems)
429 {
430 ATLASSERT(::IsWindow(m_hWnd));
431 ATLASSERT(((GetStyle() & LBS_NODATA) != 0) && ((GetStyle() & LBS_HASSTRINGS) == 0));
432 return (int)::SendMessage(m_hWnd, LB_SETCOUNT, cItems, 0L);
433 }
434 #endif // !_WIN32_WCE
435
436 int GetHorizontalExtent() const
437 {
438 ATLASSERT(::IsWindow(m_hWnd));
439 return (int)::SendMessage(m_hWnd, LB_GETHORIZONTALEXTENT, 0, 0L);
440 }
441
442 void SetHorizontalExtent(int cxExtent)
443 {
444 ATLASSERT(::IsWindow(m_hWnd));
445 ::SendMessage(m_hWnd, LB_SETHORIZONTALEXTENT, cxExtent, 0L);
446 }
447
448 int GetTopIndex() const
449 {
450 ATLASSERT(::IsWindow(m_hWnd));
451 return (int)::SendMessage(m_hWnd, LB_GETTOPINDEX, 0, 0L);
452 }
453
454 int SetTopIndex(int nIndex)
455 {
456 ATLASSERT(::IsWindow(m_hWnd));
457 return (int)::SendMessage(m_hWnd, LB_SETTOPINDEX, nIndex, 0L);
458 }
459
460 LCID GetLocale() const
461 {
462 ATLASSERT(::IsWindow(m_hWnd));
463 return (LCID)::SendMessage(m_hWnd, LB_GETLOCALE, 0, 0L);
464 }
465
466 LCID SetLocale(LCID nNewLocale)
467 {
468 ATLASSERT(::IsWindow(m_hWnd));
469 return (LCID)::SendMessage(m_hWnd, LB_SETLOCALE, (WPARAM)nNewLocale, 0L);
470 }
471
472 #if (WINVER >= 0x0500) && !defined(_WIN32_WCE)
473 DWORD GetListBoxInfo() const
474 {
475 ATLASSERT(::IsWindow(m_hWnd));
476 #if (_WIN32_WINNT >= 0x0501)
477 return (DWORD)::SendMessage(m_hWnd, LB_GETLISTBOXINFO, 0, 0L);
478 #else // !(_WIN32_WINNT >= 0x0501)
479 return ::GetListBoxInfo(m_hWnd);
480 #endif // !(_WIN32_WINNT >= 0x0501)
481 }
482 #endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE)
483
484 // for single-selection listboxes
485 int GetCurSel() const
486 {
487 ATLASSERT(::IsWindow(m_hWnd));
488 ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) == 0);
489 return (int)::SendMessage(m_hWnd, LB_GETCURSEL, 0, 0L);
490 }
491
492 int SetCurSel(int nSelect)
493 {
494 ATLASSERT(::IsWindow(m_hWnd));
495 ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) == 0);
496 return (int)::SendMessage(m_hWnd, LB_SETCURSEL, nSelect, 0L);
497 }
498
499 // for multiple-selection listboxes
500 int GetSel(int nIndex) const // also works for single-selection
501 {
502 ATLASSERT(::IsWindow(m_hWnd));
503 return (int)::SendMessage(m_hWnd, LB_GETSEL, nIndex, 0L);
504 }
505
506 int SetSel(int nIndex, BOOL bSelect = TRUE)
507 {
508 ATLASSERT(::IsWindow(m_hWnd));
509 ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0);
510 return (int)::SendMessage(m_hWnd, LB_SETSEL, bSelect, nIndex);
511 }
512
513 int GetSelCount() const
514 {
515 ATLASSERT(::IsWindow(m_hWnd));
516 ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0);
517 return (int)::SendMessage(m_hWnd, LB_GETSELCOUNT, 0, 0L);
518 }
519
520 int GetSelItems(int nMaxItems, LPINT rgIndex) const
521 {
522 ATLASSERT(::IsWindow(m_hWnd));
523 ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0);
524 return (int)::SendMessage(m_hWnd, LB_GETSELITEMS, nMaxItems, (LPARAM)rgIndex);
525 }
526
527 int GetAnchorIndex() const
528 {
529 ATLASSERT(::IsWindow(m_hWnd));
530 ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0);
531 return (int)::SendMessage(m_hWnd, LB_GETANCHORINDEX, 0, 0L);
532 }
533
534 void SetAnchorIndex(int nIndex)
535 {
536 ATLASSERT(::IsWindow(m_hWnd));
537 ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0);
538 ::SendMessage(m_hWnd, LB_SETANCHORINDEX, nIndex, 0L);
539 }
540
541 int GetCaretIndex() const
542 {
543 ATLASSERT(::IsWindow(m_hWnd));
544 return (int)::SendMessage(m_hWnd, LB_GETCARETINDEX, 0, 0);
545 }
546
547 int SetCaretIndex(int nIndex, BOOL bScroll = TRUE)
548 {
549 ATLASSERT(::IsWindow(m_hWnd));
550 return (int)::SendMessage(m_hWnd, LB_SETCARETINDEX, nIndex, MAKELONG(bScroll, 0));
551 }
552
553 // for listbox items
554 DWORD_PTR GetItemData(int nIndex) const
555 {
556 ATLASSERT(::IsWindow(m_hWnd));
557 return (DWORD_PTR)::SendMessage(m_hWnd, LB_GETITEMDATA, nIndex, 0L);
558 }
559
560 int SetItemData(int nIndex, DWORD_PTR dwItemData)
561 {
562 ATLASSERT(::IsWindow(m_hWnd));
563 return (int)::SendMessage(m_hWnd, LB_SETITEMDATA, nIndex, (LPARAM)dwItemData);
564 }
565
566 void* GetItemDataPtr(int nIndex) const
567 {
568 ATLASSERT(::IsWindow(m_hWnd));
569 return (void*)::SendMessage(m_hWnd, LB_GETITEMDATA, nIndex, 0L);
570 }
571
572 int SetItemDataPtr(int nIndex, void* pData)
573 {
574 ATLASSERT(::IsWindow(m_hWnd));
575 return SetItemData(nIndex, (DWORD_PTR)pData);
576 }
577
578 int GetItemRect(int nIndex, LPRECT lpRect) const
579 {
580 ATLASSERT(::IsWindow(m_hWnd));
581 return (int)::SendMessage(m_hWnd, LB_GETITEMRECT, nIndex, (LPARAM)lpRect);
582 }
583
584 int GetText(int nIndex, LPTSTR lpszBuffer) const
585 {
586 ATLASSERT(::IsWindow(m_hWnd));
587 return (int)::SendMessage(m_hWnd, LB_GETTEXT, nIndex, (LPARAM)lpszBuffer);
588 }
589
590 #ifndef _ATL_NO_COM
591 #ifdef _OLEAUTO_H_
592 BOOL GetTextBSTR(int nIndex, BSTR& bstrText) const
593 {
594 USES_CONVERSION;
595 ATLASSERT(::IsWindow(m_hWnd));
596 ATLASSERT(bstrText == NULL);
597
598 int nLen = GetTextLen(nIndex);
599 if(nLen == LB_ERR)
600 return FALSE;
601
602 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
603 LPTSTR lpstrText = buff.Allocate(nLen + 1);
604 if(lpstrText == NULL)
605 return FALSE;
606
607 if(GetText(nIndex, lpstrText) == LB_ERR)
608 return FALSE;
609
610 bstrText = ::SysAllocString(T2OLE(lpstrText));
611 return (bstrText != NULL) ? TRUE : FALSE;
612 }
613 #endif // _OLEAUTO_H_
614 #endif // !_ATL_NO_COM
615
616 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
617 int GetText(int nIndex, _CSTRING_NS::CString& strText) const
618 {
619 ATLASSERT(::IsWindow(m_hWnd));
620 int cchLen = GetTextLen(nIndex);
621 if(cchLen == LB_ERR)
622 return LB_ERR;
623 int nRet = LB_ERR;
624 LPTSTR lpstr = strText.GetBufferSetLength(cchLen);
625 if(lpstr != NULL)
626 {
627 nRet = GetText(nIndex, lpstr);
628 strText.ReleaseBuffer();
629 }
630 return nRet;
631 }
632 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
633
634 int GetTextLen(int nIndex) const
635 {
636 ATLASSERT(::IsWindow(m_hWnd));
637 return (int)::SendMessage(m_hWnd, LB_GETTEXTLEN, nIndex, 0L);
638 }
639
640 int GetItemHeight(int nIndex) const
641 {
642 ATLASSERT(::IsWindow(m_hWnd));
643 return (int)::SendMessage(m_hWnd, LB_GETITEMHEIGHT, nIndex, 0L);
644 }
645
646 int SetItemHeight(int nIndex, UINT cyItemHeight)
647 {
648 ATLASSERT(::IsWindow(m_hWnd));
649 return (int)::SendMessage(m_hWnd, LB_SETITEMHEIGHT, nIndex, MAKELONG(cyItemHeight, 0));
650 }
651
652 // Settable only attributes
653 void SetColumnWidth(int cxWidth)
654 {
655 ATLASSERT(::IsWindow(m_hWnd));
656 ::SendMessage(m_hWnd, LB_SETCOLUMNWIDTH, cxWidth, 0L);
657 }
658
659 BOOL SetTabStops(int nTabStops, LPINT rgTabStops)
660 {
661 ATLASSERT(::IsWindow(m_hWnd));
662 ATLASSERT((GetStyle() & LBS_USETABSTOPS) != 0);
663 return (BOOL)::SendMessage(m_hWnd, LB_SETTABSTOPS, nTabStops, (LPARAM)rgTabStops);
664 }
665
666 BOOL SetTabStops()
667 {
668 ATLASSERT(::IsWindow(m_hWnd));
669 ATLASSERT((GetStyle() & LBS_USETABSTOPS) != 0);
670 return (BOOL)::SendMessage(m_hWnd, LB_SETTABSTOPS, 0, 0L);
671 }
672
673 BOOL SetTabStops(const int& cxEachStop) // takes an 'int'
674 {
675 ATLASSERT(::IsWindow(m_hWnd));
676 ATLASSERT((GetStyle() & LBS_USETABSTOPS) != 0);
677 return (BOOL)::SendMessage(m_hWnd, LB_SETTABSTOPS, 1, (LPARAM)(LPINT)&cxEachStop);
678 }
679
680 // Operations
681 int InitStorage(int nItems, UINT nBytes)
682 {
683 ATLASSERT(::IsWindow(m_hWnd));
684 return (int)::SendMessage(m_hWnd, LB_INITSTORAGE, (WPARAM)nItems, nBytes);
685 }
686
687 void ResetContent()
688 {
689 ATLASSERT(::IsWindow(m_hWnd));
690 ::SendMessage(m_hWnd, LB_RESETCONTENT, 0, 0L);
691 }
692
693 UINT ItemFromPoint(POINT pt, BOOL& bOutside) const
694 {
695 ATLASSERT(::IsWindow(m_hWnd));
696 DWORD dw = (DWORD)::SendMessage(m_hWnd, LB_ITEMFROMPOINT, 0, MAKELPARAM(pt.x, pt.y));
697 bOutside = (BOOL)HIWORD(dw);
698 return (UINT)LOWORD(dw);
699 }
700
701 // manipulating listbox items
702 int AddString(LPCTSTR lpszItem)
703 {
704 ATLASSERT(::IsWindow(m_hWnd));
705 return (int)::SendMessage(m_hWnd, LB_ADDSTRING, 0, (LPARAM)lpszItem);
706 }
707
708 int DeleteString(UINT nIndex)
709 {
710 ATLASSERT(::IsWindow(m_hWnd));
711 return (int)::SendMessage(m_hWnd, LB_DELETESTRING, nIndex, 0L);
712 }
713
714 int InsertString(int nIndex, LPCTSTR lpszItem)
715 {
716 ATLASSERT(::IsWindow(m_hWnd));
717 return (int)::SendMessage(m_hWnd, LB_INSERTSTRING, nIndex, (LPARAM)lpszItem);
718 }
719
720 #ifndef _WIN32_WCE
721 int Dir(UINT attr, LPCTSTR lpszWildCard)
722 {
723 ATLASSERT(::IsWindow(m_hWnd));
724 return (int)::SendMessage(m_hWnd, LB_DIR, attr, (LPARAM)lpszWildCard);
725 }
726
727 int AddFile(LPCTSTR lpstrFileName)
728 {
729 ATLASSERT(::IsWindow(m_hWnd));
730 return (int)::SendMessage(m_hWnd, LB_ADDFILE, 0, (LPARAM)lpstrFileName);
731 }
732 #endif // !_WIN32_WCE
733
734 // selection helpers
735 int FindString(int nStartAfter, LPCTSTR lpszItem) const
736 {
737 ATLASSERT(::IsWindow(m_hWnd));
738 return (int)::SendMessage(m_hWnd, LB_FINDSTRING, nStartAfter, (LPARAM)lpszItem);
739 }
740
741 int FindStringExact(int nIndexStart, LPCTSTR lpszFind) const
742 {
743 ATLASSERT(::IsWindow(m_hWnd));
744 return (int)::SendMessage(m_hWnd, LB_FINDSTRINGEXACT, nIndexStart, (LPARAM)lpszFind);
745 }
746
747 int SelectString(int nStartAfter, LPCTSTR lpszItem)
748 {
749 ATLASSERT(::IsWindow(m_hWnd));
750 return (int)::SendMessage(m_hWnd, LB_SELECTSTRING, nStartAfter, (LPARAM)lpszItem);
751 }
752
753 int SelItemRange(BOOL bSelect, int nFirstItem, int nLastItem)
754 {
755 ATLASSERT(::IsWindow(m_hWnd));
756 ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0);
757 ATLASSERT(nFirstItem <= nLastItem);
758 return bSelect ? (int)::SendMessage(m_hWnd, LB_SELITEMRANGEEX, nFirstItem, nLastItem) : (int)::SendMessage(m_hWnd, LB_SELITEMRANGEEX, nLastItem, nFirstItem);
759 }
760
761 #ifdef WIN32_PLATFORM_WFSP // SmartPhone only messages
762 DWORD GetInputMode(BOOL bCurrentMode = TRUE)
763 {
764 return SendMessage(LB_GETINPUTMODE, 0, (LPARAM)bCurrentMode);
765 }
766
767 BOOL SetInputMode(DWORD dwMode)
768 {
769 return SendMessage(LB_SETINPUTMODE, 0, (LPARAM)dwMode);
770 }
771 #endif // WIN32_PLATFORM_WFSP
772 };
773
774 typedef CListBoxT<ATL::CWindow> CListBox;
775
776
777 ///////////////////////////////////////////////////////////////////////////////
778 // CComboBox - client side for a Windows COMBOBOX control
779
780 #ifndef WIN32_PLATFORM_WFSP // No COMBOBOX on SmartPhones
781
782 template <class TBase>
783 class CComboBoxT : public TBase
784 {
785 public:
786 // Constructors
787 CComboBoxT(HWND hWnd = NULL) : TBase(hWnd)
788 { }
789
790 CComboBoxT< TBase >& operator =(HWND hWnd)
791 {
792 m_hWnd = hWnd;
793 return *this;
794 }
795
796 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
797 DWORD dwStyle = 0, DWORD dwExStyle = 0,
798 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
799 {
800 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
801 }
802
803 // Attributes
804 static LPCTSTR GetWndClassName()
805 {
806 return _T("COMBOBOX");
807 }
808
809 // for entire combo box
810 int GetCount() const
811 {
812 ATLASSERT(::IsWindow(m_hWnd));
813 return (int)::SendMessage(m_hWnd, CB_GETCOUNT, 0, 0L);
814 }
815
816 int GetCurSel() const
817 {
818 ATLASSERT(::IsWindow(m_hWnd));
819 return (int)::SendMessage(m_hWnd, CB_GETCURSEL, 0, 0L);
820 }
821
822 int SetCurSel(int nSelect)
823 {
824 ATLASSERT(::IsWindow(m_hWnd));
825 return (int)::SendMessage(m_hWnd, CB_SETCURSEL, nSelect, 0L);
826 }
827
828 LCID GetLocale() const
829 {
830 ATLASSERT(::IsWindow(m_hWnd));
831 return (LCID)::SendMessage(m_hWnd, CB_GETLOCALE, 0, 0L);
832 }
833
834 LCID SetLocale(LCID nNewLocale)
835 {
836 ATLASSERT(::IsWindow(m_hWnd));
837 return (LCID)::SendMessage(m_hWnd, CB_SETLOCALE, (WPARAM)nNewLocale, 0L);
838 }
839
840 int GetTopIndex() const
841 {
842 ATLASSERT(::IsWindow(m_hWnd));
843 return (int)::SendMessage(m_hWnd, CB_GETTOPINDEX, 0, 0L);
844 }
845
846 int SetTopIndex(int nIndex)
847 {
848 ATLASSERT(::IsWindow(m_hWnd));
849 return (int)::SendMessage(m_hWnd, CB_SETTOPINDEX, nIndex, 0L);
850 }
851
852 UINT GetHorizontalExtent() const
853 {
854 ATLASSERT(::IsWindow(m_hWnd));
855 return (UINT)::SendMessage(m_hWnd, CB_GETHORIZONTALEXTENT, 0, 0L);
856 }
857
858 void SetHorizontalExtent(UINT nExtent)
859 {
860 ATLASSERT(::IsWindow(m_hWnd));
861 ::SendMessage(m_hWnd, CB_SETHORIZONTALEXTENT, nExtent, 0L);
862 }
863
864 int GetDroppedWidth() const
865 {
866 ATLASSERT(::IsWindow(m_hWnd));
867 return (int)::SendMessage(m_hWnd, CB_GETDROPPEDWIDTH, 0, 0L);
868 }
869
870 int SetDroppedWidth(UINT nWidth)
871 {
872 ATLASSERT(::IsWindow(m_hWnd));
873 return (int)::SendMessage(m_hWnd, CB_SETDROPPEDWIDTH, nWidth, 0L);
874 }
875
876 #if ((WINVER >= 0x0500) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420))
877 BOOL GetComboBoxInfo(PCOMBOBOXINFO pComboBoxInfo) const
878 {
879 ATLASSERT(::IsWindow(m_hWnd));
880 #if ((_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420))
881 return (BOOL)::SendMessage(m_hWnd, CB_GETCOMBOBOXINFO, 0, (LPARAM)pComboBoxInfo);
882 #else // !((_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420))
883 return ::GetComboBoxInfo(m_hWnd, pComboBoxInfo);
884 #endif // !((_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420))
885 }
886 #endif // ((WINVER >= 0x0500) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420))
887
888 // for edit control
889 DWORD GetEditSel() const
890 {
891 ATLASSERT(::IsWindow(m_hWnd));
892 return (DWORD)::SendMessage(m_hWnd, CB_GETEDITSEL, 0, 0L);
893 }
894
895 BOOL SetEditSel(int nStartChar, int nEndChar)
896 {
897 ATLASSERT(::IsWindow(m_hWnd));
898 return (BOOL)::SendMessage(m_hWnd, CB_SETEDITSEL, 0, MAKELONG(nStartChar, nEndChar));
899 }
900
901 // for combobox item
902 DWORD_PTR GetItemData(int nIndex) const
903 {
904 ATLASSERT(::IsWindow(m_hWnd));
905 return (DWORD_PTR)::SendMessage(m_hWnd, CB_GETITEMDATA, nIndex, 0L);
906 }
907
908 int SetItemData(int nIndex, DWORD_PTR dwItemData)
909 {
910 ATLASSERT(::IsWindow(m_hWnd));
911 return (int)::SendMessage(m_hWnd, CB_SETITEMDATA, nIndex, (LPARAM)dwItemData);
912 }
913
914 void* GetItemDataPtr(int nIndex) const
915 {
916 ATLASSERT(::IsWindow(m_hWnd));
917 return (void*)GetItemData(nIndex);
918 }
919
920 int SetItemDataPtr(int nIndex, void* pData)
921 {
922 ATLASSERT(::IsWindow(m_hWnd));
923 return SetItemData(nIndex, (DWORD_PTR)pData);
924 }
925
926 int GetLBText(int nIndex, LPTSTR lpszText) const
927 {
928 ATLASSERT(::IsWindow(m_hWnd));
929 return (int)::SendMessage(m_hWnd, CB_GETLBTEXT, nIndex, (LPARAM)lpszText);
930 }
931
932 #ifndef _ATL_NO_COM
933 BOOL GetLBTextBSTR(int nIndex, BSTR& bstrText) const
934 {
935 USES_CONVERSION;
936 ATLASSERT(::IsWindow(m_hWnd));
937 ATLASSERT(bstrText == NULL);
938
939 int nLen = GetLBTextLen(nIndex);
940 if(nLen == CB_ERR)
941 return FALSE;
942
943 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
944 LPTSTR lpstrText = buff.Allocate(nLen + 1);
945 if(lpstrText == NULL)
946 return FALSE;
947
948 if(GetLBText(nIndex, lpstrText) == CB_ERR)
949 return FALSE;
950
951 bstrText = ::SysAllocString(T2OLE(lpstrText));
952 return (bstrText != NULL) ? TRUE : FALSE;
953 }
954 #endif // !_ATL_NO_COM
955
956 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
957 int GetLBText(int nIndex, _CSTRING_NS::CString& strText) const
958 {
959 ATLASSERT(::IsWindow(m_hWnd));
960 int cchLen = GetLBTextLen(nIndex);
961 if(cchLen == CB_ERR)
962 return CB_ERR;
963 int nRet = CB_ERR;
964 LPTSTR lpstr = strText.GetBufferSetLength(cchLen);
965 if(lpstr != NULL)
966 {
967 nRet = GetLBText(nIndex, lpstr);
968 strText.ReleaseBuffer();
969 }
970 return nRet;
971 }
972 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
973
974 int GetLBTextLen(int nIndex) const
975 {
976 ATLASSERT(::IsWindow(m_hWnd));
977 return (int)::SendMessage(m_hWnd, CB_GETLBTEXTLEN, nIndex, 0L);
978 }
979
980 int GetItemHeight(int nIndex) const
981 {
982 ATLASSERT(::IsWindow(m_hWnd));
983 return (int)::SendMessage(m_hWnd, CB_GETITEMHEIGHT, nIndex, 0L);
984 }
985
986 int SetItemHeight(int nIndex, UINT cyItemHeight)
987 {
988 ATLASSERT(::IsWindow(m_hWnd));
989 return (int)::SendMessage(m_hWnd, CB_SETITEMHEIGHT, nIndex, MAKELONG(cyItemHeight, 0));
990 }
991
992 BOOL GetExtendedUI() const
993 {
994 ATLASSERT(::IsWindow(m_hWnd));
995 return (BOOL)::SendMessage(m_hWnd, CB_GETEXTENDEDUI, 0, 0L);
996 }
997
998 int SetExtendedUI(BOOL bExtended = TRUE)
999 {
1000 ATLASSERT(::IsWindow(m_hWnd));
1001 return (int)::SendMessage(m_hWnd, CB_SETEXTENDEDUI, bExtended, 0L);
1002 }
1003
1004 void GetDroppedControlRect(LPRECT lprect) const
1005 {
1006 ATLASSERT(::IsWindow(m_hWnd));
1007 ::SendMessage(m_hWnd, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)lprect);
1008 }
1009
1010 BOOL GetDroppedState() const
1011 {
1012 ATLASSERT(::IsWindow(m_hWnd));
1013 return (BOOL)::SendMessage(m_hWnd, CB_GETDROPPEDSTATE, 0, 0L);
1014 }
1015
1016 #if (_WIN32_WINNT >= 0x0501)
1017 int GetMinVisible() const
1018 {
1019 ATLASSERT(::IsWindow(m_hWnd));
1020 return (int)::SendMessage(m_hWnd, CB_GETMINVISIBLE, 0, 0L);
1021 }
1022
1023 BOOL SetMinVisible(int nMinVisible)
1024 {
1025 ATLASSERT(::IsWindow(m_hWnd));
1026 return (BOOL)::SendMessage(m_hWnd, CB_SETMINVISIBLE, nMinVisible, 0L);
1027 }
1028
1029 // Vista only
1030 BOOL GetCueBannerText(LPWSTR lpwText, int cchText) const
1031 {
1032 #ifndef CB_GETCUEBANNER
1033 const UINT CB_GETCUEBANNER = (CBM_FIRST + 4);
1034 #endif
1035 ATLASSERT(::IsWindow(m_hWnd));
1036 return (BOOL)::SendMessage(m_hWnd, CB_GETCUEBANNER, (WPARAM)lpwText, cchText);
1037 }
1038
1039 // Vista only
1040 BOOL SetCueBannerText(LPCWSTR lpcwText)
1041 {
1042 #ifndef CB_SETCUEBANNER
1043 const UINT CB_SETCUEBANNER = (CBM_FIRST + 3);
1044 #endif
1045 ATLASSERT(::IsWindow(m_hWnd));
1046 return (BOOL)::SendMessage(m_hWnd, CB_SETCUEBANNER, 0, (LPARAM)lpcwText);
1047 }
1048 #endif // (_WIN32_WINNT >= 0x0501)
1049
1050 // Operations
1051 int InitStorage(int nItems, UINT nBytes)
1052 {
1053 ATLASSERT(::IsWindow(m_hWnd));
1054 return (int)::SendMessage(m_hWnd, CB_INITSTORAGE, (WPARAM)nItems, nBytes);
1055 }
1056
1057 void ResetContent()
1058 {
1059 ATLASSERT(::IsWindow(m_hWnd));
1060 ::SendMessage(m_hWnd, CB_RESETCONTENT, 0, 0L);
1061 }
1062
1063 // for edit control
1064 BOOL LimitText(int nMaxChars)
1065 {
1066 ATLASSERT(::IsWindow(m_hWnd));
1067 return (BOOL)::SendMessage(m_hWnd, CB_LIMITTEXT, nMaxChars, 0L);
1068 }
1069
1070 // for drop-down combo boxes
1071 void ShowDropDown(BOOL bShowIt = TRUE)
1072 {
1073 ATLASSERT(::IsWindow(m_hWnd));
1074 ::SendMessage(m_hWnd, CB_SHOWDROPDOWN, bShowIt, 0L);
1075 }
1076
1077 // manipulating listbox items
1078 int AddString(LPCTSTR lpszString)
1079 {
1080 ATLASSERT(::IsWindow(m_hWnd));
1081 return (int)::SendMessage(m_hWnd, CB_ADDSTRING, 0, (LPARAM)lpszString);
1082 }
1083
1084 int DeleteString(UINT nIndex)
1085 {
1086 ATLASSERT(::IsWindow(m_hWnd));
1087 return (int)::SendMessage(m_hWnd, CB_DELETESTRING, nIndex, 0L);
1088 }
1089
1090 int InsertString(int nIndex, LPCTSTR lpszString)
1091 {
1092 ATLASSERT(::IsWindow(m_hWnd));
1093 return (int)::SendMessage(m_hWnd, CB_INSERTSTRING, nIndex, (LPARAM)lpszString);
1094 }
1095
1096 #ifndef _WIN32_WCE
1097 int Dir(UINT attr, LPCTSTR lpszWildCard)
1098 {
1099 ATLASSERT(::IsWindow(m_hWnd));
1100 return (int)::SendMessage(m_hWnd, CB_DIR, attr, (LPARAM)lpszWildCard);
1101 }
1102 #endif // !_WIN32_WCE
1103
1104 // selection helpers
1105 int FindString(int nStartAfter, LPCTSTR lpszString) const
1106 {
1107 ATLASSERT(::IsWindow(m_hWnd));
1108 return (int)::SendMessage(m_hWnd, CB_FINDSTRING, nStartAfter, (LPARAM)lpszString);
1109 }
1110
1111 int FindStringExact(int nIndexStart, LPCTSTR lpszFind) const
1112 {
1113 ATLASSERT(::IsWindow(m_hWnd));
1114 return (int)::SendMessage(m_hWnd, CB_FINDSTRINGEXACT, nIndexStart, (LPARAM)lpszFind);
1115 }
1116
1117 int SelectString(int nStartAfter, LPCTSTR lpszString)
1118 {
1119 ATLASSERT(::IsWindow(m_hWnd));
1120 return (int)::SendMessage(m_hWnd, CB_SELECTSTRING, nStartAfter, (LPARAM)lpszString);
1121 }
1122
1123 // Clipboard operations
1124 void Clear()
1125 {
1126 ATLASSERT(::IsWindow(m_hWnd));
1127 ::SendMessage(m_hWnd, WM_CLEAR, 0, 0L);
1128 }
1129
1130 void Copy()
1131 {
1132 ATLASSERT(::IsWindow(m_hWnd));
1133 ::SendMessage(m_hWnd, WM_COPY, 0, 0L);
1134 }
1135
1136 void Cut()
1137 {
1138 ATLASSERT(::IsWindow(m_hWnd));
1139 ::SendMessage(m_hWnd, WM_CUT, 0, 0L);
1140 }
1141
1142 void Paste()
1143 {
1144 ATLASSERT(::IsWindow(m_hWnd));
1145 ::SendMessage(m_hWnd, WM_PASTE, 0, 0L);
1146 }
1147 };
1148
1149 typedef CComboBoxT<ATL::CWindow> CComboBox;
1150
1151 #endif // !WIN32_PLATFORM_WFSP
1152
1153 ///////////////////////////////////////////////////////////////////////////////
1154 // CEdit - client side for a Windows EDIT control
1155
1156 template <class TBase>
1157 class CEditT : public TBase
1158 {
1159 public:
1160 // Constructors
1161 CEditT(HWND hWnd = NULL) : TBase(hWnd)
1162 { }
1163
1164 CEditT< TBase >& operator =(HWND hWnd)
1165 {
1166 m_hWnd = hWnd;
1167 return *this;
1168 }
1169
1170 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
1171 DWORD dwStyle = 0, DWORD dwExStyle = 0,
1172 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
1173 {
1174 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
1175 }
1176
1177 // Attributes
1178 static LPCTSTR GetWndClassName()
1179 {
1180 return _T("EDIT");
1181 }
1182
1183 BOOL CanUndo() const
1184 {
1185 ATLASSERT(::IsWindow(m_hWnd));
1186 return (BOOL)::SendMessage(m_hWnd, EM_CANUNDO, 0, 0L);
1187 }
1188
1189 int GetLineCount() const
1190 {
1191 ATLASSERT(::IsWindow(m_hWnd));
1192 return (int)::SendMessage(m_hWnd, EM_GETLINECOUNT, 0, 0L);
1193 }
1194
1195 BOOL GetModify() const
1196 {
1197 ATLASSERT(::IsWindow(m_hWnd));
1198 return (BOOL)::SendMessage(m_hWnd, EM_GETMODIFY, 0, 0L);
1199 }
1200
1201 void SetModify(BOOL bModified = TRUE)
1202 {
1203 ATLASSERT(::IsWindow(m_hWnd));
1204 ::SendMessage(m_hWnd, EM_SETMODIFY, bModified, 0L);
1205 }
1206
1207 void GetRect(LPRECT lpRect) const
1208 {
1209 ATLASSERT(::IsWindow(m_hWnd));
1210 ::SendMessage(m_hWnd, EM_GETRECT, 0, (LPARAM)lpRect);
1211 }
1212
1213 DWORD GetSel() const
1214 {
1215 ATLASSERT(::IsWindow(m_hWnd));
1216 return (DWORD)::SendMessage(m_hWnd, EM_GETSEL, 0, 0L);
1217 }
1218
1219 void GetSel(int& nStartChar, int& nEndChar) const
1220 {
1221 ATLASSERT(::IsWindow(m_hWnd));
1222 ::SendMessage(m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar);
1223 }
1224
1225 #ifndef _WIN32_WCE
1226 HLOCAL GetHandle() const
1227 {
1228 ATLASSERT(::IsWindow(m_hWnd));
1229 return (HLOCAL)::SendMessage(m_hWnd, EM_GETHANDLE, 0, 0L);
1230 }
1231
1232 void SetHandle(HLOCAL hBuffer)
1233 {
1234 ATLASSERT(::IsWindow(m_hWnd));
1235 ::SendMessage(m_hWnd, EM_SETHANDLE, (WPARAM)hBuffer, 0L);
1236 }
1237 #endif // !_WIN32_WCE
1238
1239 DWORD GetMargins() const
1240 {
1241 ATLASSERT(::IsWindow(m_hWnd));
1242 return (DWORD)::SendMessage(m_hWnd, EM_GETMARGINS, 0, 0L);
1243 }
1244
1245 void GetMargins(UINT& nLeft, UINT& nRight) const
1246 {
1247 ATLASSERT(::IsWindow(m_hWnd));
1248 DWORD dwRet = (DWORD)::SendMessage(m_hWnd, EM_GETMARGINS, 0, 0L);
1249 nLeft = LOWORD(dwRet);
1250 nRight = HIWORD(dwRet);
1251 }
1252
1253 void SetMargins(UINT nLeft, UINT nRight, WORD wFlags = EC_LEFTMARGIN | EC_RIGHTMARGIN)
1254 {
1255 ATLASSERT(::IsWindow(m_hWnd));
1256 ::SendMessage(m_hWnd, EM_SETMARGINS, wFlags, MAKELONG(nLeft, nRight));
1257 }
1258
1259 UINT GetLimitText() const
1260 {
1261 ATLASSERT(::IsWindow(m_hWnd));
1262 return (UINT)::SendMessage(m_hWnd, EM_GETLIMITTEXT, 0, 0L);
1263 }
1264
1265 void SetLimitText(UINT nMax)
1266 {
1267 ATLASSERT(::IsWindow(m_hWnd));
1268 ::SendMessage(m_hWnd, EM_SETLIMITTEXT, nMax, 0L);
1269 }
1270
1271 POINT PosFromChar(UINT nChar) const
1272 {
1273 ATLASSERT(::IsWindow(m_hWnd));
1274 DWORD dwRet = (DWORD)::SendMessage(m_hWnd, EM_POSFROMCHAR, nChar, 0);
1275 POINT point = { GET_X_LPARAM(dwRet), GET_Y_LPARAM(dwRet) };
1276 return point;
1277 }
1278
1279 int CharFromPos(POINT pt, int* pLine = NULL) const
1280 {
1281 ATLASSERT(::IsWindow(m_hWnd));
1282 DWORD dwRet = (DWORD)::SendMessage(m_hWnd, EM_CHARFROMPOS, 0, MAKELPARAM(pt.x, pt.y));
1283 if(pLine != NULL)
1284 *pLine = (int)(short)HIWORD(dwRet);
1285 return (int)(short)LOWORD(dwRet);
1286 }
1287
1288 // NOTE: first word in lpszBuffer must contain the size of the buffer!
1289 int GetLine(int nIndex, LPTSTR lpszBuffer) const
1290 {
1291 ATLASSERT(::IsWindow(m_hWnd));
1292 return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer);
1293 }
1294
1295 int GetLine(int nIndex, LPTSTR lpszBuffer, int nMaxLength) const
1296 {
1297 ATLASSERT(::IsWindow(m_hWnd));
1298 *(LPWORD)lpszBuffer = (WORD)nMaxLength;
1299 return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer);
1300 }
1301
1302 TCHAR GetPasswordChar() const
1303 {
1304 ATLASSERT(::IsWindow(m_hWnd));
1305 return (TCHAR)::SendMessage(m_hWnd, EM_GETPASSWORDCHAR, 0, 0L);
1306 }
1307
1308 void SetPasswordChar(TCHAR ch)
1309 {
1310 ATLASSERT(::IsWindow(m_hWnd));
1311 ::SendMessage(m_hWnd, EM_SETPASSWORDCHAR, ch, 0L);
1312 }
1313
1314 #ifndef _WIN32_WCE
1315 EDITWORDBREAKPROC GetWordBreakProc() const
1316 {
1317 ATLASSERT(::IsWindow(m_hWnd));
1318 return (EDITWORDBREAKPROC)::SendMessage(m_hWnd, EM_GETWORDBREAKPROC, 0, 0L);
1319 }
1320
1321 void SetWordBreakProc(EDITWORDBREAKPROC ewbprc)
1322 {
1323 ATLASSERT(::IsWindow(m_hWnd));
1324 ::SendMessage(m_hWnd, EM_SETWORDBREAKPROC, 0, (LPARAM)ewbprc);
1325 }
1326 #endif // !_WIN32_WCE
1327
1328 int GetFirstVisibleLine() const
1329 {
1330 ATLASSERT(::IsWindow(m_hWnd));
1331 return (int)::SendMessage(m_hWnd, EM_GETFIRSTVISIBLELINE, 0, 0L);
1332 }
1333
1334 #ifndef _WIN32_WCE
1335 int GetThumb() const
1336 {
1337 ATLASSERT(::IsWindow(m_hWnd));
1338 ATLASSERT((GetStyle() & ES_MULTILINE) != 0);
1339 return (int)::SendMessage(m_hWnd, EM_GETTHUMB, 0, 0L);
1340 }
1341 #endif // !_WIN32_WCE
1342
1343 BOOL SetReadOnly(BOOL bReadOnly = TRUE)
1344 {
1345 ATLASSERT(::IsWindow(m_hWnd));
1346 return (BOOL)::SendMessage(m_hWnd, EM_SETREADONLY, bReadOnly, 0L);
1347 }
1348
1349 #if (WINVER >= 0x0500) && !defined(_WIN32_WCE)
1350 UINT GetImeStatus(UINT uStatus) const
1351 {
1352 ATLASSERT(::IsWindow(m_hWnd));
1353 return (UINT)::SendMessage(m_hWnd, EM_GETIMESTATUS, uStatus, 0L);
1354 }
1355
1356 UINT SetImeStatus(UINT uStatus, UINT uData)
1357 {
1358 ATLASSERT(::IsWindow(m_hWnd));
1359 return (UINT)::SendMessage(m_hWnd, EM_SETIMESTATUS, uStatus, uData);
1360 }
1361 #endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE)
1362
1363 #if (_WIN32_WINNT >= 0x0501)
1364 BOOL GetCueBannerText(LPCWSTR lpstrText, int cchText) const
1365 {
1366 ATLASSERT(::IsWindow(m_hWnd));
1367 return (BOOL)::SendMessage(m_hWnd, EM_GETCUEBANNER, (WPARAM)lpstrText, cchText);
1368 }
1369
1370 // bKeepWithFocus - Vista only
1371 BOOL SetCueBannerText(LPCWSTR lpstrText, BOOL bKeepWithFocus = FALSE)
1372 {
1373 ATLASSERT(::IsWindow(m_hWnd));
1374 return (BOOL)::SendMessage(m_hWnd, EM_SETCUEBANNER, (WPARAM)bKeepWithFocus, (LPARAM)(lpstrText));
1375 }
1376 #endif // (_WIN32_WINNT >= 0x0501)
1377
1378 // Operations
1379 void EmptyUndoBuffer()
1380 {
1381 ATLASSERT(::IsWindow(m_hWnd));
1382 ::SendMessage(m_hWnd, EM_EMPTYUNDOBUFFER, 0, 0L);
1383 }
1384
1385 BOOL FmtLines(BOOL bAddEOL)
1386 {
1387 ATLASSERT(::IsWindow(m_hWnd));
1388 return (BOOL)::SendMessage(m_hWnd, EM_FMTLINES, bAddEOL, 0L);
1389 }
1390
1391 void LimitText(int nChars = 0)
1392 {
1393 ATLASSERT(::IsWindow(m_hWnd));
1394 ::SendMessage(m_hWnd, EM_LIMITTEXT, nChars, 0L);
1395 }
1396
1397 int LineFromChar(int nIndex = -1) const
1398 {
1399 ATLASSERT(::IsWindow(m_hWnd));
1400 return (int)::SendMessage(m_hWnd, EM_LINEFROMCHAR, nIndex, 0L);
1401 }
1402
1403 int LineIndex(int nLine = -1) const
1404 {
1405 ATLASSERT(::IsWindow(m_hWnd));
1406 return (int)::SendMessage(m_hWnd, EM_LINEINDEX, nLine, 0L);
1407 }
1408
1409 int LineLength(int nLine = -1) const
1410 {
1411 ATLASSERT(::IsWindow(m_hWnd));
1412 return (int)::SendMessage(m_hWnd, EM_LINELENGTH, nLine, 0L);
1413 }
1414
1415 void LineScroll(int nLines, int nChars = 0)
1416 {
1417 ATLASSERT(::IsWindow(m_hWnd));
1418 ::SendMessage(m_hWnd, EM_LINESCROLL, nChars, nLines);
1419 }
1420
1421 void ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo = FALSE)
1422 {
1423 ATLASSERT(::IsWindow(m_hWnd));
1424 ::SendMessage(m_hWnd, EM_REPLACESEL, (WPARAM) bCanUndo, (LPARAM)lpszNewText);
1425 }
1426
1427 void SetRect(LPCRECT lpRect)
1428 {
1429 ATLASSERT(::IsWindow(m_hWnd));
1430 ::SendMessage(m_hWnd, EM_SETRECT, 0, (LPARAM)lpRect);
1431 }
1432
1433 void SetRectNP(LPCRECT lpRect)
1434 {
1435 ATLASSERT(::IsWindow(m_hWnd));
1436 ::SendMessage(m_hWnd, EM_SETRECTNP, 0, (LPARAM)lpRect);
1437 }
1438
1439 void SetSel(DWORD dwSelection, BOOL bNoScroll = FALSE)
1440 {
1441 ATLASSERT(::IsWindow(m_hWnd));
1442 ::SendMessage(m_hWnd, EM_SETSEL, LOWORD(dwSelection), HIWORD(dwSelection));
1443 if(!bNoScroll)
1444 ::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L);
1445 }
1446
1447 void SetSel(int nStartChar, int nEndChar, BOOL bNoScroll = FALSE)
1448 {
1449 ATLASSERT(::IsWindow(m_hWnd));
1450 ::SendMessage(m_hWnd, EM_SETSEL, nStartChar, nEndChar);
1451 if(!bNoScroll)
1452 ::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L);
1453 }
1454
1455 void SetSelAll(BOOL bNoScroll = FALSE)
1456 {
1457 SetSel(0, -1, bNoScroll);
1458 }
1459
1460 void SetSelNone(BOOL bNoScroll = FALSE)
1461 {
1462 SetSel(-1, 0, bNoScroll);
1463 }
1464
1465 BOOL SetTabStops(int nTabStops, LPINT rgTabStops)
1466 {
1467 ATLASSERT(::IsWindow(m_hWnd));
1468 return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, nTabStops, (LPARAM)rgTabStops);
1469 }
1470
1471 BOOL SetTabStops()
1472 {
1473 ATLASSERT(::IsWindow(m_hWnd));
1474 return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 0, 0L);
1475 }
1476
1477 BOOL SetTabStops(const int& cxEachStop) // takes an 'int'
1478 {
1479 ATLASSERT(::IsWindow(m_hWnd));
1480 return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 1, (LPARAM)(LPINT)&cxEachStop);
1481 }
1482
1483 void ScrollCaret()
1484 {
1485 ATLASSERT(::IsWindow(m_hWnd));
1486 ::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L);
1487 }
1488
1489 int Scroll(int nScrollAction)
1490 {
1491 ATLASSERT(::IsWindow(m_hWnd));
1492 ATLASSERT((GetStyle() & ES_MULTILINE) != 0);
1493 LRESULT lRet = ::SendMessage(m_hWnd, EM_SCROLL, nScrollAction, 0L);
1494 if(!(BOOL)HIWORD(lRet))
1495 return -1; // failed
1496 return (int)(short)LOWORD(lRet);
1497
1498 }
1499
1500 void InsertText(int nInsertAfterChar, LPCTSTR lpstrText, BOOL bNoScroll = FALSE, BOOL bCanUndo = FALSE)
1501 {
1502 SetSel(nInsertAfterChar, nInsertAfterChar, bNoScroll);
1503 ReplaceSel(lpstrText, bCanUndo);
1504 }
1505
1506 void AppendText(LPCTSTR lpstrText, BOOL bNoScroll = FALSE, BOOL bCanUndo = FALSE)
1507 {
1508 InsertText(GetWindowTextLength(), lpstrText, bNoScroll, bCanUndo);
1509 }
1510
1511 #if (_WIN32_WINNT >= 0x0501)
1512 BOOL ShowBalloonTip(PEDITBALLOONTIP pEditBaloonTip)
1513 {
1514 ATLASSERT(::IsWindow(m_hWnd));
1515 return (BOOL)::SendMessage(m_hWnd, EM_SHOWBALLOONTIP, 0, (LPARAM)pEditBaloonTip);
1516 }
1517
1518 BOOL HideBalloonTip()
1519 {
1520 ATLASSERT(::IsWindow(m_hWnd));
1521 return (BOOL)::SendMessage(m_hWnd, EM_HIDEBALLOONTIP, 0, 0L);
1522 }
1523 #endif // (_WIN32_WINNT >= 0x0501)
1524
1525 #if (_WIN32_WINNT >= 0x0600)
1526 DWORD GetHilite() const
1527 {
1528 ATLASSERT(::IsWindow(m_hWnd));
1529 return (DWORD)::SendMessage(m_hWnd, EM_GETHILITE, 0, 0L);
1530 }
1531
1532 void GetHilite(int& nStartChar, int& nEndChar) const
1533 {
1534 ATLASSERT(::IsWindow(m_hWnd));
1535 DWORD dwRet = (DWORD)::SendMessage(m_hWnd, EM_GETHILITE, 0, 0L);
1536 nStartChar = (int)(short)LOWORD(dwRet);
1537 nEndChar = (int)(short)HIWORD(dwRet);
1538 }
1539
1540 void SetHilite(int nStartChar, int nEndChar)
1541 {
1542 ATLASSERT(::IsWindow(m_hWnd));
1543 ::SendMessage(m_hWnd, EM_SETHILITE, nStartChar, nEndChar);
1544 }
1545 #endif // (_WIN32_WINNT >= 0x0600)
1546
1547 // Clipboard operations
1548 BOOL Undo()
1549 {
1550 ATLASSERT(::IsWindow(m_hWnd));
1551 return (BOOL)::SendMessage(m_hWnd, EM_UNDO, 0, 0L);
1552 }
1553
1554 void Clear()
1555 {
1556 ATLASSERT(::IsWindow(m_hWnd));
1557 ::SendMessage(m_hWnd, WM_CLEAR, 0, 0L);
1558 }
1559
1560 void Copy()
1561 {
1562 ATLASSERT(::IsWindow(m_hWnd));
1563 ::SendMessage(m_hWnd, WM_COPY, 0, 0L);
1564 }
1565
1566 void Cut()
1567 {
1568 ATLASSERT(::IsWindow(m_hWnd));
1569 ::SendMessage(m_hWnd, WM_CUT, 0, 0L);
1570 }
1571
1572 void Paste()
1573 {
1574 ATLASSERT(::IsWindow(m_hWnd));
1575 ::SendMessage(m_hWnd, WM_PASTE, 0, 0L);
1576 }
1577
1578 #ifdef WIN32_PLATFORM_WFSP // SmartPhone only messages
1579 DWORD GetExtendedStyle()
1580 {
1581 return SendMessage(EM_GETEXTENDEDSTYLE);
1582 }
1583
1584 DWORD SetExtendedStyle(DWORD dwMask, DWORD dwExStyle)
1585 {
1586 return SendMessage(EM_SETEXTENDEDSTYLE, (WPARAM)dwMask, (LPARAM)dwExStyle);
1587 }
1588
1589 DWORD GetInputMode(BOOL bCurrentMode = TRUE)
1590 {
1591 return SendMessage(EM_GETINPUTMODE, 0, (LPARAM)bCurrentMode);
1592 }
1593
1594 BOOL SetInputMode(DWORD dwMode)
1595 {
1596 return SendMessage(EM_SETINPUTMODE, 0, (LPARAM)dwMode);
1597 }
1598
1599 BOOL SetSymbols(LPCTSTR szSymbols)
1600 {
1601 return SendMessage(EM_SETSYMBOLS, 0, (LPARAM)szSymbols);
1602 }
1603
1604 BOOL ResetSymbols()
1605 {
1606 return SendMessage(EM_SETSYMBOLS);
1607 }
1608 #endif // WIN32_PLATFORM_WFSP
1609 };
1610
1611 typedef CEditT<ATL::CWindow> CEdit;
1612
1613
1614 ///////////////////////////////////////////////////////////////////////////////
1615 // CEditCommands - message handlers for standard EDIT commands
1616
1617 // Chain to CEditCommands message map. Your class must also derive from CEdit.
1618 // Example:
1619 // class CMyEdit : public CWindowImpl<CMyEdit, CEdit>,
1620 // public CEditCommands<CMyEdit>
1621 // {
1622 // public:
1623 // BEGIN_MSG_MAP(CMyEdit)
1624 // // your handlers...
1625 // CHAIN_MSG_MAP_ALT(CEditCommands<CMyEdit>, 1)
1626 // END_MSG_MAP()
1627 // // other stuff...
1628 // };
1629
1630 template <class T>
1631 class CEditCommands
1632 {
1633 public:
1634 BEGIN_MSG_MAP(CEditCommands< T >)
1635 ALT_MSG_MAP(1)
1636 COMMAND_ID_HANDLER(ID_EDIT_CLEAR, OnEditClear)
1637 COMMAND_ID_HANDLER(ID_EDIT_CLEAR_ALL, OnEditClearAll)
1638 COMMAND_ID_HANDLER(ID_EDIT_COPY, OnEditCopy)
1639 COMMAND_ID_HANDLER(ID_EDIT_CUT, OnEditCut)
1640 COMMAND_ID_HANDLER(ID_EDIT_PASTE, OnEditPaste)
1641 COMMAND_ID_HANDLER(ID_EDIT_SELECT_ALL, OnEditSelectAll)
1642 COMMAND_ID_HANDLER(ID_EDIT_UNDO, OnEditUndo)
1643 END_MSG_MAP()
1644
1645 LRESULT OnEditClear(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
1646 {
1647 T* pT = static_cast<T*>(this);
1648 pT->Clear();
1649 return 0;
1650 }
1651
1652 LRESULT OnEditClearAll(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
1653 {
1654 T* pT = static_cast<T*>(this);
1655 pT->SetSel(0, -1);
1656 pT->Clear();
1657 return 0;
1658 }
1659
1660 LRESULT OnEditCopy(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
1661 {
1662 T* pT = static_cast<T*>(this);
1663 pT->Copy();
1664 return 0;
1665 }
1666
1667 LRESULT OnEditCut(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
1668 {
1669 T* pT = static_cast<T*>(this);
1670 pT->Cut();
1671 return 0;
1672 }
1673
1674 LRESULT OnEditPaste(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
1675 {
1676 T* pT = static_cast<T*>(this);
1677 pT->Paste();
1678 return 0;
1679 }
1680
1681 LRESULT OnEditSelectAll(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
1682 {
1683 T* pT = static_cast<T*>(this);
1684 pT->SetSel(0, -1);
1685 return 0;
1686 }
1687
1688 LRESULT OnEditUndo(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
1689 {
1690 T* pT = static_cast<T*>(this);
1691 pT->Undo();
1692 return 0;
1693 }
1694
1695 // State (update UI) helpers
1696 BOOL CanCut() const
1697 { return HasSelection(); }
1698
1699 BOOL CanCopy() const
1700 { return HasSelection(); }
1701
1702 BOOL CanClear() const
1703 { return HasSelection(); }
1704
1705 BOOL CanSelectAll() const
1706 { return HasText(); }
1707
1708 BOOL CanFind() const
1709 { return HasText(); }
1710
1711 BOOL CanRepeat() const
1712 { return HasText(); }
1713
1714 BOOL CanReplace() const
1715 { return HasText(); }
1716
1717 BOOL CanClearAll() const
1718 { return HasText(); }
1719
1720 // Implementation
1721 BOOL HasSelection() const
1722 {
1723 const T* pT = static_cast<const T*>(this);
1724 int nMin = 0, nMax = 0;
1725 ::SendMessage(pT->m_hWnd, EM_GETSEL, (WPARAM)&nMin, (LPARAM)&nMax);
1726 return (nMin != nMax);
1727 }
1728
1729 BOOL HasText() const
1730 {
1731 const T* pT = static_cast<const T*>(this);
1732 return (pT->GetWindowTextLength() > 0);
1733 }
1734 };
1735
1736
1737 ///////////////////////////////////////////////////////////////////////////////
1738 // CScrollBar - client side for a Windows SCROLLBAR control
1739
1740 template <class TBase>
1741 class CScrollBarT : public TBase
1742 {
1743 public:
1744 // Constructors
1745 CScrollBarT(HWND hWnd = NULL) : TBase(hWnd)
1746 { }
1747
1748 CScrollBarT< TBase >& operator =(HWND hWnd)
1749 {
1750 m_hWnd = hWnd;
1751 return *this;
1752 }
1753
1754 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
1755 DWORD dwStyle = 0, DWORD dwExStyle = 0,
1756 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
1757 {
1758 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
1759 }
1760
1761 // Attributes
1762 static LPCTSTR GetWndClassName()
1763 {
1764 return _T("SCROLLBAR");
1765 }
1766
1767 #ifndef _WIN32_WCE
1768 int GetScrollPos() const
1769 {
1770 ATLASSERT(::IsWindow(m_hWnd));
1771 return ::GetScrollPos(m_hWnd, SB_CTL);
1772 }
1773 #endif // !_WIN32_WCE
1774
1775 int SetScrollPos(int nPos, BOOL bRedraw = TRUE)
1776 {
1777 ATLASSERT(::IsWindow(m_hWnd));
1778 return ::SetScrollPos(m_hWnd, SB_CTL, nPos, bRedraw);
1779 }
1780
1781 #ifndef _WIN32_WCE
1782 void GetScrollRange(LPINT lpMinPos, LPINT lpMaxPos) const
1783 {
1784 ATLASSERT(::IsWindow(m_hWnd));
1785 ::GetScrollRange(m_hWnd, SB_CTL, lpMinPos, lpMaxPos);
1786 }
1787 #endif // !_WIN32_WCE
1788
1789 void SetScrollRange(int nMinPos, int nMaxPos, BOOL bRedraw = TRUE)
1790 {
1791 ATLASSERT(::IsWindow(m_hWnd));
1792 ::SetScrollRange(m_hWnd, SB_CTL, nMinPos, nMaxPos, bRedraw);
1793 }
1794
1795 BOOL GetScrollInfo(LPSCROLLINFO lpScrollInfo) const
1796 {
1797 ATLASSERT(::IsWindow(m_hWnd));
1798 return ::GetScrollInfo(m_hWnd, SB_CTL, lpScrollInfo);
1799 }
1800
1801 int SetScrollInfo(LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE)
1802 {
1803 ATLASSERT(::IsWindow(m_hWnd));
1804 return ::SetScrollInfo(m_hWnd, SB_CTL, lpScrollInfo, bRedraw);
1805 }
1806
1807 #ifndef _WIN32_WCE
1808 int GetScrollLimit() const
1809 {
1810 SCROLLINFO info = { sizeof(SCROLLINFO), SIF_RANGE | SIF_PAGE };
1811 ::GetScrollInfo(m_hWnd, SB_CTL, &info);
1812 if(info.nPage > 1)
1813 info.nMax -= info.nPage - 1;
1814
1815 return info.nMax;
1816 }
1817
1818 #if (WINVER >= 0x0500)
1819 BOOL GetScrollBarInfo(PSCROLLBARINFO pScrollBarInfo) const
1820 {
1821 ATLASSERT(::IsWindow(m_hWnd));
1822 #if (_WIN32_WINNT >= 0x0501)
1823 return (BOOL)::SendMessage(m_hWnd, SBM_GETSCROLLBARINFO, 0, (LPARAM)pScrollBarInfo);
1824 #else // !(_WIN32_WINNT >= 0x0501)
1825 return ::GetScrollBarInfo(m_hWnd, OBJID_CLIENT, pScrollBarInfo);
1826 #endif // !(_WIN32_WINNT >= 0x0501)
1827 }
1828 #endif // (WINVER >= 0x0500)
1829
1830 // Operations
1831 void ShowScrollBar(BOOL bShow = TRUE)
1832 {
1833 ATLASSERT(::IsWindow(m_hWnd));
1834 ::ShowScrollBar(m_hWnd, SB_CTL, bShow);
1835 }
1836
1837 BOOL EnableScrollBar(UINT nArrowFlags = ESB_ENABLE_BOTH)
1838 {
1839 ATLASSERT(::IsWindow(m_hWnd));
1840 return ::EnableScrollBar(m_hWnd, SB_CTL, nArrowFlags);
1841 }
1842 #endif // !_WIN32_WCE
1843 };
1844
1845 typedef CScrollBarT<ATL::CWindow> CScrollBar;
1846
1847
1848 // --- Windows Common Controls ---
1849
1850 ///////////////////////////////////////////////////////////////////////////////
1851 // CImageList
1852
1853 // forward declarations
1854 template <bool t_bManaged> class CImageListT;
1855 typedef CImageListT<false> CImageList;
1856 typedef CImageListT<true> CImageListManaged;
1857
1858
1859 template <bool t_bManaged>
1860 class CImageListT
1861 {
1862 public:
1863 // Data members
1864 HIMAGELIST m_hImageList;
1865
1866 // Constructor/destructor/operators
1867 CImageListT(HIMAGELIST hImageList = NULL) : m_hImageList(hImageList)
1868 { }
1869
1870 ~CImageListT()
1871 {
1872 if(t_bManaged && (m_hImageList != NULL))
1873 Destroy();
1874 }
1875
1876 CImageListT<t_bManaged>& operator =(HIMAGELIST hImageList)
1877 {
1878 Attach(hImageList);
1879 return *this;
1880 }
1881
1882 void Attach(HIMAGELIST hImageList)
1883 {
1884 if(t_bManaged && (m_hImageList != NULL) && (m_hImageList != hImageList))
1885 ImageList_Destroy(m_hImageList);
1886 m_hImageList = hImageList;
1887 }
1888
1889 HIMAGELIST Detach()
1890 {
1891 HIMAGELIST hImageList = m_hImageList;
1892 m_hImageList = NULL;
1893 return hImageList;
1894 }
1895
1896 operator HIMAGELIST() const { return m_hImageList; }
1897
1898 bool IsNull() const { return (m_hImageList == NULL); }
1899
1900 // Attributes
1901 int GetImageCount() const
1902 {
1903 ATLASSERT(m_hImageList != NULL);
1904 return ImageList_GetImageCount(m_hImageList);
1905 }
1906
1907 COLORREF GetBkColor() const
1908 {
1909 ATLASSERT(m_hImageList != NULL);
1910 return ImageList_GetBkColor(m_hImageList);
1911 }
1912
1913 COLORREF SetBkColor(COLORREF cr)
1914 {
1915 ATLASSERT(m_hImageList != NULL);
1916 return ImageList_SetBkColor(m_hImageList, cr);
1917 }
1918
1919 BOOL GetImageInfo(int nImage, IMAGEINFO* pImageInfo) const
1920 {
1921 ATLASSERT(m_hImageList != NULL);
1922 return ImageList_GetImageInfo(m_hImageList, nImage, pImageInfo);
1923 }
1924
1925 HICON GetIcon(int nIndex, UINT uFlags = ILD_NORMAL) const
1926 {
1927 ATLASSERT(m_hImageList != NULL);
1928 return ImageList_GetIcon(m_hImageList, nIndex, uFlags);
1929 }
1930
1931 BOOL GetIconSize(int& cx, int& cy) const
1932 {
1933 ATLASSERT(m_hImageList != NULL);
1934 return ImageList_GetIconSize(m_hImageList, &cx, &cy);
1935 }
1936
1937 BOOL GetIconSize(SIZE& size) const
1938 {
1939 ATLASSERT(m_hImageList != NULL);
1940 return ImageList_GetIconSize(m_hImageList, (int*)&size.cx, (int*)&size.cy);
1941 }
1942
1943 BOOL SetIconSize(int cx, int cy)
1944 {
1945 ATLASSERT(m_hImageList != NULL);
1946 return ImageList_SetIconSize(m_hImageList, cx, cy);
1947 }
1948
1949 BOOL SetIconSize(SIZE size)
1950 {
1951 ATLASSERT(m_hImageList != NULL);
1952 return ImageList_SetIconSize(m_hImageList, size.cx, size.cy);
1953 }
1954
1955 BOOL SetImageCount(UINT uNewCount)
1956 {
1957 ATLASSERT(m_hImageList != NULL);
1958 return ImageList_SetImageCount(m_hImageList, uNewCount);
1959 }
1960
1961 BOOL SetOverlayImage(int nImage, int nOverlay)
1962 {
1963 ATLASSERT(m_hImageList != NULL);
1964 return ImageList_SetOverlayImage(m_hImageList, nImage, nOverlay);
1965 }
1966
1967 // Operations
1968 BOOL Create(int cx, int cy, UINT nFlags, int nInitial, int nGrow)
1969 {
1970 ATLASSERT(m_hImageList == NULL);
1971 m_hImageList = ImageList_Create(cx, cy, nFlags, nInitial, nGrow);
1972 return (m_hImageList != NULL) ? TRUE : FALSE;
1973 }
1974
1975 BOOL Create(ATL::_U_STRINGorID bitmap, int cx, int nGrow, COLORREF crMask)
1976 {
1977 ATLASSERT(m_hImageList == NULL);
1978 m_hImageList = ImageList_LoadBitmap(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr, cx, nGrow, crMask);
1979 return (m_hImageList != NULL) ? TRUE : FALSE;
1980 }
1981
1982 BOOL CreateFromImage(ATL::_U_STRINGorID image, int cx, int nGrow, COLORREF crMask, UINT uType, UINT uFlags = LR_DEFAULTCOLOR | LR_DEFAULTSIZE)
1983 {
1984 ATLASSERT(m_hImageList == NULL);
1985 m_hImageList = ImageList_LoadImage(ModuleHelper::GetResourceInstance(), image.m_lpstr, cx, nGrow, crMask, uType, uFlags);
1986 return (m_hImageList != NULL) ? TRUE : FALSE;
1987 }
1988
1989 BOOL Merge(HIMAGELIST hImageList1, int nImage1, HIMAGELIST hImageList2, int nImage2, int dx, int dy)
1990 {
1991 ATLASSERT(m_hImageList == NULL);
1992 m_hImageList = ImageList_Merge(hImageList1, nImage1, hImageList2, nImage2, dx, dy);
1993 return (m_hImageList != NULL) ? TRUE : FALSE;
1994 }
1995
1996 #ifndef _WIN32_WCE
1997 #ifdef __IStream_INTERFACE_DEFINED__
1998 BOOL CreateFromStream(LPSTREAM lpStream)
1999 {
2000 ATLASSERT(m_hImageList == NULL);
2001 m_hImageList = ImageList_Read(lpStream);
2002 return (m_hImageList != NULL) ? TRUE : FALSE;
2003 }
2004 #endif // __IStream_INTERFACE_DEFINED__
2005 #endif // !_WIN32_WCE
2006
2007 BOOL Destroy()
2008 {
2009 if (m_hImageList == NULL)
2010 return FALSE;
2011 BOOL bRet = ImageList_Destroy(m_hImageList);
2012 if(bRet)
2013 m_hImageList = NULL;
2014 return bRet;
2015 }
2016
2017 int Add(HBITMAP hBitmap, HBITMAP hBitmapMask = NULL)
2018 {
2019 ATLASSERT(m_hImageList != NULL);
2020 return ImageList_Add(m_hImageList, hBitmap, hBitmapMask);
2021 }
2022
2023 int Add(HBITMAP hBitmap, COLORREF crMask)
2024 {
2025 ATLASSERT(m_hImageList != NULL);
2026 return ImageList_AddMasked(m_hImageList, hBitmap, crMask);
2027 }
2028
2029 BOOL Remove(int nImage)
2030 {
2031 ATLASSERT(m_hImageList != NULL);
2032 return ImageList_Remove(m_hImageList, nImage);
2033 }
2034
2035 BOOL RemoveAll()
2036 {
2037 ATLASSERT(m_hImageList != NULL);
2038 return ImageList_RemoveAll(m_hImageList);
2039 }
2040
2041 BOOL Replace(int nImage, HBITMAP hBitmap, HBITMAP hBitmapMask)
2042 {
2043 ATLASSERT(m_hImageList != NULL);
2044 return ImageList_Replace(m_hImageList, nImage, hBitmap, hBitmapMask);
2045 }
2046
2047 int AddIcon(HICON hIcon)
2048 {
2049 ATLASSERT(m_hImageList != NULL);
2050 return ImageList_AddIcon(m_hImageList, hIcon);
2051 }
2052
2053 int ReplaceIcon(int nImage, HICON hIcon)
2054 {
2055 ATLASSERT(m_hImageList != NULL);
2056 return ImageList_ReplaceIcon(m_hImageList, nImage, hIcon);
2057 }
2058
2059 HICON ExtractIcon(int nImage)
2060 {
2061 ATLASSERT(m_hImageList != NULL);
2062 return ImageList_ExtractIcon(NULL, m_hImageList, nImage);
2063 }
2064
2065 BOOL Draw(HDC hDC, int nImage, int x, int y, UINT nStyle)
2066 {
2067 ATLASSERT(m_hImageList != NULL);
2068 ATLASSERT(hDC != NULL);
2069 return ImageList_Draw(m_hImageList, nImage, hDC, x, y, nStyle);
2070 }
2071
2072 BOOL Draw(HDC hDC, int nImage, POINT pt, UINT nStyle)
2073 {
2074 ATLASSERT(m_hImageList != NULL);
2075 ATLASSERT(hDC != NULL);
2076 return ImageList_Draw(m_hImageList, nImage, hDC, pt.x, pt.y, nStyle);
2077 }
2078
2079 BOOL DrawEx(int nImage, HDC hDC, int x, int y, int dx, int dy, COLORREF rgbBk, COLORREF rgbFg, UINT fStyle)
2080 {
2081 ATLASSERT(m_hImageList != NULL);
2082 ATLASSERT(hDC != NULL);
2083 return ImageList_DrawEx(m_hImageList, nImage, hDC, x, y, dx, dy, rgbBk, rgbFg, fStyle);
2084 }
2085
2086 BOOL DrawEx(int nImage, HDC hDC, RECT& rect, COLORREF rgbBk, COLORREF rgbFg, UINT fStyle)
2087 {
2088 ATLASSERT(m_hImageList != NULL);
2089 ATLASSERT(hDC != NULL);
2090 return ImageList_DrawEx(m_hImageList, nImage, hDC, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, rgbBk, rgbFg, fStyle);
2091 }
2092
2093 static BOOL DrawIndirect(IMAGELISTDRAWPARAMS* pimldp)
2094 {
2095 return ImageList_DrawIndirect(pimldp);
2096 }
2097
2098 BOOL Copy(int nSrc, int nDst, UINT uFlags = ILCF_MOVE)
2099 {
2100 ATLASSERT(m_hImageList != NULL);
2101 return ImageList_Copy(m_hImageList, nDst, m_hImageList, nSrc, uFlags);
2102 }
2103
2104 #ifdef __IStream_INTERFACE_DEFINED__
2105 #ifndef _WIN32_WCE
2106 static HIMAGELIST Read(LPSTREAM lpStream)
2107 {
2108 return ImageList_Read(lpStream);
2109 }
2110
2111 BOOL Write(LPSTREAM lpStream)
2112 {
2113 ATLASSERT(m_hImageList != NULL);
2114 return ImageList_Write(m_hImageList, lpStream);
2115 }
2116 #endif // !_WIN32_WCE
2117
2118 #if (_WIN32_WINNT >= 0x0501)
2119 static HRESULT ReadEx(DWORD dwFlags, LPSTREAM lpStream, REFIID riid, PVOID* ppv)
2120 {
2121 return ImageList_ReadEx(dwFlags, lpStream, riid, ppv);
2122 }
2123
2124 HRESULT WriteEx(DWORD dwFlags, LPSTREAM lpStream)
2125 {
2126 ATLASSERT(m_hImageList != NULL);
2127 return ImageList_WriteEx(m_hImageList, dwFlags, lpStream);
2128 }
2129 #endif // (_WIN32_WINNT >= 0x0501)
2130 #endif // __IStream_INTERFACE_DEFINED__
2131
2132 // Drag operations
2133 BOOL BeginDrag(int nImage, POINT ptHotSpot)
2134 {
2135 ATLASSERT(m_hImageList != NULL);
2136 return ImageList_BeginDrag(m_hImageList, nImage, ptHotSpot.x, ptHotSpot.y);
2137 }
2138
2139 BOOL BeginDrag(int nImage, int xHotSpot, int yHotSpot)
2140 {
2141 ATLASSERT(m_hImageList != NULL);
2142 return ImageList_BeginDrag(m_hImageList, nImage, xHotSpot, yHotSpot);
2143 }
2144
2145 static void EndDrag()
2146 {
2147 ImageList_EndDrag();
2148 }
2149
2150 static BOOL DragMove(POINT pt)
2151 {
2152 return ImageList_DragMove(pt.x, pt.y);
2153 }
2154
2155 static BOOL DragMove(int x, int y)
2156 {
2157 return ImageList_DragMove(x, y);
2158 }
2159
2160 BOOL SetDragCursorImage(int nDrag, POINT ptHotSpot)
2161 {
2162 ATLASSERT(m_hImageList != NULL);
2163 return ImageList_SetDragCursorImage(m_hImageList, nDrag, ptHotSpot.x, ptHotSpot.y);
2164 }
2165
2166 BOOL SetDragCursorImage(int nDrag, int xHotSpot, int yHotSpot)
2167 {
2168 ATLASSERT(m_hImageList != NULL);
2169 return ImageList_SetDragCursorImage(m_hImageList, nDrag, xHotSpot, yHotSpot);
2170 }
2171
2172 static BOOL DragShowNolock(BOOL bShow = TRUE)
2173 {
2174 return ImageList_DragShowNolock(bShow);
2175 }
2176
2177 static CImageList GetDragImage(LPPOINT lpPoint, LPPOINT lpPointHotSpot)
2178 {
2179 return CImageList(ImageList_GetDragImage(lpPoint, lpPointHotSpot));
2180 }
2181
2182 static BOOL DragEnter(HWND hWnd, POINT point)
2183 {
2184 return ImageList_DragEnter(hWnd, point.x, point.y);
2185 }
2186
2187 static BOOL DragEnter(HWND hWnd, int x, int y)
2188 {
2189 return ImageList_DragEnter(hWnd, x, y);
2190 }
2191
2192 static BOOL DragLeave(HWND hWnd)
2193 {
2194 return ImageList_DragLeave(hWnd);
2195 }
2196
2197 #if (_WIN32_IE >= 0x0400)
2198 CImageList Duplicate() const
2199 {
2200 ATLASSERT(m_hImageList != NULL);
2201 return CImageList(ImageList_Duplicate(m_hImageList));
2202 }
2203
2204 static CImageList Duplicate(HIMAGELIST hImageList)
2205 {
2206 ATLASSERT(hImageList != NULL);
2207 return CImageList(ImageList_Duplicate(hImageList));
2208 }
2209 #endif // (_WIN32_IE >= 0x0400)
2210 };
2211
2212
2213 ///////////////////////////////////////////////////////////////////////////////
2214 // CToolTipCtrl
2215
2216 #ifndef _WIN32_WCE
2217
2218 class CToolInfo : public TOOLINFO
2219 {
2220 public:
2221 CToolInfo(UINT nFlags, HWND hWnd, UINT_PTR nIDTool = 0, LPRECT lpRect = NULL, LPTSTR lpstrText = LPSTR_TEXTCALLBACK, LPARAM lUserParam = NULL)
2222 {
2223 Init(nFlags, hWnd, nIDTool, lpRect, lpstrText, lUserParam);
2224 }
2225
2226 operator LPTOOLINFO() { return this; }
2227
2228 operator LPARAM() { return (LPARAM)this; }
2229
2230 void Init(UINT nFlags, HWND hWnd, UINT_PTR nIDTool = 0, LPRECT lpRect = NULL, LPTSTR lpstrText = LPSTR_TEXTCALLBACK, LPARAM lUserParam = NULL)
2231 {
2232 ATLASSERT(::IsWindow(hWnd));
2233 memset(this, 0, sizeof(TOOLINFO));
2234 cbSize = RunTimeHelper::SizeOf_TOOLINFO();
2235 uFlags = nFlags;
2236 if(nIDTool == 0)
2237 {
2238 hwnd = ::GetParent(hWnd);
2239 uFlags |= TTF_IDISHWND;
2240 uId = (UINT_PTR)hWnd;
2241 }
2242 else
2243 {
2244 hwnd = hWnd;
2245 uId = nIDTool;
2246 }
2247 if(lpRect != NULL)
2248 rect = *lpRect;
2249 hinst = ModuleHelper::GetResourceInstance();
2250 lpszText = lpstrText;
2251 lParam = lUserParam;
2252 }
2253 };
2254
2255 template <class TBase>
2256 class CToolTipCtrlT : public TBase
2257 {
2258 public:
2259 // Constructors
2260 CToolTipCtrlT(HWND hWnd = NULL) : TBase(hWnd)
2261 { }
2262
2263 CToolTipCtrlT< TBase >& operator =(HWND hWnd)
2264 {
2265 m_hWnd = hWnd;
2266 return *this;
2267 }
2268
2269 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
2270 DWORD dwStyle = 0, DWORD dwExStyle = 0,
2271 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
2272 {
2273 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
2274 }
2275
2276 // Attributes
2277 static LPCTSTR GetWndClassName()
2278 {
2279 return TOOLTIPS_CLASS;
2280 }
2281
2282 void GetText(LPTOOLINFO lpToolInfo) const
2283 {
2284 ATLASSERT(::IsWindow(m_hWnd));
2285 ::SendMessage(m_hWnd, TTM_GETTEXT, 0, (LPARAM)&lpToolInfo);
2286 }
2287
2288 void GetText(LPTSTR lpstrText, HWND hWnd, UINT_PTR nIDTool = 0) const
2289 {
2290 ATLASSERT(::IsWindow(m_hWnd));
2291 ATLASSERT(hWnd != NULL);
2292 CToolInfo ti(0, hWnd, nIDTool, NULL, lpstrText);
2293 ::SendMessage(m_hWnd, TTM_GETTEXT, 0, ti);
2294 }
2295
2296 BOOL GetToolInfo(LPTOOLINFO lpToolInfo) const
2297 {
2298 ATLASSERT(::IsWindow(m_hWnd));
2299 return (BOOL)::SendMessage(m_hWnd, TTM_GETTOOLINFO, 0, (LPARAM)lpToolInfo);
2300 }
2301
2302 BOOL GetToolInfo(HWND hWnd, UINT_PTR nIDTool, UINT* puFlags, LPRECT lpRect, LPTSTR lpstrText) const
2303 {
2304 ATLASSERT(::IsWindow(m_hWnd));
2305 ATLASSERT(hWnd != NULL);
2306 ATLASSERT(puFlags != NULL);
2307 ATLASSERT(lpRect != NULL);
2308 CToolInfo ti(0, hWnd, nIDTool, NULL, lpstrText);
2309 BOOL bRet = (BOOL)::SendMessage(m_hWnd, TTM_GETTOOLINFO, 0, ti);
2310 if(bRet != FALSE)
2311 {
2312 *puFlags = ti.uFlags;
2313 *lpRect = ti.rect;
2314 }
2315 return bRet;
2316 }
2317
2318 void SetToolInfo(LPTOOLINFO lpToolInfo)
2319 {
2320 ATLASSERT(::IsWindow(m_hWnd));
2321 ::SendMessage(m_hWnd, TTM_SETTOOLINFO, 0, (LPARAM)lpToolInfo);
2322 }
2323
2324 void SetToolRect(LPTOOLINFO lpToolInfo)
2325 {
2326 ATLASSERT(::IsWindow(m_hWnd));
2327 ::SendMessage(m_hWnd, TTM_NEWTOOLRECT, 0, (LPARAM)lpToolInfo);
2328 }
2329
2330 void SetToolRect(HWND hWnd, UINT_PTR nIDTool, LPCRECT lpRect)
2331 {
2332 ATLASSERT(::IsWindow(m_hWnd));
2333 ATLASSERT(hWnd != NULL);
2334 ATLASSERT(nIDTool != 0);
2335
2336 CToolInfo ti(0, hWnd, nIDTool, (LPRECT)lpRect, NULL);
2337 ::SendMessage(m_hWnd, TTM_NEWTOOLRECT, 0, ti);
2338 }
2339
2340 int GetToolCount() const
2341 {
2342 ATLASSERT(::IsWindow(m_hWnd));
2343 return (int)::SendMessage(m_hWnd, TTM_GETTOOLCOUNT, 0, 0L);
2344 }
2345
2346 int GetDelayTime(DWORD dwType) const
2347 {
2348 ATLASSERT(::IsWindow(m_hWnd));
2349 return (int)::SendMessage(m_hWnd, TTM_GETDELAYTIME, dwType, 0L);
2350 }
2351
2352 void SetDelayTime(DWORD dwType, int nTime)
2353 {
2354 ATLASSERT(::IsWindow(m_hWnd));
2355 ::SendMessage(m_hWnd, TTM_SETDELAYTIME, dwType, MAKELPARAM(nTime, 0));
2356 }
2357
2358 void GetMargin(LPRECT lpRect) const
2359 {
2360 ATLASSERT(::IsWindow(m_hWnd));
2361 ::SendMessage(m_hWnd, TTM_GETMARGIN, 0, (LPARAM)lpRect);
2362 }
2363
2364 void SetMargin(LPRECT lpRect)
2365 {
2366 ATLASSERT(::IsWindow(m_hWnd));
2367 ::SendMessage(m_hWnd, TTM_SETMARGIN, 0, (LPARAM)lpRect);
2368 }
2369
2370 int GetMaxTipWidth() const
2371 {
2372 ATLASSERT(::IsWindow(m_hWnd));
2373 return (int)::SendMessage(m_hWnd, TTM_GETMAXTIPWIDTH, 0, 0L);
2374 }
2375
2376 int SetMaxTipWidth(int nWidth)
2377 {
2378 ATLASSERT(::IsWindow(m_hWnd));
2379 return (int)::SendMessage(m_hWnd, TTM_SETMAXTIPWIDTH, 0, nWidth);
2380 }
2381
2382 COLORREF GetTipBkColor() const
2383 {
2384 ATLASSERT(::IsWindow(m_hWnd));
2385 return (COLORREF)::SendMessage(m_hWnd, TTM_GETTIPBKCOLOR, 0, 0L);
2386 }
2387
2388 void SetTipBkColor(COLORREF clr)
2389 {
2390 ATLASSERT(::IsWindow(m_hWnd));
2391 ::SendMessage(m_hWnd, TTM_SETTIPBKCOLOR, (WPARAM)clr, 0L);
2392 }
2393
2394 COLORREF GetTipTextColor() const
2395 {
2396 ATLASSERT(::IsWindow(m_hWnd));
2397 return (COLORREF)::SendMessage(m_hWnd, TTM_GETTIPTEXTCOLOR, 0, 0L);
2398 }
2399
2400 void SetTipTextColor(COLORREF clr)
2401 {
2402 ATLASSERT(::IsWindow(m_hWnd));
2403 ::SendMessage(m_hWnd, TTM_SETTIPTEXTCOLOR, (WPARAM)clr, 0L);
2404 }
2405
2406 BOOL GetCurrentTool(LPTOOLINFO lpToolInfo) const
2407 {
2408 ATLASSERT(::IsWindow(m_hWnd));
2409 return (BOOL)::SendMessage(m_hWnd, TTM_GETCURRENTTOOL, 0, (LPARAM)lpToolInfo);
2410 }
2411
2412 #if (_WIN32_IE >= 0x0500)
2413 SIZE GetBubbleSize(LPTOOLINFO lpToolInfo) const
2414 {
2415 ATLASSERT(::IsWindow(m_hWnd));
2416 DWORD dwRet = (DWORD)::SendMessage(m_hWnd, TTM_GETBUBBLESIZE, 0, (LPARAM)lpToolInfo);
2417 SIZE size = { GET_X_LPARAM(dwRet), GET_Y_LPARAM(dwRet) };
2418 return size;
2419 }
2420
2421 BOOL SetTitle(UINT_PTR uIcon, LPCTSTR lpstrTitle)
2422 {
2423 ATLASSERT(::IsWindow(m_hWnd));
2424 return (BOOL)::SendMessage(m_hWnd, TTM_SETTITLE, uIcon, (LPARAM)lpstrTitle);
2425 }
2426
2427 BOOL SetTitle(HICON hIcon, LPCTSTR lpstrTitle)
2428 {
2429 ATLASSERT(::IsWindow(m_hWnd));
2430 return (BOOL)::SendMessage(m_hWnd, TTM_SETTITLE, (WPARAM)hIcon, (LPARAM)lpstrTitle);
2431 }
2432 #endif // (_WIN32_IE >= 0x0500)
2433
2434 #if (_WIN32_WINNT >= 0x0501)
2435 void GetTitle(PTTGETTITLE pTTGetTitle) const
2436 {
2437 ATLASSERT(::IsWindow(m_hWnd));
2438 ::SendMessage(m_hWnd, TTM_GETTITLE, 0, (LPARAM)pTTGetTitle);
2439 }
2440
2441 void SetWindowTheme(LPCWSTR lpstrTheme)
2442 {
2443 ATLASSERT(::IsWindow(m_hWnd));
2444 ::SendMessage(m_hWnd, TTM_SETWINDOWTHEME, 0, (LPARAM)lpstrTheme);
2445 }
2446 #endif // (_WIN32_WINNT >= 0x0501)
2447
2448 // Operations
2449 void Activate(BOOL bActivate)
2450 {
2451 ATLASSERT(::IsWindow(m_hWnd));
2452 ::SendMessage(m_hWnd, TTM_ACTIVATE, bActivate, 0L);
2453 }
2454
2455 BOOL AddTool(LPTOOLINFO lpToolInfo)
2456 {
2457 ATLASSERT(::IsWindow(m_hWnd));
2458 return (BOOL)::SendMessage(m_hWnd, TTM_ADDTOOL, 0, (LPARAM)lpToolInfo);
2459 }
2460
2461 BOOL AddTool(HWND hWnd, ATL::_U_STRINGorID text = LPSTR_TEXTCALLBACK, LPCRECT lpRectTool = NULL, UINT_PTR nIDTool = 0)
2462 {
2463 ATLASSERT(::IsWindow(m_hWnd));
2464 ATLASSERT(hWnd != NULL);
2465 // the toolrect and toolid must both be zero or both valid
2466 ATLASSERT((lpRectTool != NULL && nIDTool != 0) || (lpRectTool == NULL && nIDTool == 0));
2467
2468 CToolInfo ti(0, hWnd, nIDTool, (LPRECT)lpRectTool, (LPTSTR)text.m_lpstr);
2469 return (BOOL)::SendMessage(m_hWnd, TTM_ADDTOOL, 0, ti);
2470 }
2471
2472 void DelTool(LPTOOLINFO lpToolInfo)
2473 {
2474 ATLASSERT(::IsWindow(m_hWnd));
2475 ::SendMessage(m_hWnd, TTM_DELTOOL, 0, (LPARAM)lpToolInfo);
2476 }
2477
2478 void DelTool(HWND hWnd, UINT_PTR nIDTool = 0)
2479 {
2480 ATLASSERT(::IsWindow(m_hWnd));
2481 ATLASSERT(hWnd != NULL);
2482
2483 CToolInfo ti(0, hWnd, nIDTool, NULL, NULL);
2484 ::SendMessage(m_hWnd, TTM_DELTOOL, 0, ti);
2485 }
2486
2487 BOOL HitTest(LPTTHITTESTINFO lpHitTestInfo) const
2488 {
2489 ATLASSERT(::IsWindow(m_hWnd));
2490 return (BOOL)::SendMessage(m_hWnd, TTM_HITTEST, 0, (LPARAM)lpHitTestInfo);
2491 }
2492
2493 BOOL HitTest(HWND hWnd, POINT pt, LPTOOLINFO lpToolInfo) const
2494 {
2495 ATLASSERT(::IsWindow(m_hWnd));
2496 ATLASSERT(hWnd != NULL);
2497 ATLASSERT(lpToolInfo != NULL);
2498
2499 TTHITTESTINFO hti = { 0 };
2500 hti.ti.cbSize = RunTimeHelper::SizeOf_TOOLINFO();
2501 hti.hwnd = hWnd;
2502 hti.pt.x = pt.x;
2503 hti.pt.y = pt.y;
2504 if((BOOL)::SendMessage(m_hWnd, TTM_HITTEST, 0, (LPARAM)&hti) != FALSE)
2505 {
2506 *lpToolInfo = hti.ti;
2507 return TRUE;
2508 }
2509 return FALSE;
2510 }
2511
2512 void RelayEvent(LPMSG lpMsg)
2513 {
2514 ATLASSERT(::IsWindow(m_hWnd));
2515 ::SendMessage(m_hWnd, TTM_RELAYEVENT, 0, (LPARAM)lpMsg);
2516 }
2517
2518 void UpdateTipText(LPTOOLINFO lpToolInfo)
2519 {
2520 ATLASSERT(::IsWindow(m_hWnd));
2521 ::SendMessage(m_hWnd, TTM_UPDATETIPTEXT, 0, (LPARAM)lpToolInfo);
2522 }
2523
2524 void UpdateTipText(ATL::_U_STRINGorID text, HWND hWnd, UINT_PTR nIDTool = 0)
2525 {
2526 ATLASSERT(::IsWindow(m_hWnd));
2527 ATLASSERT(hWnd != NULL);
2528
2529 CToolInfo ti(0, hWnd, nIDTool, NULL, (LPTSTR)text.m_lpstr);
2530 ::SendMessage(m_hWnd, TTM_UPDATETIPTEXT, 0, ti);
2531 }
2532
2533 BOOL EnumTools(UINT_PTR nTool, LPTOOLINFO lpToolInfo) const
2534 {
2535 ATLASSERT(::IsWindow(m_hWnd));
2536 return (BOOL)::SendMessage(m_hWnd, TTM_ENUMTOOLS, nTool, (LPARAM)lpToolInfo);
2537 }
2538
2539 void Pop()
2540 {
2541 ATLASSERT(::IsWindow(m_hWnd));
2542 ::SendMessage(m_hWnd, TTM_POP, 0, 0L);
2543 }
2544
2545 void TrackActivate(LPTOOLINFO lpToolInfo, BOOL bActivate)
2546 {
2547 ATLASSERT(::IsWindow(m_hWnd));
2548 ::SendMessage(m_hWnd, TTM_TRACKACTIVATE, bActivate, (LPARAM)lpToolInfo);
2549 }
2550
2551 void TrackActivate(HWND hWnd, UINT_PTR nIDTool, BOOL bActivate)
2552 {
2553 ATLASSERT(::IsWindow(m_hWnd));
2554 ATLASSERT(hWnd != NULL);
2555
2556 CToolInfo ti(0, hWnd, nIDTool);
2557 ::SendMessage(m_hWnd, TTM_TRACKACTIVATE, bActivate, ti);
2558 }
2559
2560 void TrackPosition(int xPos, int yPos)
2561 {
2562 ATLASSERT(::IsWindow(m_hWnd));
2563 ::SendMessage(m_hWnd, TTM_TRACKPOSITION, 0, MAKELPARAM(xPos, yPos));
2564 }
2565
2566 #if (_WIN32_IE >= 0x0400)
2567 void Update()
2568 {
2569 ATLASSERT(::IsWindow(m_hWnd));
2570 ::SendMessage(m_hWnd, TTM_UPDATE, 0, 0L);
2571 }
2572 #endif // (_WIN32_IE >= 0x0400)
2573
2574 #if (_WIN32_IE >= 0x0500)
2575 BOOL AdjustRect(LPRECT lpRect, BOOL bLarger /*= TRUE*/)
2576 {
2577 ATLASSERT(::IsWindow(m_hWnd));
2578 return (BOOL)::SendMessage(m_hWnd, TTM_ADJUSTRECT, bLarger, (LPARAM)lpRect);
2579 }
2580 #endif // (_WIN32_IE >= 0x0500)
2581
2582 #if (_WIN32_WINNT >= 0x0501)
2583 void Popup()
2584 {
2585 ATLASSERT(::IsWindow(m_hWnd));
2586 ::SendMessage(m_hWnd, TTM_POPUP, 0, 0L);
2587 }
2588 #endif // (_WIN32_WINNT >= 0x0501)
2589 };
2590
2591 typedef CToolTipCtrlT<ATL::CWindow> CToolTipCtrl;
2592
2593 #endif // !_WIN32_WCE
2594
2595
2596 ///////////////////////////////////////////////////////////////////////////////
2597 // CHeaderCtrl
2598
2599 template <class TBase>
2600 class CHeaderCtrlT : public TBase
2601 {
2602 public:
2603 // Constructors
2604 CHeaderCtrlT(HWND hWnd = NULL) : TBase(hWnd)
2605 { }
2606
2607 CHeaderCtrlT< TBase >& operator =(HWND hWnd)
2608 {
2609 m_hWnd = hWnd;
2610 return *this;
2611 }
2612
2613 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
2614 DWORD dwStyle = 0, DWORD dwExStyle = 0,
2615 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
2616 {
2617 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
2618 }
2619
2620 // Attributes
2621 static LPCTSTR GetWndClassName()
2622 {
2623 return WC_HEADER;
2624 }
2625
2626 int GetItemCount() const
2627 {
2628 ATLASSERT(::IsWindow(m_hWnd));
2629 return (int)::SendMessage(m_hWnd, HDM_GETITEMCOUNT, 0, 0L);
2630 }
2631
2632 BOOL GetItem(int nIndex, LPHDITEM pHeaderItem) const
2633 {
2634 ATLASSERT(::IsWindow(m_hWnd));
2635 return (BOOL)::SendMessage(m_hWnd, HDM_GETITEM, nIndex, (LPARAM)pHeaderItem);
2636 }
2637
2638 BOOL SetItem(int nIndex, LPHDITEM pHeaderItem)
2639 {
2640 ATLASSERT(::IsWindow(m_hWnd));
2641 return (BOOL)::SendMessage(m_hWnd, HDM_SETITEM, nIndex, (LPARAM)pHeaderItem);
2642 }
2643
2644 CImageList GetImageList() const
2645 {
2646 ATLASSERT(::IsWindow(m_hWnd));
2647 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, HDM_GETIMAGELIST, 0, 0L));
2648 }
2649
2650 CImageList SetImageList(HIMAGELIST hImageList)
2651 {
2652 ATLASSERT(::IsWindow(m_hWnd));
2653 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, HDM_SETIMAGELIST, 0, (LPARAM)hImageList));
2654 }
2655
2656 BOOL GetOrderArray(int nSize, int* lpnArray) const
2657 {
2658 ATLASSERT(::IsWindow(m_hWnd));
2659 return (BOOL)::SendMessage(m_hWnd, HDM_GETORDERARRAY, nSize, (LPARAM)lpnArray);
2660 }
2661
2662 BOOL SetOrderArray(int nSize, int* lpnArray)
2663 {
2664 ATLASSERT(::IsWindow(m_hWnd));
2665 return (BOOL)::SendMessage(m_hWnd, HDM_SETORDERARRAY, nSize, (LPARAM)lpnArray);
2666 }
2667
2668 BOOL GetItemRect(int nIndex, LPRECT lpItemRect) const
2669 {
2670 ATLASSERT(::IsWindow(m_hWnd));
2671 return (BOOL)::SendMessage(m_hWnd, HDM_GETITEMRECT, nIndex, (LPARAM)lpItemRect);
2672 }
2673
2674 int SetHotDivider(BOOL bPos, DWORD dwInputValue)
2675 {
2676 ATLASSERT(::IsWindow(m_hWnd));
2677 return (int)::SendMessage(m_hWnd, HDM_SETHOTDIVIDER, bPos, dwInputValue);
2678 }
2679
2680 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
2681 BOOL GetUnicodeFormat() const
2682 {
2683 ATLASSERT(::IsWindow(m_hWnd));
2684 return (BOOL)::SendMessage(m_hWnd, HDM_GETUNICODEFORMAT, 0, 0L);
2685 }
2686
2687 BOOL SetUnicodeFormat(BOOL bUnicode = TRUE)
2688 {
2689 ATLASSERT(::IsWindow(m_hWnd));
2690 return (BOOL)::SendMessage(m_hWnd, HDM_SETUNICODEFORMAT, bUnicode, 0L);
2691 }
2692 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
2693
2694 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
2695 int GetBitmapMargin() const
2696 {
2697 ATLASSERT(::IsWindow(m_hWnd));
2698 return (int)::SendMessage(m_hWnd, HDM_GETBITMAPMARGIN, 0, 0L);
2699 }
2700
2701 int SetBitmapMargin(int nWidth)
2702 {
2703 ATLASSERT(::IsWindow(m_hWnd));
2704 return (int)::SendMessage(m_hWnd, HDM_SETBITMAPMARGIN, nWidth, 0L);
2705 }
2706
2707 int SetFilterChangeTimeout(DWORD dwTimeOut)
2708 {
2709 ATLASSERT(::IsWindow(m_hWnd));
2710 return (int)::SendMessage(m_hWnd, HDM_SETFILTERCHANGETIMEOUT, 0, dwTimeOut);
2711 }
2712 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
2713
2714 #if (_WIN32_WINNT >= 0x0600)
2715 BOOL GetItemDropDownRect(int nIndex, LPRECT lpRect) const
2716 {
2717 ATLASSERT(::IsWindow(m_hWnd));
2718 return (BOOL)::SendMessage(m_hWnd, HDM_GETITEMDROPDOWNRECT, nIndex, (LPARAM)lpRect);
2719 }
2720
2721 BOOL GetOverflowRect(LPRECT lpRect) const
2722 {
2723 ATLASSERT(::IsWindow(m_hWnd));
2724 return (BOOL)::SendMessage(m_hWnd, HDM_GETOVERFLOWRECT, 0, (LPARAM)lpRect);
2725 }
2726
2727 int GetFocusedItem() const
2728 {
2729 ATLASSERT(::IsWindow(m_hWnd));
2730 return (int)::SendMessage(m_hWnd, HDM_GETFOCUSEDITEM, 0, 0L);
2731 }
2732
2733 BOOL SetFocusedItem(int nIndex)
2734 {
2735 ATLASSERT(::IsWindow(m_hWnd));
2736 return (BOOL)::SendMessage(m_hWnd, HDM_SETFOCUSEDITEM, 0, nIndex);
2737 }
2738 #endif // (_WIN32_WINNT >= 0x0600)
2739
2740 // Operations
2741 int InsertItem(int nIndex, LPHDITEM phdi)
2742 {
2743 ATLASSERT(::IsWindow(m_hWnd));
2744 return (int)::SendMessage(m_hWnd, HDM_INSERTITEM, nIndex, (LPARAM)phdi);
2745 }
2746
2747 int AddItem(LPHDITEM phdi)
2748 {
2749 return InsertItem(GetItemCount(), phdi);
2750 }
2751
2752 BOOL DeleteItem(int nIndex)
2753 {
2754 ATLASSERT(::IsWindow(m_hWnd));
2755 return (BOOL)::SendMessage(m_hWnd, HDM_DELETEITEM, nIndex, 0L);
2756 }
2757
2758 BOOL Layout(HD_LAYOUT* pHeaderLayout)
2759 {
2760 ATLASSERT(::IsWindow(m_hWnd));
2761 return (BOOL)::SendMessage(m_hWnd, HDM_LAYOUT, 0, (LPARAM)pHeaderLayout);
2762 }
2763
2764 int HitTest(LPHDHITTESTINFO lpHitTestInfo) const
2765 {
2766 ATLASSERT(::IsWindow(m_hWnd));
2767 return (int)::SendMessage(m_hWnd, HDM_HITTEST, 0, (LPARAM)lpHitTestInfo);
2768 }
2769
2770 int OrderToIndex(int nOrder)
2771 {
2772 ATLASSERT(::IsWindow(m_hWnd));
2773 return (int)::SendMessage(m_hWnd, HDM_ORDERTOINDEX, nOrder, 0L);
2774 }
2775
2776 CImageList CreateDragImage(int nIndex)
2777 {
2778 ATLASSERT(::IsWindow(m_hWnd));
2779 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, HDM_CREATEDRAGIMAGE, nIndex, 0L));
2780 }
2781
2782 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
2783 int EditFilter(int nColumn, BOOL bDiscardChanges)
2784 {
2785 ATLASSERT(::IsWindow(m_hWnd));
2786 return (int)::SendMessage(m_hWnd, HDM_EDITFILTER, nColumn, MAKELPARAM(bDiscardChanges, 0));
2787 }
2788
2789 int ClearFilter(int nColumn)
2790 {
2791 ATLASSERT(::IsWindow(m_hWnd));
2792 return (int)::SendMessage(m_hWnd, HDM_CLEARFILTER, nColumn, 0L);
2793 }
2794
2795 int ClearAllFilters()
2796 {
2797 ATLASSERT(::IsWindow(m_hWnd));
2798 return (int)::SendMessage(m_hWnd, HDM_CLEARFILTER, (WPARAM)-1, 0L);
2799 }
2800 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
2801 };
2802
2803 typedef CHeaderCtrlT<ATL::CWindow> CHeaderCtrl;
2804
2805
2806 ///////////////////////////////////////////////////////////////////////////////
2807 // CListViewCtrl
2808
2809 template <class TBase>
2810 class CListViewCtrlT : public TBase
2811 {
2812 public:
2813 // Constructors
2814 CListViewCtrlT(HWND hWnd = NULL) : TBase(hWnd)
2815 { }
2816
2817 CListViewCtrlT< TBase >& operator =(HWND hWnd)
2818 {
2819 m_hWnd = hWnd;
2820 return *this;
2821 }
2822
2823 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
2824 DWORD dwStyle = 0, DWORD dwExStyle = 0,
2825 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
2826 {
2827 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
2828 }
2829
2830 // Attributes
2831 static LPCTSTR GetWndClassName()
2832 {
2833 return WC_LISTVIEW;
2834 }
2835
2836 COLORREF GetBkColor() const
2837 {
2838 ATLASSERT(::IsWindow(m_hWnd));
2839 return (COLORREF)::SendMessage(m_hWnd, LVM_GETBKCOLOR, 0, 0L);
2840 }
2841
2842 BOOL SetBkColor(COLORREF cr)
2843 {
2844 ATLASSERT(::IsWindow(m_hWnd));
2845 return (BOOL)::SendMessage(m_hWnd, LVM_SETBKCOLOR, 0, cr);
2846 }
2847
2848 CImageList GetImageList(int nImageListType) const
2849 {
2850 ATLASSERT(::IsWindow(m_hWnd));
2851 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, LVM_GETIMAGELIST, nImageListType, 0L));
2852 }
2853
2854 CImageList SetImageList(HIMAGELIST hImageList, int nImageList)
2855 {
2856 ATLASSERT(::IsWindow(m_hWnd));
2857 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, LVM_SETIMAGELIST, nImageList, (LPARAM)hImageList));
2858 }
2859
2860 int GetItemCount() const
2861 {
2862 ATLASSERT(::IsWindow(m_hWnd));
2863 return (int)::SendMessage(m_hWnd, LVM_GETITEMCOUNT, 0, 0L);
2864 }
2865
2866 BOOL SetItemCount(int nItems)
2867 {
2868 ATLASSERT(::IsWindow(m_hWnd));
2869 return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMCOUNT, nItems, 0L);
2870 }
2871
2872 BOOL GetItem(LPLVITEM pItem) const
2873 {
2874 ATLASSERT(::IsWindow(m_hWnd));
2875 return (BOOL)::SendMessage(m_hWnd, LVM_GETITEM, 0, (LPARAM)pItem);
2876 }
2877
2878 BOOL SetItem(const LVITEM* pItem)
2879 {
2880 ATLASSERT(::IsWindow(m_hWnd));
2881 return (BOOL)::SendMessage(m_hWnd, LVM_SETITEM, 0, (LPARAM)pItem);
2882 }
2883
2884 BOOL SetItem(int nItem, int nSubItem, UINT nMask, LPCTSTR lpszItem,
2885 int nImage, UINT nState, UINT nStateMask, LPARAM lParam)
2886 {
2887 ATLASSERT(::IsWindow(m_hWnd));
2888 LVITEM lvi = { 0 };
2889 lvi.mask = nMask;
2890 lvi.iItem = nItem;
2891 lvi.iSubItem = nSubItem;
2892 lvi.stateMask = nStateMask;
2893 lvi.state = nState;
2894 lvi.pszText = (LPTSTR) lpszItem;
2895 lvi.iImage = nImage;
2896 lvi.lParam = lParam;
2897 return (BOOL)::SendMessage(m_hWnd, LVM_SETITEM, 0, (LPARAM)&lvi);
2898 }
2899
2900 UINT GetItemState(int nItem, UINT nMask) const
2901 {
2902 ATLASSERT(::IsWindow(m_hWnd));
2903 return (UINT)::SendMessage(m_hWnd, LVM_GETITEMSTATE, nItem, nMask);
2904 }
2905
2906 BOOL SetItemState(int nItem, UINT nState, UINT nStateMask)
2907 {
2908 ATLASSERT(::IsWindow(m_hWnd));
2909 LVITEM lvi = { 0 };
2910 lvi.state = nState;
2911 lvi.stateMask = nStateMask;
2912 return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMSTATE, nItem, (LPARAM)&lvi);
2913 }
2914
2915 BOOL SetItemState(int nItem, LPLVITEM pItem)
2916 {
2917 ATLASSERT(::IsWindow(m_hWnd));
2918 return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMSTATE, nItem, (LPARAM)pItem);
2919 }
2920
2921 #ifndef _ATL_NO_COM
2922 BOOL GetItemText(int nItem, int nSubItem, BSTR& bstrText) const
2923 {
2924 USES_CONVERSION;
2925 ATLASSERT(::IsWindow(m_hWnd));
2926 ATLASSERT(bstrText == NULL);
2927 LVITEM lvi = { 0 };
2928 lvi.iSubItem = nSubItem;
2929
2930 LPTSTR lpstrText = NULL;
2931 int nRes = 0;
2932 for(int nLen = 256; ; nLen *= 2)
2933 {
2934 ATLTRY(lpstrText = new TCHAR[nLen]);
2935 if(lpstrText == NULL)
2936 break;
2937 lpstrText[0] = NULL;
2938 lvi.cchTextMax = nLen;
2939 lvi.pszText = lpstrText;
2940 nRes = (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem, (LPARAM)&lvi);
2941 if(nRes < nLen - 1)
2942 break;
2943 delete [] lpstrText;
2944 lpstrText = NULL;
2945 }
2946
2947 if(lpstrText != NULL)
2948 {
2949 if(nRes != 0)
2950 bstrText = ::SysAllocString(T2OLE(lpstrText));
2951 delete [] lpstrText;
2952 }
2953
2954 return (bstrText != NULL) ? TRUE : FALSE;
2955 }
2956 #endif // !_ATL_NO_COM
2957
2958 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
2959 int GetItemText(int nItem, int nSubItem, _CSTRING_NS::CString& strText) const
2960 {
2961 ATLASSERT(::IsWindow(m_hWnd));
2962 LVITEM lvi = { 0 };
2963 lvi.iSubItem = nSubItem;
2964
2965 strText.Empty();
2966 int nRes = 0;
2967 for(int nLen = 256; ; nLen *= 2)
2968 {
2969 lvi.cchTextMax = nLen;
2970 lvi.pszText = strText.GetBufferSetLength(nLen);
2971 if(lvi.pszText == NULL)
2972 {
2973 nRes = 0;
2974 break;
2975 }
2976 nRes = (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem, (LPARAM)&lvi);
2977 if(nRes < nLen - 1)
2978 break;
2979 }
2980 strText.ReleaseBuffer();
2981 return nRes;
2982 }
2983 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
2984
2985 int GetItemText(int nItem, int nSubItem, LPTSTR lpszText, int nLen) const
2986 {
2987 ATLASSERT(::IsWindow(m_hWnd));
2988 LVITEM lvi = { 0 };
2989 lvi.iSubItem = nSubItem;
2990 lvi.cchTextMax = nLen;
2991 lvi.pszText = lpszText;
2992 return (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem, (LPARAM)&lvi);
2993 }
2994
2995 BOOL SetItemText(int nItem, int nSubItem, LPCTSTR lpszText)
2996 {
2997 ATLASSERT(::IsWindow(m_hWnd));
2998 return SetItem(nItem, nSubItem, LVIF_TEXT, lpszText, 0, 0, 0, 0);
2999 }
3000
3001 DWORD_PTR GetItemData(int nItem) const
3002 {
3003 ATLASSERT(::IsWindow(m_hWnd));
3004 LVITEM lvi = { 0 };
3005 lvi.iItem = nItem;
3006 lvi.mask = LVIF_PARAM;
3007 BOOL bRet = (BOOL)::SendMessage(m_hWnd, LVM_GETITEM, 0, (LPARAM)&lvi);
3008 return (DWORD_PTR)(bRet ? lvi.lParam : NULL);
3009 }
3010
3011 BOOL SetItemData(int nItem, DWORD_PTR dwData)
3012 {
3013 ATLASSERT(::IsWindow(m_hWnd));
3014 return SetItem(nItem, 0, LVIF_PARAM, NULL, 0, 0, 0, (LPARAM)dwData);
3015 }
3016
3017 UINT GetCallbackMask() const
3018 {
3019 ATLASSERT(::IsWindow(m_hWnd));
3020 return (UINT)::SendMessage(m_hWnd, LVM_GETCALLBACKMASK, 0, 0L);
3021 }
3022
3023 BOOL SetCallbackMask(UINT nMask)
3024 {
3025 ATLASSERT(::IsWindow(m_hWnd));
3026 return (BOOL)::SendMessage(m_hWnd, LVM_SETCALLBACKMASK, nMask, 0L);
3027 }
3028
3029 BOOL GetItemPosition(int nItem, LPPOINT lpPoint) const
3030 {
3031 ATLASSERT(::IsWindow(m_hWnd));
3032 return (BOOL)::SendMessage(m_hWnd, LVM_GETITEMPOSITION, nItem, (LPARAM)lpPoint);
3033 }
3034
3035 BOOL SetItemPosition(int nItem, POINT pt)
3036 {
3037 ATLASSERT(::IsWindow(m_hWnd));
3038 ATLASSERT(((GetStyle() & LVS_TYPEMASK) == LVS_ICON) || ((GetStyle() & LVS_TYPEMASK) == LVS_SMALLICON));
3039 return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMPOSITION32, nItem, (LPARAM)&pt);
3040 }
3041
3042 BOOL SetItemPosition(int nItem, int x, int y)
3043 {
3044 ATLASSERT(::IsWindow(m_hWnd));
3045 ATLASSERT(((GetStyle() & LVS_TYPEMASK) == LVS_ICON) || ((GetStyle() & LVS_TYPEMASK) == LVS_SMALLICON));
3046 POINT pt = { x, y };
3047 return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMPOSITION32, nItem, (LPARAM)&pt);
3048 }
3049
3050 int GetStringWidth(LPCTSTR lpsz) const
3051 {
3052 ATLASSERT(::IsWindow(m_hWnd));
3053 return (int)::SendMessage(m_hWnd, LVM_GETSTRINGWIDTH, 0, (LPARAM)lpsz);
3054 }
3055
3056 CEdit GetEditControl() const
3057 {
3058 ATLASSERT(::IsWindow(m_hWnd));
3059 return CEdit((HWND)::SendMessage(m_hWnd, LVM_GETEDITCONTROL, 0, 0L));
3060 }
3061
3062 BOOL GetColumn(int nCol, LVCOLUMN* pColumn) const
3063 {
3064 ATLASSERT(::IsWindow(m_hWnd));
3065 return (BOOL)::SendMessage(m_hWnd, LVM_GETCOLUMN, nCol, (LPARAM)pColumn);
3066 }
3067
3068 BOOL SetColumn(int nCol, const LVCOLUMN* pColumn)
3069 {
3070 ATLASSERT(::IsWindow(m_hWnd));
3071 return (BOOL)::SendMessage(m_hWnd, LVM_SETCOLUMN, nCol, (LPARAM)pColumn);
3072 }
3073
3074 int GetColumnWidth(int nCol) const
3075 {
3076 ATLASSERT(::IsWindow(m_hWnd));
3077 return (int)::SendMessage(m_hWnd, LVM_GETCOLUMNWIDTH, nCol, 0L);
3078 }
3079
3080 BOOL SetColumnWidth(int nCol, int cx)
3081 {
3082 ATLASSERT(::IsWindow(m_hWnd));
3083 return (BOOL)::SendMessage(m_hWnd, LVM_SETCOLUMNWIDTH, nCol, MAKELPARAM(cx, 0));
3084 }
3085
3086 BOOL GetViewRect(LPRECT lpRect) const
3087 {
3088 ATLASSERT(::IsWindow(m_hWnd));
3089 return (BOOL)::SendMessage(m_hWnd, LVM_GETVIEWRECT, 0, (LPARAM)lpRect);
3090 }
3091
3092 COLORREF GetTextColor() const
3093 {
3094 ATLASSERT(::IsWindow(m_hWnd));
3095 return (COLORREF)::SendMessage(m_hWnd, LVM_GETTEXTCOLOR, 0, 0L);
3096 }
3097
3098 BOOL SetTextColor(COLORREF cr)
3099 {
3100 ATLASSERT(::IsWindow(m_hWnd));
3101 return (BOOL)::SendMessage(m_hWnd, LVM_SETTEXTCOLOR, 0, cr);
3102 }
3103
3104 COLORREF GetTextBkColor() const
3105 {
3106 ATLASSERT(::IsWindow(m_hWnd));
3107 return (COLORREF)::SendMessage(m_hWnd, LVM_GETTEXTBKCOLOR, 0, 0L);
3108 }
3109
3110 BOOL SetTextBkColor(COLORREF cr)
3111 {
3112 ATLASSERT(::IsWindow(m_hWnd));
3113 return (BOOL)::SendMessage(m_hWnd, LVM_SETTEXTBKCOLOR, 0, cr);
3114 }
3115
3116 int GetTopIndex() const
3117 {
3118 ATLASSERT(::IsWindow(m_hWnd));
3119 return (int)::SendMessage(m_hWnd, LVM_GETTOPINDEX, 0, 0L);
3120 }
3121
3122 int GetCountPerPage() const
3123 {
3124 ATLASSERT(::IsWindow(m_hWnd));
3125 return (int)::SendMessage(m_hWnd, LVM_GETCOUNTPERPAGE, 0, 0L);
3126 }
3127
3128 BOOL GetOrigin(LPPOINT lpPoint) const
3129 {
3130 ATLASSERT(::IsWindow(m_hWnd));
3131 return (BOOL)::SendMessage(m_hWnd, LVM_GETORIGIN, 0, (LPARAM)lpPoint);
3132 }
3133
3134 UINT GetSelectedCount() const
3135 {
3136 ATLASSERT(::IsWindow(m_hWnd));
3137 return (UINT)::SendMessage(m_hWnd, LVM_GETSELECTEDCOUNT, 0, 0L);
3138 }
3139
3140 BOOL GetItemRect(int nItem, LPRECT lpRect, UINT nCode) const
3141 {
3142 ATLASSERT(::IsWindow(m_hWnd));
3143 lpRect->left = nCode;
3144 return (BOOL)::SendMessage(m_hWnd, LVM_GETITEMRECT, (WPARAM)nItem, (LPARAM)lpRect);
3145 }
3146
3147 #ifndef _WIN32_WCE
3148 HCURSOR GetHotCursor() const
3149 {
3150 ATLASSERT(::IsWindow(m_hWnd));
3151 return (HCURSOR)::SendMessage(m_hWnd, LVM_GETHOTCURSOR, 0, 0L);
3152 }
3153
3154 HCURSOR SetHotCursor(HCURSOR hHotCursor)
3155 {
3156 ATLASSERT(::IsWindow(m_hWnd));
3157 return (HCURSOR)::SendMessage(m_hWnd, LVM_SETHOTCURSOR, 0, (LPARAM)hHotCursor);
3158 }
3159
3160 int GetHotItem() const
3161 {
3162 ATLASSERT(::IsWindow(m_hWnd));
3163 return (int)::SendMessage(m_hWnd, LVM_GETHOTITEM, 0, 0L);
3164 }
3165
3166 int SetHotItem(int nIndex)
3167 {
3168 ATLASSERT(::IsWindow(m_hWnd));
3169 return (int)::SendMessage(m_hWnd, LVM_SETHOTITEM, nIndex, 0L);
3170 }
3171 #endif // !_WIN32_WCE
3172
3173 BOOL GetColumnOrderArray(int nCount, int* lpnArray) const
3174 {
3175 ATLASSERT(::IsWindow(m_hWnd));
3176 return (BOOL)::SendMessage(m_hWnd, LVM_GETCOLUMNORDERARRAY, nCount, (LPARAM)lpnArray);
3177 }
3178
3179 BOOL SetColumnOrderArray(int nCount, int* lpnArray)
3180 {
3181 ATLASSERT(::IsWindow(m_hWnd));
3182 return (BOOL)::SendMessage(m_hWnd, LVM_SETCOLUMNORDERARRAY, nCount, (LPARAM)lpnArray);
3183 }
3184
3185 CHeaderCtrl GetHeader() const
3186 {
3187 ATLASSERT(::IsWindow(m_hWnd));
3188 return CHeaderCtrl((HWND)::SendMessage(m_hWnd, LVM_GETHEADER, 0, 0L));
3189 }
3190
3191 BOOL GetSubItemRect(int nItem, int nSubItem, int nFlag, LPRECT lpRect) const
3192 {
3193 ATLASSERT(::IsWindow(m_hWnd));
3194 ATLASSERT((GetStyle() & LVS_TYPEMASK) == LVS_REPORT);
3195 ATLASSERT(lpRect != NULL);
3196 lpRect->top = nSubItem;
3197 lpRect->left = nFlag;
3198 return (BOOL)::SendMessage(m_hWnd, LVM_GETSUBITEMRECT, nItem, (LPARAM)lpRect);
3199 }
3200
3201 DWORD SetIconSpacing(int cx, int cy)
3202 {
3203 ATLASSERT(::IsWindow(m_hWnd));
3204 ATLASSERT((GetStyle() & LVS_TYPEMASK) == LVS_ICON);
3205 return (DWORD)::SendMessage(m_hWnd, LVM_SETICONSPACING, 0, MAKELPARAM(cx, cy));
3206 }
3207
3208 int GetISearchString(LPTSTR lpstr) const
3209 {
3210 ATLASSERT(::IsWindow(m_hWnd));
3211 return (int)::SendMessage(m_hWnd, LVM_GETISEARCHSTRING, 0, (LPARAM)lpstr);
3212 }
3213
3214 void GetItemSpacing(SIZE& sizeSpacing, BOOL bSmallIconView = FALSE) const
3215 {
3216 ATLASSERT(::IsWindow(m_hWnd));
3217 DWORD dwRet = (DWORD)::SendMessage(m_hWnd, LVM_GETITEMSPACING, bSmallIconView, 0L);
3218 sizeSpacing.cx = GET_X_LPARAM(dwRet);
3219 sizeSpacing.cy = GET_Y_LPARAM(dwRet);
3220 }
3221
3222 #if (_WIN32_WCE >= 410)
3223 void SetItemSpacing(INT cySpacing)
3224 {
3225 ATLASSERT(::IsWindow(m_hWnd));
3226 ListView_SetItemSpacing(m_hWnd, cySpacing);
3227 }
3228 #endif // (_WIN32_WCE >= 410)
3229
3230 // single-selection only
3231 int GetSelectedIndex() const
3232 {
3233 ATLASSERT(::IsWindow(m_hWnd));
3234 ATLASSERT((GetStyle() & LVS_SINGLESEL) != 0);
3235 return (int)::SendMessage(m_hWnd, LVM_GETNEXTITEM, (WPARAM)-1, MAKELPARAM(LVNI_ALL | LVNI_SELECTED, 0));
3236 }
3237
3238 BOOL GetSelectedItem(LPLVITEM pItem) const
3239 {
3240 ATLASSERT(::IsWindow(m_hWnd));
3241 ATLASSERT((GetStyle() & LVS_SINGLESEL) != 0);
3242 ATLASSERT(pItem != NULL);
3243 pItem->iItem = (int)::SendMessage(m_hWnd, LVM_GETNEXTITEM, (WPARAM)-1, MAKELPARAM(LVNI_ALL | LVNI_SELECTED, 0));
3244 if(pItem->iItem == -1)
3245 return FALSE;
3246 return (BOOL)::SendMessage(m_hWnd, LVM_GETITEM, 0, (LPARAM)pItem);
3247 }
3248
3249 // extended list view styles
3250 DWORD GetExtendedListViewStyle() const
3251 {
3252 ATLASSERT(::IsWindow(m_hWnd));
3253 return (DWORD)::SendMessage(m_hWnd, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0L);
3254 }
3255
3256 // dwExMask = 0 means all styles
3257 DWORD SetExtendedListViewStyle(DWORD dwExStyle, DWORD dwExMask = 0)
3258 {
3259 ATLASSERT(::IsWindow(m_hWnd));
3260 return (DWORD)::SendMessage(m_hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE, dwExMask, dwExStyle);
3261 }
3262
3263 // checkboxes only
3264 BOOL GetCheckState(int nIndex) const
3265 {
3266 ATLASSERT(::IsWindow(m_hWnd));
3267 ATLASSERT((GetExtendedListViewStyle() & LVS_EX_CHECKBOXES) != 0);
3268 UINT uRet = GetItemState(nIndex, LVIS_STATEIMAGEMASK);
3269 return (uRet >> 12) - 1;
3270 }
3271
3272 BOOL SetCheckState(int nItem, BOOL bCheck)
3273 {
3274 int nCheck = bCheck ? 2 : 1; // one based index
3275 return SetItemState(nItem, INDEXTOSTATEIMAGEMASK(nCheck), LVIS_STATEIMAGEMASK);
3276 }
3277
3278 // view type
3279 DWORD GetViewType() const
3280 {
3281 ATLASSERT(::IsWindow(m_hWnd));
3282 return (GetStyle() & LVS_TYPEMASK);
3283 }
3284
3285 DWORD SetViewType(DWORD dwType)
3286 {
3287 ATLASSERT(::IsWindow(m_hWnd));
3288 ATLASSERT(dwType == LVS_ICON || dwType == LVS_SMALLICON || dwType == LVS_LIST || dwType == LVS_REPORT);
3289 DWORD dwOldType = GetViewType();
3290 if(dwType != dwOldType)
3291 ModifyStyle(LVS_TYPEMASK, (dwType & LVS_TYPEMASK));
3292 return dwOldType;
3293 }
3294
3295 #if (_WIN32_IE >= 0x0400)
3296 #ifndef _WIN32_WCE
3297 BOOL GetBkImage(LPLVBKIMAGE plvbki) const
3298 {
3299 ATLASSERT(::IsWindow(m_hWnd));
3300 return (BOOL)::SendMessage(m_hWnd, LVM_GETBKIMAGE, 0, (LPARAM)plvbki);
3301 }
3302
3303 BOOL SetBkImage(LPLVBKIMAGE plvbki)
3304 {
3305 ATLASSERT(::IsWindow(m_hWnd));
3306 return (BOOL)::SendMessage(m_hWnd, LVM_SETBKIMAGE, 0, (LPARAM)plvbki);
3307 }
3308 #endif // !_WIN32_WCE
3309
3310 int GetSelectionMark() const
3311 {
3312 ATLASSERT(::IsWindow(m_hWnd));
3313 return (int)::SendMessage(m_hWnd, LVM_GETSELECTIONMARK, 0, 0L);
3314 }
3315
3316 int SetSelectionMark(int nIndex)
3317 {
3318 ATLASSERT(::IsWindow(m_hWnd));
3319 return (int)::SendMessage(m_hWnd, LVM_SETSELECTIONMARK, 0, nIndex);
3320 }
3321
3322 #ifndef _WIN32_WCE
3323 BOOL GetWorkAreas(int nWorkAreas, LPRECT lpRect) const
3324 {
3325 ATLASSERT(::IsWindow(m_hWnd));
3326 return (BOOL)::SendMessage(m_hWnd, LVM_GETWORKAREAS, nWorkAreas, (LPARAM)lpRect);
3327 }
3328
3329 BOOL SetWorkAreas(int nWorkAreas, LPRECT lpRect)
3330 {
3331 ATLASSERT(::IsWindow(m_hWnd));
3332 return (BOOL)::SendMessage(m_hWnd, LVM_SETWORKAREAS, nWorkAreas, (LPARAM)lpRect);
3333 }
3334
3335 DWORD GetHoverTime() const
3336 {
3337 ATLASSERT(::IsWindow(m_hWnd));
3338 ATLASSERT((GetExtendedListViewStyle() & (LVS_EX_TRACKSELECT | LVS_EX_ONECLICKACTIVATE | LVS_EX_TWOCLICKACTIVATE)) != 0);
3339 return (DWORD)::SendMessage(m_hWnd, LVM_GETHOVERTIME, 0, 0L);
3340 }
3341
3342 DWORD SetHoverTime(DWORD dwHoverTime)
3343 {
3344 ATLASSERT(::IsWindow(m_hWnd));
3345 ATLASSERT((GetExtendedListViewStyle() & (LVS_EX_TRACKSELECT | LVS_EX_ONECLICKACTIVATE | LVS_EX_TWOCLICKACTIVATE)) != 0);
3346 return (DWORD)::SendMessage(m_hWnd, LVM_SETHOVERTIME, 0, dwHoverTime);
3347 }
3348
3349 BOOL GetNumberOfWorkAreas(int* pnWorkAreas) const
3350 {
3351 ATLASSERT(::IsWindow(m_hWnd));
3352 return (BOOL)::SendMessage(m_hWnd, LVM_GETNUMBEROFWORKAREAS, 0, (LPARAM)pnWorkAreas);
3353 }
3354 #endif // !_WIN32_WCE
3355
3356 BOOL SetItemCountEx(int nItems, DWORD dwFlags)
3357 {
3358 ATLASSERT(::IsWindow(m_hWnd));
3359 ATLASSERT(((GetStyle() & LVS_OWNERDATA) != 0) && (((GetStyle() & LVS_TYPEMASK) == LVS_REPORT) || ((GetStyle() & LVS_TYPEMASK) == LVS_LIST)));
3360 return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMCOUNT, nItems, dwFlags);
3361 }
3362
3363 #ifndef _WIN32_WCE
3364 CToolTipCtrl GetToolTips() const
3365 {
3366 ATLASSERT(::IsWindow(m_hWnd));
3367 return CToolTipCtrl((HWND)::SendMessage(m_hWnd, LVM_GETTOOLTIPS, 0, 0L));
3368 }
3369
3370 CToolTipCtrl SetToolTips(HWND hWndTT)
3371 {
3372 ATLASSERT(::IsWindow(m_hWnd));
3373 return CToolTipCtrl((HWND)::SendMessage(m_hWnd, LVM_SETTOOLTIPS, (WPARAM)hWndTT, 0L));
3374 }
3375
3376 BOOL GetUnicodeFormat() const
3377 {
3378 ATLASSERT(::IsWindow(m_hWnd));
3379 return (BOOL)::SendMessage(m_hWnd, LVM_GETUNICODEFORMAT, 0, 0L);
3380 }
3381
3382 BOOL SetUnicodeFormat(BOOL bUnicode = TRUE)
3383 {
3384 ATLASSERT(::IsWindow(m_hWnd));
3385 return (BOOL)::SendMessage(m_hWnd, LVM_SETUNICODEFORMAT, bUnicode, 0L);
3386 }
3387 #endif // !_WIN32_WCE
3388 #endif // (_WIN32_IE >= 0x0400)
3389
3390 #if (_WIN32_WINNT >= 0x0501)
3391 int GetSelectedColumn() const
3392 {
3393 ATLASSERT(::IsWindow(m_hWnd));
3394 return (int)::SendMessage(m_hWnd, LVM_GETSELECTEDCOLUMN, 0, 0L);
3395 }
3396
3397 void SetSelectedColumn(int nColumn)
3398 {
3399 ATLASSERT(::IsWindow(m_hWnd));
3400 ::SendMessage(m_hWnd, LVM_SETSELECTEDCOLUMN, nColumn, 0L);
3401 }
3402
3403 DWORD GetView() const
3404 {
3405 ATLASSERT(::IsWindow(m_hWnd));
3406 return (DWORD)::SendMessage(m_hWnd, LVM_GETVIEW, 0, 0L);
3407 }
3408
3409 int SetView(DWORD dwView)
3410 {
3411 ATLASSERT(::IsWindow(m_hWnd));
3412 return (int)::SendMessage(m_hWnd, LVM_SETVIEW, dwView, 0L);
3413 }
3414
3415 BOOL IsGroupViewEnabled() const
3416 {
3417 ATLASSERT(::IsWindow(m_hWnd));
3418 return (BOOL)::SendMessage(m_hWnd, LVM_ISGROUPVIEWENABLED, 0, 0L);
3419 }
3420
3421 int GetGroupInfo(int nGroupID, PLVGROUP pGroup) const
3422 {
3423 ATLASSERT(::IsWindow(m_hWnd));
3424 return (int)::SendMessage(m_hWnd, LVM_GETGROUPINFO, nGroupID, (LPARAM)pGroup);
3425 }
3426
3427 int SetGroupInfo(int nGroupID, PLVGROUP pGroup)
3428 {
3429 ATLASSERT(::IsWindow(m_hWnd));
3430 return (int)::SendMessage(m_hWnd, LVM_SETGROUPINFO, nGroupID, (LPARAM)pGroup);
3431 }
3432
3433 void GetGroupMetrics(PLVGROUPMETRICS pGroupMetrics) const
3434 {
3435 ATLASSERT(::IsWindow(m_hWnd));
3436 ::SendMessage(m_hWnd, LVM_GETGROUPMETRICS, 0, (LPARAM)pGroupMetrics);
3437 }
3438
3439 void SetGroupMetrics(PLVGROUPMETRICS pGroupMetrics)
3440 {
3441 ATLASSERT(::IsWindow(m_hWnd));
3442 ::SendMessage(m_hWnd, LVM_SETGROUPMETRICS, 0, (LPARAM)pGroupMetrics);
3443 }
3444
3445 void GetTileViewInfo(PLVTILEVIEWINFO pTileViewInfo) const
3446 {
3447 ATLASSERT(::IsWindow(m_hWnd));
3448 ::SendMessage(m_hWnd, LVM_GETTILEVIEWINFO, 0, (LPARAM)pTileViewInfo);
3449 }
3450
3451 BOOL SetTileViewInfo(PLVTILEVIEWINFO pTileViewInfo)
3452 {
3453 ATLASSERT(::IsWindow(m_hWnd));
3454 return (BOOL)::SendMessage(m_hWnd, LVM_SETTILEVIEWINFO, 0, (LPARAM)pTileViewInfo);
3455 }
3456
3457 void GetTileInfo(PLVTILEINFO pTileInfo) const
3458 {
3459 ATLASSERT(::IsWindow(m_hWnd));
3460 ::SendMessage(m_hWnd, LVM_GETTILEINFO, 0, (LPARAM)pTileInfo);
3461 }
3462
3463 BOOL SetTileInfo(PLVTILEINFO pTileInfo)
3464 {
3465 ATLASSERT(::IsWindow(m_hWnd));
3466 return (BOOL)::SendMessage(m_hWnd, LVM_SETTILEINFO, 0, (LPARAM)pTileInfo);
3467 }
3468
3469 BOOL GetInsertMark(LPLVINSERTMARK pInsertMark) const
3470 {
3471 ATLASSERT(::IsWindow(m_hWnd));
3472 return (BOOL)::SendMessage(m_hWnd, LVM_GETINSERTMARK, 0, (LPARAM)pInsertMark);
3473 }
3474
3475 BOOL SetInsertMark(LPLVINSERTMARK pInsertMark)
3476 {
3477 ATLASSERT(::IsWindow(m_hWnd));
3478 return (BOOL)::SendMessage(m_hWnd, LVM_SETINSERTMARK, 0, (LPARAM)pInsertMark);
3479 }
3480
3481 int GetInsertMarkRect(LPRECT lpRect) const
3482 {
3483 ATLASSERT(::IsWindow(m_hWnd));
3484 return (int)::SendMessage(m_hWnd, LVM_GETINSERTMARKRECT, 0, (LPARAM)lpRect);
3485 }
3486
3487 COLORREF GetInsertMarkColor() const
3488 {
3489 ATLASSERT(::IsWindow(m_hWnd));
3490 return (COLORREF)::SendMessage(m_hWnd, LVM_GETINSERTMARKCOLOR, 0, 0L);
3491 }
3492
3493 COLORREF SetInsertMarkColor(COLORREF clr)
3494 {
3495 ATLASSERT(::IsWindow(m_hWnd));
3496 return (COLORREF)::SendMessage(m_hWnd, LVM_SETINSERTMARKCOLOR, 0, clr);
3497 }
3498
3499 COLORREF GetOutlineColor() const
3500 {
3501 ATLASSERT(::IsWindow(m_hWnd));
3502 return (COLORREF)::SendMessage(m_hWnd, LVM_GETOUTLINECOLOR, 0, 0L);
3503 }
3504
3505 COLORREF SetOutlineColor(COLORREF clr)
3506 {
3507 ATLASSERT(::IsWindow(m_hWnd));
3508 return (COLORREF)::SendMessage(m_hWnd, LVM_SETOUTLINECOLOR, 0, clr);
3509 }
3510 #endif // (_WIN32_WINNT >= 0x0501)
3511
3512 #if (_WIN32_WINNT >= 0x0600)
3513 int GetGroupCount() const
3514 {
3515 ATLASSERT(::IsWindow(m_hWnd));
3516 return (int)::SendMessage(m_hWnd, LVM_GETGROUPCOUNT, 0, 0L);
3517 }
3518
3519 BOOL GetGroupInfoByIndex(int nIndex, PLVGROUP pGroup) const
3520 {
3521 ATLASSERT(::IsWindow(m_hWnd));
3522 return (BOOL)::SendMessage(m_hWnd, LVM_GETGROUPINFOBYINDEX, nIndex, (LPARAM)pGroup);
3523 }
3524
3525 BOOL GetGroupRect(int nGroupID, int nType, LPRECT lpRect) const
3526 {
3527 ATLASSERT(::IsWindow(m_hWnd));
3528 ATLASSERT(lpRect != NULL);
3529 if(lpRect != NULL)
3530 lpRect->top = nType;
3531 return (BOOL)::SendMessage(m_hWnd, LVM_GETGROUPRECT, nGroupID, (LPARAM)lpRect);
3532 }
3533
3534 UINT GetGroupState(int nGroupID, UINT uMask) const
3535 {
3536 ATLASSERT(::IsWindow(m_hWnd));
3537 return (UINT)::SendMessage(m_hWnd, LVM_GETGROUPSTATE, nGroupID, (LPARAM)uMask);
3538 }
3539
3540 int GetFocusedGroup() const
3541 {
3542 ATLASSERT(::IsWindow(m_hWnd));
3543 return (int)::SendMessage(m_hWnd, LVM_GETFOCUSEDGROUP, 0, 0L);
3544 }
3545
3546 BOOL GetEmptyText(LPWSTR lpstrText, int cchText) const
3547 {
3548 ATLASSERT(::IsWindow(m_hWnd));
3549 return (BOOL)::SendMessage(m_hWnd, LVM_GETEMPTYTEXT, cchText, (LPARAM)lpstrText);
3550 }
3551
3552 BOOL GetFooterRect(LPRECT lpRect) const
3553 {
3554 ATLASSERT(::IsWindow(m_hWnd));
3555 return (BOOL)::SendMessage(m_hWnd, LVM_GETFOOTERRECT, 0, (LPARAM)lpRect);
3556 }
3557
3558 BOOL GetFooterInfo(LPLVFOOTERINFO lpFooterInfo) const
3559 {
3560 ATLASSERT(::IsWindow(m_hWnd));
3561 return (BOOL)::SendMessage(m_hWnd, LVM_GETFOOTERINFO, 0, (LPARAM)lpFooterInfo);
3562 }
3563
3564 BOOL GetFooterItemRect(int nItem, LPRECT lpRect) const
3565 {
3566 ATLASSERT(::IsWindow(m_hWnd));
3567 return (BOOL)::SendMessage(m_hWnd, LVM_GETFOOTERITEMRECT, nItem, (LPARAM)lpRect);
3568 }
3569
3570 BOOL GetFooterItem(int nItem, LPLVFOOTERITEM lpFooterItem) const
3571 {
3572 ATLASSERT(::IsWindow(m_hWnd));
3573 return (BOOL)::SendMessage(m_hWnd, LVM_GETFOOTERITEM, nItem, (LPARAM)lpFooterItem);
3574 }
3575
3576 BOOL GetItemIndexRect(PLVITEMINDEX pItemIndex, int nSubItem, int nType, LPRECT lpRect) const
3577 {
3578 ATLASSERT(::IsWindow(m_hWnd));
3579 ATLASSERT(pItemIndex != NULL);
3580 ATLASSERT(lpRect != NULL);
3581 if(lpRect != NULL)
3582 {
3583 lpRect->top = nSubItem;
3584 lpRect->left = nType;
3585 }
3586 return (BOOL)::SendMessage(m_hWnd, LVM_GETITEMINDEXRECT, (WPARAM)pItemIndex, (LPARAM)lpRect);
3587 }
3588
3589 BOOL SetItemIndexState(PLVITEMINDEX pItemIndex, UINT uState, UINT dwMask)
3590 {
3591 ATLASSERT(::IsWindow(m_hWnd));
3592 LVITEM lvi = { 0 };
3593 lvi.state = uState;
3594 lvi.stateMask = dwMask;
3595 return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMINDEXSTATE, (WPARAM)pItemIndex, (LPARAM)&lvi);
3596 }
3597
3598 BOOL GetNextItemIndex(PLVITEMINDEX pItemIndex, WORD wFlags) const
3599 {
3600 ATLASSERT(::IsWindow(m_hWnd));
3601 return (BOOL)::SendMessage(m_hWnd, LVM_GETNEXTITEMINDEX, (WPARAM)pItemIndex, MAKELPARAM(wFlags, 0));
3602 }
3603 #endif // (_WIN32_WINNT >= 0x0600)
3604
3605 // Operations
3606 int InsertColumn(int nCol, const LVCOLUMN* pColumn)
3607 {
3608 ATLASSERT(::IsWindow(m_hWnd));
3609 return (int)::SendMessage(m_hWnd, LVM_INSERTCOLUMN, nCol, (LPARAM)pColumn);
3610 }
3611
3612 int InsertColumn(int nCol, LPCTSTR lpszColumnHeading, int nFormat = LVCFMT_LEFT,
3613 int nWidth = -1, int nSubItem = -1, int iImage = -1, int iOrder = -1)
3614 {
3615 LVCOLUMN column = { 0 };
3616 column.mask = LVCF_TEXT|LVCF_FMT;
3617 column.pszText = (LPTSTR)lpszColumnHeading;
3618 column.fmt = nFormat;
3619 if (nWidth != -1)
3620 {
3621 column.mask |= LVCF_WIDTH;
3622 column.cx = nWidth;
3623 }
3624 if (nSubItem != -1)
3625 {
3626 column.mask |= LVCF_SUBITEM;
3627 column.iSubItem = nSubItem;
3628 }
3629 if (iImage != -1)
3630 {
3631 column.mask |= LVCF_IMAGE;
3632 column.iImage = iImage;
3633 }
3634 if (iOrder != -1)
3635 {
3636 column.mask |= LVCF_ORDER;
3637 column.iOrder = iOrder;
3638 }
3639 return InsertColumn(nCol, &column);
3640 }
3641
3642 BOOL DeleteColumn(int nCol)
3643 {
3644 ATLASSERT(::IsWindow(m_hWnd));
3645 return (BOOL)::SendMessage(m_hWnd, LVM_DELETECOLUMN, nCol, 0L);
3646 }
3647
3648 int InsertItem(UINT nMask, int nItem, LPCTSTR lpszItem, UINT nState, UINT nStateMask, int nImage, LPARAM lParam)
3649 {
3650 ATLASSERT(::IsWindow(m_hWnd));
3651 LVITEM item = { 0 };
3652 item.mask = nMask;
3653 item.iItem = nItem;
3654 item.iSubItem = 0;
3655 item.pszText = (LPTSTR)lpszItem;
3656 item.state = nState;
3657 item.stateMask = nStateMask;
3658 item.iImage = nImage;
3659 item.lParam = lParam;
3660 return InsertItem(&item);
3661 }
3662
3663 int InsertItem(const LVITEM* pItem)
3664 {
3665 ATLASSERT(::IsWindow(m_hWnd));
3666 return (int)::SendMessage(m_hWnd, LVM_INSERTITEM, 0, (LPARAM)pItem);
3667 }
3668
3669 int InsertItem(int nItem, LPCTSTR lpszItem)
3670 {
3671 ATLASSERT(::IsWindow(m_hWnd));
3672 return InsertItem(LVIF_TEXT, nItem, lpszItem, 0, 0, 0, 0);
3673 }
3674
3675 int InsertItem(int nItem, LPCTSTR lpszItem, int nImage)
3676 {
3677 ATLASSERT(::IsWindow(m_hWnd));
3678 return InsertItem(LVIF_TEXT|LVIF_IMAGE, nItem, lpszItem, 0, 0, nImage, 0);
3679 }
3680
3681 int GetNextItem(int nItem, int nFlags) const
3682 {
3683 ATLASSERT(::IsWindow(m_hWnd));
3684 return (int)::SendMessage(m_hWnd, LVM_GETNEXTITEM, nItem, MAKELPARAM(nFlags, 0));
3685 }
3686
3687 BOOL DeleteItem(int nItem)
3688 {
3689 ATLASSERT(::IsWindow(m_hWnd));
3690 return (BOOL)::SendMessage(m_hWnd, LVM_DELETEITEM, nItem, 0L);
3691 }
3692
3693 BOOL DeleteAllItems()
3694 {
3695 ATLASSERT(::IsWindow(m_hWnd));
3696 return (BOOL)::SendMessage(m_hWnd, LVM_DELETEALLITEMS, 0, 0L);
3697 }
3698
3699 int FindItem(LVFINDINFO* pFindInfo, int nStart = -1) const
3700 {
3701 ATLASSERT(::IsWindow(m_hWnd));
3702 return (int)::SendMessage(m_hWnd, LVM_FINDITEM, nStart, (LPARAM)pFindInfo);
3703 }
3704
3705 int FindItem(LPCTSTR lpstrFind, bool bPartial = true, bool bWrap = false, int nStart = -1) const
3706 {
3707 ATLASSERT(::IsWindow(m_hWnd));
3708 LVFINDINFO lvfi = { 0 };
3709 lvfi.flags = LVFI_STRING | (bWrap ? LVFI_WRAP : 0) | (bPartial ? LVFI_PARTIAL : 0);
3710 lvfi.psz = lpstrFind;
3711 return (int)::SendMessage(m_hWnd, LVM_FINDITEM, nStart, (LPARAM)&lvfi);
3712 }
3713
3714 int HitTest(LVHITTESTINFO* pHitTestInfo) const
3715 {
3716 ATLASSERT(::IsWindow(m_hWnd));
3717 return (int)::SendMessage(m_hWnd, LVM_HITTEST, 0, (LPARAM)pHitTestInfo);
3718 }
3719
3720 int HitTest(POINT pt, UINT* pFlags) const
3721 {
3722 ATLASSERT(::IsWindow(m_hWnd));
3723 LVHITTESTINFO hti = { 0 };
3724 hti.pt = pt;
3725 int nRes = (int)::SendMessage(m_hWnd, LVM_HITTEST, 0, (LPARAM)&hti);
3726 if (pFlags != NULL)
3727 *pFlags = hti.flags;
3728 return nRes;
3729 }
3730
3731 BOOL EnsureVisible(int nItem, BOOL bPartialOK)
3732 {
3733 ATLASSERT(::IsWindow(m_hWnd));
3734 return (BOOL)::SendMessage(m_hWnd, LVM_ENSUREVISIBLE, nItem, MAKELPARAM(bPartialOK, 0));
3735 }
3736
3737 BOOL Scroll(SIZE size)
3738 {
3739 ATLASSERT(::IsWindow(m_hWnd));
3740 return (BOOL)::SendMessage(m_hWnd, LVM_SCROLL, size.cx, size.cy);
3741 }
3742
3743 BOOL RedrawItems(int nFirst, int nLast)
3744 {
3745 ATLASSERT(::IsWindow(m_hWnd));
3746 return (BOOL)::SendMessage(m_hWnd, LVM_REDRAWITEMS, nFirst, nLast);
3747 }
3748
3749 BOOL Arrange(UINT nCode)
3750 {
3751 ATLASSERT(::IsWindow(m_hWnd));
3752 return (BOOL)::SendMessage(m_hWnd, LVM_ARRANGE, nCode, 0L);
3753 }
3754
3755 CEdit EditLabel(int nItem)
3756 {
3757 ATLASSERT(::IsWindow(m_hWnd));
3758 return CEdit((HWND)::SendMessage(m_hWnd, LVM_EDITLABEL, nItem, 0L));
3759 }
3760
3761 BOOL Update(int nItem)
3762 {
3763 ATLASSERT(::IsWindow(m_hWnd));
3764 return (BOOL)::SendMessage(m_hWnd, LVM_UPDATE, nItem, 0L);
3765 }
3766
3767 BOOL SortItems(PFNLVCOMPARE pfnCompare, LPARAM lParamSort)
3768 {
3769 ATLASSERT(::IsWindow(m_hWnd));
3770 return (BOOL)::SendMessage(m_hWnd, LVM_SORTITEMS, (WPARAM)lParamSort, (LPARAM)pfnCompare);
3771 }
3772
3773 CImageList RemoveImageList(int nImageList)
3774 {
3775 ATLASSERT(::IsWindow(m_hWnd));
3776 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, LVM_SETIMAGELIST, (WPARAM)nImageList, NULL));
3777 }
3778
3779 CImageList CreateDragImage(int nItem, LPPOINT lpPoint)
3780 {
3781 ATLASSERT(::IsWindow(m_hWnd));
3782 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, LVM_CREATEDRAGIMAGE, nItem, (LPARAM)lpPoint));
3783 }
3784
3785 DWORD ApproximateViewRect(int cx = -1, int cy = -1, int nCount = -1)
3786 {
3787 ATLASSERT(::IsWindow(m_hWnd));
3788 return (DWORD)::SendMessage(m_hWnd, LVM_APPROXIMATEVIEWRECT, nCount, MAKELPARAM(cx, cy));
3789 }
3790
3791 int SubItemHitTest(LPLVHITTESTINFO lpInfo) const
3792 {
3793 ATLASSERT(::IsWindow(m_hWnd));
3794 return (int)::SendMessage(m_hWnd, LVM_SUBITEMHITTEST, 0, (LPARAM)lpInfo);
3795 }
3796
3797 int AddColumn(LPCTSTR strItem, int nItem, int nSubItem = -1,
3798 int nMask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM,
3799 int nFmt = LVCFMT_LEFT)
3800 {
3801 const int cxOffset = 15;
3802 ATLASSERT(::IsWindow(m_hWnd));
3803 LVCOLUMN lvc = { 0 };
3804 lvc.mask = nMask;
3805 lvc.fmt = nFmt;
3806 lvc.pszText = (LPTSTR)strItem;
3807 lvc.cx = GetStringWidth(lvc.pszText) + cxOffset;
3808 if(nMask & LVCF_SUBITEM)
3809 lvc.iSubItem = (nSubItem != -1) ? nSubItem : nItem;
3810 return InsertColumn(nItem, &lvc);
3811 }
3812
3813 int AddItem(int nItem, int nSubItem, LPCTSTR strItem, int nImageIndex = -3)
3814 {
3815 ATLASSERT(::IsWindow(m_hWnd));
3816 LVITEM lvItem = { 0 };
3817 lvItem.mask = LVIF_TEXT;
3818 lvItem.iItem = nItem;
3819 lvItem.iSubItem = nSubItem;
3820 lvItem.pszText = (LPTSTR)strItem;
3821 if(nImageIndex != -3)
3822 {
3823 lvItem.mask |= LVIF_IMAGE;
3824 lvItem.iImage = nImageIndex;
3825 }
3826 if(nSubItem == 0)
3827 return InsertItem(&lvItem);
3828 return SetItem(&lvItem) ? nItem : -1;
3829 }
3830
3831 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
3832 BOOL SortItemsEx(PFNLVCOMPARE pfnCompare, LPARAM lParamSort)
3833 {
3834 ATLASSERT(::IsWindow(m_hWnd));
3835 return (BOOL)::SendMessage(m_hWnd, LVM_SORTITEMSEX, (WPARAM)lParamSort, (LPARAM)pfnCompare);
3836 }
3837 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
3838
3839 #if (_WIN32_WINNT >= 0x0501)
3840 int InsertGroup(int nItem, PLVGROUP pGroup)
3841 {
3842 ATLASSERT(::IsWindow(m_hWnd));
3843 return (int)::SendMessage(m_hWnd, LVM_INSERTGROUP, nItem, (LPARAM)pGroup);
3844 }
3845
3846 int AddGroup(PLVGROUP pGroup)
3847 {
3848 return InsertGroup(-1, pGroup);
3849 }
3850
3851 int RemoveGroup(int nGroupID)
3852 {
3853 ATLASSERT(::IsWindow(m_hWnd));
3854 return (int)::SendMessage(m_hWnd, LVM_REMOVEGROUP, nGroupID, 0L);
3855 }
3856
3857 void MoveGroup(int nGroupID, int nItem)
3858 {
3859 ATLASSERT(::IsWindow(m_hWnd));
3860 ::SendMessage(m_hWnd, LVM_MOVEGROUP, nGroupID, nItem);
3861 }
3862
3863 void MoveItemToGroup(int nItem, int nGroupID)
3864 {
3865 ATLASSERT(::IsWindow(m_hWnd));
3866 ::SendMessage(m_hWnd, LVM_MOVEITEMTOGROUP, nItem, nGroupID);
3867 }
3868
3869 int EnableGroupView(BOOL bEnable)
3870 {
3871 ATLASSERT(::IsWindow(m_hWnd));
3872 return (int)::SendMessage(m_hWnd, LVM_ENABLEGROUPVIEW, bEnable, 0L);
3873 }
3874
3875 int SortGroups(PFNLVGROUPCOMPARE pCompareFunc, LPVOID lpVoid = NULL)
3876 {
3877 ATLASSERT(::IsWindow(m_hWnd));
3878 return (int)::SendMessage(m_hWnd, LVM_SORTGROUPS, (WPARAM)pCompareFunc, (LPARAM)lpVoid);
3879 }
3880
3881 void InsertGroupSorted(PLVINSERTGROUPSORTED pInsertGroupSorted)
3882 {
3883 ATLASSERT(::IsWindow(m_hWnd));
3884 ::SendMessage(m_hWnd, LVM_INSERTGROUPSORTED, (WPARAM)pInsertGroupSorted, 0L);
3885 }
3886
3887 void RemoveAllGroups()
3888 {
3889 ATLASSERT(::IsWindow(m_hWnd));
3890 ::SendMessage(m_hWnd, LVM_REMOVEALLGROUPS, 0, 0L);
3891 }
3892
3893 BOOL HasGroup(int nGroupID)
3894 {
3895 ATLASSERT(::IsWindow(m_hWnd));
3896 return (BOOL)::SendMessage(m_hWnd, LVM_HASGROUP, nGroupID, 0L);
3897 }
3898
3899 BOOL InsertMarkHitTest(LPPOINT lpPoint, LPLVINSERTMARK pInsertMark) const
3900 {
3901 ATLASSERT(::IsWindow(m_hWnd));
3902 return (BOOL)::SendMessage(m_hWnd, LVM_INSERTMARKHITTEST, (WPARAM)lpPoint, (LPARAM)pInsertMark);
3903 }
3904
3905 BOOL SetInfoTip(PLVSETINFOTIP pSetInfoTip)
3906 {
3907 ATLASSERT(::IsWindow(m_hWnd));
3908 return (BOOL)::SendMessage(m_hWnd, LVM_SETINFOTIP, 0, (LPARAM)pSetInfoTip);
3909 }
3910
3911 void CancelEditLabel()
3912 {
3913 ATLASSERT(::IsWindow(m_hWnd));
3914 ::SendMessage(m_hWnd, LVM_CANCELEDITLABEL, 0, 0L);
3915 }
3916
3917 UINT MapIndexToID(int nIndex) const
3918 {
3919 ATLASSERT(::IsWindow(m_hWnd));
3920 return (UINT)::SendMessage(m_hWnd, LVM_MAPINDEXTOID, nIndex, 0L);
3921 }
3922
3923 int MapIDToIndex(UINT uID) const
3924 {
3925 ATLASSERT(::IsWindow(m_hWnd));
3926 return (int)::SendMessage(m_hWnd, LVM_MAPIDTOINDEX, uID, 0L);
3927 }
3928 #endif // (_WIN32_WINNT >= 0x0501)
3929
3930 #if (_WIN32_WINNT >= 0x0600)
3931 int HitTestEx(LPLVHITTESTINFO lpHitTestInfo) const
3932 {
3933 ATLASSERT(::IsWindow(m_hWnd));
3934 return (int)::SendMessage(m_hWnd, LVM_HITTEST, (WPARAM)-1, (LPARAM)lpHitTestInfo);
3935 }
3936
3937 int HitTestEx(POINT pt, UINT* pFlags) const
3938 {
3939 ATLASSERT(::IsWindow(m_hWnd));
3940 LVHITTESTINFO hti = { 0 };
3941 hti.pt = pt;
3942 int nRes = (int)::SendMessage(m_hWnd, LVM_HITTEST, (WPARAM)-1, (LPARAM)&hti);
3943 if (pFlags != NULL)
3944 *pFlags = hti.flags;
3945 return nRes;
3946 }
3947
3948 int SubItemHitTestEx(LPLVHITTESTINFO lpHitTestInfo) const
3949 {
3950 ATLASSERT(::IsWindow(m_hWnd));
3951 return (int)::SendMessage(m_hWnd, LVM_SUBITEMHITTEST, (WPARAM)-1, (LPARAM)lpHitTestInfo);
3952 }
3953 #endif // (_WIN32_WINNT >= 0x0600)
3954
3955 // Note: selects only one item
3956 BOOL SelectItem(int nIndex)
3957 {
3958 ATLASSERT(::IsWindow(m_hWnd));
3959
3960 // multi-selection only: de-select all items
3961 if((GetStyle() & LVS_SINGLESEL) == 0)
3962 SetItemState(-1, 0, LVIS_SELECTED);
3963
3964 BOOL bRet = SetItemState(nIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
3965 if(bRet)
3966 bRet = EnsureVisible(nIndex, FALSE);
3967
3968 return bRet;
3969 }
3970 };
3971
3972 typedef CListViewCtrlT<ATL::CWindow> CListViewCtrl;
3973
3974
3975 ///////////////////////////////////////////////////////////////////////////////
3976 // CTreeViewCtrl
3977
3978 template <class TBase>
3979 class CTreeViewCtrlT : public TBase
3980 {
3981 public:
3982 // Constructors
3983 CTreeViewCtrlT(HWND hWnd = NULL) : TBase(hWnd)
3984 { }
3985
3986 CTreeViewCtrlT< TBase >& operator =(HWND hWnd)
3987 {
3988 m_hWnd = hWnd;
3989 return *this;
3990 }
3991
3992 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
3993 DWORD dwStyle = 0, DWORD dwExStyle = 0,
3994 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
3995 {
3996 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
3997 }
3998
3999 // Attributes
4000 static LPCTSTR GetWndClassName()
4001 {
4002 return WC_TREEVIEW;
4003 }
4004
4005 UINT GetCount() const
4006 {
4007 ATLASSERT(::IsWindow(m_hWnd));
4008 return (UINT)::SendMessage(m_hWnd, TVM_GETCOUNT, 0, 0L);
4009 }
4010
4011 UINT GetIndent() const
4012 {
4013 ATLASSERT(::IsWindow(m_hWnd));
4014 return (UINT)::SendMessage(m_hWnd, TVM_GETINDENT, 0, 0L);
4015 }
4016
4017 void SetIndent(UINT nIndent)
4018 {
4019 ATLASSERT(::IsWindow(m_hWnd));
4020 ::SendMessage(m_hWnd, TVM_SETINDENT, nIndent, 0L);
4021 }
4022
4023 CImageList GetImageList(int nImageListType = TVSIL_NORMAL) const
4024 {
4025 ATLASSERT(::IsWindow(m_hWnd));
4026 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TVM_GETIMAGELIST, (WPARAM)nImageListType, 0L));
4027 }
4028
4029 CImageList SetImageList(HIMAGELIST hImageList, int nImageListType = TVSIL_NORMAL)
4030 {
4031 ATLASSERT(::IsWindow(m_hWnd));
4032 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TVM_SETIMAGELIST, (WPARAM)nImageListType, (LPARAM)hImageList));
4033 }
4034
4035 BOOL GetItem(LPTVITEM pItem) const
4036 {
4037 ATLASSERT(::IsWindow(m_hWnd));
4038 return (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)pItem);
4039 }
4040
4041 BOOL SetItem(LPTVITEM pItem)
4042 {
4043 ATLASSERT(::IsWindow(m_hWnd));
4044 return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)pItem);
4045 }
4046
4047 BOOL SetItem(HTREEITEM hItem, UINT nMask, LPCTSTR lpszItem, int nImage,
4048 int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam)
4049 {
4050 ATLASSERT(::IsWindow(m_hWnd));
4051 TVITEM item = { 0 };
4052 item.hItem = hItem;
4053 item.mask = nMask;
4054 item.pszText = (LPTSTR) lpszItem;
4055 item.iImage = nImage;
4056 item.iSelectedImage = nSelectedImage;
4057 item.state = nState;
4058 item.stateMask = nStateMask;
4059 item.lParam = lParam;
4060 return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)&item);
4061 }
4062
4063 BOOL GetItemText(HTREEITEM hItem, LPTSTR lpstrText, int nLen) const
4064 {
4065 ATLASSERT(::IsWindow(m_hWnd));
4066 ATLASSERT(lpstrText != NULL);
4067
4068 TVITEM item = { 0 };
4069 item.hItem = hItem;
4070 item.mask = TVIF_TEXT;
4071 item.pszText = lpstrText;
4072 item.cchTextMax = nLen;
4073
4074 return (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
4075 }
4076
4077 #ifndef _ATL_NO_COM
4078 BOOL GetItemText(HTREEITEM hItem, BSTR& bstrText) const
4079 {
4080 USES_CONVERSION;
4081 ATLASSERT(::IsWindow(m_hWnd));
4082 ATLASSERT(bstrText == NULL);
4083 TVITEM item = { 0 };
4084 item.hItem = hItem;
4085 item.mask = TVIF_TEXT;
4086
4087 LPTSTR lpstrText = NULL;
4088 BOOL bRet = FALSE;
4089 for(int nLen = 256; ; nLen *= 2)
4090 {
4091 ATLTRY(lpstrText = new TCHAR[nLen]);
4092 if(lpstrText == NULL)
4093 break;
4094 lpstrText[0] = NULL;
4095 item.pszText = lpstrText;
4096 item.cchTextMax = nLen;
4097 bRet = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
4098 if(!bRet || (lstrlen(item.pszText) < nLen - 1))
4099 break;
4100 delete [] lpstrText;
4101 lpstrText = NULL;
4102 }
4103
4104 if(lpstrText != NULL)
4105 {
4106 if(bRet)
4107 bstrText = ::SysAllocString(T2OLE(lpstrText));
4108 delete [] lpstrText;
4109 }
4110
4111 return (bstrText != NULL) ? TRUE : FALSE;
4112 }
4113 #endif // !_ATL_NO_COM
4114
4115 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
4116 BOOL GetItemText(HTREEITEM hItem, _CSTRING_NS::CString& strText) const
4117 {
4118 ATLASSERT(::IsWindow(m_hWnd));
4119 TVITEM item = { 0 };
4120 item.hItem = hItem;
4121 item.mask = TVIF_TEXT;
4122
4123 strText.Empty();
4124 BOOL bRet = FALSE;
4125 for(int nLen = 256; ; nLen *= 2)
4126 {
4127 item.pszText = strText.GetBufferSetLength(nLen);
4128 if(item.pszText == NULL)
4129 {
4130 bRet = FALSE;
4131 break;
4132 }
4133 item.cchTextMax = nLen;
4134 bRet = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
4135 if(!bRet || (lstrlen(item.pszText) < nLen - 1))
4136 break;
4137 }
4138 strText.ReleaseBuffer();
4139 return bRet;
4140 }
4141 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
4142
4143 BOOL SetItemText(HTREEITEM hItem, LPCTSTR lpszItem)
4144 {
4145 ATLASSERT(::IsWindow(m_hWnd));
4146 return SetItem(hItem, TVIF_TEXT, lpszItem, 0, 0, 0, 0, NULL);
4147 }
4148
4149 BOOL GetItemImage(HTREEITEM hItem, int& nImage, int& nSelectedImage) const
4150 {
4151 ATLASSERT(::IsWindow(m_hWnd));
4152 TVITEM item = { 0 };
4153 item.hItem = hItem;
4154 item.mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE;
4155 BOOL bRes = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
4156 if (bRes)
4157 {
4158 nImage = item.iImage;
4159 nSelectedImage = item.iSelectedImage;
4160 }
4161 return bRes;
4162 }
4163
4164 BOOL SetItemImage(HTREEITEM hItem, int nImage, int nSelectedImage)
4165 {
4166 ATLASSERT(::IsWindow(m_hWnd));
4167 return SetItem(hItem, TVIF_IMAGE|TVIF_SELECTEDIMAGE, NULL, nImage, nSelectedImage, 0, 0, NULL);
4168 }
4169
4170 UINT GetItemState(HTREEITEM hItem, UINT nStateMask) const
4171 {
4172 ATLASSERT(::IsWindow(m_hWnd));
4173 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
4174 return (((UINT)::SendMessage(m_hWnd, TVM_GETITEMSTATE, (WPARAM)hItem, (LPARAM)nStateMask)) & nStateMask);
4175 #else // !((_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE))
4176 TVITEM item = { 0 };
4177 item.hItem = hItem;
4178 item.mask = TVIF_STATE;
4179 item.state = 0;
4180 item.stateMask = nStateMask;
4181 ::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
4182 return (item.state & nStateMask);
4183 #endif // !((_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE))
4184 }
4185
4186 BOOL SetItemState(HTREEITEM hItem, UINT nState, UINT nStateMask)
4187 {
4188 ATLASSERT(::IsWindow(m_hWnd));
4189 return SetItem(hItem, TVIF_STATE, NULL, 0, 0, nState, nStateMask, NULL);
4190 }
4191
4192 DWORD_PTR GetItemData(HTREEITEM hItem) const
4193 {
4194 ATLASSERT(::IsWindow(m_hWnd));
4195 TVITEM item = { 0 };
4196 item.hItem = hItem;
4197 item.mask = TVIF_PARAM;
4198 BOOL bRet = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
4199 return (DWORD_PTR)(bRet ? item.lParam : NULL);
4200 }
4201
4202 BOOL SetItemData(HTREEITEM hItem, DWORD_PTR dwData)
4203 {
4204 ATLASSERT(::IsWindow(m_hWnd));
4205 return SetItem(hItem, TVIF_PARAM, NULL, 0, 0, 0, 0, (LPARAM)dwData);
4206 }
4207
4208 CEdit GetEditControl() const
4209 {
4210 ATLASSERT(::IsWindow(m_hWnd));
4211 return CEdit((HWND)::SendMessage(m_hWnd, TVM_GETEDITCONTROL, 0, 0L));
4212 }
4213
4214 UINT GetVisibleCount() const
4215 {
4216 ATLASSERT(::IsWindow(m_hWnd));
4217 return (UINT)::SendMessage(m_hWnd, TVM_GETVISIBLECOUNT, 0, 0L);
4218 }
4219
4220 BOOL GetItemRect(HTREEITEM hItem, LPRECT lpRect, BOOL bTextOnly) const
4221 {
4222 ATLASSERT(::IsWindow(m_hWnd));
4223 *(HTREEITEM*)lpRect = hItem;
4224 return (BOOL)::SendMessage(m_hWnd, TVM_GETITEMRECT, (WPARAM)bTextOnly, (LPARAM)lpRect);
4225 }
4226
4227 BOOL ItemHasChildren(HTREEITEM hItem) const
4228 {
4229 ATLASSERT(::IsWindow(m_hWnd));
4230 TVITEM item = { 0 };
4231 item.hItem = hItem;
4232 item.mask = TVIF_CHILDREN;
4233 ::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
4234 return item.cChildren;
4235 }
4236
4237 #ifndef _WIN32_WCE
4238 CToolTipCtrl GetToolTips() const
4239 {
4240 ATLASSERT(::IsWindow(m_hWnd));
4241 return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TVM_GETTOOLTIPS, 0, 0L));
4242 }
4243
4244 CToolTipCtrl SetToolTips(HWND hWndTT)
4245 {
4246 ATLASSERT(::IsWindow(m_hWnd));
4247 return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TVM_SETTOOLTIPS, (WPARAM)hWndTT, 0L));
4248 }
4249 #endif // !_WIN32_WCE
4250
4251 int GetISearchString(LPTSTR lpstr) const
4252 {
4253 ATLASSERT(::IsWindow(m_hWnd));
4254 return (int)::SendMessage(m_hWnd, TVM_GETISEARCHSTRING, 0, (LPARAM)lpstr);
4255 }
4256
4257 // checkboxes only
4258 BOOL GetCheckState(HTREEITEM hItem) const
4259 {
4260 ATLASSERT(::IsWindow(m_hWnd));
4261 ATLASSERT((GetStyle() & TVS_CHECKBOXES) != 0);
4262 UINT uRet = GetItemState(hItem, TVIS_STATEIMAGEMASK);
4263 return (uRet >> 12) - 1;
4264 }
4265
4266 BOOL SetCheckState(HTREEITEM hItem, BOOL bCheck)
4267 {
4268 int nCheck = bCheck ? 2 : 1; // one based index
4269 return SetItemState(hItem, INDEXTOSTATEIMAGEMASK(nCheck), TVIS_STATEIMAGEMASK);
4270 }
4271
4272 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
4273 COLORREF GetBkColor() const
4274 {
4275 ATLASSERT(::IsWindow(m_hWnd));
4276 return (COLORREF)::SendMessage(m_hWnd, TVM_GETBKCOLOR, 0, 0L);
4277 }
4278
4279 COLORREF SetBkColor(COLORREF clr)
4280 {
4281 ATLASSERT(::IsWindow(m_hWnd));
4282 return (COLORREF)::SendMessage(m_hWnd, TVM_SETBKCOLOR, 0, (LPARAM)clr);
4283 }
4284
4285 COLORREF GetInsertMarkColor() const
4286 {
4287 ATLASSERT(::IsWindow(m_hWnd));
4288 return (COLORREF)::SendMessage(m_hWnd, TVM_GETINSERTMARKCOLOR, 0, 0L);
4289 }
4290
4291 COLORREF SetInsertMarkColor(COLORREF clr)
4292 {
4293 ATLASSERT(::IsWindow(m_hWnd));
4294 return (COLORREF)::SendMessage(m_hWnd, TVM_SETINSERTMARKCOLOR, 0, (LPARAM)clr);
4295 }
4296
4297 int GetItemHeight() const
4298 {
4299 ATLASSERT(::IsWindow(m_hWnd));
4300 return (int)::SendMessage(m_hWnd, TVM_GETITEMHEIGHT, 0, 0L);
4301 }
4302
4303 int SetItemHeight(int cyHeight)
4304 {
4305 ATLASSERT(::IsWindow(m_hWnd));
4306 return (int)::SendMessage(m_hWnd, TVM_SETITEMHEIGHT, cyHeight, 0L);
4307 }
4308
4309 int GetScrollTime() const
4310 {
4311 ATLASSERT(::IsWindow(m_hWnd));
4312 return (int)::SendMessage(m_hWnd, TVM_GETSCROLLTIME, 0, 0L);
4313 }
4314
4315 int SetScrollTime(int nScrollTime)
4316 {
4317 ATLASSERT(::IsWindow(m_hWnd));
4318 return (int)::SendMessage(m_hWnd, TVM_SETSCROLLTIME, nScrollTime, 0L);
4319 }
4320
4321 COLORREF GetTextColor() const
4322 {
4323 ATLASSERT(::IsWindow(m_hWnd));
4324 return (COLORREF)::SendMessage(m_hWnd, TVM_GETTEXTCOLOR, 0, 0L);
4325 }
4326
4327 COLORREF SetTextColor(COLORREF clr)
4328 {
4329 ATLASSERT(::IsWindow(m_hWnd));
4330 return (COLORREF)::SendMessage(m_hWnd, TVM_SETTEXTCOLOR, 0, (LPARAM)clr);
4331 }
4332
4333 BOOL GetUnicodeFormat() const
4334 {
4335 ATLASSERT(::IsWindow(m_hWnd));
4336 return (BOOL)::SendMessage(m_hWnd, TVM_GETUNICODEFORMAT, 0, 0L);
4337 }
4338
4339 BOOL SetUnicodeFormat(BOOL bUnicode = TRUE)
4340 {
4341 ATLASSERT(::IsWindow(m_hWnd));
4342 return (BOOL)::SendMessage(m_hWnd, TVM_SETUNICODEFORMAT, bUnicode, 0L);
4343 }
4344 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
4345
4346 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
4347 COLORREF GetLineColor() const
4348 {
4349 ATLASSERT(::IsWindow(m_hWnd));
4350 return (COLORREF)::SendMessage(m_hWnd, TVM_GETLINECOLOR, 0, 0L);
4351 }
4352
4353 COLORREF SetLineColor(COLORREF clrNew /*= CLR_DEFAULT*/)
4354 {
4355 ATLASSERT(::IsWindow(m_hWnd));
4356 return (COLORREF)::SendMessage(m_hWnd, TVM_SETLINECOLOR, 0, (LPARAM)clrNew);
4357 }
4358 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
4359
4360 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
4361 BOOL GetItem(LPTVITEMEX pItem) const
4362 {
4363 ATLASSERT(::IsWindow(m_hWnd));
4364 return (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)pItem);
4365 }
4366
4367 BOOL SetItem(LPTVITEMEX pItem)
4368 {
4369 ATLASSERT(::IsWindow(m_hWnd));
4370 return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)pItem);
4371 }
4372 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
4373
4374 DWORD GetExtendedStyle() const
4375 {
4376 #ifndef TVM_GETEXTENDEDSTYLE
4377 const UINT TVM_GETEXTENDEDSTYLE = (TV_FIRST + 45);
4378 #endif
4379 ATLASSERT(::IsWindow(m_hWnd));
4380 return (DWORD)::SendMessage(m_hWnd, TVM_GETEXTENDEDSTYLE, 0, 0L);
4381 }
4382
4383 DWORD SetExtendedStyle(DWORD dwStyle, DWORD dwMask)
4384 {
4385 #ifndef TVM_SETEXTENDEDSTYLE
4386 const UINT TVM_SETEXTENDEDSTYLE = (TV_FIRST + 44);
4387 #endif
4388 ATLASSERT(::IsWindow(m_hWnd));
4389 return (DWORD)::SendMessage(m_hWnd, TVM_SETEXTENDEDSTYLE, dwMask, dwStyle);
4390 }
4391
4392 #if (_WIN32_WINNT >= 0x0600)
4393 BOOL SetAutoScrollInfo(UINT uPixPerSec, UINT uUpdateTime)
4394 {
4395 ATLASSERT(::IsWindow(m_hWnd));
4396 return (BOOL)::SendMessage(m_hWnd, TVM_SETAUTOSCROLLINFO, (WPARAM)uPixPerSec, (LPARAM)uUpdateTime);
4397 }
4398
4399 DWORD GetSelectedCount() const
4400 {
4401 ATLASSERT(::IsWindow(m_hWnd));
4402 return (DWORD)::SendMessage(m_hWnd, TVM_GETSELECTEDCOUNT, 0, 0L);
4403 }
4404
4405 BOOL GetItemPartRect(HTREEITEM hItem, TVITEMPART partID, LPRECT lpRect) const
4406 {
4407 ATLASSERT(::IsWindow(m_hWnd));
4408 TVGETITEMPARTRECTINFO gipri = { hItem, lpRect, partID };
4409 return (BOOL)::SendMessage(m_hWnd, TVM_GETITEMPARTRECT, 0, (LPARAM)&gipri);
4410 }
4411 #endif // (_WIN32_WINNT >= 0x0600)
4412
4413 // Operations
4414 HTREEITEM InsertItem(LPTVINSERTSTRUCT lpInsertStruct)
4415 {
4416 ATLASSERT(::IsWindow(m_hWnd));
4417 return (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)lpInsertStruct);
4418 }
4419
4420 HTREEITEM InsertItem(LPCTSTR lpszItem, int nImage,
4421 int nSelectedImage, HTREEITEM hParent, HTREEITEM hInsertAfter)
4422 {
4423 ATLASSERT(::IsWindow(m_hWnd));
4424 return InsertItem(TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE, lpszItem, nImage, nSelectedImage, 0, 0, 0, hParent, hInsertAfter);
4425 }
4426
4427 HTREEITEM InsertItem(LPCTSTR lpszItem, HTREEITEM hParent, HTREEITEM hInsertAfter)
4428 {
4429 ATLASSERT(::IsWindow(m_hWnd));
4430 return InsertItem(TVIF_TEXT, lpszItem, 0, 0, 0, 0, 0, hParent, hInsertAfter);
4431 }
4432
4433 HTREEITEM InsertItem(UINT nMask, LPCTSTR lpszItem, int nImage,
4434 int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam,
4435 HTREEITEM hParent, HTREEITEM hInsertAfter)
4436 {
4437 ATLASSERT(::IsWindow(m_hWnd));
4438 TVINSERTSTRUCT tvis = { 0 };
4439 tvis.hParent = hParent;
4440 tvis.hInsertAfter = hInsertAfter;
4441 tvis.item.mask = nMask;
4442 tvis.item.pszText = (LPTSTR) lpszItem;
4443 tvis.item.iImage = nImage;
4444 tvis.item.iSelectedImage = nSelectedImage;
4445 tvis.item.state = nState;
4446 tvis.item.stateMask = nStateMask;
4447 tvis.item.lParam = lParam;
4448 return (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)&tvis);
4449 }
4450
4451 BOOL DeleteItem(HTREEITEM hItem)
4452 {
4453 ATLASSERT(::IsWindow(m_hWnd));
4454 return (BOOL)::SendMessage(m_hWnd, TVM_DELETEITEM, 0, (LPARAM)hItem);
4455 }
4456
4457 BOOL DeleteAllItems()
4458 {
4459 ATLASSERT(::IsWindow(m_hWnd));
4460 return (BOOL)::SendMessage(m_hWnd, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT);
4461 }
4462
4463 BOOL Expand(HTREEITEM hItem, UINT nCode = TVE_EXPAND)
4464 {
4465 ATLASSERT(::IsWindow(m_hWnd));
4466 return (BOOL)::SendMessage(m_hWnd, TVM_EXPAND, nCode, (LPARAM)hItem);
4467 }
4468
4469 HTREEITEM GetNextItem(HTREEITEM hItem, UINT nCode) const
4470 {
4471 ATLASSERT(::IsWindow(m_hWnd));
4472 return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, nCode, (LPARAM)hItem);
4473 }
4474
4475 HTREEITEM GetChildItem(HTREEITEM hItem) const
4476 {
4477 ATLASSERT(::IsWindow(m_hWnd));
4478 return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
4479 }
4480
4481 HTREEITEM GetNextSiblingItem(HTREEITEM hItem) const
4482 {
4483 ATLASSERT(::IsWindow(m_hWnd));
4484 return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem);
4485 }
4486
4487 HTREEITEM GetPrevSiblingItem(HTREEITEM hItem) const
4488 {
4489 ATLASSERT(::IsWindow(m_hWnd));
4490 return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PREVIOUS, (LPARAM)hItem);
4491 }
4492
4493 HTREEITEM GetParentItem(HTREEITEM hItem) const
4494 {
4495 ATLASSERT(::IsWindow(m_hWnd));
4496 return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItem);
4497 }
4498
4499 HTREEITEM GetFirstVisibleItem() const
4500 {
4501 ATLASSERT(::IsWindow(m_hWnd));
4502 return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_FIRSTVISIBLE, 0L);
4503 }
4504
4505 HTREEITEM GetNextVisibleItem(HTREEITEM hItem) const
4506 {
4507 ATLASSERT(::IsWindow(m_hWnd));
4508 return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, (LPARAM)hItem);
4509 }
4510
4511 HTREEITEM GetPrevVisibleItem(HTREEITEM hItem) const
4512 {
4513 ATLASSERT(::IsWindow(m_hWnd));
4514 return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PREVIOUSVISIBLE, (LPARAM)hItem);
4515 }
4516
4517 HTREEITEM GetSelectedItem() const
4518 {
4519 ATLASSERT(::IsWindow(m_hWnd));
4520 return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CARET, 0L);
4521 }
4522
4523 HTREEITEM GetDropHilightItem() const
4524 {
4525 ATLASSERT(::IsWindow(m_hWnd));
4526 return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_DROPHILITE, 0L);
4527 }
4528
4529 HTREEITEM GetRootItem() const
4530 {
4531 ATLASSERT(::IsWindow(m_hWnd));
4532 return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_ROOT, 0L);
4533 }
4534
4535 #if !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400)
4536 HTREEITEM GetLastVisibleItem() const
4537 {
4538 ATLASSERT(::IsWindow(m_hWnd));
4539 return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_LASTVISIBLE, 0L);
4540 }
4541 #endif // !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400)
4542
4543 #if (_WIN32_IE >= 0x0600)
4544 HTREEITEM GetNextSelectedItem() const
4545 {
4546 #ifndef TVGN_NEXTSELECTED
4547 const WORD TVGN_NEXTSELECTED = 0x000B;
4548 #endif
4549 ATLASSERT(::IsWindow(m_hWnd));
4550 return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXTSELECTED, 0L);
4551 }
4552 #endif // (_WIN32_IE >= 0x0600)
4553
4554 BOOL Select(HTREEITEM hItem, UINT nCode)
4555 {
4556 ATLASSERT(::IsWindow(m_hWnd));
4557 return (BOOL)::SendMessage(m_hWnd, TVM_SELECTITEM, nCode, (LPARAM)hItem);
4558 }
4559
4560 BOOL SelectItem(HTREEITEM hItem)
4561 {
4562 ATLASSERT(::IsWindow(m_hWnd));
4563 return (BOOL)::SendMessage(m_hWnd, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hItem);
4564 }
4565
4566 BOOL SelectDropTarget(HTREEITEM hItem)
4567 {
4568 ATLASSERT(::IsWindow(m_hWnd));
4569 return (BOOL)::SendMessage(m_hWnd, TVM_SELECTITEM, TVGN_DROPHILITE, (LPARAM)hItem);
4570 }
4571
4572 BOOL SelectSetFirstVisible(HTREEITEM hItem)
4573 {
4574 ATLASSERT(::IsWindow(m_hWnd));
4575 return (BOOL)::SendMessage(m_hWnd, TVM_SELECTITEM, TVGN_FIRSTVISIBLE, (LPARAM)hItem);
4576 }
4577
4578 CEdit EditLabel(HTREEITEM hItem)
4579 {
4580 ATLASSERT(::IsWindow(m_hWnd));
4581 return CEdit((HWND)::SendMessage(m_hWnd, TVM_EDITLABEL, 0, (LPARAM)hItem));
4582 }
4583
4584 BOOL EndEditLabelNow(BOOL bCancel)
4585 {
4586 ATLASSERT(::IsWindow(m_hWnd));
4587 return (BOOL)::SendMessage(m_hWnd, TVM_ENDEDITLABELNOW, bCancel, 0L);
4588 }
4589
4590 HTREEITEM HitTest(TVHITTESTINFO* pHitTestInfo) const
4591 {
4592 ATLASSERT(::IsWindow(m_hWnd));
4593 return (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0, (LPARAM)pHitTestInfo);
4594 }
4595
4596 HTREEITEM HitTest(POINT pt, UINT* pFlags) const
4597 {
4598 ATLASSERT(::IsWindow(m_hWnd));
4599 TVHITTESTINFO hti = { 0 };
4600 hti.pt = pt;
4601 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0, (LPARAM)&hti);
4602 if (pFlags != NULL)
4603 *pFlags = hti.flags;
4604 return hTreeItem;
4605 }
4606
4607 BOOL SortChildren(HTREEITEM hItem, BOOL bRecurse = FALSE)
4608 {
4609 ATLASSERT(::IsWindow(m_hWnd));
4610 return (BOOL)::SendMessage(m_hWnd, TVM_SORTCHILDREN, (WPARAM)bRecurse, (LPARAM)hItem);
4611 }
4612
4613 BOOL EnsureVisible(HTREEITEM hItem)
4614 {
4615 ATLASSERT(::IsWindow(m_hWnd));
4616 return (BOOL)::SendMessage(m_hWnd, TVM_ENSUREVISIBLE, 0, (LPARAM)hItem);
4617 }
4618
4619 BOOL SortChildrenCB(LPTVSORTCB pSort, BOOL bRecurse = FALSE)
4620 {
4621 ATLASSERT(::IsWindow(m_hWnd));
4622 return (BOOL)::SendMessage(m_hWnd, TVM_SORTCHILDRENCB, (WPARAM)bRecurse, (LPARAM)pSort);
4623 }
4624
4625 CImageList RemoveImageList(int nImageList)
4626 {
4627 ATLASSERT(::IsWindow(m_hWnd));
4628 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TVM_SETIMAGELIST, (WPARAM)nImageList, NULL));
4629 }
4630
4631 CImageList CreateDragImage(HTREEITEM hItem)
4632 {
4633 ATLASSERT(::IsWindow(m_hWnd));
4634 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TVM_CREATEDRAGIMAGE, 0, (LPARAM)hItem));
4635 }
4636
4637 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
4638 BOOL SetInsertMark(HTREEITEM hTreeItem, BOOL bAfter)
4639 {
4640 ATLASSERT(::IsWindow(m_hWnd));
4641 return (BOOL)::SendMessage(m_hWnd, TVM_SETINSERTMARK, bAfter, (LPARAM)hTreeItem);
4642 }
4643
4644 BOOL RemoveInsertMark()
4645 {
4646 ATLASSERT(::IsWindow(m_hWnd));
4647 return (BOOL)::SendMessage(m_hWnd, TVM_SETINSERTMARK, 0, 0L);
4648 }
4649 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
4650
4651 #if (_WIN32_WINNT >= 0x0501)
4652 HTREEITEM MapAccIDToHTREEITEM(UINT uID) const
4653 {
4654 ATLASSERT(::IsWindow(m_hWnd));
4655 return (HTREEITEM)::SendMessage(m_hWnd, TVM_MAPACCIDTOHTREEITEM, uID, 0L);
4656 }
4657
4658 UINT MapHTREEITEMToAccID(HTREEITEM hTreeItem) const
4659 {
4660 ATLASSERT(::IsWindow(m_hWnd));
4661 return (UINT)::SendMessage(m_hWnd, TVM_MAPHTREEITEMTOACCID, (WPARAM)hTreeItem, 0L);
4662 }
4663 #endif // (_WIN32_WINNT >= 0x0501)
4664
4665 #if (_WIN32_WINNT >= 0x0600)
4666 void ShowInfoTip(HTREEITEM hItem)
4667 {
4668 ATLASSERT(::IsWindow(m_hWnd));
4669 ::SendMessage(m_hWnd, TVM_SHOWINFOTIP, 0, (LPARAM)hItem);
4670 }
4671 #endif // (_WIN32_WINNT >= 0x0600)
4672 };
4673
4674 typedef CTreeViewCtrlT<ATL::CWindow> CTreeViewCtrl;
4675
4676
4677 ///////////////////////////////////////////////////////////////////////////////
4678 // CTreeViewCtrlEx
4679
4680 // forward declaration
4681 template <class TBase> class CTreeViewCtrlExT;
4682
4683 // Note: TBase here is for CTreeViewCtrlExT, and not for CTreeItemT itself
4684 template <class TBase>
4685 class CTreeItemT
4686 {
4687 public:
4688 HTREEITEM m_hTreeItem;
4689 CTreeViewCtrlExT<TBase>* m_pTreeView;
4690
4691 // Construction
4692 CTreeItemT(HTREEITEM hTreeItem = NULL, CTreeViewCtrlExT<TBase>* pTreeView = NULL) : m_hTreeItem(hTreeItem), m_pTreeView(pTreeView)
4693 { }
4694
4695 CTreeItemT(const CTreeItemT<TBase>& posSrc)
4696 {
4697 *this = posSrc;
4698 }
4699
4700 operator HTREEITEM() { return m_hTreeItem; }
4701
4702 CTreeItemT<TBase>& operator =(const CTreeItemT<TBase>& itemSrc)
4703 {
4704 m_hTreeItem = itemSrc.m_hTreeItem;
4705 m_pTreeView = itemSrc.m_pTreeView;
4706 return *this;
4707 }
4708
4709 // Attributes
4710 CTreeViewCtrlExT<TBase>* GetTreeView() const { return m_pTreeView; }
4711
4712 BOOL operator !() const { return m_hTreeItem == NULL; }
4713
4714 BOOL IsNull() const { return m_hTreeItem == NULL; }
4715
4716 BOOL GetRect(LPRECT lpRect, BOOL bTextOnly) const;
4717 BOOL GetText(LPTSTR lpstrText, int nLen) const;
4718 #ifndef _ATL_NO_COM
4719 BOOL GetText(BSTR& bstrText) const;
4720 #endif // !_ATL_NO_COM
4721 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
4722 BOOL GetText(_CSTRING_NS::CString& strText) const;
4723 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
4724 BOOL SetText(LPCTSTR lpszItem);
4725 BOOL GetImage(int& nImage, int& nSelectedImage) const;
4726 BOOL SetImage(int nImage, int nSelectedImage);
4727 UINT GetState(UINT nStateMask) const;
4728 BOOL SetState(UINT nState, UINT nStateMask);
4729 DWORD_PTR GetData() const;
4730 BOOL SetData(DWORD_PTR dwData);
4731 BOOL SetItem(UINT nMask, LPCTSTR lpszItem, int nImage, int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam);
4732
4733 // Operations
4734 CTreeItemT<TBase> InsertAfter(LPCTSTR lpstrItem, HTREEITEM hItemAfter, int nImageIndex)
4735 {
4736 return _Insert(lpstrItem, nImageIndex, hItemAfter);
4737 }
4738
4739 CTreeItemT<TBase> AddHead(LPCTSTR lpstrItem, int nImageIndex)
4740 {
4741 return _Insert(lpstrItem, nImageIndex, TVI_FIRST);
4742 }
4743
4744 CTreeItemT<TBase> AddTail(LPCTSTR lpstrItem, int nImageIndex)
4745 {
4746 return _Insert(lpstrItem, nImageIndex, TVI_LAST);
4747 }
4748
4749 CTreeItemT<TBase> GetChild() const;
4750 CTreeItemT<TBase> GetNext(UINT nCode) const;
4751 CTreeItemT<TBase> GetNextSibling() const;
4752 CTreeItemT<TBase> GetPrevSibling() const;
4753 CTreeItemT<TBase> GetParent() const;
4754 CTreeItemT<TBase> GetFirstVisible() const;
4755 CTreeItemT<TBase> GetNextVisible() const;
4756 CTreeItemT<TBase> GetPrevVisible() const;
4757 CTreeItemT<TBase> GetSelected() const;
4758 CTreeItemT<TBase> GetDropHilight() const;
4759 CTreeItemT<TBase> GetRoot() const;
4760 #if !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400)
4761 CTreeItemT<TBase> GetLastVisible() const;
4762 #endif // !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400)
4763 #if (_WIN32_IE >= 0x0600)
4764 CTreeItemT<TBase> GetNextSelected() const;
4765 #endif // (_WIN32_IE >= 0x0600)
4766 BOOL HasChildren() const;
4767 BOOL Delete();
4768 BOOL Expand(UINT nCode = TVE_EXPAND);
4769 BOOL Select(UINT nCode);
4770 BOOL Select();
4771 BOOL SelectDropTarget();
4772 BOOL SelectSetFirstVisible();
4773 HWND EditLabel();
4774 HIMAGELIST CreateDragImage();
4775 BOOL SortChildren(BOOL bRecurse = FALSE);
4776 BOOL EnsureVisible();
4777 CTreeItemT<TBase> _Insert(LPCTSTR lpstrItem, int nImageIndex, HTREEITEM hItemAfter);
4778 int GetImageIndex() const;
4779 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
4780 BOOL SetInsertMark(BOOL bAfter);
4781 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
4782 #if (_WIN32_WINNT >= 0x0501)
4783 UINT MapHTREEITEMToAccID() const;
4784 #endif // (_WIN32_WINNT >= 0x0501)
4785 #if (_WIN32_WINNT >= 0x0600)
4786 void ShowInfoTip();
4787 BOOL GetPartRect(TVITEMPART partID, LPRECT lpRect) const;
4788 #endif // (_WIN32_WINNT >= 0x0600)
4789 };
4790
4791 typedef CTreeItemT<ATL::CWindow> CTreeItem;
4792
4793
4794 template <class TBase>
4795 class CTreeViewCtrlExT : public CTreeViewCtrlT< TBase >
4796 {
4797 public:
4798 // Constructors
4799 CTreeViewCtrlExT(HWND hWnd = NULL) : CTreeViewCtrlT< TBase >(hWnd)
4800 { }
4801
4802 CTreeViewCtrlExT< TBase >& operator =(HWND hWnd)
4803 {
4804 m_hWnd = hWnd;
4805 return *this;
4806 }
4807
4808 // Operations (overides that return CTreeItem)
4809 CTreeItemT<TBase> InsertItem(LPTVINSERTSTRUCT lpInsertStruct)
4810 {
4811 ATLASSERT(::IsWindow(m_hWnd));
4812 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)lpInsertStruct);
4813 return CTreeItemT<TBase>(hTreeItem, this);
4814 }
4815
4816 CTreeItemT<TBase> InsertItem(LPCTSTR lpszItem, int nImage,
4817 int nSelectedImage, HTREEITEM hParent, HTREEITEM hInsertAfter)
4818 {
4819 ATLASSERT(::IsWindow(m_hWnd));
4820 return InsertItem(TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE, lpszItem, nImage, nSelectedImage, 0, 0, 0, hParent, hInsertAfter);
4821 }
4822
4823 CTreeItemT<TBase> InsertItem(LPCTSTR lpszItem, HTREEITEM hParent, HTREEITEM hInsertAfter)
4824 {
4825 ATLASSERT(::IsWindow(m_hWnd));
4826 return InsertItem(TVIF_TEXT, lpszItem, 0, 0, 0, 0, 0, hParent, hInsertAfter);
4827 }
4828
4829 CTreeItemT<TBase> GetNextItem(HTREEITEM hItem, UINT nCode) const
4830 {
4831 ATLASSERT(::IsWindow(m_hWnd));
4832 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, nCode, (LPARAM)hItem);
4833 return CTreeItemT<TBase>(hTreeItem, (CTreeViewCtrlExT<TBase>*)this);
4834 }
4835
4836 CTreeItemT<TBase> GetChildItem(HTREEITEM hItem) const
4837 {
4838 ATLASSERT(::IsWindow(m_hWnd));
4839 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
4840 return CTreeItemT<TBase>(hTreeItem, (CTreeViewCtrlExT<TBase>*)this);
4841 }
4842
4843 CTreeItemT<TBase> GetNextSiblingItem(HTREEITEM hItem) const
4844 {
4845 ATLASSERT(::IsWindow(m_hWnd));
4846 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem);
4847 return CTreeItemT<TBase>(hTreeItem, (CTreeViewCtrlExT<TBase>*)this);
4848 }
4849
4850 CTreeItemT<TBase> GetPrevSiblingItem(HTREEITEM hItem) const
4851 {
4852 ATLASSERT(::IsWindow(m_hWnd));
4853 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PREVIOUS, (LPARAM)hItem);
4854 return CTreeItemT<TBase>(hTreeItem, (CTreeViewCtrlExT<TBase>*)this);
4855 }
4856
4857 CTreeItemT<TBase> GetParentItem(HTREEITEM hItem) const
4858 {
4859 ATLASSERT(::IsWindow(m_hWnd));
4860 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItem);
4861 return CTreeItemT<TBase>(hTreeItem, (CTreeViewCtrlExT<TBase>*)this);
4862 }
4863
4864 CTreeItemT<TBase> GetFirstVisibleItem() const
4865 {
4866 ATLASSERT(::IsWindow(m_hWnd));
4867 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_FIRSTVISIBLE, 0L);
4868 return CTreeItemT<TBase>(hTreeItem, (CTreeViewCtrlExT<TBase>*)this);
4869 }
4870
4871 CTreeItemT<TBase> GetNextVisibleItem(HTREEITEM hItem) const
4872 {
4873 ATLASSERT(::IsWindow(m_hWnd));
4874 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, (LPARAM)hItem);
4875 return CTreeItemT<TBase>(hTreeItem, (CTreeViewCtrlExT<TBase>*)this);
4876 }
4877
4878 CTreeItemT<TBase> GetPrevVisibleItem(HTREEITEM hItem) const
4879 {
4880 ATLASSERT(::IsWindow(m_hWnd));
4881 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PREVIOUSVISIBLE, (LPARAM)hItem);
4882 return CTreeItemT<TBase>(hTreeItem, (CTreeViewCtrlExT<TBase>*)this);
4883 }
4884
4885 CTreeItemT<TBase> GetSelectedItem() const
4886 {
4887 ATLASSERT(::IsWindow(m_hWnd));
4888 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CARET, 0L);
4889 return CTreeItemT<TBase>(hTreeItem, (CTreeViewCtrlExT<TBase>*)this);
4890 }
4891
4892 CTreeItemT<TBase> GetDropHilightItem() const
4893 {
4894 ATLASSERT(::IsWindow(m_hWnd));
4895 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_DROPHILITE, 0L);
4896 return CTreeItemT<TBase>(hTreeItem, (CTreeViewCtrlExT<TBase>*)this);
4897 }
4898
4899 CTreeItemT<TBase> GetRootItem() const
4900 {
4901 ATLASSERT(::IsWindow(m_hWnd));
4902 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_ROOT, 0L);
4903 return CTreeItemT<TBase>(hTreeItem, (CTreeViewCtrlExT<TBase>*)this);
4904 }
4905
4906 #if !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400)
4907 CTreeItemT<TBase> GetLastVisibleItem() const
4908 {
4909 ATLASSERT(::IsWindow(m_hWnd));
4910 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_LASTVISIBLE, 0L);
4911 return CTreeItemT<TBase>(hTreeItem, (CTreeViewCtrlExT<TBase>*)this);
4912 }
4913 #endif // !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400)
4914
4915 #if (_WIN32_IE >= 0x0600)
4916 CTreeItemT<TBase> GetNextSelectedItem() const
4917 {
4918 #ifndef TVGN_NEXTSELECTED
4919 const WORD TVGN_NEXTSELECTED = 0x000B;
4920 #endif
4921 ATLASSERT(::IsWindow(m_hWnd));
4922 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXTSELECTED, 0L);
4923 return CTreeItemT<TBase>(hTreeItem, (CTreeViewCtrlExT<TBase>*)this);
4924 }
4925 #endif // (_WIN32_IE >= 0x0600)
4926
4927 CTreeItemT<TBase> HitTest(TVHITTESTINFO* pHitTestInfo) const
4928 {
4929 ATLASSERT(::IsWindow(m_hWnd));
4930 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0, (LPARAM)pHitTestInfo);
4931 return CTreeItemT<TBase>(hTreeItem, (CTreeViewCtrlExT<TBase>*)this);
4932 }
4933
4934 CTreeItemT<TBase> InsertItem(UINT nMask, LPCTSTR lpszItem, int nImage,
4935 int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam,
4936 HTREEITEM hParent, HTREEITEM hInsertAfter)
4937 {
4938 ATLASSERT(::IsWindow(m_hWnd));
4939 TVINSERTSTRUCT tvis = { 0 };
4940 tvis.hParent = hParent;
4941 tvis.hInsertAfter = hInsertAfter;
4942 tvis.item.mask = nMask;
4943 tvis.item.pszText = (LPTSTR) lpszItem;
4944 tvis.item.iImage = nImage;
4945 tvis.item.iSelectedImage = nSelectedImage;
4946 tvis.item.state = nState;
4947 tvis.item.stateMask = nStateMask;
4948 tvis.item.lParam = lParam;
4949 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)&tvis);
4950 return CTreeItemT<TBase>(hTreeItem, this);
4951 }
4952
4953 CTreeItemT<TBase> HitTest(POINT pt, UINT* pFlags) const
4954 {
4955 ATLASSERT(::IsWindow(m_hWnd));
4956 TVHITTESTINFO hti = { 0 };
4957 hti.pt = pt;
4958 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0, (LPARAM)&hti);
4959 if (pFlags != NULL)
4960 *pFlags = hti.flags;
4961 return CTreeItemT<TBase>(hTreeItem, (CTreeViewCtrlExT<TBase>*)this);
4962 }
4963
4964 #if (_WIN32_WINNT >= 0x0501)
4965 CTreeItemT<TBase> MapAccIDToHTREEITEM(UINT uID) const
4966 {
4967 ATLASSERT(::IsWindow(m_hWnd));
4968 HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_MAPACCIDTOHTREEITEM, uID, 0L);
4969 return CTreeItemT<TBase>(hTreeItem, (CTreeViewCtrlExT<TBase>*)this);
4970 }
4971 #endif // (_WIN32_WINNT >= 0x0501)
4972 };
4973
4974 typedef CTreeViewCtrlExT<ATL::CWindow> CTreeViewCtrlEx;
4975
4976
4977 // CTreeItem inline methods
4978 template <class TBase>
4979 inline BOOL CTreeItemT<TBase>::GetRect(LPRECT lpRect, BOOL bTextOnly) const
4980 {
4981 ATLASSERT(m_pTreeView != NULL);
4982 return m_pTreeView->GetItemRect(m_hTreeItem,lpRect,bTextOnly);
4983 }
4984
4985 template <class TBase>
4986 inline CTreeItemT<TBase> CTreeItemT<TBase>::GetNext(UINT nCode) const
4987 {
4988 ATLASSERT(m_pTreeView != NULL);
4989 return m_pTreeView->GetNextItem(m_hTreeItem,nCode);
4990 }
4991
4992 template <class TBase>
4993 inline CTreeItemT<TBase> CTreeItemT<TBase>::GetChild() const
4994 {
4995 ATLASSERT(m_pTreeView != NULL);
4996 return m_pTreeView->GetChildItem(m_hTreeItem);
4997 }
4998
4999 template <class TBase>
5000 inline CTreeItemT<TBase> CTreeItemT<TBase>::GetNextSibling() const
5001 {
5002 ATLASSERT(m_pTreeView != NULL);
5003 return m_pTreeView->GetNextSiblingItem(m_hTreeItem);
5004 }
5005
5006 template <class TBase>
5007 inline CTreeItemT<TBase> CTreeItemT<TBase>::GetPrevSibling() const
5008 {
5009 ATLASSERT(m_pTreeView != NULL);
5010 return m_pTreeView->GetPrevSiblingItem(m_hTreeItem);
5011 }
5012
5013 template <class TBase>
5014 inline CTreeItemT<TBase> CTreeItemT<TBase>::GetParent() const
5015 {
5016 ATLASSERT(m_pTreeView != NULL);
5017 return m_pTreeView->GetParentItem(m_hTreeItem);
5018 }
5019
5020 template <class TBase>
5021 inline CTreeItemT<TBase> CTreeItemT<TBase>::GetFirstVisible() const
5022 {
5023 ATLASSERT(m_pTreeView != NULL);
5024 return m_pTreeView->GetFirstVisibleItem();
5025 }
5026
5027 template <class TBase>
5028 inline CTreeItemT<TBase> CTreeItemT<TBase>::GetNextVisible() const
5029 {
5030 ATLASSERT(m_pTreeView != NULL);
5031 return m_pTreeView->GetNextVisibleItem(m_hTreeItem);
5032 }
5033
5034 template <class TBase>
5035 inline CTreeItemT<TBase> CTreeItemT<TBase>::GetPrevVisible() const
5036 {
5037 ATLASSERT(m_pTreeView != NULL);
5038 return m_pTreeView->GetPrevVisibleItem(m_hTreeItem);
5039 }
5040
5041 template <class TBase>
5042 inline CTreeItemT<TBase> CTreeItemT<TBase>::GetSelected() const
5043 {
5044 ATLASSERT(m_pTreeView != NULL);
5045 return m_pTreeView->GetSelectedItem();
5046 }
5047
5048 template <class TBase>
5049 inline CTreeItemT<TBase> CTreeItemT<TBase>::GetDropHilight() const
5050 {
5051 ATLASSERT(m_pTreeView != NULL);
5052 return m_pTreeView->GetDropHilightItem();
5053 }
5054
5055 template <class TBase>
5056 inline CTreeItemT<TBase> CTreeItemT<TBase>::GetRoot() const
5057 {
5058 ATLASSERT(m_pTreeView != NULL);
5059 return m_pTreeView->GetRootItem();
5060 }
5061
5062 #if !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400)
5063 template <class TBase>
5064 inline CTreeItemT<TBase> CTreeItemT<TBase>::GetLastVisible() const
5065 {
5066 ATLASSERT(m_pTreeView != NULL);
5067 return m_pTreeView->GetLastVisibleItem();
5068 }
5069 #endif // !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400)
5070
5071 #if (_WIN32_IE >= 0x0600)
5072 template <class TBase>
5073 inline CTreeItemT<TBase> CTreeItemT<TBase>::GetNextSelected() const
5074 {
5075 ATLASSERT(m_pTreeView != NULL);
5076 return m_pTreeView->GetNextSelectedItem();
5077 }
5078 #endif // (_WIN32_IE >= 0x0600)
5079
5080 template <class TBase>
5081 inline BOOL CTreeItemT<TBase>::GetText(LPTSTR lpstrText, int nLen) const
5082 {
5083 ATLASSERT(m_pTreeView != NULL);
5084 return m_pTreeView->GetItemText(m_hTreeItem, lpstrText, nLen);
5085 }
5086
5087 #ifndef _ATL_NO_COM
5088 #ifdef _OLEAUTO_H_
5089 template <class TBase>
5090 inline BOOL CTreeItemT<TBase>::GetText(BSTR& bstrText) const
5091 {
5092 ATLASSERT(m_pTreeView != NULL);
5093 return m_pTreeView->GetItemText(m_hTreeItem, bstrText);
5094 }
5095 #endif // _OLEAUTO_H_
5096 #endif // !_ATL_NO_COM
5097
5098 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
5099 template <class TBase>
5100 inline BOOL CTreeItemT<TBase>::GetText(_CSTRING_NS::CString& strText) const
5101 {
5102 ATLASSERT(m_pTreeView != NULL);
5103 return m_pTreeView->GetItemText(m_hTreeItem, strText);
5104 }
5105 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
5106
5107 template <class TBase>
5108 inline BOOL CTreeItemT<TBase>::GetImage(int& nImage, int& nSelectedImage) const
5109 {
5110 ATLASSERT(m_pTreeView != NULL);
5111 return m_pTreeView->GetItemImage(m_hTreeItem,nImage,nSelectedImage);
5112 }
5113
5114 template <class TBase>
5115 inline UINT CTreeItemT<TBase>::GetState(UINT nStateMask) const
5116 {
5117 ATLASSERT(m_pTreeView != NULL);
5118 return m_pTreeView->GetItemState(m_hTreeItem,nStateMask);
5119 }
5120
5121 template <class TBase>
5122 inline DWORD_PTR CTreeItemT<TBase>::GetData() const
5123 {
5124 ATLASSERT(m_pTreeView != NULL);
5125 return m_pTreeView->GetItemData(m_hTreeItem);
5126 }
5127
5128 template <class TBase>
5129 inline BOOL CTreeItemT<TBase>::SetItem(UINT nMask, LPCTSTR lpszItem, int nImage,
5130 int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam)
5131 {
5132 ATLASSERT(m_pTreeView != NULL);
5133 return m_pTreeView->SetItem(m_hTreeItem, nMask, lpszItem, nImage, nSelectedImage, nState, nStateMask, lParam);
5134 }
5135
5136 template <class TBase>
5137 inline BOOL CTreeItemT<TBase>::SetText(LPCTSTR lpszItem)
5138 {
5139 ATLASSERT(m_pTreeView != NULL);
5140 return m_pTreeView->SetItemText(m_hTreeItem,lpszItem);
5141 }
5142
5143 template <class TBase>
5144 inline BOOL CTreeItemT<TBase>::SetImage(int nImage, int nSelectedImage)
5145 {
5146 ATLASSERT(m_pTreeView != NULL);
5147 return m_pTreeView->SetItemImage(m_hTreeItem,nImage,nSelectedImage);
5148 }
5149
5150 template <class TBase>
5151 inline BOOL CTreeItemT<TBase>::SetState(UINT nState, UINT nStateMask)
5152 {
5153 ATLASSERT(m_pTreeView != NULL);
5154 return m_pTreeView->SetItemState(m_hTreeItem,nState,nStateMask);
5155 }
5156
5157 template <class TBase>
5158 inline BOOL CTreeItemT<TBase>::SetData(DWORD_PTR dwData)
5159 {
5160 ATLASSERT(m_pTreeView != NULL);
5161 return m_pTreeView->SetItemData(m_hTreeItem,dwData);
5162 }
5163
5164 template <class TBase>
5165 inline BOOL CTreeItemT<TBase>::HasChildren() const
5166 {
5167 ATLASSERT(m_pTreeView != NULL);
5168 return m_pTreeView->ItemHasChildren(m_hTreeItem);
5169 }
5170
5171 template <class TBase>
5172 inline BOOL CTreeItemT<TBase>::Delete()
5173 {
5174 ATLASSERT(m_pTreeView != NULL);
5175 return m_pTreeView->DeleteItem(m_hTreeItem);
5176 }
5177
5178 template <class TBase>
5179 inline BOOL CTreeItemT<TBase>::Expand(UINT nCode /*= TVE_EXPAND*/)
5180 {
5181 ATLASSERT(m_pTreeView != NULL);
5182 return m_pTreeView->Expand(m_hTreeItem,nCode);
5183 }
5184
5185 template <class TBase>
5186 inline BOOL CTreeItemT<TBase>::Select(UINT nCode)
5187 {
5188 ATLASSERT(m_pTreeView != NULL);
5189 return m_pTreeView->Select(m_hTreeItem,nCode);
5190 }
5191
5192 template <class TBase>
5193 inline BOOL CTreeItemT<TBase>::Select()
5194 {
5195 ATLASSERT(m_pTreeView != NULL);
5196 return m_pTreeView->SelectItem(m_hTreeItem);
5197 }
5198
5199 template <class TBase>
5200 inline BOOL CTreeItemT<TBase>::SelectDropTarget()
5201 {
5202 ATLASSERT(m_pTreeView != NULL);
5203 return m_pTreeView->SelectDropTarget(m_hTreeItem);
5204 }
5205
5206 template <class TBase>
5207 inline BOOL CTreeItemT<TBase>::SelectSetFirstVisible()
5208 {
5209 ATLASSERT(m_pTreeView != NULL);
5210 return m_pTreeView->SelectSetFirstVisible(m_hTreeItem);
5211 }
5212
5213 template <class TBase>
5214 inline HWND CTreeItemT<TBase>::EditLabel()
5215 {
5216 ATLASSERT(m_pTreeView != NULL);
5217 return m_pTreeView->EditLabel(m_hTreeItem);
5218 }
5219
5220 template <class TBase>
5221 inline HIMAGELIST CTreeItemT<TBase>::CreateDragImage()
5222 {
5223 ATLASSERT(m_pTreeView != NULL);
5224 return m_pTreeView->CreateDragImage(m_hTreeItem);
5225 }
5226
5227 template <class TBase>
5228 inline BOOL CTreeItemT<TBase>::SortChildren(BOOL bRecurse /*= FALSE*/)
5229 {
5230 ATLASSERT(m_pTreeView != NULL);
5231 return m_pTreeView->SortChildren(m_hTreeItem, bRecurse);
5232 }
5233
5234 template <class TBase>
5235 inline BOOL CTreeItemT<TBase>::EnsureVisible()
5236 {
5237 ATLASSERT(m_pTreeView != NULL);
5238 return m_pTreeView->EnsureVisible(m_hTreeItem);
5239 }
5240
5241 template <class TBase>
5242 inline CTreeItemT<TBase> CTreeItemT<TBase>::_Insert(LPCTSTR lpstrItem, int nImageIndex, HTREEITEM hItemAfter)
5243 {
5244 ATLASSERT(m_pTreeView != NULL);
5245 TVINSERTSTRUCT ins = { 0 };
5246 ins.hParent = m_hTreeItem;
5247 ins.hInsertAfter = hItemAfter;
5248 ins.item.mask = TVIF_TEXT;
5249 ins.item.pszText = (LPTSTR)lpstrItem;
5250 if(nImageIndex != -1)
5251 {
5252 ins.item.mask |= TVIF_IMAGE | TVIF_SELECTEDIMAGE;
5253 ins.item.iImage = nImageIndex;
5254 ins.item.iSelectedImage = nImageIndex;
5255 }
5256 return CTreeItemT<TBase>(m_pTreeView->InsertItem(&ins), m_pTreeView);
5257 }
5258
5259 template <class TBase>
5260 inline int CTreeItemT<TBase>::GetImageIndex() const
5261 {
5262 ATLASSERT(m_pTreeView != NULL);
5263 TVITEM item = { 0 };
5264 item.mask = TVIF_HANDLE | TVIF_IMAGE;
5265 item.hItem = m_hTreeItem;
5266 m_pTreeView->GetItem(&item);
5267 return item.iImage;
5268 }
5269
5270 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
5271 template <class TBase>
5272 inline BOOL CTreeItemT<TBase>::SetInsertMark(BOOL bAfter)
5273 {
5274 ATLASSERT(m_pTreeView != NULL);
5275 return m_pTreeView->SetInsertMark(m_hTreeItem, bAfter);
5276 }
5277 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
5278
5279 #if (_WIN32_WINNT >= 0x0501)
5280 template <class TBase>
5281 inline UINT CTreeItemT<TBase>::MapHTREEITEMToAccID() const
5282 {
5283 ATLASSERT(m_pTreeView != NULL);
5284 return m_pTreeView->MapHTREEITEMToAccID(m_hTreeItem);
5285 }
5286 #endif // (_WIN32_WINNT >= 0x0501)
5287
5288 #if (_WIN32_WINNT >= 0x0600)
5289 template <class TBase>
5290 inline void CTreeItemT<TBase>::ShowInfoTip()
5291 {
5292 ATLASSERT(m_pTreeView != NULL);
5293 m_pTreeView->ShowInfoTip(m_hTreeItem);
5294 }
5295
5296 template <class TBase>
5297 inline BOOL CTreeItemT<TBase>::GetPartRect(TVITEMPART partID, LPRECT lpRect) const
5298 {
5299 ATLASSERT(m_pTreeView != NULL);
5300 return m_pTreeView->GetItemPartRect(m_hTreeItem, partID, lpRect);
5301 }
5302 #endif // (_WIN32_WINNT >= 0x0600)
5303
5304
5305 ///////////////////////////////////////////////////////////////////////////////
5306 // CToolBarCtrl
5307
5308 template <class TBase>
5309 class CToolBarCtrlT : public TBase
5310 {
5311 public:
5312 // Construction
5313 CToolBarCtrlT(HWND hWnd = NULL) : TBase(hWnd)
5314 { }
5315
5316 CToolBarCtrlT< TBase >& operator =(HWND hWnd)
5317 {
5318 m_hWnd = hWnd;
5319 return *this;
5320 }
5321
5322 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
5323 DWORD dwStyle = 0, DWORD dwExStyle = 0,
5324 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
5325 {
5326 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
5327 }
5328
5329 // Attributes
5330 static LPCTSTR GetWndClassName()
5331 {
5332 return TOOLBARCLASSNAME;
5333 }
5334
5335 BOOL IsButtonEnabled(int nID) const
5336 {
5337 ATLASSERT(::IsWindow(m_hWnd));
5338 return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONENABLED, nID, 0L);
5339 }
5340
5341 BOOL IsButtonChecked(int nID) const
5342 {
5343 ATLASSERT(::IsWindow(m_hWnd));
5344 return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONCHECKED, nID, 0L);
5345 }
5346
5347 BOOL IsButtonPressed(int nID) const
5348 {
5349 ATLASSERT(::IsWindow(m_hWnd));
5350 return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONPRESSED, nID, 0L);
5351 }
5352
5353 BOOL IsButtonHidden(int nID) const
5354 {
5355 ATLASSERT(::IsWindow(m_hWnd));
5356 return(BOOL) ::SendMessage(m_hWnd, TB_ISBUTTONHIDDEN, nID, 0L);
5357 }
5358
5359 BOOL IsButtonIndeterminate(int nID) const
5360 {
5361 ATLASSERT(::IsWindow(m_hWnd));
5362 return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONINDETERMINATE, nID, 0L);
5363 }
5364
5365 int GetState(int nID) const
5366 {
5367 ATLASSERT(::IsWindow(m_hWnd));
5368 return (int)::SendMessage(m_hWnd, TB_GETSTATE, nID, 0L);
5369 }
5370
5371 BOOL SetState(int nID, UINT nState)
5372 {
5373 ATLASSERT(::IsWindow(m_hWnd));
5374 return (BOOL)::SendMessage(m_hWnd, TB_SETSTATE, nID, MAKELPARAM(nState, 0));
5375 }
5376
5377 BOOL GetButton(int nIndex, LPTBBUTTON lpButton) const
5378 {
5379 ATLASSERT(::IsWindow(m_hWnd));
5380 return (BOOL)::SendMessage(m_hWnd, TB_GETBUTTON, nIndex, (LPARAM)lpButton);
5381 }
5382
5383 int GetButtonCount() const
5384 {
5385 ATLASSERT(::IsWindow(m_hWnd));
5386 return (int)::SendMessage(m_hWnd, TB_BUTTONCOUNT, 0, 0L);
5387 }
5388
5389 BOOL GetItemRect(int nIndex, LPRECT lpRect) const
5390 {
5391 ATLASSERT(::IsWindow(m_hWnd));
5392 return (BOOL)::SendMessage(m_hWnd, TB_GETITEMRECT, nIndex, (LPARAM)lpRect);
5393 }
5394
5395 void SetButtonStructSize(int nSize = sizeof(TBBUTTON))
5396 {
5397 ATLASSERT(::IsWindow(m_hWnd));
5398 ::SendMessage(m_hWnd, TB_BUTTONSTRUCTSIZE, nSize, 0L);
5399 }
5400
5401 BOOL SetButtonSize(SIZE size)
5402 {
5403 ATLASSERT(::IsWindow(m_hWnd));
5404 return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONSIZE, 0, MAKELPARAM(size.cx, size.cy));
5405 }
5406
5407 BOOL SetButtonSize(int cx, int cy)
5408 {
5409 ATLASSERT(::IsWindow(m_hWnd));
5410 return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONSIZE, 0, MAKELPARAM(cx, cy));
5411 }
5412
5413 BOOL SetBitmapSize(SIZE size)
5414 {
5415 ATLASSERT(::IsWindow(m_hWnd));
5416 return (BOOL)::SendMessage(m_hWnd, TB_SETBITMAPSIZE, 0, MAKELPARAM(size.cx, size.cy));
5417 }
5418
5419 BOOL SetBitmapSize(int cx, int cy)
5420 {
5421 ATLASSERT(::IsWindow(m_hWnd));
5422 return (BOOL)::SendMessage(m_hWnd, TB_SETBITMAPSIZE, 0, MAKELPARAM(cx, cy));
5423 }
5424
5425 #ifndef _WIN32_WCE
5426 CToolTipCtrl GetToolTips() const
5427 {
5428 ATLASSERT(::IsWindow(m_hWnd));
5429 return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TB_GETTOOLTIPS, 0, 0L));
5430 }
5431
5432 void SetToolTips(HWND hWndToolTip)
5433 {
5434 ATLASSERT(::IsWindow(m_hWnd));
5435 ::SendMessage(m_hWnd, TB_SETTOOLTIPS, (WPARAM)hWndToolTip, 0L);
5436 }
5437 #endif // !_WIN32_WCE
5438
5439 void SetNotifyWnd(HWND hWnd)
5440 {
5441 ATLASSERT(::IsWindow(m_hWnd));
5442 ::SendMessage(m_hWnd, TB_SETPARENT, (WPARAM)hWnd, 0L);
5443 }
5444
5445 int GetRows() const
5446 {
5447 ATLASSERT(::IsWindow(m_hWnd));
5448 return (int)::SendMessage(m_hWnd, TB_GETROWS, 0, 0L);
5449 }
5450
5451 void SetRows(int nRows, BOOL bLarger, LPRECT lpRect)
5452 {
5453 ATLASSERT(::IsWindow(m_hWnd));
5454 ::SendMessage(m_hWnd, TB_SETROWS, MAKELPARAM(nRows, bLarger), (LPARAM)lpRect);
5455 }
5456
5457 BOOL SetCmdID(int nIndex, UINT nID)
5458 {
5459 ATLASSERT(::IsWindow(m_hWnd));
5460 return (BOOL)::SendMessage(m_hWnd, TB_SETCMDID, nIndex, nID);
5461 }
5462
5463 DWORD GetBitmapFlags() const
5464 {
5465 ATLASSERT(::IsWindow(m_hWnd));
5466 return (DWORD)::SendMessage(m_hWnd, TB_GETBITMAPFLAGS, 0, 0L);
5467 }
5468
5469 int GetBitmap(int nID) const
5470 {
5471 ATLASSERT(::IsWindow(m_hWnd));
5472 return (int)::SendMessage(m_hWnd, TB_GETBITMAP, nID, 0L);
5473 }
5474
5475 int GetButtonText(int nID, LPTSTR lpstrText) const
5476 {
5477 ATLASSERT(::IsWindow(m_hWnd));
5478 return (int)::SendMessage(m_hWnd, TB_GETBUTTONTEXT, nID, (LPARAM)lpstrText);
5479 }
5480
5481 // nIndex - IE5 or higher only
5482 CImageList GetImageList(int nIndex = 0) const
5483 {
5484 ATLASSERT(::IsWindow(m_hWnd));
5485 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_GETIMAGELIST, nIndex, 0L));
5486 }
5487
5488 // nIndex - IE5 or higher only
5489 CImageList SetImageList(HIMAGELIST hImageList, int nIndex = 0)
5490 {
5491 ATLASSERT(::IsWindow(m_hWnd));
5492 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_SETIMAGELIST, nIndex, (LPARAM)hImageList));
5493 }
5494
5495 // nIndex - IE5 or higher only
5496 CImageList GetDisabledImageList(int nIndex = 0) const
5497 {
5498 ATLASSERT(::IsWindow(m_hWnd));
5499 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_GETDISABLEDIMAGELIST, nIndex, 0L));
5500 }
5501
5502 // nIndex - IE5 or higher only
5503 CImageList SetDisabledImageList(HIMAGELIST hImageList, int nIndex = 0)
5504 {
5505 ATLASSERT(::IsWindow(m_hWnd));
5506 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_SETDISABLEDIMAGELIST, nIndex, (LPARAM)hImageList));
5507 }
5508
5509 #ifndef _WIN32_WCE
5510 // nIndex - IE5 or higher only
5511 CImageList GetHotImageList(int nIndex = 0) const
5512 {
5513 ATLASSERT(::IsWindow(m_hWnd));
5514 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_GETHOTIMAGELIST, nIndex, 0L));
5515 }
5516
5517 // nIndex - IE5 or higher only
5518 CImageList SetHotImageList(HIMAGELIST hImageList, int nIndex = 0)
5519 {
5520 ATLASSERT(::IsWindow(m_hWnd));
5521 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_SETHOTIMAGELIST, nIndex, (LPARAM)hImageList));
5522 }
5523 #endif // !_WIN32_WCE
5524
5525 DWORD GetStyle() const
5526 {
5527 ATLASSERT(::IsWindow(m_hWnd));
5528 return (DWORD)::SendMessage(m_hWnd, TB_GETSTYLE, 0, 0L);
5529 }
5530
5531 void SetStyle(DWORD dwStyle)
5532 {
5533 ATLASSERT(::IsWindow(m_hWnd));
5534 ::SendMessage(m_hWnd, TB_SETSTYLE, 0, dwStyle);
5535 }
5536
5537 DWORD GetButtonSize() const
5538 {
5539 ATLASSERT(::IsWindow(m_hWnd));
5540 return (DWORD)::SendMessage(m_hWnd, TB_GETBUTTONSIZE, 0, 0L);
5541 }
5542
5543 void GetButtonSize(SIZE& size) const
5544 {
5545 ATLASSERT(::IsWindow(m_hWnd));
5546 DWORD dwRet = (DWORD)::SendMessage(m_hWnd, TB_GETBUTTONSIZE, 0, 0L);
5547 size.cx = LOWORD(dwRet);
5548 size.cy = HIWORD(dwRet);
5549 }
5550
5551 BOOL GetRect(int nID, LPRECT lpRect) const
5552 {
5553 ATLASSERT(::IsWindow(m_hWnd));
5554 return (BOOL)::SendMessage(m_hWnd, TB_GETRECT, nID, (LPARAM)lpRect);
5555 }
5556
5557 int GetTextRows() const
5558 {
5559 ATLASSERT(::IsWindow(m_hWnd));
5560 return (int)::SendMessage(m_hWnd, TB_GETTEXTROWS, 0, 0L);
5561 }
5562
5563 BOOL SetButtonWidth(int cxMin, int cxMax)
5564 {
5565 ATLASSERT(::IsWindow(m_hWnd));
5566 return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONWIDTH, 0, MAKELPARAM(cxMin, cxMax));
5567 }
5568
5569 BOOL SetIndent(int nIndent)
5570 {
5571 ATLASSERT(::IsWindow(m_hWnd));
5572 return (BOOL)::SendMessage(m_hWnd, TB_SETINDENT, nIndent, 0L);
5573 }
5574
5575 BOOL SetMaxTextRows(int nMaxTextRows)
5576 {
5577 ATLASSERT(::IsWindow(m_hWnd));
5578 return (BOOL)::SendMessage(m_hWnd, TB_SETMAXTEXTROWS, nMaxTextRows, 0L);
5579 }
5580
5581 #if (_WIN32_IE >= 0x0400)
5582 #ifndef _WIN32_WCE
5583 BOOL GetAnchorHighlight() const
5584 {
5585 ATLASSERT(::IsWindow(m_hWnd));
5586 return (BOOL)::SendMessage(m_hWnd, TB_GETANCHORHIGHLIGHT, 0, 0L);
5587 }
5588
5589 BOOL SetAnchorHighlight(BOOL bEnable = TRUE)
5590 {
5591 ATLASSERT(::IsWindow(m_hWnd));
5592 return (BOOL)::SendMessage(m_hWnd, TB_SETANCHORHIGHLIGHT, bEnable, 0L);
5593 }
5594 #endif // !_WIN32_WCE
5595
5596 int GetButtonInfo(int nID, LPTBBUTTONINFO lptbbi) const
5597 {
5598 ATLASSERT(::IsWindow(m_hWnd));
5599 return (int)::SendMessage(m_hWnd, TB_GETBUTTONINFO, nID, (LPARAM)lptbbi);
5600 }
5601
5602 BOOL SetButtonInfo(int nID, LPTBBUTTONINFO lptbbi)
5603 {
5604 ATLASSERT(::IsWindow(m_hWnd));
5605 return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONINFO, nID, (LPARAM)lptbbi);
5606 }
5607
5608 BOOL SetButtonInfo(int nID, DWORD dwMask, BYTE Style, BYTE State, LPCTSTR lpszItem,
5609 int iImage, WORD cx, int iCommand, DWORD_PTR lParam)
5610 {
5611 ATLASSERT(::IsWindow(m_hWnd));
5612 TBBUTTONINFO tbbi = { 0 };
5613 tbbi.cbSize = sizeof(TBBUTTONINFO);
5614 tbbi.dwMask = dwMask;
5615 tbbi.idCommand = iCommand;
5616 tbbi.iImage = iImage;
5617 tbbi.fsState = State;
5618 tbbi.fsStyle = Style;
5619 tbbi.cx = cx;
5620 tbbi.pszText = (LPTSTR) lpszItem;
5621 tbbi.lParam = lParam;
5622 return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONINFO, nID, (LPARAM)&tbbi);
5623 }
5624
5625 #ifndef _WIN32_WCE
5626 int GetHotItem() const
5627 {
5628 ATLASSERT(::IsWindow(m_hWnd));
5629 return (int)::SendMessage(m_hWnd, TB_GETHOTITEM, 0, 0L);
5630 }
5631
5632 int SetHotItem(int nItem)
5633 {
5634 ATLASSERT(::IsWindow(m_hWnd));
5635 return (int)::SendMessage(m_hWnd, TB_SETHOTITEM, nItem, 0L);
5636 }
5637 #endif // !_WIN32_WCE
5638
5639 BOOL IsButtonHighlighted(int nButtonID) const
5640 {
5641 ATLASSERT(::IsWindow(m_hWnd));
5642 return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONHIGHLIGHTED, nButtonID, 0L);
5643 }
5644
5645 DWORD SetDrawTextFlags(DWORD dwMask, DWORD dwFlags)
5646 {
5647 ATLASSERT(::IsWindow(m_hWnd));
5648 return (DWORD)::SendMessage(m_hWnd, TB_SETDRAWTEXTFLAGS, dwMask, dwFlags);
5649 }
5650
5651 #ifndef _WIN32_WCE
5652 BOOL GetColorScheme(LPCOLORSCHEME lpcs) const
5653 {
5654 ATLASSERT(::IsWindow(m_hWnd));
5655 return (BOOL)::SendMessage(m_hWnd, TB_GETCOLORSCHEME, 0, (LPARAM)lpcs);
5656 }
5657
5658 void SetColorScheme(LPCOLORSCHEME lpcs)
5659 {
5660 ATLASSERT(::IsWindow(m_hWnd));
5661 ::SendMessage(m_hWnd, TB_SETCOLORSCHEME, 0, (LPARAM)lpcs);
5662 }
5663
5664 DWORD GetExtendedStyle() const
5665 {
5666 ATLASSERT(::IsWindow(m_hWnd));
5667 return (DWORD)::SendMessage(m_hWnd, TB_GETEXTENDEDSTYLE, 0, 0L);
5668 }
5669
5670 DWORD SetExtendedStyle(DWORD dwStyle)
5671 {
5672 ATLASSERT(::IsWindow(m_hWnd));
5673 return (DWORD)::SendMessage(m_hWnd, TB_SETEXTENDEDSTYLE, 0, dwStyle);
5674 }
5675
5676 void GetInsertMark(LPTBINSERTMARK lptbim) const
5677 {
5678 ATLASSERT(::IsWindow(m_hWnd));
5679 ::SendMessage(m_hWnd, TB_GETINSERTMARK, 0, (LPARAM)lptbim);
5680 }
5681
5682 void SetInsertMark(LPTBINSERTMARK lptbim)
5683 {
5684 ATLASSERT(::IsWindow(m_hWnd));
5685 ::SendMessage(m_hWnd, TB_SETINSERTMARK, 0, (LPARAM)lptbim);
5686 }
5687
5688 COLORREF GetInsertMarkColor() const
5689 {
5690 ATLASSERT(::IsWindow(m_hWnd));
5691 return (COLORREF)::SendMessage(m_hWnd, TB_GETINSERTMARKCOLOR, 0, 0L);
5692 }
5693
5694 COLORREF SetInsertMarkColor(COLORREF clr)
5695 {
5696 ATLASSERT(::IsWindow(m_hWnd));
5697 return (COLORREF)::SendMessage(m_hWnd, TB_SETINSERTMARKCOLOR, 0, (LPARAM)clr);
5698 }
5699
5700 BOOL GetMaxSize(LPSIZE lpSize) const
5701 {
5702 ATLASSERT(::IsWindow(m_hWnd));
5703 return (BOOL)::SendMessage(m_hWnd, TB_GETMAXSIZE, 0, (LPARAM)lpSize);
5704 }
5705
5706 void GetPadding(LPSIZE lpSizePadding) const
5707 {
5708 ATLASSERT(::IsWindow(m_hWnd));
5709 ATLASSERT(lpSizePadding != NULL);
5710 DWORD dwRet = (DWORD)::SendMessage(m_hWnd, TB_GETPADDING, 0, 0L);
5711 lpSizePadding->cx = GET_X_LPARAM(dwRet);
5712 lpSizePadding->cy = GET_Y_LPARAM(dwRet);
5713 }
5714
5715 void SetPadding(int cx, int cy, LPSIZE lpSizePadding = NULL)
5716 {
5717 ATLASSERT(::IsWindow(m_hWnd));
5718 DWORD dwRet = (DWORD)::SendMessage(m_hWnd, TB_SETPADDING, 0, MAKELPARAM(cx, cy));
5719 if(lpSizePadding != NULL)
5720 {
5721 lpSizePadding->cx = GET_X_LPARAM(dwRet);
5722 lpSizePadding->cy = GET_Y_LPARAM(dwRet);
5723 }
5724 }
5725
5726 BOOL GetUnicodeFormat() const
5727 {
5728 ATLASSERT(::IsWindow(m_hWnd));
5729 return (BOOL)::SendMessage(m_hWnd, TB_GETUNICODEFORMAT, 0, 0L);
5730 }
5731
5732 BOOL SetUnicodeFormat(BOOL bUnicode = TRUE)
5733 {
5734 ATLASSERT(::IsWindow(m_hWnd));
5735 return (BOOL)::SendMessage(m_hWnd, TB_SETUNICODEFORMAT, bUnicode, 0L);
5736 }
5737 #endif // !_WIN32_WCE
5738 #endif // (_WIN32_IE >= 0x0400)
5739
5740 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
5741 int GetString(int nString, LPTSTR lpstrString, int cchMaxLen) const
5742 {
5743 ATLASSERT(::IsWindow(m_hWnd));
5744 return (int)::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(cchMaxLen, nString), (LPARAM)lpstrString);
5745 }
5746
5747 int GetStringBSTR(int nString, BSTR& bstrString) const
5748 {
5749 USES_CONVERSION;
5750 ATLASSERT(::IsWindow(m_hWnd));
5751 ATLASSERT(bstrString == NULL);
5752 int nLength = (int)(short)LOWORD(::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(0, nString), NULL));
5753 if(nLength != -1)
5754 {
5755 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
5756 LPTSTR lpstrText = buff.Allocate(nLength + 1);
5757 if(lpstrText != NULL)
5758 {
5759 nLength = (int)::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(nLength + 1, nString), (LPARAM)lpstrText);
5760 if(nLength != -1)
5761 bstrString = ::SysAllocString(T2OLE(lpstrText));
5762 }
5763 else
5764 {
5765 nLength = -1;
5766 }
5767 }
5768
5769 return nLength;
5770 }
5771
5772 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
5773 int GetString(int nString, _CSTRING_NS::CString& str) const
5774 {
5775 ATLASSERT(::IsWindow(m_hWnd));
5776 int nLength = (int)(short)LOWORD(::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(0, nString), NULL));
5777 if(nLength != -1)
5778 {
5779 LPTSTR lpstr = str.GetBufferSetLength(nLength + 1);
5780 if(lpstr != NULL)
5781 nLength = (int)::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(nLength + 1, nString), (LPARAM)lpstr);
5782 else
5783 nLength = -1;
5784 str.ReleaseBuffer();
5785 }
5786 return nLength;
5787 }
5788 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
5789 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
5790
5791 #if (_WIN32_WINNT >= 0x0501)
5792 void GetMetrics(LPTBMETRICS lptbm) const
5793 {
5794 ATLASSERT(::IsWindow(m_hWnd));
5795 ::SendMessage(m_hWnd, TB_GETMETRICS, 0, (LPARAM)lptbm);
5796 }
5797
5798 void SetMetrics(LPTBMETRICS lptbm)
5799 {
5800 ATLASSERT(::IsWindow(m_hWnd));
5801 ::SendMessage(m_hWnd, TB_SETMETRICS, 0, (LPARAM)lptbm);
5802 }
5803
5804 void SetWindowTheme(LPCWSTR lpstrTheme)
5805 {
5806 ATLASSERT(::IsWindow(m_hWnd));
5807 ::SendMessage(m_hWnd, TB_SETWINDOWTHEME, 0, (LPARAM)lpstrTheme);
5808 }
5809 #endif // (_WIN32_WINNT >= 0x0501)
5810
5811 #if (_WIN32_WINNT >= 0x0600)
5812 CImageList GetPressedImageList(int nIndex = 0) const
5813 {
5814 ATLASSERT(::IsWindow(m_hWnd));
5815 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_GETPRESSEDIMAGELIST, nIndex, 0L));
5816 }
5817
5818 CImageList SetPressedImageList(HIMAGELIST hImageList, int nIndex = 0)
5819 {
5820 ATLASSERT(::IsWindow(m_hWnd));
5821 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_SETPRESSEDIMAGELIST, nIndex, (LPARAM)hImageList));
5822 }
5823
5824 void GetItemDropDownRect(int nIndex, LPRECT lpRect) const
5825 {
5826 #ifndef TB_GETITEMDROPDOWNRECT
5827 const int TB_GETITEMDROPDOWNRECT = WM_USER + 103;
5828 #endif
5829 ATLASSERT(::IsWindow(m_hWnd));
5830 BOOL bRet = (BOOL)::SendMessage(m_hWnd, TB_GETITEMDROPDOWNRECT, nIndex, (LPARAM)lpRect);
5831 bRet; // avoid level 4 warning
5832 ATLASSERT(bRet != FALSE);
5833 }
5834 #endif // (_WIN32_WINNT >= 0x0600)
5835
5836 // Operations
5837 BOOL EnableButton(int nID, BOOL bEnable = TRUE)
5838 {
5839 ATLASSERT(::IsWindow(m_hWnd));
5840 return (BOOL)::SendMessage(m_hWnd, TB_ENABLEBUTTON, nID, MAKELPARAM(bEnable, 0));
5841 }
5842
5843 BOOL CheckButton(int nID, BOOL bCheck = TRUE)
5844 {
5845 ATLASSERT(::IsWindow(m_hWnd));
5846 return (BOOL)::SendMessage(m_hWnd, TB_CHECKBUTTON, nID, MAKELPARAM(bCheck, 0));
5847 }
5848
5849 BOOL PressButton(int nID, BOOL bPress = TRUE)
5850 {
5851 ATLASSERT(::IsWindow(m_hWnd));
5852 return (BOOL)::SendMessage(m_hWnd, TB_PRESSBUTTON, nID, MAKELPARAM(bPress, 0));
5853 }
5854
5855 BOOL HideButton(int nID, BOOL bHide = TRUE)
5856 {
5857 ATLASSERT(::IsWindow(m_hWnd));
5858 return (BOOL)::SendMessage(m_hWnd, TB_HIDEBUTTON, nID, MAKELPARAM(bHide, 0));
5859 }
5860
5861 BOOL Indeterminate(int nID, BOOL bIndeterminate = TRUE)
5862 {
5863 ATLASSERT(::IsWindow(m_hWnd));
5864 return (BOOL)::SendMessage(m_hWnd, TB_INDETERMINATE, nID, MAKELPARAM(bIndeterminate, 0));
5865 }
5866
5867 int AddBitmap(int nNumButtons, UINT nBitmapID)
5868 {
5869 ATLASSERT(::IsWindow(m_hWnd));
5870 TBADDBITMAP tbab = { 0 };
5871 tbab.hInst = ModuleHelper::GetResourceInstance();
5872 ATLASSERT(tbab.hInst != NULL);
5873 tbab.nID = nBitmapID;
5874 return (int)::SendMessage(m_hWnd, TB_ADDBITMAP, (WPARAM)nNumButtons, (LPARAM)&tbab);
5875 }
5876
5877 int AddBitmap(int nNumButtons, HBITMAP hBitmap)
5878 {
5879 ATLASSERT(::IsWindow(m_hWnd));
5880 TBADDBITMAP tbab = { 0 };
5881 tbab.hInst = NULL;
5882 tbab.nID = (UINT_PTR)hBitmap;
5883 return (int)::SendMessage(m_hWnd, TB_ADDBITMAP, (WPARAM)nNumButtons, (LPARAM)&tbab);
5884 }
5885
5886 BOOL AddButtons(int nNumButtons, LPTBBUTTON lpButtons)
5887 {
5888 ATLASSERT(::IsWindow(m_hWnd));
5889 return (BOOL)::SendMessage(m_hWnd, TB_ADDBUTTONS, nNumButtons, (LPARAM)lpButtons);
5890 }
5891
5892 BOOL InsertButton(int nIndex, LPTBBUTTON lpButton)
5893 {
5894 ATLASSERT(::IsWindow(m_hWnd));
5895 return (BOOL)::SendMessage(m_hWnd, TB_INSERTBUTTON, nIndex, (LPARAM)lpButton);
5896 }
5897
5898 BOOL InsertButton(int nIndex, int iCommand, BYTE Style, BYTE State, int iBitmap,
5899 INT_PTR iString, DWORD_PTR lParam)
5900 {
5901 ATLASSERT(::IsWindow(m_hWnd));
5902 TBBUTTON tbb = { 0 };
5903 tbb.fsStyle = Style;
5904 tbb.fsState = State;
5905 tbb.idCommand = iCommand;
5906 tbb.iBitmap = iBitmap;
5907 tbb.iString = iString;
5908 tbb.dwData = lParam;
5909 return (BOOL)::SendMessage(m_hWnd, TB_INSERTBUTTON, nIndex, (LPARAM)&tbb);
5910 }
5911
5912 BOOL InsertButton(int nIndex, int iCommand, BYTE Style, BYTE State, int iBitmap,
5913 LPCTSTR lpszItem, DWORD_PTR lParam)
5914 {
5915 return InsertButton(nIndex, iCommand, Style, State, iBitmap, (INT_PTR)lpszItem, lParam);
5916 }
5917
5918 BOOL AddButton(LPTBBUTTON lpButton)
5919 {
5920 return InsertButton(-1, lpButton);
5921 }
5922
5923 BOOL AddButton(int iCommand, BYTE Style, BYTE State, int iBitmap, INT_PTR iString, DWORD_PTR lParam)
5924 {
5925 return InsertButton(-1, iCommand, Style, State, iBitmap, iString, lParam);
5926 }
5927
5928 BOOL AddButton(int iCommand, BYTE Style, BYTE State, int iBitmap, LPCTSTR lpszItem, DWORD_PTR lParam)
5929 {
5930 return InsertButton(-1, iCommand, Style, State, iBitmap, lpszItem, lParam);
5931 }
5932
5933 BOOL DeleteButton(int nIndex)
5934 {
5935 ATLASSERT(::IsWindow(m_hWnd));
5936 return (BOOL)::SendMessage(m_hWnd, TB_DELETEBUTTON, nIndex, 0L);
5937 }
5938
5939 BOOL InsertSeparator(int nIndex, int cxWidth = 8)
5940 {
5941 return InsertButton(nIndex, 0, BTNS_SEP, 0, cxWidth, (INT_PTR)0, 0);
5942 }
5943
5944 BOOL AddSeparator(int cxWidth = 8)
5945 {
5946 return AddButton(0, BTNS_SEP, 0, cxWidth, (INT_PTR)0, 0);
5947 }
5948
5949 int CommandToIndex(UINT nID) const
5950 {
5951 ATLASSERT(::IsWindow(m_hWnd));
5952 return (int)::SendMessage(m_hWnd, TB_COMMANDTOINDEX, nID, 0L);
5953 }
5954
5955 #ifndef _WIN32_WCE
5956 void SaveState(HKEY hKeyRoot, LPCTSTR lpszSubKey, LPCTSTR lpszValueName)
5957 {
5958 ATLASSERT(::IsWindow(m_hWnd));
5959 TBSAVEPARAMS tbs = { 0 };
5960 tbs.hkr = hKeyRoot;
5961 tbs.pszSubKey = lpszSubKey;
5962 tbs.pszValueName = lpszValueName;
5963 ::SendMessage(m_hWnd, TB_SAVERESTORE, (WPARAM)TRUE, (LPARAM)&tbs);
5964 }
5965
5966 void RestoreState(HKEY hKeyRoot, LPCTSTR lpszSubKey, LPCTSTR lpszValueName)
5967 {
5968 ATLASSERT(::IsWindow(m_hWnd));
5969 TBSAVEPARAMS tbs = { 0 };
5970 tbs.hkr = hKeyRoot;
5971 tbs.pszSubKey = lpszSubKey;
5972 tbs.pszValueName = lpszValueName;
5973 ::SendMessage(m_hWnd, TB_SAVERESTORE, (WPARAM)FALSE, (LPARAM)&tbs);
5974 }
5975
5976 void Customize()
5977 {
5978 ATLASSERT(::IsWindow(m_hWnd));
5979 ::SendMessage(m_hWnd, TB_CUSTOMIZE, 0, 0L);
5980 }
5981 #endif // !_WIN32_WCE
5982
5983 int AddString(UINT nStringID)
5984 {
5985 ATLASSERT(::IsWindow(m_hWnd));
5986 return (int)::SendMessage(m_hWnd, TB_ADDSTRING, (WPARAM)ModuleHelper::GetResourceInstance(), (LPARAM)nStringID);
5987 }
5988
5989 int AddStrings(LPCTSTR lpszStrings)
5990 {
5991 ATLASSERT(::IsWindow(m_hWnd));
5992 return (int)::SendMessage(m_hWnd, TB_ADDSTRING, 0, (LPARAM)lpszStrings);
5993 }
5994
5995 void AutoSize()
5996 {
5997 ATLASSERT(::IsWindow(m_hWnd));
5998 ::SendMessage(m_hWnd, TB_AUTOSIZE, 0, 0L);
5999 }
6000
6001 BOOL ChangeBitmap(int nID, int nBitmap)
6002 {
6003 ATLASSERT(::IsWindow(m_hWnd));
6004 return (BOOL)::SendMessage(m_hWnd, TB_CHANGEBITMAP, nID, MAKELPARAM(nBitmap, 0));
6005 }
6006
6007 int LoadImages(int nBitmapID)
6008 {
6009 ATLASSERT(::IsWindow(m_hWnd));
6010 return (int)::SendMessage(m_hWnd, TB_LOADIMAGES, nBitmapID, (LPARAM)ModuleHelper::GetResourceInstance());
6011 }
6012
6013 int LoadStdImages(int nBitmapID)
6014 {
6015 ATLASSERT(::IsWindow(m_hWnd));
6016 return (int)::SendMessage(m_hWnd, TB_LOADIMAGES, nBitmapID, (LPARAM)HINST_COMMCTRL);
6017 }
6018
6019 BOOL ReplaceBitmap(LPTBREPLACEBITMAP ptbrb)
6020 {
6021 ATLASSERT(::IsWindow(m_hWnd));
6022 return (BOOL)::SendMessage(m_hWnd, TB_REPLACEBITMAP, 0, (LPARAM)ptbrb);
6023 }
6024
6025 #if (_WIN32_IE >= 0x0400)
6026 int HitTest(LPPOINT lpPoint) const
6027 {
6028 ATLASSERT(::IsWindow(m_hWnd));
6029 return (int)::SendMessage(m_hWnd, TB_HITTEST, 0, (LPARAM)lpPoint);
6030 }
6031
6032 #ifndef _WIN32_WCE
6033 BOOL InsertMarkHitTest(LPPOINT lpPoint, LPTBINSERTMARK lptbim) const
6034 {
6035 ATLASSERT(::IsWindow(m_hWnd));
6036 return (BOOL)::SendMessage(m_hWnd, TB_INSERTMARKHITTEST, (WPARAM)lpPoint, (LPARAM)lptbim);
6037 }
6038
6039 BOOL InsertMarkHitTest(int x, int y, LPTBINSERTMARK lptbim) const
6040 {
6041 ATLASSERT(::IsWindow(m_hWnd));
6042 POINT pt = { x, y };
6043 return (BOOL)::SendMessage(m_hWnd, TB_INSERTMARKHITTEST, (WPARAM)&pt, (LPARAM)lptbim);
6044 }
6045
6046 BOOL MapAccelerator(TCHAR chAccel, int& nID) const
6047 {
6048 ATLASSERT(::IsWindow(m_hWnd));
6049 return (BOOL)::SendMessage(m_hWnd, TB_MAPACCELERATOR, (WPARAM)chAccel, (LPARAM)&nID);
6050 }
6051
6052 BOOL MarkButton(int nID, BOOL bHighlight = TRUE)
6053 {
6054 ATLASSERT(::IsWindow(m_hWnd));
6055 return (BOOL)::SendMessage(m_hWnd, TB_MARKBUTTON, nID, MAKELPARAM(bHighlight, 0));
6056 }
6057
6058 BOOL MoveButton(int nOldPos, int nNewPos)
6059 {
6060 ATLASSERT(::IsWindow(m_hWnd));
6061 return (BOOL)::SendMessage(m_hWnd, TB_MOVEBUTTON, nOldPos, nNewPos);
6062 }
6063
6064 HRESULT GetObject(REFIID iid, LPVOID* ppvObject)
6065 {
6066 ATLASSERT(::IsWindow(m_hWnd));
6067 return (HRESULT)::SendMessage(m_hWnd, TB_GETOBJECT, (WPARAM)&iid, (LPARAM)ppvObject);
6068 }
6069 #endif // !_WIN32_WCE
6070 #endif // (_WIN32_IE >= 0x0400)
6071 };
6072
6073 typedef CToolBarCtrlT<ATL::CWindow> CToolBarCtrl;
6074
6075
6076 ///////////////////////////////////////////////////////////////////////////////
6077 // CStatusBarCtrl
6078
6079 template <class TBase>
6080 class CStatusBarCtrlT : public TBase
6081 {
6082 public:
6083 // Constructors
6084 CStatusBarCtrlT(HWND hWnd = NULL) : TBase(hWnd)
6085 { }
6086
6087 CStatusBarCtrlT< TBase >& operator =(HWND hWnd)
6088 {
6089 m_hWnd = hWnd;
6090 return *this;
6091 }
6092
6093 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
6094 DWORD dwStyle = 0, DWORD dwExStyle = 0,
6095 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
6096 {
6097 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
6098 }
6099
6100 // Methods
6101 static LPCTSTR GetWndClassName()
6102 {
6103 return STATUSCLASSNAME;
6104 }
6105
6106 int GetParts(int nParts, int* pParts) const
6107 {
6108 ATLASSERT(::IsWindow(m_hWnd));
6109 return (int)::SendMessage(m_hWnd, SB_GETPARTS, nParts, (LPARAM)pParts);
6110 }
6111
6112 BOOL SetParts(int nParts, int* pWidths)
6113 {
6114 ATLASSERT(::IsWindow(m_hWnd));
6115 return (BOOL)::SendMessage(m_hWnd, SB_SETPARTS, nParts, (LPARAM)pWidths);
6116 }
6117
6118 int GetTextLength(int nPane, int* pType = NULL) const
6119 {
6120 ATLASSERT(::IsWindow(m_hWnd));
6121 ATLASSERT(nPane < 256);
6122 DWORD dwRet = (DWORD)::SendMessage(m_hWnd, SB_GETTEXTLENGTH, (WPARAM)nPane, 0L);
6123 if (pType != NULL)
6124 *pType = (int)(short)HIWORD(dwRet);
6125 return (int)(short)LOWORD(dwRet);
6126 }
6127
6128 int GetText(int nPane, LPTSTR lpszText, int* pType = NULL) const
6129 {
6130 ATLASSERT(::IsWindow(m_hWnd));
6131 ATLASSERT(nPane < 256);
6132 DWORD dwRet = (DWORD)::SendMessage(m_hWnd, SB_GETTEXT, (WPARAM)nPane, (LPARAM)lpszText);
6133 if(pType != NULL)
6134 *pType = (int)(short)HIWORD(dwRet);
6135 return (int)(short)LOWORD(dwRet);
6136 }
6137
6138 #ifndef _ATL_NO_COM
6139 BOOL GetTextBSTR(int nPane, BSTR& bstrText, int* pType = NULL) const
6140 {
6141 USES_CONVERSION;
6142 ATLASSERT(::IsWindow(m_hWnd));
6143 ATLASSERT(nPane < 256);
6144 ATLASSERT(bstrText == NULL);
6145 int nLength = (int)(short)LOWORD(::SendMessage(m_hWnd, SB_GETTEXTLENGTH, (WPARAM)nPane, 0L));
6146 if(nLength == 0)
6147 return FALSE;
6148
6149 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
6150 LPTSTR lpstrText = buff.Allocate(nLength + 1);
6151 if(lpstrText == NULL)
6152 return FALSE;
6153
6154 if(!GetText(nPane, lpstrText, pType))
6155 return FALSE;
6156
6157 bstrText = ::SysAllocString(T2OLE(lpstrText));
6158 return (bstrText != NULL) ? TRUE : FALSE;
6159 }
6160 #endif // !_ATL_NO_COM
6161
6162 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
6163 int GetText(int nPane, _CSTRING_NS::CString& strText, int* pType = NULL) const
6164 {
6165 ATLASSERT(::IsWindow(m_hWnd));
6166 ATLASSERT(nPane < 256);
6167 int nLength = (int)(short)LOWORD(::SendMessage(m_hWnd, SB_GETTEXTLENGTH, (WPARAM)nPane, 0L));
6168 if(nLength == 0)
6169 return 0;
6170
6171 LPTSTR lpstr = strText.GetBufferSetLength(nLength);
6172 if(lpstr == NULL)
6173 return 0;
6174 return GetText(nPane, lpstr, pType);
6175 }
6176 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
6177
6178 BOOL SetText(int nPane, LPCTSTR lpszText, int nType = 0)
6179 {
6180 ATLASSERT(::IsWindow(m_hWnd));
6181 ATLASSERT(nPane < 256);
6182 return (BOOL)::SendMessage(m_hWnd, SB_SETTEXT, (nPane | nType), (LPARAM)lpszText);
6183 }
6184
6185 BOOL GetRect(int nPane, LPRECT lpRect) const
6186 {
6187 ATLASSERT(::IsWindow(m_hWnd));
6188 ATLASSERT(nPane < 256);
6189 return (BOOL)::SendMessage(m_hWnd, SB_GETRECT, nPane, (LPARAM)lpRect);
6190 }
6191
6192 BOOL GetBorders(int* pBorders) const
6193 {
6194 ATLASSERT(::IsWindow(m_hWnd));
6195 return (BOOL)::SendMessage(m_hWnd, SB_GETBORDERS, 0, (LPARAM)pBorders);
6196 }
6197
6198 BOOL GetBorders(int& nHorz, int& nVert, int& nSpacing) const
6199 {
6200 ATLASSERT(::IsWindow(m_hWnd));
6201 int borders[3] = { 0, 0, 0 };
6202 BOOL bResult = (BOOL)::SendMessage(m_hWnd, SB_GETBORDERS, 0, (LPARAM)&borders);
6203 if(bResult)
6204 {
6205 nHorz = borders[0];
6206 nVert = borders[1];
6207 nSpacing = borders[2];
6208 }
6209 return bResult;
6210 }
6211
6212 void SetMinHeight(int nMin)
6213 {
6214 ATLASSERT(::IsWindow(m_hWnd));
6215 ::SendMessage(m_hWnd, SB_SETMINHEIGHT, nMin, 0L);
6216 }
6217
6218 BOOL SetSimple(BOOL bSimple = TRUE)
6219 {
6220 ATLASSERT(::IsWindow(m_hWnd));
6221 return (BOOL)::SendMessage(m_hWnd, SB_SIMPLE, bSimple, 0L);
6222 }
6223
6224 BOOL IsSimple() const
6225 {
6226 ATLASSERT(::IsWindow(m_hWnd));
6227 return (BOOL)::SendMessage(m_hWnd, SB_ISSIMPLE, 0, 0L);
6228 }
6229
6230 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
6231 BOOL GetUnicodeFormat() const
6232 {
6233 ATLASSERT(::IsWindow(m_hWnd));
6234 return (BOOL)::SendMessage(m_hWnd, SB_GETUNICODEFORMAT, 0, 0L);
6235 }
6236
6237 BOOL SetUnicodeFormat(BOOL bUnicode = TRUE)
6238 {
6239 ATLASSERT(::IsWindow(m_hWnd));
6240 return (BOOL)::SendMessage(m_hWnd, SB_SETUNICODEFORMAT, bUnicode, 0L);
6241 }
6242
6243 void GetTipText(int nPane, LPTSTR lpstrText, int nSize) const
6244 {
6245 ATLASSERT(::IsWindow(m_hWnd));
6246 ATLASSERT(nPane < 256);
6247 ::SendMessage(m_hWnd, SB_GETTIPTEXT, MAKEWPARAM(nPane, nSize), (LPARAM)lpstrText);
6248 }
6249
6250 void SetTipText(int nPane, LPCTSTR lpstrText)
6251 {
6252 ATLASSERT(::IsWindow(m_hWnd));
6253 ATLASSERT(nPane < 256);
6254 ::SendMessage(m_hWnd, SB_SETTIPTEXT, nPane, (LPARAM)lpstrText);
6255 }
6256 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
6257
6258 #if ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500))
6259 COLORREF SetBkColor(COLORREF clrBk)
6260 {
6261 ATLASSERT(::IsWindow(m_hWnd));
6262 return (COLORREF)::SendMessage(m_hWnd, SB_SETBKCOLOR, 0, (LPARAM)clrBk);
6263 }
6264
6265 HICON GetIcon(int nPane) const
6266 {
6267 ATLASSERT(::IsWindow(m_hWnd));
6268 ATLASSERT(nPane < 256);
6269 return (HICON)::SendMessage(m_hWnd, SB_GETICON, nPane, 0L);
6270 }
6271
6272 BOOL SetIcon(int nPane, HICON hIcon)
6273 {
6274 ATLASSERT(::IsWindow(m_hWnd));
6275 ATLASSERT(nPane < 256);
6276 return (BOOL)::SendMessage(m_hWnd, SB_SETICON, nPane, (LPARAM)hIcon);
6277 }
6278 #endif // ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500))
6279 };
6280
6281 typedef CStatusBarCtrlT<ATL::CWindow> CStatusBarCtrl;
6282
6283
6284 ///////////////////////////////////////////////////////////////////////////////
6285 // CTabCtrl
6286
6287 template <class TBase>
6288 class CTabCtrlT : public TBase
6289 {
6290 public:
6291 // Constructors
6292 CTabCtrlT(HWND hWnd = NULL) : TBase(hWnd)
6293 { }
6294
6295 CTabCtrlT< TBase >& operator =(HWND hWnd)
6296 {
6297 m_hWnd = hWnd;
6298 return *this;
6299 }
6300
6301 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
6302 DWORD dwStyle = 0, DWORD dwExStyle = 0,
6303 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
6304 {
6305 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
6306 }
6307
6308 // Attributes
6309 static LPCTSTR GetWndClassName()
6310 {
6311 return WC_TABCONTROL;
6312 }
6313
6314 CImageList GetImageList() const
6315 {
6316 ATLASSERT(::IsWindow(m_hWnd));
6317 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TCM_GETIMAGELIST, 0, 0L));
6318 }
6319
6320 CImageList SetImageList(HIMAGELIST hImageList)
6321 {
6322 ATLASSERT(::IsWindow(m_hWnd));
6323 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TCM_SETIMAGELIST, 0, (LPARAM)hImageList));
6324 }
6325
6326 int GetItemCount() const
6327 {
6328 ATLASSERT(::IsWindow(m_hWnd));
6329 return (int)::SendMessage(m_hWnd, TCM_GETITEMCOUNT, 0, 0L);
6330 }
6331
6332 BOOL GetItem(int nItem, LPTCITEM pTabCtrlItem) const
6333 {
6334 ATLASSERT(::IsWindow(m_hWnd));
6335 return (BOOL)::SendMessage(m_hWnd, TCM_GETITEM, nItem, (LPARAM)pTabCtrlItem);
6336 }
6337
6338 BOOL SetItem(int nItem, LPTCITEM pTabCtrlItem)
6339 {
6340 ATLASSERT(::IsWindow(m_hWnd));
6341 return (BOOL)::SendMessage(m_hWnd, TCM_SETITEM, nItem, (LPARAM)pTabCtrlItem);
6342 }
6343
6344 int SetItem(int nItem, UINT mask, LPCTSTR lpszItem, DWORD dwState, DWORD dwStateMask, int iImage, LPARAM lParam)
6345 {
6346 ATLASSERT(::IsWindow(m_hWnd));
6347 TCITEM tci = { 0 };
6348 tci.mask = mask;
6349 tci.pszText = (LPTSTR) lpszItem;
6350 tci.dwState = dwState;
6351 tci.dwStateMask = dwStateMask;
6352 tci.iImage = iImage;
6353 tci.lParam = lParam;
6354 return (int)::SendMessage(m_hWnd, TCM_SETITEM, nItem, (LPARAM)&tci);
6355 }
6356
6357 BOOL GetItemRect(int nItem, LPRECT lpRect) const
6358 {
6359 ATLASSERT(::IsWindow(m_hWnd));
6360 return (BOOL)::SendMessage(m_hWnd, TCM_GETITEMRECT, nItem, (LPARAM)lpRect);
6361 }
6362
6363 int GetCurSel() const
6364 {
6365 ATLASSERT(::IsWindow(m_hWnd));
6366 return (int)::SendMessage(m_hWnd, TCM_GETCURSEL, 0, 0L);
6367 }
6368
6369 int SetCurSel(int nItem)
6370 {
6371 ATLASSERT(::IsWindow(m_hWnd));
6372 return (int)::SendMessage(m_hWnd, TCM_SETCURSEL, nItem, 0L);
6373 }
6374
6375 SIZE SetItemSize(SIZE size)
6376 {
6377 ATLASSERT(::IsWindow(m_hWnd));
6378 DWORD dwSize = (DWORD)::SendMessage(m_hWnd, TCM_SETITEMSIZE, 0, MAKELPARAM(size.cx, size.cy));
6379 SIZE sizeRet = { GET_X_LPARAM(dwSize), GET_Y_LPARAM(dwSize) };
6380 return sizeRet;
6381 }
6382
6383 void SetItemSize(int cx, int cy)
6384 {
6385 ATLASSERT(::IsWindow(m_hWnd));
6386 ::SendMessage(m_hWnd, TCM_SETITEMSIZE, 0, MAKELPARAM(cx, cy));
6387 }
6388
6389 void SetPadding(SIZE size)
6390 {
6391 ATLASSERT(::IsWindow(m_hWnd));
6392 ::SendMessage(m_hWnd, TCM_SETPADDING, 0, MAKELPARAM(size.cx, size.cy));
6393 }
6394
6395 int GetRowCount() const
6396 {
6397 ATLASSERT(::IsWindow(m_hWnd));
6398 return (int)::SendMessage(m_hWnd, TCM_GETROWCOUNT, 0, 0L);
6399 }
6400
6401 #ifndef _WIN32_WCE
6402 CToolTipCtrl GetToolTips() const
6403 {
6404 ATLASSERT(::IsWindow(m_hWnd));
6405 return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TCM_GETTOOLTIPS, 0, 0L));
6406 }
6407
6408 // this method is deprecated, please use GetToolTips
6409 CToolTipCtrl GetTooltips() const { return GetToolTips(); }
6410
6411 void SetToolTips(HWND hWndToolTip)
6412 {
6413 ATLASSERT(::IsWindow(m_hWnd));
6414 ::SendMessage(m_hWnd, TCM_SETTOOLTIPS, (WPARAM)hWndToolTip, 0L);
6415 }
6416
6417 // this method is deprecated, please use SetToolTips
6418 void SetTooltips(HWND hWndToolTip) { SetToolTips(hWndToolTip); }
6419
6420 #endif // !_WIN32_WCE
6421
6422 int GetCurFocus() const
6423 {
6424 ATLASSERT(::IsWindow(m_hWnd));
6425 return (int)::SendMessage(m_hWnd, TCM_GETCURFOCUS, 0, 0L);
6426 }
6427
6428 void SetCurFocus(int nItem)
6429 {
6430 ATLASSERT(::IsWindow(m_hWnd));
6431 ::SendMessage(m_hWnd, TCM_SETCURFOCUS, nItem, 0L);
6432 }
6433
6434 BOOL SetItemExtra(int cbExtra)
6435 {
6436 ATLASSERT(::IsWindow(m_hWnd));
6437 ATLASSERT(GetItemCount() == 0); // must be empty
6438 return (BOOL)::SendMessage(m_hWnd, TCM_SETITEMEXTRA, cbExtra, 0L);
6439 }
6440
6441 int SetMinTabWidth(int nWidth = -1)
6442 {
6443 ATLASSERT(::IsWindow(m_hWnd));
6444 return (int)::SendMessage(m_hWnd, TCM_SETMINTABWIDTH, 0, nWidth);
6445 }
6446
6447 #if (_WIN32_IE >= 0x0400)
6448 DWORD GetExtendedStyle() const
6449 {
6450 ATLASSERT(::IsWindow(m_hWnd));
6451 return (DWORD)::SendMessage(m_hWnd, TCM_GETEXTENDEDSTYLE, 0, 0L);
6452 }
6453
6454 DWORD SetExtendedStyle(DWORD dwExMask, DWORD dwExStyle)
6455 {
6456 ATLASSERT(::IsWindow(m_hWnd));
6457 return (DWORD)::SendMessage(m_hWnd, TCM_SETEXTENDEDSTYLE, dwExMask, dwExStyle);
6458 }
6459
6460 #ifndef _WIN32_WCE
6461 BOOL GetUnicodeFormat() const
6462 {
6463 ATLASSERT(::IsWindow(m_hWnd));
6464 return (BOOL)::SendMessage(m_hWnd, TCM_GETUNICODEFORMAT, 0, 0L);
6465 }
6466
6467 BOOL SetUnicodeFormat(BOOL bUnicode = TRUE)
6468 {
6469 ATLASSERT(::IsWindow(m_hWnd));
6470 return (BOOL)::SendMessage(m_hWnd, TCM_SETUNICODEFORMAT, bUnicode, 0L);
6471 }
6472 #endif // !_WIN32_WCE
6473 #endif // (_WIN32_IE >= 0x0400)
6474
6475 // Operations
6476 int InsertItem(int nItem, LPTCITEM pTabCtrlItem)
6477 {
6478 ATLASSERT(::IsWindow(m_hWnd));
6479 return (int)::SendMessage(m_hWnd, TCM_INSERTITEM, nItem, (LPARAM)pTabCtrlItem);
6480 }
6481
6482 int InsertItem(int nItem, UINT mask, LPCTSTR lpszItem, int iImage, LPARAM lParam)
6483 {
6484 ATLASSERT(::IsWindow(m_hWnd));
6485 TCITEM tci = { 0 };
6486 tci.mask = mask;
6487 tci.pszText = (LPTSTR) lpszItem;
6488 tci.iImage = iImage;
6489 tci.lParam = lParam;
6490 return (int)::SendMessage(m_hWnd, TCM_INSERTITEM, nItem, (LPARAM)&tci);
6491 }
6492
6493 int InsertItem(int nItem, LPCTSTR lpszItem)
6494 {
6495 ATLASSERT(::IsWindow(m_hWnd));
6496 TCITEM tci = { 0 };
6497 tci.mask = TCIF_TEXT;
6498 tci.pszText = (LPTSTR) lpszItem;
6499 return (int)::SendMessage(m_hWnd, TCM_INSERTITEM, nItem, (LPARAM)&tci);
6500 }
6501
6502 int AddItem(LPTCITEM pTabCtrlItem)
6503 {
6504 return InsertItem(GetItemCount(), pTabCtrlItem);
6505 }
6506
6507 int AddItem(UINT mask, LPCTSTR lpszItem, int iImage, LPARAM lParam)
6508 {
6509 return InsertItem(GetItemCount(), mask, lpszItem, iImage, lParam);
6510 }
6511
6512 int AddItem(LPCTSTR lpszItem)
6513 {
6514 return InsertItem(GetItemCount(), lpszItem);
6515 }
6516
6517 BOOL DeleteItem(int nItem)
6518 {
6519 ATLASSERT(::IsWindow(m_hWnd));
6520 return (BOOL)::SendMessage(m_hWnd, TCM_DELETEITEM, nItem, 0L);
6521 }
6522
6523 BOOL DeleteAllItems()
6524 {
6525 ATLASSERT(::IsWindow(m_hWnd));
6526 return (BOOL)::SendMessage(m_hWnd, TCM_DELETEALLITEMS, 0, 0L);
6527 }
6528
6529 void AdjustRect(BOOL bLarger, LPRECT lpRect)
6530 {
6531 ATLASSERT(::IsWindow(m_hWnd));
6532 ::SendMessage(m_hWnd, TCM_ADJUSTRECT, bLarger, (LPARAM)lpRect);
6533 }
6534
6535 void RemoveImage(int nImage)
6536 {
6537 ATLASSERT(::IsWindow(m_hWnd));
6538 ::SendMessage(m_hWnd, TCM_REMOVEIMAGE, nImage, 0L);
6539 }
6540
6541 int HitTest(TC_HITTESTINFO* pHitTestInfo) const
6542 {
6543 ATLASSERT(::IsWindow(m_hWnd));
6544 return (int)::SendMessage(m_hWnd, TCM_HITTEST, 0, (LPARAM)pHitTestInfo);
6545 }
6546
6547 void DeselectAll(BOOL bExcludeFocus = TRUE)
6548 {
6549 ATLASSERT(::IsWindow(m_hWnd));
6550 ::SendMessage(m_hWnd, TCM_DESELECTALL, bExcludeFocus, 0L);
6551 }
6552
6553 #if (_WIN32_IE >= 0x0400)
6554 BOOL HighlightItem(int nIndex, BOOL bHighlight = TRUE)
6555 {
6556 ATLASSERT(::IsWindow(m_hWnd));
6557 return (BOOL)::SendMessage(m_hWnd, TCM_HIGHLIGHTITEM, nIndex, MAKELPARAM(bHighlight, 0));
6558 }
6559 #endif // (_WIN32_IE >= 0x0400)
6560 };
6561
6562 typedef CTabCtrlT<ATL::CWindow> CTabCtrl;
6563
6564
6565 ///////////////////////////////////////////////////////////////////////////////
6566 // CTrackBarCtrl
6567
6568 template <class TBase>
6569 class CTrackBarCtrlT : public TBase
6570 {
6571 public:
6572 // Constructors
6573 CTrackBarCtrlT(HWND hWnd = NULL) : TBase(hWnd)
6574 { }
6575
6576 CTrackBarCtrlT< TBase >& operator =(HWND hWnd)
6577 {
6578 m_hWnd = hWnd;
6579 return *this;
6580 }
6581
6582 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
6583 DWORD dwStyle = 0, DWORD dwExStyle = 0,
6584 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
6585 {
6586 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
6587 }
6588
6589 // Attributes
6590 static LPCTSTR GetWndClassName()
6591 {
6592 return TRACKBAR_CLASS;
6593 }
6594
6595 int GetLineSize() const
6596 {
6597 ATLASSERT(::IsWindow(m_hWnd));
6598 return (int)::SendMessage(m_hWnd, TBM_GETLINESIZE, 0, 0L);
6599 }
6600
6601 int SetLineSize(int nSize)
6602 {
6603 ATLASSERT(::IsWindow(m_hWnd));
6604 return (int)::SendMessage(m_hWnd, TBM_SETLINESIZE, 0, nSize);
6605 }
6606
6607 int GetPageSize() const
6608 {
6609 ATLASSERT(::IsWindow(m_hWnd));
6610 return (int)::SendMessage(m_hWnd, TBM_GETPAGESIZE, 0, 0L);
6611 }
6612
6613 int SetPageSize(int nSize)
6614 {
6615 ATLASSERT(::IsWindow(m_hWnd));
6616 return (int)::SendMessage(m_hWnd, TBM_SETPAGESIZE, 0, nSize);
6617 }
6618
6619 int GetRangeMin() const
6620 {
6621 ATLASSERT(::IsWindow(m_hWnd));
6622 return (int)::SendMessage(m_hWnd, TBM_GETRANGEMIN, 0, 0L);
6623 }
6624
6625 void SetRangeMin(int nMin, BOOL bRedraw = FALSE)
6626 {
6627 ATLASSERT(::IsWindow(m_hWnd));
6628 ::SendMessage(m_hWnd, TBM_SETRANGEMIN, bRedraw, nMin);
6629 }
6630
6631 int GetRangeMax() const
6632 {
6633 ATLASSERT(::IsWindow(m_hWnd));
6634 return (int)::SendMessage(m_hWnd, TBM_GETRANGEMAX, 0, 0L);
6635 }
6636
6637 void SetRangeMax(int nMax, BOOL bRedraw = FALSE)
6638 {
6639 ATLASSERT(::IsWindow(m_hWnd));
6640 ::SendMessage(m_hWnd, TBM_SETRANGEMAX, bRedraw, nMax);
6641 }
6642
6643 void GetRange(int& nMin, int& nMax) const
6644 {
6645 nMin = GetRangeMin();
6646 nMax = GetRangeMax();
6647 }
6648
6649 void SetRange(int nMin, int nMax, BOOL bRedraw = TRUE)
6650 {
6651 ATLASSERT(::IsWindow(m_hWnd));
6652 ::SendMessage(m_hWnd, TBM_SETRANGE, bRedraw, MAKELPARAM(nMin, nMax));
6653 }
6654
6655 int GetSelStart() const
6656 {
6657 ATLASSERT(::IsWindow(m_hWnd));
6658 return (int)::SendMessage(m_hWnd, TBM_GETSELSTART, 0, 0L);
6659 }
6660
6661 void SetSelStart(int nMin, BOOL bRedraw = FALSE)
6662 {
6663 ATLASSERT(::IsWindow(m_hWnd));
6664 ::SendMessage(m_hWnd, TBM_SETSELSTART, bRedraw, (LPARAM)nMin);
6665 }
6666
6667 int GetSelEnd() const
6668 {
6669 ATLASSERT(::IsWindow(m_hWnd));
6670 return (int)::SendMessage(m_hWnd, TBM_GETSELEND, 0, 0L);
6671 }
6672
6673 void SetSelEnd(int nMax, BOOL bRedraw = FALSE)
6674 {
6675 ATLASSERT(::IsWindow(m_hWnd));
6676 ::SendMessage(m_hWnd, TBM_SETSELEND, bRedraw, (LPARAM)nMax);
6677 }
6678
6679 void GetSelection(int& nMin, int& nMax) const
6680 {
6681 nMin = GetSelStart();
6682 nMax = GetSelEnd();
6683 }
6684
6685 void SetSelection(int nMin, int nMax, BOOL bRedraw = TRUE)
6686 {
6687 SetSelStart(nMin, FALSE);
6688 SetSelEnd(nMax, bRedraw);
6689 }
6690
6691 void GetChannelRect(LPRECT lprc) const
6692 {
6693 ATLASSERT(::IsWindow(m_hWnd));
6694 ::SendMessage(m_hWnd, TBM_GETCHANNELRECT, 0, (LPARAM)lprc);
6695 }
6696
6697 void GetThumbRect(LPRECT lprc) const
6698 {
6699 ATLASSERT(::IsWindow(m_hWnd));
6700 ::SendMessage(m_hWnd, TBM_GETTHUMBRECT, 0, (LPARAM)lprc);
6701 }
6702
6703 int GetPos() const
6704 {
6705 ATLASSERT(::IsWindow(m_hWnd));
6706 return (int)::SendMessage(m_hWnd, TBM_GETPOS, 0, 0L);
6707 }
6708
6709 void SetPos(int nPos)
6710 {
6711 ATLASSERT(::IsWindow(m_hWnd));
6712 ::SendMessage(m_hWnd, TBM_SETPOS, TRUE, nPos);
6713 }
6714
6715 UINT GetNumTics() const
6716 {
6717 ATLASSERT(::IsWindow(m_hWnd));
6718 return (UINT)::SendMessage(m_hWnd, TBM_GETNUMTICS, 0, 0L);
6719 }
6720
6721 DWORD* GetTicArray() const
6722 {
6723 ATLASSERT(::IsWindow(m_hWnd));
6724 return (DWORD*)::SendMessage(m_hWnd, TBM_GETPTICS, 0, 0L);
6725 }
6726
6727 int GetTic(int nTic) const
6728 {
6729 ATLASSERT(::IsWindow(m_hWnd));
6730 return (int)::SendMessage(m_hWnd, TBM_GETTIC, nTic, 0L);
6731 }
6732
6733 BOOL SetTic(int nTic)
6734 {
6735 ATLASSERT(::IsWindow(m_hWnd));
6736 return (BOOL)::SendMessage(m_hWnd, TBM_SETTIC, 0, nTic);
6737 }
6738
6739 int GetTicPos(int nTic) const
6740 {
6741 ATLASSERT(::IsWindow(m_hWnd));
6742 return (int)::SendMessage(m_hWnd, TBM_GETTICPOS, nTic, 0L);
6743 }
6744
6745 void SetTicFreq(int nFreq)
6746 {
6747 ATLASSERT(::IsWindow(m_hWnd));
6748 ::SendMessage(m_hWnd, TBM_SETTICFREQ, nFreq, 0L);
6749 }
6750
6751 int GetThumbLength() const
6752 {
6753 ATLASSERT(::IsWindow(m_hWnd));
6754 return (int)::SendMessage(m_hWnd, TBM_GETTHUMBLENGTH, 0, 0L);
6755 }
6756
6757 void SetThumbLength(int nLength)
6758 {
6759 ATLASSERT(::IsWindow(m_hWnd));
6760 ::SendMessage(m_hWnd, TBM_SETTHUMBLENGTH, nLength, 0L);
6761 }
6762
6763 void SetSel(int nStart, int nEnd, BOOL bRedraw = TRUE)
6764 {
6765 ATLASSERT(::IsWindow(m_hWnd));
6766 ATLASSERT((GetStyle() & TBS_ENABLESELRANGE) != 0);
6767 ::SendMessage(m_hWnd, TBM_SETSEL, bRedraw, MAKELPARAM(nStart, nEnd));
6768 }
6769
6770 ATL::CWindow GetBuddy(BOOL bLeft = TRUE) const
6771 {
6772 ATLASSERT(::IsWindow(m_hWnd));
6773 return ATL::CWindow((HWND)::SendMessage(m_hWnd, TBM_GETBUDDY, bLeft, 0L));
6774 }
6775
6776 ATL::CWindow SetBuddy(HWND hWndBuddy, BOOL bLeft = TRUE)
6777 {
6778 ATLASSERT(::IsWindow(m_hWnd));
6779 return ATL::CWindow((HWND)::SendMessage(m_hWnd, TBM_SETBUDDY, bLeft, (LPARAM)hWndBuddy));
6780 }
6781
6782 #ifndef _WIN32_WCE
6783 CToolTipCtrl GetToolTips() const
6784 {
6785 ATLASSERT(::IsWindow(m_hWnd));
6786 return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TBM_GETTOOLTIPS, 0, 0L));
6787 }
6788
6789 void SetToolTips(HWND hWndTT)
6790 {
6791 ATLASSERT(::IsWindow(m_hWnd));
6792 ::SendMessage(m_hWnd, TBM_SETTOOLTIPS, (WPARAM)hWndTT, 0L);
6793 }
6794
6795 int SetTipSide(int nSide)
6796 {
6797 ATLASSERT(::IsWindow(m_hWnd));
6798 return (int)::SendMessage(m_hWnd, TBM_SETTIPSIDE, nSide, 0L);
6799 }
6800 #endif // !_WIN32_WCE
6801
6802 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
6803 BOOL GetUnicodeFormat() const
6804 {
6805 ATLASSERT(::IsWindow(m_hWnd));
6806 return (BOOL)::SendMessage(m_hWnd, TBM_GETUNICODEFORMAT, 0, 0L);
6807 }
6808
6809 BOOL SetUnicodeFormat(BOOL bUnicode = TRUE)
6810 {
6811 ATLASSERT(::IsWindow(m_hWnd));
6812 return (BOOL)::SendMessage(m_hWnd, TBM_SETUNICODEFORMAT, bUnicode, 0L);
6813 }
6814 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
6815
6816 // Operations
6817 void ClearSel(BOOL bRedraw = FALSE)
6818 {
6819 ATLASSERT(::IsWindow(m_hWnd));
6820 ::SendMessage(m_hWnd, TBM_CLEARSEL, bRedraw, 0L);
6821 }
6822
6823 void VerifyPos()
6824 {
6825 ATLASSERT(::IsWindow(m_hWnd));
6826 ::SendMessage(m_hWnd, TBM_SETPOS, FALSE, 0L);
6827 }
6828
6829 void ClearTics(BOOL bRedraw = FALSE)
6830 {
6831 ATLASSERT(::IsWindow(m_hWnd));
6832 ::SendMessage(m_hWnd, TBM_CLEARTICS, bRedraw, 0L);
6833 }
6834 };
6835
6836 typedef CTrackBarCtrlT<ATL::CWindow> CTrackBarCtrl;
6837
6838
6839 ///////////////////////////////////////////////////////////////////////////////
6840 // CUpDownCtrl
6841
6842 template <class TBase>
6843 class CUpDownCtrlT : public TBase
6844 {
6845 public:
6846 // Constructors
6847 CUpDownCtrlT(HWND hWnd = NULL) : TBase(hWnd)
6848 { }
6849
6850 CUpDownCtrlT< TBase >& operator =(HWND hWnd)
6851 {
6852 m_hWnd = hWnd;
6853 return *this;
6854 }
6855
6856 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
6857 DWORD dwStyle = 0, DWORD dwExStyle = 0,
6858 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
6859 {
6860 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
6861 }
6862
6863 // Attributes
6864 static LPCTSTR GetWndClassName()
6865 {
6866 return UPDOWN_CLASS;
6867 }
6868
6869 UINT GetAccel(int nAccel, UDACCEL* pAccel) const
6870 {
6871 ATLASSERT(::IsWindow(m_hWnd));
6872 return (UINT)LOWORD(::SendMessage(m_hWnd, UDM_GETACCEL, nAccel, (LPARAM)pAccel));
6873 }
6874
6875 BOOL SetAccel(int nAccel, UDACCEL* pAccel)
6876 {
6877 ATLASSERT(::IsWindow(m_hWnd));
6878 return (BOOL)LOWORD(::SendMessage(m_hWnd, UDM_SETACCEL, nAccel, (LPARAM)pAccel));
6879 }
6880
6881 UINT GetBase() const
6882 {
6883 ATLASSERT(::IsWindow(m_hWnd));
6884 return (UINT)LOWORD(::SendMessage(m_hWnd, UDM_GETBASE, 0, 0L));
6885 }
6886
6887 int SetBase(int nBase)
6888 {
6889 ATLASSERT(::IsWindow(m_hWnd));
6890 return (int)::SendMessage(m_hWnd, UDM_SETBASE, nBase, 0L);
6891 }
6892
6893 ATL::CWindow GetBuddy() const
6894 {
6895 ATLASSERT(::IsWindow(m_hWnd));
6896 return ATL::CWindow((HWND)::SendMessage(m_hWnd, UDM_GETBUDDY, 0, 0L));
6897 }
6898
6899 ATL::CWindow SetBuddy(HWND hWndBuddy)
6900 {
6901 ATLASSERT(::IsWindow(m_hWnd));
6902 return ATL::CWindow((HWND)::SendMessage(m_hWnd, UDM_SETBUDDY, (WPARAM)hWndBuddy, 0L));
6903 }
6904
6905 int GetPos(LPBOOL lpbError = NULL) const
6906 {
6907 ATLASSERT(::IsWindow(m_hWnd));
6908 DWORD dwRet = (DWORD)::SendMessage(m_hWnd, UDM_GETPOS, 0, 0L);
6909 // Note: Seems that Windows always sets error to TRUE if
6910 // UDS_SETBUDDYINT style is not used
6911 if(lpbError != NULL)
6912 *lpbError = (HIWORD(dwRet) != 0) ? TRUE : FALSE;
6913 return (int)(short)LOWORD(dwRet);
6914 }
6915
6916 int SetPos(int nPos)
6917 {
6918 ATLASSERT(::IsWindow(m_hWnd));
6919 return (int)(short)LOWORD(::SendMessage(m_hWnd, UDM_SETPOS, 0, MAKELPARAM(nPos, 0)));
6920 }
6921
6922 DWORD GetRange() const
6923 {
6924 ATLASSERT(::IsWindow(m_hWnd));
6925 return (DWORD)::SendMessage(m_hWnd, UDM_GETRANGE, 0, 0L);
6926 }
6927
6928 void GetRange(int& nLower, int& nUpper) const
6929 {
6930 ATLASSERT(::IsWindow(m_hWnd));
6931 DWORD dwRet = (DWORD)::SendMessage(m_hWnd, UDM_GETRANGE, 0, 0L);
6932 nLower = (int)(short)HIWORD(dwRet);
6933 nUpper = (int)(short)LOWORD(dwRet);
6934 }
6935
6936 void SetRange(int nLower, int nUpper)
6937 {
6938 ATLASSERT(::IsWindow(m_hWnd));
6939 ::SendMessage(m_hWnd, UDM_SETRANGE, 0, MAKELPARAM(nUpper, nLower));
6940 }
6941
6942 #if (_WIN32_IE >= 0x0400)
6943 void SetRange32(int nLower, int nUpper)
6944 {
6945 ATLASSERT(::IsWindow(m_hWnd));
6946 ::SendMessage(m_hWnd, UDM_SETRANGE32, nLower, nUpper);
6947 }
6948
6949 void GetRange32(int& nLower, int& nUpper) const
6950 {
6951 ATLASSERT(::IsWindow(m_hWnd));
6952 ::SendMessage(m_hWnd, UDM_GETRANGE32, (WPARAM)&nLower, (LPARAM)&nUpper);
6953 }
6954
6955 #ifndef _WIN32_WCE
6956 BOOL GetUnicodeFormat() const
6957 {
6958 ATLASSERT(::IsWindow(m_hWnd));
6959 return (BOOL)::SendMessage(m_hWnd, UDM_GETUNICODEFORMAT, 0, 0L);
6960 }
6961
6962 BOOL SetUnicodeFormat(BOOL bUnicode = TRUE)
6963 {
6964 ATLASSERT(::IsWindow(m_hWnd));
6965 return (BOOL)::SendMessage(m_hWnd, UDM_SETUNICODEFORMAT, bUnicode, 0L);
6966 }
6967 #endif // !_WIN32_WCE
6968 #endif // (_WIN32_IE >= 0x0400)
6969
6970 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
6971 int GetPos32(LPBOOL lpbError = NULL) const
6972 {
6973 ATLASSERT(::IsWindow(m_hWnd));
6974 // Note: Seems that Windows always sets error to TRUE if
6975 // UDS_SETBUDDYINT style is not used
6976 return (int)::SendMessage(m_hWnd, UDM_GETPOS32, 0, (LPARAM)lpbError);
6977 }
6978
6979 int SetPos32(int nPos)
6980 {
6981 ATLASSERT(::IsWindow(m_hWnd));
6982 return (int)::SendMessage(m_hWnd, UDM_SETPOS32, 0, (LPARAM)nPos);
6983 }
6984 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
6985 };
6986
6987 typedef CUpDownCtrlT<ATL::CWindow> CUpDownCtrl;
6988
6989
6990 ///////////////////////////////////////////////////////////////////////////////
6991 // CProgressBarCtrl
6992
6993 template <class TBase>
6994 class CProgressBarCtrlT : public TBase
6995 {
6996 public:
6997 // Constructors
6998 CProgressBarCtrlT(HWND hWnd = NULL) : TBase(hWnd)
6999 { }
7000
7001 CProgressBarCtrlT< TBase >& operator =(HWND hWnd)
7002 {
7003 m_hWnd = hWnd;
7004 return *this;
7005 }
7006
7007 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
7008 DWORD dwStyle = 0, DWORD dwExStyle = 0,
7009 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
7010 {
7011 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
7012 }
7013
7014 // Attributes
7015 static LPCTSTR GetWndClassName()
7016 {
7017 return PROGRESS_CLASS;
7018 }
7019
7020 DWORD SetRange(int nLower, int nUpper)
7021 {
7022 ATLASSERT(::IsWindow(m_hWnd));
7023 return (DWORD)::SendMessage(m_hWnd, PBM_SETRANGE, 0, MAKELPARAM(nLower, nUpper));
7024 }
7025
7026 int SetPos(int nPos)
7027 {
7028 ATLASSERT(::IsWindow(m_hWnd));
7029 return (int)(short)LOWORD(::SendMessage(m_hWnd, PBM_SETPOS, nPos, 0L));
7030 }
7031
7032 int OffsetPos(int nPos)
7033 {
7034 ATLASSERT(::IsWindow(m_hWnd));
7035 return (int)(short)LOWORD(::SendMessage(m_hWnd, PBM_DELTAPOS, nPos, 0L));
7036 }
7037
7038 int SetStep(int nStep)
7039 {
7040 ATLASSERT(::IsWindow(m_hWnd));
7041 return (int)(short)LOWORD(::SendMessage(m_hWnd, PBM_SETSTEP, nStep, 0L));
7042 }
7043
7044 UINT GetPos() const
7045 {
7046 ATLASSERT(::IsWindow(m_hWnd));
7047 return (UINT)::SendMessage(m_hWnd, PBM_GETPOS, 0, 0L);
7048 }
7049
7050 void GetRange(PPBRANGE pPBRange) const
7051 {
7052 ATLASSERT(::IsWindow(m_hWnd));
7053 ATLASSERT(pPBRange != NULL);
7054 ::SendMessage(m_hWnd, PBM_GETRANGE, TRUE, (LPARAM)pPBRange);
7055 }
7056
7057 void GetRange(int& nLower, int& nUpper) const
7058 {
7059 ATLASSERT(::IsWindow(m_hWnd));
7060 PBRANGE range = { 0 };
7061 ::SendMessage(m_hWnd, PBM_GETRANGE, TRUE, (LPARAM)&range);
7062 nLower = range.iLow;
7063 nUpper = range.iHigh;
7064 }
7065
7066 int GetRangeLimit(BOOL bLowLimit) const
7067 {
7068 ATLASSERT(::IsWindow(m_hWnd));
7069 return (int)::SendMessage(m_hWnd, PBM_GETRANGE, bLowLimit, (LPARAM)NULL);
7070 }
7071
7072 DWORD SetRange32(int nMin, int nMax)
7073 {
7074 ATLASSERT(::IsWindow(m_hWnd));
7075 return (DWORD)::SendMessage(m_hWnd, PBM_SETRANGE32, nMin, nMax);
7076 }
7077
7078 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
7079 COLORREF SetBarColor(COLORREF clr)
7080 {
7081 ATLASSERT(::IsWindow(m_hWnd));
7082 return (COLORREF)::SendMessage(m_hWnd, PBM_SETBARCOLOR, 0, (LPARAM)clr);
7083 }
7084
7085 COLORREF SetBkColor(COLORREF clr)
7086 {
7087 ATLASSERT(::IsWindow(m_hWnd));
7088 return (COLORREF)::SendMessage(m_hWnd, PBM_SETBKCOLOR, 0, (LPARAM)clr);
7089 }
7090 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
7091
7092 #if (_WIN32_WINNT >= 0x0501) && defined(PBM_SETMARQUEE)
7093 BOOL SetMarquee(BOOL bMarquee, UINT uUpdateTime = 0U)
7094 {
7095 ATLASSERT(::IsWindow(m_hWnd));
7096 return (BOOL)::SendMessage(m_hWnd, PBM_SETMARQUEE, (WPARAM)bMarquee, (LPARAM)uUpdateTime);
7097 }
7098 #endif // (_WIN32_WINNT >= 0x0501) && defined(PBM_SETMARQUEE)
7099
7100 #if (_WIN32_WINNT >= 0x0600)
7101 int GetStep() const
7102 {
7103 ATLASSERT(::IsWindow(m_hWnd));
7104 return (int)::SendMessage(m_hWnd, PBM_GETSTEP, 0, 0L);
7105 }
7106
7107 COLORREF GetBkColor() const
7108 {
7109 ATLASSERT(::IsWindow(m_hWnd));
7110 return (COLORREF)::SendMessage(m_hWnd, PBM_GETBKCOLOR, 0, 0L);
7111 }
7112
7113 COLORREF GetBarColor() const
7114 {
7115 ATLASSERT(::IsWindow(m_hWnd));
7116 return (COLORREF)::SendMessage(m_hWnd, PBM_GETBARCOLOR, 0, 0L);
7117 }
7118
7119 int GetState() const
7120 {
7121 ATLASSERT(::IsWindow(m_hWnd));
7122 return (int)::SendMessage(m_hWnd, PBM_GETSTATE, 0, 0L);
7123 }
7124
7125 int SetState(int nState)
7126 {
7127 ATLASSERT(::IsWindow(m_hWnd));
7128 return (int)::SendMessage(m_hWnd, PBM_SETSTATE, nState, 0L);
7129 }
7130 #endif // (_WIN32_WINNT >= 0x0600)
7131
7132 // Operations
7133 int StepIt()
7134 {
7135 ATLASSERT(::IsWindow(m_hWnd));
7136 return (int)(short)LOWORD(::SendMessage(m_hWnd, PBM_STEPIT, 0, 0L));
7137 }
7138 };
7139
7140 typedef CProgressBarCtrlT<ATL::CWindow> CProgressBarCtrl;
7141
7142
7143 ///////////////////////////////////////////////////////////////////////////////
7144 // CHotKeyCtrl
7145
7146 #ifndef _WIN32_WCE
7147
7148 template <class TBase>
7149 class CHotKeyCtrlT : public TBase
7150 {
7151 public:
7152 // Constructors
7153 CHotKeyCtrlT(HWND hWnd = NULL) : TBase(hWnd)
7154 { }
7155
7156 CHotKeyCtrlT< TBase >& operator =(HWND hWnd)
7157 {
7158 m_hWnd = hWnd;
7159 return *this;
7160 }
7161
7162 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
7163 DWORD dwStyle = 0, DWORD dwExStyle = 0,
7164 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
7165 {
7166 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
7167 }
7168
7169 // Attributes
7170 static LPCTSTR GetWndClassName()
7171 {
7172 return HOTKEY_CLASS;
7173 }
7174
7175 DWORD GetHotKey() const
7176 {
7177 ATLASSERT(::IsWindow(m_hWnd));
7178 return (DWORD)::SendMessage(m_hWnd, HKM_GETHOTKEY, 0, 0L);
7179 }
7180
7181 void GetHotKey(WORD &wVirtualKeyCode, WORD &wModifiers) const
7182 {
7183 ATLASSERT(::IsWindow(m_hWnd));
7184 DWORD dw = (DWORD)::SendMessage(m_hWnd, HKM_GETHOTKEY, 0, 0L);
7185 wVirtualKeyCode = LOBYTE(LOWORD(dw));
7186 wModifiers = HIBYTE(LOWORD(dw));
7187 }
7188
7189 void SetHotKey(WORD wVirtualKeyCode, WORD wModifiers)
7190 {
7191 ATLASSERT(::IsWindow(m_hWnd));
7192 ::SendMessage(m_hWnd, HKM_SETHOTKEY, MAKEWORD(wVirtualKeyCode, wModifiers), 0L);
7193 }
7194
7195 void SetRules(WORD wInvalidComb, WORD wModifiers)
7196 {
7197 ATLASSERT(::IsWindow(m_hWnd));
7198 ::SendMessage(m_hWnd, HKM_SETRULES, wInvalidComb, MAKELPARAM(wModifiers, 0));
7199 }
7200 };
7201
7202 typedef CHotKeyCtrlT<ATL::CWindow> CHotKeyCtrl;
7203
7204 #endif // !_WIN32_WCE
7205
7206
7207 ///////////////////////////////////////////////////////////////////////////////
7208 // CAnimateCtrl
7209
7210 #ifndef _WIN32_WCE
7211
7212 template <class TBase>
7213 class CAnimateCtrlT : public TBase
7214 {
7215 public:
7216 // Constructors
7217 CAnimateCtrlT(HWND hWnd = NULL) : TBase(hWnd)
7218 { }
7219
7220 CAnimateCtrlT< TBase >& operator =(HWND hWnd)
7221 {
7222 m_hWnd = hWnd;
7223 return *this;
7224 }
7225
7226 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
7227 DWORD dwStyle = 0, DWORD dwExStyle = 0,
7228 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
7229 {
7230 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
7231 }
7232
7233 // Attributes
7234 static LPCTSTR GetWndClassName()
7235 {
7236 return ANIMATE_CLASS;
7237 }
7238
7239 // Operations
7240 BOOL Open(ATL::_U_STRINGorID FileName)
7241 {
7242 ATLASSERT(::IsWindow(m_hWnd));
7243 return (BOOL)::SendMessage(m_hWnd, ACM_OPEN, 0, (LPARAM)FileName.m_lpstr);
7244 }
7245
7246 BOOL Play(UINT nFrom, UINT nTo, UINT nRep)
7247 {
7248 ATLASSERT(::IsWindow(m_hWnd));
7249 return (BOOL)::SendMessage(m_hWnd, ACM_PLAY, nRep, MAKELPARAM(nFrom, nTo));
7250 }
7251
7252 BOOL Stop()
7253 {
7254 ATLASSERT(::IsWindow(m_hWnd));
7255 return (BOOL)::SendMessage(m_hWnd, ACM_STOP, 0, 0L);
7256 }
7257
7258 BOOL Close()
7259 {
7260 ATLASSERT(::IsWindow(m_hWnd));
7261 return (BOOL)::SendMessage(m_hWnd, ACM_OPEN, 0, 0L);
7262 }
7263
7264 BOOL Seek(UINT nTo)
7265 {
7266 ATLASSERT(::IsWindow(m_hWnd));
7267 return (BOOL)::SendMessage(m_hWnd, ACM_PLAY, 0, MAKELPARAM(nTo, nTo));
7268 }
7269
7270 // Vista only
7271 BOOL IsPlaying() const
7272 {
7273 #ifndef ACM_ISPLAYING
7274 const UINT ACM_ISPLAYING = (WM_USER+104);
7275 #endif
7276 ATLASSERT(::IsWindow(m_hWnd));
7277 return (BOOL)::SendMessage(m_hWnd, ACM_ISPLAYING, 0, 0L);
7278 }
7279 };
7280
7281 typedef CAnimateCtrlT<ATL::CWindow> CAnimateCtrl;
7282
7283 #endif // !_WIN32_WCE
7284
7285
7286 ///////////////////////////////////////////////////////////////////////////////
7287 // CRichEditCtrl
7288
7289 #ifndef _WIN32_WCE
7290
7291 #if defined(_UNICODE) && (_RICHEDIT_VER == 0x0100)
7292 #undef RICHEDIT_CLASS
7293 #define RICHEDIT_CLASS L"RICHEDIT"
7294 #endif
7295
7296 #if !defined(_UNICODE) && (_RICHEDIT_VER >= 0x0500)
7297 #undef MSFTEDIT_CLASS
7298 #define MSFTEDIT_CLASS "RICHEDIT50W"
7299 #endif
7300
7301 template <class TBase>
7302 class CRichEditCtrlT : public TBase
7303 {
7304 public:
7305 // Constructors
7306 CRichEditCtrlT(HWND hWnd = NULL) : TBase(hWnd)
7307 { }
7308
7309 CRichEditCtrlT< TBase >& operator =(HWND hWnd)
7310 {
7311 m_hWnd = hWnd;
7312 return *this;
7313 }
7314
7315 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
7316 DWORD dwStyle = 0, DWORD dwExStyle = 0,
7317 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
7318 {
7319 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
7320 }
7321
7322 // Attributes
7323 static LPCTSTR GetWndClassName()
7324 {
7325 #if (_RICHEDIT_VER >= 0x0500)
7326 return MSFTEDIT_CLASS;
7327 #else
7328 return RICHEDIT_CLASS;
7329 #endif
7330 }
7331
7332 static LPCTSTR GetLibraryName()
7333 {
7334 #if (_RICHEDIT_VER >= 0x0500)
7335 return _T("MSFTEDIT.DLL");
7336 #elif (_RICHEDIT_VER >= 0x0200)
7337 return _T("RICHED20.DLL");
7338 #else
7339 return _T("RICHED32.DLL");
7340 #endif
7341 }
7342
7343 int GetLineCount() const
7344 {
7345 ATLASSERT(::IsWindow(m_hWnd));
7346 return (int)::SendMessage(m_hWnd, EM_GETLINECOUNT, 0, 0L);
7347 }
7348
7349 BOOL GetModify() const
7350 {
7351 ATLASSERT(::IsWindow(m_hWnd));
7352 return (BOOL)::SendMessage(m_hWnd, EM_GETMODIFY, 0, 0L);
7353 }
7354
7355 void SetModify(BOOL bModified = TRUE)
7356 {
7357 ATLASSERT(::IsWindow(m_hWnd));
7358 ::SendMessage(m_hWnd, EM_SETMODIFY, bModified, 0L);
7359 }
7360
7361 void GetRect(LPRECT lpRect) const
7362 {
7363 ATLASSERT(::IsWindow(m_hWnd));
7364 ::SendMessage(m_hWnd, EM_GETRECT, 0, (LPARAM)lpRect);
7365 }
7366
7367 DWORD GetOptions() const
7368 {
7369 ATLASSERT(::IsWindow(m_hWnd));
7370 return (DWORD)::SendMessage(m_hWnd, EM_GETOPTIONS, 0, 0L);
7371 }
7372
7373 DWORD SetOptions(WORD wOperation, DWORD dwOptions)
7374 {
7375 ATLASSERT(::IsWindow(m_hWnd));
7376 return (DWORD)::SendMessage(m_hWnd, EM_SETOPTIONS, wOperation, dwOptions);
7377 }
7378
7379 // NOTE: first word in lpszBuffer must contain the size of the buffer!
7380 int GetLine(int nIndex, LPTSTR lpszBuffer) const
7381 {
7382 ATLASSERT(::IsWindow(m_hWnd));
7383 return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer);
7384 }
7385
7386 int GetLine(int nIndex, LPTSTR lpszBuffer, int nMaxLength) const
7387 {
7388 ATLASSERT(::IsWindow(m_hWnd));
7389 *(LPWORD)lpszBuffer = (WORD)nMaxLength;
7390 return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer);
7391 }
7392
7393 BOOL CanUndo() const
7394 {
7395 ATLASSERT(::IsWindow(m_hWnd));
7396 return (BOOL)::SendMessage(m_hWnd, EM_CANUNDO, 0, 0L);
7397 }
7398
7399 BOOL CanPaste(UINT nFormat = 0) const
7400 {
7401 ATLASSERT(::IsWindow(m_hWnd));
7402 return (BOOL)::SendMessage(m_hWnd, EM_CANPASTE, nFormat, 0L);
7403 }
7404
7405 void GetSel(LONG& nStartChar, LONG& nEndChar) const
7406 {
7407 ATLASSERT(::IsWindow(m_hWnd));
7408 CHARRANGE cr = { 0, 0 };
7409 ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr);
7410 nStartChar = cr.cpMin;
7411 nEndChar = cr.cpMax;
7412 }
7413
7414 void GetSel(CHARRANGE &cr) const
7415 {
7416 ATLASSERT(::IsWindow(m_hWnd));
7417 ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr);
7418 }
7419
7420 int SetSel(LONG nStartChar, LONG nEndChar)
7421 {
7422 ATLASSERT(::IsWindow(m_hWnd));
7423 CHARRANGE cr = { nStartChar, nEndChar };
7424 return (int)::SendMessage(m_hWnd, EM_EXSETSEL, 0, (LPARAM)&cr);
7425 }
7426
7427 int SetSel(CHARRANGE &cr)
7428 {
7429 ATLASSERT(::IsWindow(m_hWnd));
7430 return (int)::SendMessage(m_hWnd, EM_EXSETSEL, 0, (LPARAM)&cr);
7431 }
7432
7433 int SetSelAll()
7434 {
7435 return SetSel(0, -1);
7436 }
7437
7438 int SetSelNone()
7439 {
7440 return SetSel(-1, 0);
7441 }
7442
7443 DWORD GetDefaultCharFormat(CHARFORMAT& cf) const
7444 {
7445 ATLASSERT(::IsWindow(m_hWnd));
7446 cf.cbSize = sizeof(CHARFORMAT);
7447 return (DWORD)::SendMessage(m_hWnd, EM_GETCHARFORMAT, 0, (LPARAM)&cf);
7448 }
7449
7450 DWORD GetSelectionCharFormat(CHARFORMAT& cf) const
7451 {
7452 ATLASSERT(::IsWindow(m_hWnd));
7453 cf.cbSize = sizeof(CHARFORMAT);
7454 return (DWORD)::SendMessage(m_hWnd, EM_GETCHARFORMAT, 1, (LPARAM)&cf);
7455 }
7456
7457 DWORD GetEventMask() const
7458 {
7459 ATLASSERT(::IsWindow(m_hWnd));
7460 return (DWORD)::SendMessage(m_hWnd, EM_GETEVENTMASK, 0, 0L);
7461 }
7462
7463 LONG GetLimitText() const
7464 {
7465 ATLASSERT(::IsWindow(m_hWnd));
7466 return (LONG)::SendMessage(m_hWnd, EM_GETLIMITTEXT, 0, 0L);
7467 }
7468
7469 DWORD GetParaFormat(PARAFORMAT& pf) const
7470 {
7471 ATLASSERT(::IsWindow(m_hWnd));
7472 pf.cbSize = sizeof(PARAFORMAT);
7473 return (DWORD)::SendMessage(m_hWnd, EM_GETPARAFORMAT, 0, (LPARAM)&pf);
7474 }
7475
7476 #if (_RICHEDIT_VER >= 0x0200)
7477 LONG GetSelText(LPTSTR lpstrBuff) const
7478 {
7479 ATLASSERT(::IsWindow(m_hWnd));
7480 return (LONG)::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrBuff);
7481 }
7482 #else // !(_RICHEDIT_VER >= 0x0200)
7483 // RichEdit 1.0 EM_GETSELTEXT is ANSI only
7484 LONG GetSelText(LPSTR lpstrBuff) const
7485 {
7486 ATLASSERT(::IsWindow(m_hWnd));
7487 return (LONG)::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrBuff);
7488 }
7489 #endif // !(_RICHEDIT_VER >= 0x0200)
7490
7491 #ifndef _ATL_NO_COM
7492 BOOL GetSelTextBSTR(BSTR& bstrText) const
7493 {
7494 USES_CONVERSION;
7495 ATLASSERT(::IsWindow(m_hWnd));
7496 ATLASSERT(bstrText == NULL);
7497
7498 CHARRANGE cr = { 0, 0 };
7499 ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr);
7500
7501 #if (_RICHEDIT_VER >= 0x0200)
7502 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
7503 LPTSTR lpstrText = buff.Allocate(cr.cpMax - cr.cpMin + 1);
7504 if(lpstrText == NULL)
7505 return FALSE;
7506 if(::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrText) == 0)
7507 return FALSE;
7508
7509 bstrText = ::SysAllocString(T2W(lpstrText));
7510 #else // !(_RICHEDIT_VER >= 0x0200)
7511 CTempBuffer<char, _WTL_STACK_ALLOC_THRESHOLD> buff;
7512 LPSTR lpstrText = buff.Allocate(cr.cpMax - cr.cpMin + 1);
7513 if(lpstrText == NULL)
7514 return FALSE;
7515 if(::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrText) == 0)
7516 return FALSE;
7517
7518 bstrText = ::SysAllocString(A2W(lpstrText));
7519 #endif // !(_RICHEDIT_VER >= 0x0200)
7520
7521 return (bstrText != NULL) ? TRUE : FALSE;
7522 }
7523 #endif // !_ATL_NO_COM
7524
7525 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
7526 LONG GetSelText(_CSTRING_NS::CString& strText) const
7527 {
7528 ATLASSERT(::IsWindow(m_hWnd));
7529
7530 CHARRANGE cr = { 0, 0 };
7531 ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr);
7532
7533 #if (_RICHEDIT_VER >= 0x0200)
7534 LONG lLen = 0;
7535 LPTSTR lpstrText = strText.GetBufferSetLength(cr.cpMax - cr.cpMin);
7536 if(lpstrText != NULL)
7537 {
7538 lLen = (LONG)::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrText);
7539 strText.ReleaseBuffer();
7540 }
7541 #else // !(_RICHEDIT_VER >= 0x0200)
7542 CTempBuffer<char, _WTL_STACK_ALLOC_THRESHOLD> buff;
7543 LPSTR lpstrText = buff.Allocate(cr.cpMax - cr.cpMin + 1);
7544 if(lpstrText == NULL)
7545 return 0;
7546 LONG lLen = (LONG)::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrText);
7547 if(lLen == 0)
7548 return 0;
7549
7550 USES_CONVERSION;
7551 strText = A2T(lpstrText);
7552 #endif // !(_RICHEDIT_VER >= 0x0200)
7553
7554 return lLen;
7555 }
7556 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
7557
7558 WORD GetSelectionType() const
7559 {
7560 ATLASSERT(::IsWindow(m_hWnd));
7561 return (WORD)::SendMessage(m_hWnd, EM_SELECTIONTYPE, 0, 0L);
7562 }
7563
7564 COLORREF SetBackgroundColor(COLORREF cr)
7565 {
7566 ATLASSERT(::IsWindow(m_hWnd));
7567 return (COLORREF)::SendMessage(m_hWnd, EM_SETBKGNDCOLOR, 0, cr);
7568 }
7569
7570 COLORREF SetBackgroundColor() // sets to system background
7571 {
7572 ATLASSERT(::IsWindow(m_hWnd));
7573 return (COLORREF)::SendMessage(m_hWnd, EM_SETBKGNDCOLOR, 1, 0);
7574 }
7575
7576 BOOL SetCharFormat(CHARFORMAT& cf, WORD wFlags)
7577 {
7578 ATLASSERT(::IsWindow(m_hWnd));
7579 cf.cbSize = sizeof(CHARFORMAT);
7580 return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, (WPARAM)wFlags, (LPARAM)&cf);
7581 }
7582
7583 BOOL SetDefaultCharFormat(CHARFORMAT& cf)
7584 {
7585 ATLASSERT(::IsWindow(m_hWnd));
7586 cf.cbSize = sizeof(CHARFORMAT);
7587 return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, 0, (LPARAM)&cf);
7588 }
7589
7590 BOOL SetSelectionCharFormat(CHARFORMAT& cf)
7591 {
7592 ATLASSERT(::IsWindow(m_hWnd));
7593 cf.cbSize = sizeof(CHARFORMAT);
7594 return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
7595 }
7596
7597 BOOL SetWordCharFormat(CHARFORMAT& cf)
7598 {
7599 ATLASSERT(::IsWindow(m_hWnd));
7600 cf.cbSize = sizeof(CHARFORMAT);
7601 return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_SELECTION | SCF_WORD, (LPARAM)&cf);
7602 }
7603
7604 DWORD SetEventMask(DWORD dwEventMask)
7605 {
7606 ATLASSERT(::IsWindow(m_hWnd));
7607 return (DWORD)::SendMessage(m_hWnd, EM_SETEVENTMASK, 0, dwEventMask);
7608 }
7609
7610 BOOL SetParaFormat(PARAFORMAT& pf)
7611 {
7612 ATLASSERT(::IsWindow(m_hWnd));
7613 pf.cbSize = sizeof(PARAFORMAT);
7614 return (BOOL)::SendMessage(m_hWnd, EM_SETPARAFORMAT, 0, (LPARAM)&pf);
7615 }
7616
7617 BOOL SetTargetDevice(HDC hDC, int cxLineWidth)
7618 {
7619 ATLASSERT(::IsWindow(m_hWnd));
7620 return (BOOL)::SendMessage(m_hWnd, EM_SETTARGETDEVICE, (WPARAM)hDC, cxLineWidth);
7621 }
7622
7623 int GetTextLength() const
7624 {
7625 ATLASSERT(::IsWindow(m_hWnd));
7626 return (int)::SendMessage(m_hWnd, WM_GETTEXTLENGTH, 0, 0L);
7627 }
7628
7629 BOOL SetReadOnly(BOOL bReadOnly = TRUE)
7630 {
7631 ATLASSERT(::IsWindow(m_hWnd));
7632 return (BOOL)::SendMessage(m_hWnd, EM_SETREADONLY, bReadOnly, 0L);
7633 }
7634
7635 int GetFirstVisibleLine() const
7636 {
7637 ATLASSERT(::IsWindow(m_hWnd));
7638 return (int)::SendMessage(m_hWnd, EM_GETFIRSTVISIBLELINE, 0, 0L);
7639 }
7640
7641 int GetTextRange(TEXTRANGE* pTextRange) const
7642 {
7643 ATLASSERT(::IsWindow(m_hWnd));
7644 return (int)::SendMessage(m_hWnd, EM_GETTEXTRANGE, 0, (LPARAM)pTextRange);
7645 }
7646
7647 #if (_RICHEDIT_VER < 0x0200)
7648 EDITWORDBREAKPROCEX GetWordBreakProcEx() const
7649 {
7650 ATLASSERT(::IsWindow(m_hWnd));
7651 return (EDITWORDBREAKPROCEX)::SendMessage(m_hWnd, EM_GETWORDBREAKPROCEX, 0, 0L);
7652 }
7653
7654 EDITWORDBREAKPROCEX SetWordBreakProcEx(EDITWORDBREAKPROCEX pfnEditWordBreakProcEx)
7655 {
7656 ATLASSERT(::IsWindow(m_hWnd));
7657 return (EDITWORDBREAKPROCEX)::SendMessage(m_hWnd, EM_SETWORDBREAKPROCEX, 0, (LPARAM)pfnEditWordBreakProcEx);
7658 }
7659 #endif // (_RICHEDIT_VER < 0x0200)
7660
7661 #if (_RICHEDIT_VER >= 0x0200)
7662 int GetTextRange(LONG nStartChar, LONG nEndChar, LPTSTR lpstrText) const
7663 {
7664 ATLASSERT(::IsWindow(m_hWnd));
7665 TEXTRANGE tr = { 0 };
7666 tr.chrg.cpMin = nStartChar;
7667 tr.chrg.cpMax = nEndChar;
7668 tr.lpstrText = lpstrText;
7669 return (int)::SendMessage(m_hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
7670 }
7671 #else // !(_RICHEDIT_VER >= 0x0200)
7672 int GetTextRange(LONG nStartChar, LONG nEndChar, LPSTR lpstrText) const
7673 {
7674 ATLASSERT(::IsWindow(m_hWnd));
7675 TEXTRANGE tr = { 0 };
7676 tr.chrg.cpMin = nStartChar;
7677 tr.chrg.cpMax = nEndChar;
7678 tr.lpstrText = lpstrText;
7679 return (int)::SendMessage(m_hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
7680 }
7681 #endif // !(_RICHEDIT_VER >= 0x0200)
7682
7683 #if (_RICHEDIT_VER >= 0x0200)
7684 DWORD GetDefaultCharFormat(CHARFORMAT2& cf) const
7685 {
7686 ATLASSERT(::IsWindow(m_hWnd));
7687 cf.cbSize = sizeof(CHARFORMAT2);
7688 return (DWORD)::SendMessage(m_hWnd, EM_GETCHARFORMAT, 0, (LPARAM)&cf);
7689 }
7690
7691 BOOL SetCharFormat(CHARFORMAT2& cf, WORD wFlags)
7692 {
7693 ATLASSERT(::IsWindow(m_hWnd));
7694 cf.cbSize = sizeof(CHARFORMAT2);
7695 return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, (WPARAM)wFlags, (LPARAM)&cf);
7696 }
7697
7698 BOOL SetDefaultCharFormat(CHARFORMAT2& cf)
7699 {
7700 ATLASSERT(::IsWindow(m_hWnd));
7701 cf.cbSize = sizeof(CHARFORMAT2);
7702 return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, 0, (LPARAM)&cf);
7703 }
7704
7705 DWORD GetSelectionCharFormat(CHARFORMAT2& cf) const
7706 {
7707 ATLASSERT(::IsWindow(m_hWnd));
7708 cf.cbSize = sizeof(CHARFORMAT2);
7709 return (DWORD)::SendMessage(m_hWnd, EM_GETCHARFORMAT, 1, (LPARAM)&cf);
7710 }
7711
7712 BOOL SetSelectionCharFormat(CHARFORMAT2& cf)
7713 {
7714 ATLASSERT(::IsWindow(m_hWnd));
7715 cf.cbSize = sizeof(CHARFORMAT2);
7716 return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
7717 }
7718
7719 BOOL SetWordCharFormat(CHARFORMAT2& cf)
7720 {
7721 ATLASSERT(::IsWindow(m_hWnd));
7722 cf.cbSize = sizeof(CHARFORMAT2);
7723 return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_SELECTION | SCF_WORD, (LPARAM)&cf);
7724 }
7725
7726 DWORD GetParaFormat(PARAFORMAT2& pf) const
7727 {
7728 ATLASSERT(::IsWindow(m_hWnd));
7729 pf.cbSize = sizeof(PARAFORMAT2);
7730 return (DWORD)::SendMessage(m_hWnd, EM_GETPARAFORMAT, 0, (LPARAM)&pf);
7731 }
7732
7733 BOOL SetParaFormat(PARAFORMAT2& pf)
7734 {
7735 ATLASSERT(::IsWindow(m_hWnd));
7736 pf.cbSize = sizeof(PARAFORMAT2);
7737 return (BOOL)::SendMessage(m_hWnd, EM_SETPARAFORMAT, 0, (LPARAM)&pf);
7738 }
7739
7740 TEXTMODE GetTextMode() const
7741 {
7742 ATLASSERT(::IsWindow(m_hWnd));
7743 return (TEXTMODE)::SendMessage(m_hWnd, EM_GETTEXTMODE, 0, 0L);
7744 }
7745
7746 BOOL SetTextMode(TEXTMODE enumTextMode)
7747 {
7748 ATLASSERT(::IsWindow(m_hWnd));
7749 return !(BOOL)::SendMessage(m_hWnd, EM_SETTEXTMODE, enumTextMode, 0L);
7750 }
7751
7752 UNDONAMEID GetUndoName() const
7753 {
7754 ATLASSERT(::IsWindow(m_hWnd));
7755 return (UNDONAMEID)::SendMessage(m_hWnd, EM_GETUNDONAME, 0, 0L);
7756 }
7757
7758 UNDONAMEID GetRedoName() const
7759 {
7760 ATLASSERT(::IsWindow(m_hWnd));
7761 return (UNDONAMEID)::SendMessage(m_hWnd, EM_GETREDONAME, 0, 0L);
7762 }
7763
7764 BOOL CanRedo() const
7765 {
7766 ATLASSERT(::IsWindow(m_hWnd));
7767 return (BOOL)::SendMessage(m_hWnd, EM_CANREDO, 0, 0L);
7768 }
7769
7770 BOOL GetAutoURLDetect() const
7771 {
7772 ATLASSERT(::IsWindow(m_hWnd));
7773 return (BOOL)::SendMessage(m_hWnd, EM_GETAUTOURLDETECT, 0, 0L);
7774 }
7775
7776 BOOL SetAutoURLDetect(BOOL bAutoDetect = TRUE)
7777 {
7778 ATLASSERT(::IsWindow(m_hWnd));
7779 return !(BOOL)::SendMessage(m_hWnd, EM_AUTOURLDETECT, bAutoDetect, 0L);
7780 }
7781
7782 // this method is deprecated, please use SetAutoURLDetect
7783 BOOL EnableAutoURLDetect(BOOL bEnable = TRUE) { return SetAutoURLDetect(bEnable); }
7784
7785 UINT SetUndoLimit(UINT uUndoLimit)
7786 {
7787 ATLASSERT(::IsWindow(m_hWnd));
7788 return (UINT)::SendMessage(m_hWnd, EM_SETUNDOLIMIT, uUndoLimit, 0L);
7789 }
7790
7791 void SetPalette(HPALETTE hPalette)
7792 {
7793 ATLASSERT(::IsWindow(m_hWnd));
7794 ::SendMessage(m_hWnd, EM_SETPALETTE, (WPARAM)hPalette, 0L);
7795 }
7796
7797 int GetTextEx(GETTEXTEX* pGetTextEx, LPTSTR lpstrText) const
7798 {
7799 ATLASSERT(::IsWindow(m_hWnd));
7800 return (int)::SendMessage(m_hWnd, EM_GETTEXTEX, (WPARAM)pGetTextEx, (LPARAM)lpstrText);
7801 }
7802
7803 int GetTextEx(LPTSTR lpstrText, int nTextLen, DWORD dwFlags = GT_DEFAULT, UINT uCodePage = CP_ACP, LPCSTR lpDefaultChar = NULL, LPBOOL lpUsedDefChar = NULL) const
7804 {
7805 ATLASSERT(::IsWindow(m_hWnd));
7806 GETTEXTEX gte = { 0 };
7807 gte.cb = nTextLen * sizeof(TCHAR);
7808 gte.codepage = uCodePage;
7809 gte.flags = dwFlags;
7810 gte.lpDefaultChar = lpDefaultChar;
7811 gte.lpUsedDefChar = lpUsedDefChar;
7812 return (int)::SendMessage(m_hWnd, EM_GETTEXTEX, (WPARAM)&gte, (LPARAM)lpstrText);
7813 }
7814
7815 int GetTextLengthEx(GETTEXTLENGTHEX* pGetTextLengthEx) const
7816 {
7817 ATLASSERT(::IsWindow(m_hWnd));
7818 return (int)::SendMessage(m_hWnd, EM_GETTEXTLENGTHEX, (WPARAM)pGetTextLengthEx, 0L);
7819 }
7820
7821 int GetTextLengthEx(DWORD dwFlags = GTL_DEFAULT, UINT uCodePage = CP_ACP) const
7822 {
7823 ATLASSERT(::IsWindow(m_hWnd));
7824 GETTEXTLENGTHEX gtle = { 0 };
7825 gtle.codepage = uCodePage;
7826 gtle.flags = dwFlags;
7827 return (int)::SendMessage(m_hWnd, EM_GETTEXTLENGTHEX, (WPARAM)&gtle, 0L);
7828 }
7829
7830 EDITWORDBREAKPROC GetWordBreakProc() const
7831 {
7832 ATLASSERT(::IsWindow(m_hWnd));
7833 return (EDITWORDBREAKPROC)::SendMessage(m_hWnd, EM_GETWORDBREAKPROC, 0, 0L);
7834 }
7835
7836 void SetWordBreakProc(EDITWORDBREAKPROC ewbprc)
7837 {
7838 ATLASSERT(::IsWindow(m_hWnd));
7839 ::SendMessage(m_hWnd, EM_SETWORDBREAKPROC, 0, (LPARAM)ewbprc);
7840 }
7841 #endif // (_RICHEDIT_VER >= 0x0200)
7842
7843 #if (_RICHEDIT_VER >= 0x0300)
7844 int SetTextEx(SETTEXTEX* pSetTextEx, LPCTSTR lpstrText)
7845 {
7846 ATLASSERT(::IsWindow(m_hWnd));
7847 return (int)::SendMessage(m_hWnd, EM_SETTEXTEX, (WPARAM)pSetTextEx, (LPARAM)lpstrText);
7848 }
7849
7850 int SetTextEx(LPCTSTR lpstrText, DWORD dwFlags = ST_DEFAULT, UINT uCodePage = CP_ACP)
7851 {
7852 ATLASSERT(::IsWindow(m_hWnd));
7853 SETTEXTEX ste = { 0 };
7854 ste.flags = dwFlags;
7855 ste.codepage = uCodePage;
7856 return (int)::SendMessage(m_hWnd, EM_SETTEXTEX, (WPARAM)&ste, (LPARAM)lpstrText);
7857 }
7858
7859 int GetEditStyle() const
7860 {
7861 ATLASSERT(::IsWindow(m_hWnd));
7862 return (int)::SendMessage(m_hWnd, EM_GETEDITSTYLE, 0, 0L);
7863 }
7864
7865 int SetEditStyle(int nStyle, int nMask = -1)
7866 {
7867 ATLASSERT(::IsWindow(m_hWnd));
7868 if(nMask == -1)
7869 nMask = nStyle; // set everything specified
7870 return (int)::SendMessage(m_hWnd, EM_SETEDITSTYLE, nStyle, nMask);
7871 }
7872
7873 BOOL SetFontSize(int nFontSizeDelta)
7874 {
7875 ATLASSERT(::IsWindow(m_hWnd));
7876 ATLASSERT(nFontSizeDelta >= -1637 && nFontSizeDelta <= 1638);
7877 return (BOOL)::SendMessage(m_hWnd, EM_SETFONTSIZE, nFontSizeDelta, 0L);
7878 }
7879
7880 void GetScrollPos(LPPOINT lpPoint) const
7881 {
7882 ATLASSERT(::IsWindow(m_hWnd));
7883 ATLASSERT(lpPoint != NULL);
7884 ::SendMessage(m_hWnd, EM_GETSCROLLPOS, 0, (LPARAM)lpPoint);
7885 }
7886
7887 void SetScrollPos(LPPOINT lpPoint)
7888 {
7889 ATLASSERT(::IsWindow(m_hWnd));
7890 ATLASSERT(lpPoint != NULL);
7891 ::SendMessage(m_hWnd, EM_SETSCROLLPOS, 0, (LPARAM)lpPoint);
7892 }
7893
7894 BOOL GetZoom(int& nNum, int& nDen) const
7895 {
7896 ATLASSERT(::IsWindow(m_hWnd));
7897 return (BOOL)::SendMessage(m_hWnd, EM_GETZOOM, (WPARAM)&nNum, (LPARAM)&nDen);
7898 }
7899
7900 BOOL SetZoom(int nNum, int nDen)
7901 {
7902 ATLASSERT(::IsWindow(m_hWnd));
7903 ATLASSERT(nNum >= 0 && nNum <= 64);
7904 ATLASSERT(nDen >= 0 && nDen <= 64);
7905 return (BOOL)::SendMessage(m_hWnd, EM_SETZOOM, nNum, nDen);
7906 }
7907
7908 BOOL SetZoomOff()
7909 {
7910 ATLASSERT(::IsWindow(m_hWnd));
7911 return (BOOL)::SendMessage(m_hWnd, EM_SETZOOM, 0, 0L);
7912 }
7913
7914 void SetMargins(UINT nLeft, UINT nRight, WORD wFlags = EC_LEFTMARGIN | EC_RIGHTMARGIN)
7915 {
7916 ATLASSERT(::IsWindow(m_hWnd));
7917 ::SendMessage(m_hWnd, EM_SETMARGINS, wFlags, MAKELONG(nLeft, nRight));
7918 }
7919 #endif // (_RICHEDIT_VER >= 0x0300)
7920
7921 // Operations
7922 void LimitText(LONG nChars = 0)
7923 {
7924 ATLASSERT(::IsWindow(m_hWnd));
7925 ::SendMessage(m_hWnd, EM_EXLIMITTEXT, 0, nChars);
7926 }
7927
7928 int LineFromChar(LONG nIndex) const
7929 {
7930 ATLASSERT(::IsWindow(m_hWnd));
7931 return (int)::SendMessage(m_hWnd, EM_EXLINEFROMCHAR, 0, nIndex);
7932 }
7933
7934 POINT PosFromChar(LONG nChar) const
7935 {
7936 ATLASSERT(::IsWindow(m_hWnd));
7937 POINT point = { 0, 0 };
7938 ::SendMessage(m_hWnd, EM_POSFROMCHAR, (WPARAM)&point, nChar);
7939 return point;
7940 }
7941
7942 int CharFromPos(POINT pt) const
7943 {
7944 ATLASSERT(::IsWindow(m_hWnd));
7945 POINTL ptl = { pt.x, pt.y };
7946 return (int)::SendMessage(m_hWnd, EM_CHARFROMPOS, 0, (LPARAM)&ptl);
7947 }
7948
7949 void EmptyUndoBuffer()
7950 {
7951 ATLASSERT(::IsWindow(m_hWnd));
7952 ::SendMessage(m_hWnd, EM_EMPTYUNDOBUFFER, 0, 0L);
7953 }
7954
7955 int LineIndex(int nLine = -1) const
7956 {
7957 ATLASSERT(::IsWindow(m_hWnd));
7958 return (int)::SendMessage(m_hWnd, EM_LINEINDEX, nLine, 0L);
7959 }
7960
7961 int LineLength(int nLine = -1) const
7962 {
7963 ATLASSERT(::IsWindow(m_hWnd));
7964 return (int)::SendMessage(m_hWnd, EM_LINELENGTH, nLine, 0L);
7965 }
7966
7967 BOOL LineScroll(int nLines)
7968 {
7969 ATLASSERT(::IsWindow(m_hWnd));
7970 return (BOOL)::SendMessage(m_hWnd, EM_LINESCROLL, 0, nLines);
7971 }
7972
7973 void ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo = FALSE)
7974 {
7975 ATLASSERT(::IsWindow(m_hWnd));
7976 ::SendMessage(m_hWnd, EM_REPLACESEL, (WPARAM) bCanUndo, (LPARAM)lpszNewText);
7977 }
7978
7979 void SetRect(LPCRECT lpRect)
7980 {
7981 ATLASSERT(::IsWindow(m_hWnd));
7982 ::SendMessage(m_hWnd, EM_SETRECT, 0, (LPARAM)lpRect);
7983 }
7984
7985 BOOL DisplayBand(LPRECT pDisplayRect)
7986 {
7987 ATLASSERT(::IsWindow(m_hWnd));
7988 return (BOOL)::SendMessage(m_hWnd, EM_DISPLAYBAND, 0, (LPARAM)pDisplayRect);
7989 }
7990
7991 LONG FindText(DWORD dwFlags, FINDTEXT& ft) const
7992 {
7993 ATLASSERT(::IsWindow(m_hWnd));
7994 #if (_RICHEDIT_VER >= 0x0200) && defined(_UNICODE)
7995 return (LONG)::SendMessage(m_hWnd, EM_FINDTEXTW, dwFlags, (LPARAM)&ft);
7996 #else
7997 return (LONG)::SendMessage(m_hWnd, EM_FINDTEXT, dwFlags, (LPARAM)&ft);
7998 #endif
7999 }
8000
8001 LONG FindText(DWORD dwFlags, FINDTEXTEX& ft) const
8002 {
8003 ATLASSERT(::IsWindow(m_hWnd));
8004 #if (_RICHEDIT_VER >= 0x0200) && defined(_UNICODE)
8005 return (LONG)::SendMessage(m_hWnd, EM_FINDTEXTEXW, dwFlags, (LPARAM)&ft);
8006 #else
8007 return (LONG)::SendMessage(m_hWnd, EM_FINDTEXTEX, dwFlags, (LPARAM)&ft);
8008 #endif
8009 }
8010
8011 LONG FormatRange(FORMATRANGE& fr, BOOL bDisplay = TRUE)
8012 {
8013 ATLASSERT(::IsWindow(m_hWnd));
8014 return (LONG)::SendMessage(m_hWnd, EM_FORMATRANGE, bDisplay, (LPARAM)&fr);
8015 }
8016
8017 LONG FormatRange(FORMATRANGE* pFormatRange, BOOL bDisplay = TRUE)
8018 {
8019 ATLASSERT(::IsWindow(m_hWnd));
8020 return (LONG)::SendMessage(m_hWnd, EM_FORMATRANGE, bDisplay, (LPARAM)pFormatRange);
8021 }
8022
8023 void HideSelection(BOOL bHide = TRUE, BOOL bChangeStyle = FALSE)
8024 {
8025 ATLASSERT(::IsWindow(m_hWnd));
8026 ::SendMessage(m_hWnd, EM_HIDESELECTION, bHide, bChangeStyle);
8027 }
8028
8029 void PasteSpecial(UINT uClipFormat, DWORD dwAspect = 0, HMETAFILE hMF = 0)
8030 {
8031 ATLASSERT(::IsWindow(m_hWnd));
8032 REPASTESPECIAL reps = { dwAspect, (DWORD_PTR)hMF };
8033 ::SendMessage(m_hWnd, EM_PASTESPECIAL, uClipFormat, (LPARAM)&reps);
8034 }
8035
8036 void RequestResize()
8037 {
8038 ATLASSERT(::IsWindow(m_hWnd));
8039 ::SendMessage(m_hWnd, EM_REQUESTRESIZE, 0, 0L);
8040 }
8041
8042 LONG StreamIn(UINT uFormat, EDITSTREAM& es)
8043 {
8044 ATLASSERT(::IsWindow(m_hWnd));
8045 return (LONG)::SendMessage(m_hWnd, EM_STREAMIN, uFormat, (LPARAM)&es);
8046 }
8047
8048 LONG StreamOut(UINT uFormat, EDITSTREAM& es)
8049 {
8050 ATLASSERT(::IsWindow(m_hWnd));
8051 return (LONG)::SendMessage(m_hWnd, EM_STREAMOUT, uFormat, (LPARAM)&es);
8052 }
8053
8054 DWORD FindWordBreak(int nCode, LONG nStartChar)
8055 {
8056 ATLASSERT(::IsWindow(m_hWnd));
8057 return (DWORD)::SendMessage(m_hWnd, EM_FINDWORDBREAK, nCode, nStartChar);
8058 }
8059
8060 // Additional operations
8061 void ScrollCaret()
8062 {
8063 ATLASSERT(::IsWindow(m_hWnd));
8064 ::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L);
8065 }
8066
8067 int InsertText(long nInsertAfterChar, LPCTSTR lpstrText, BOOL bCanUndo = FALSE)
8068 {
8069 int nRet = SetSel(nInsertAfterChar, nInsertAfterChar);
8070 ReplaceSel(lpstrText, bCanUndo);
8071 return nRet;
8072 }
8073
8074 int AppendText(LPCTSTR lpstrText, BOOL bCanUndo = FALSE)
8075 {
8076 return InsertText(GetWindowTextLength(), lpstrText, bCanUndo);
8077 }
8078
8079 // Clipboard operations
8080 BOOL Undo()
8081 {
8082 ATLASSERT(::IsWindow(m_hWnd));
8083 return (BOOL)::SendMessage(m_hWnd, EM_UNDO, 0, 0L);
8084 }
8085
8086 void Clear()
8087 {
8088 ATLASSERT(::IsWindow(m_hWnd));
8089 ::SendMessage(m_hWnd, WM_CLEAR, 0, 0L);
8090 }
8091
8092 void Copy()
8093 {
8094 ATLASSERT(::IsWindow(m_hWnd));
8095 ::SendMessage(m_hWnd, WM_COPY, 0, 0L);
8096 }
8097
8098 void Cut()
8099 {
8100 ATLASSERT(::IsWindow(m_hWnd));
8101 ::SendMessage(m_hWnd, WM_CUT, 0, 0L);
8102 }
8103
8104 void Paste()
8105 {
8106 ATLASSERT(::IsWindow(m_hWnd));
8107 ::SendMessage(m_hWnd, WM_PASTE, 0, 0L);
8108 }
8109
8110 // OLE support
8111 IRichEditOle* GetOleInterface() const
8112 {
8113 ATLASSERT(::IsWindow(m_hWnd));
8114 IRichEditOle *pRichEditOle = NULL;
8115 ::SendMessage(m_hWnd, EM_GETOLEINTERFACE, 0, (LPARAM)&pRichEditOle);
8116 return pRichEditOle;
8117 }
8118
8119 BOOL SetOleCallback(IRichEditOleCallback* pCallback)
8120 {
8121 ATLASSERT(::IsWindow(m_hWnd));
8122 return (BOOL)::SendMessage(m_hWnd, EM_SETOLECALLBACK, 0, (LPARAM)pCallback);
8123 }
8124
8125 #if (_RICHEDIT_VER >= 0x0200)
8126 BOOL Redo()
8127 {
8128 ATLASSERT(::IsWindow(m_hWnd));
8129 return (BOOL)::SendMessage(m_hWnd, EM_REDO, 0, 0L);
8130 }
8131
8132 void StopGroupTyping()
8133 {
8134 ATLASSERT(::IsWindow(m_hWnd));
8135 ::SendMessage(m_hWnd, EM_STOPGROUPTYPING, 0, 0L);
8136 }
8137
8138 void ShowScrollBar(int nBarType, BOOL bVisible = TRUE)
8139 {
8140 ATLASSERT(::IsWindow(m_hWnd));
8141 ::SendMessage(m_hWnd, EM_SHOWSCROLLBAR, nBarType, bVisible);
8142 }
8143 #endif // (_RICHEDIT_VER >= 0x0200)
8144
8145 #if (_RICHEDIT_VER >= 0x0300)
8146 BOOL SetTabStops(int nTabStops, LPINT rgTabStops)
8147 {
8148 ATLASSERT(::IsWindow(m_hWnd));
8149 return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, nTabStops, (LPARAM)rgTabStops);
8150 }
8151
8152 BOOL SetTabStops()
8153 {
8154 ATLASSERT(::IsWindow(m_hWnd));
8155 return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 0, 0L);
8156 }
8157
8158 BOOL SetTabStops(const int& cxEachStop) // takes an 'int'
8159 {
8160 ATLASSERT(::IsWindow(m_hWnd));
8161 return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 1, (LPARAM)(LPINT)&cxEachStop);
8162 }
8163 #endif // (_RICHEDIT_VER >= 0x0300)
8164
8165 #if (_RICHEDIT_VER >= 0x0800)
8166 AutoCorrectProc GetAutoCorrectProc() const
8167 {
8168 ATLASSERT(::IsWindow(m_hWnd));
8169 return (AutoCorrectProc)::SendMessage(m_hWnd, EM_GETAUTOCORRECTPROC, 0, 0L);
8170 }
8171
8172 BOOL SetAutoCorrectProc(AutoCorrectProc pfn)
8173 {
8174 ATLASSERT(::IsWindow(m_hWnd));
8175 return (BOOL)::SendMessage(m_hWnd, EM_SETAUTOCORRECTPROC, (WPARAM)pfn, 0L);
8176 }
8177
8178 BOOL CallAutoCorrectProc(WCHAR ch)
8179 {
8180 ATLASSERT(::IsWindow(m_hWnd));
8181 return (BOOL)::SendMessage(m_hWnd, EM_CALLAUTOCORRECTPROC, (WPARAM)ch, 0L);
8182 }
8183
8184 DWORD GetEditStyleEx() const
8185 {
8186 ATLASSERT(::IsWindow(m_hWnd));
8187 return (DWORD)::SendMessage(m_hWnd, EM_GETEDITSTYLEEX, 0, 0L);
8188 }
8189
8190 DWORD SetEditStyleEx(DWORD dwStyleEx, DWORD dwMask)
8191 {
8192 ATLASSERT(::IsWindow(m_hWnd));
8193 return (DWORD)::SendMessage(m_hWnd, EM_SETEDITSTYLEEX, dwStyleEx, dwMask);
8194 }
8195
8196 DWORD GetStoryType(int nStoryIndex) const
8197 {
8198 ATLASSERT(::IsWindow(m_hWnd));
8199 return (DWORD)::SendMessage(m_hWnd, EM_GETSTORYTYPE, nStoryIndex, 0L);
8200 }
8201
8202 DWORD SetStoryType(int nStoryIndex, DWORD dwStoryType)
8203 {
8204 ATLASSERT(::IsWindow(m_hWnd));
8205 return (DWORD)::SendMessage(m_hWnd, EM_SETSTORYTYPE, nStoryIndex, dwStoryType);
8206 }
8207
8208 DWORD GetEllipsisMode() const
8209 {
8210 ATLASSERT(::IsWindow(m_hWnd));
8211
8212 DWORD dwMode = 0;
8213 BOOL bRet = (BOOL)::SendMessage(m_hWnd, EM_GETELLIPSISMODE, 0, (LPARAM)&dwMode);
8214 bRet; // avoid level 4 warning
8215 ATLASSERT(bRet != FALSE);
8216
8217 return dwMode;
8218 }
8219
8220 BOOL SetEllipsisMode(DWORD dwEllipsisMode)
8221 {
8222 ATLASSERT(::IsWindow(m_hWnd));
8223 return (BOOL)::SendMessage(m_hWnd, EM_SETELLIPSISMODE, 0, dwEllipsisMode);
8224 }
8225
8226 BOOL GetEllipsisState() const
8227 {
8228 ATLASSERT(::IsWindow(m_hWnd));
8229 return (BOOL)::SendMessage(m_hWnd, EM_GETELLIPSISSTATE, 0, 0L);
8230 }
8231
8232 BOOL GetTouchOptions(int nTouchOptions) const
8233 {
8234 ATLASSERT(::IsWindow(m_hWnd));
8235 return (BOOL)::SendMessage(m_hWnd, EM_GETTOUCHOPTIONS, nTouchOptions, 0L);
8236 }
8237
8238 void SetTouchOptions(int nTouchOptions, BOOL bEnable)
8239 {
8240 ATLASSERT(::IsWindow(m_hWnd));
8241 ::SendMessage(m_hWnd, EM_SETTOUCHOPTIONS, nTouchOptions, bEnable);
8242 }
8243
8244 HRESULT InsertTable(TABLEROWPARMS* pRowParams, TABLECELLPARMS* pCellParams)
8245 {
8246 ATLASSERT(::IsWindow(m_hWnd));
8247 return (HRESULT)::SendMessage(m_hWnd, EM_INSERTTABLE, (WPARAM)pRowParams, (LPARAM)pCellParams);
8248 }
8249
8250 HRESULT GetTableParams(TABLEROWPARMS* pRowParams, TABLECELLPARMS* pCellParams) const
8251 {
8252 ATLASSERT(::IsWindow(m_hWnd));
8253 return (HRESULT)::SendMessage(m_hWnd, EM_GETTABLEPARMS, (WPARAM)pRowParams, (LPARAM)pCellParams);
8254 }
8255
8256 HRESULT SetTableParams(TABLEROWPARMS* pRowParams, TABLECELLPARMS* pCellParams)
8257 {
8258 ATLASSERT(::IsWindow(m_hWnd));
8259 return (HRESULT)::SendMessage(m_hWnd, EM_SETTABLEPARMS, (WPARAM)pRowParams, (LPARAM)pCellParams);
8260 }
8261
8262 HRESULT InsertImage(RICHEDIT_IMAGE_PARAMETERS* pParams)
8263 {
8264 ATLASSERT(::IsWindow(m_hWnd));
8265 return (HRESULT)::SendMessage(m_hWnd, EM_INSERTIMAGE, 0, (LPARAM)pParams);
8266 }
8267
8268 BOOL SetUiaName(LPCTSTR lpstrName)
8269 {
8270 ATLASSERT(::IsWindow(m_hWnd));
8271 return (BOOL)::SendMessage(m_hWnd, EM_SETUIANAME, 0, (LPARAM)lpstrName);
8272 }
8273 #endif // (_RICHEDIT_VER >= 0x0800)
8274 };
8275
8276 typedef CRichEditCtrlT<ATL::CWindow> CRichEditCtrl;
8277
8278 #endif // !_WIN32_WCE
8279
8280
8281 ///////////////////////////////////////////////////////////////////////////////
8282 // CRichEditCommands - message handlers for standard EDIT commands
8283
8284 #ifndef _WIN32_WCE
8285
8286 // Chain to CRichEditCommands message map. Your class must also derive from CRichEditCtrl.
8287 // Example:
8288 // class CMyRichEdit : public CWindowImpl<CMyRichEdit, CRichEditCtrl>,
8289 // public CRichEditCommands<CMyRichEdit>
8290 // {
8291 // public:
8292 // BEGIN_MSG_MAP(CMyRichEdit)
8293 // // your handlers...
8294 // CHAIN_MSG_MAP_ALT(CRichEditCommands<CMyRichEdit>, 1)
8295 // END_MSG_MAP()
8296 // // other stuff...
8297 // };
8298
8299 template <class T>
8300 class CRichEditCommands : public CEditCommands< T >
8301 {
8302 public:
8303 BEGIN_MSG_MAP(CRichEditCommands< T >)
8304 ALT_MSG_MAP(1)
8305 COMMAND_ID_HANDLER(ID_EDIT_CLEAR, CEditCommands< T >::OnEditClear)
8306 COMMAND_ID_HANDLER(ID_EDIT_CLEAR_ALL, CEditCommands< T >::OnEditClearAll)
8307 COMMAND_ID_HANDLER(ID_EDIT_COPY, CEditCommands< T >::OnEditCopy)
8308 COMMAND_ID_HANDLER(ID_EDIT_CUT, CEditCommands< T >::OnEditCut)
8309 COMMAND_ID_HANDLER(ID_EDIT_PASTE, CEditCommands< T >::OnEditPaste)
8310 COMMAND_ID_HANDLER(ID_EDIT_SELECT_ALL, CEditCommands< T >::OnEditSelectAll)
8311 COMMAND_ID_HANDLER(ID_EDIT_UNDO, CEditCommands< T >::OnEditUndo)
8312 #if (_RICHEDIT_VER >= 0x0200)
8313 COMMAND_ID_HANDLER(ID_EDIT_REDO, OnEditRedo)
8314 #endif // (_RICHEDIT_VER >= 0x0200)
8315 END_MSG_MAP()
8316
8317 #if (_RICHEDIT_VER >= 0x0200)
8318 LRESULT OnEditRedo(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
8319 {
8320 T* pT = static_cast<T*>(this);
8321 pT->Redo();
8322 return 0;
8323 }
8324 #endif // (_RICHEDIT_VER >= 0x0200)
8325
8326 // State (update UI) helpers
8327 BOOL CanCut() const
8328 { return HasSelection(); }
8329
8330 BOOL CanCopy() const
8331 { return HasSelection(); }
8332
8333 BOOL CanClear() const
8334 { return HasSelection(); }
8335
8336 // Implementation
8337 BOOL HasSelection() const
8338 {
8339 const T* pT = static_cast<const T*>(this);
8340 return (pT->GetSelectionType() != SEL_EMPTY);
8341 }
8342 };
8343
8344 #endif // _WIN32_WCE
8345
8346
8347 ///////////////////////////////////////////////////////////////////////////////
8348 // CDragListBox
8349
8350 #ifndef _WIN32_WCE
8351
8352 template <class TBase>
8353 class CDragListBoxT : public CListBoxT< TBase >
8354 {
8355 public:
8356 // Constructors
8357 CDragListBoxT(HWND hWnd = NULL) : CListBoxT< TBase >(hWnd)
8358 { }
8359
8360 CDragListBoxT< TBase >& operator =(HWND hWnd)
8361 {
8362 m_hWnd = hWnd;
8363 return *this;
8364 }
8365
8366 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
8367 DWORD dwStyle = 0, DWORD dwExStyle = 0,
8368 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
8369 {
8370 HWND hWnd = TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
8371 if(hWnd != NULL)
8372 MakeDragList();
8373 return hWnd;
8374 }
8375
8376 // Operations
8377 BOOL MakeDragList()
8378 {
8379 ATLASSERT(::IsWindow(m_hWnd));
8380 ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) == 0);
8381 return ::MakeDragList(m_hWnd);
8382 }
8383
8384 int LBItemFromPt(POINT pt, BOOL bAutoScroll = TRUE)
8385 {
8386 ATLASSERT(::IsWindow(m_hWnd));
8387 return ::LBItemFromPt(m_hWnd, pt, bAutoScroll);
8388 }
8389
8390 void DrawInsert(int nItem)
8391 {
8392 ATLASSERT(::IsWindow(m_hWnd));
8393 ::DrawInsert(GetParent(), m_hWnd, nItem);
8394 }
8395
8396 static UINT GetDragListMessage()
8397 {
8398 static UINT uDragListMessage = 0;
8399 if(uDragListMessage == 0)
8400 {
8401 CStaticDataInitCriticalSectionLock lock;
8402 if(FAILED(lock.Lock()))
8403 {
8404 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CDragListBox::GetDragListMessage.\n"));
8405 ATLASSERT(FALSE);
8406 return 0;
8407 }
8408
8409 if(uDragListMessage == 0)
8410 uDragListMessage = ::RegisterWindowMessage(DRAGLISTMSGSTRING);
8411
8412 lock.Unlock();
8413 }
8414 ATLASSERT(uDragListMessage != 0);
8415 return uDragListMessage;
8416 }
8417 };
8418
8419 typedef CDragListBoxT<ATL::CWindow> CDragListBox;
8420
8421 template <class T>
8422 class CDragListNotifyImpl
8423 {
8424 public:
8425 BEGIN_MSG_MAP(CDragListNotifyImpl< T >)
8426 MESSAGE_HANDLER(CDragListBox::GetDragListMessage(), OnDragListNotify)
8427 END_MSG_MAP()
8428
8429 LRESULT OnDragListNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
8430 {
8431 uMsg; // avoid level 4 warning
8432 ATLASSERT(uMsg == CDragListBox::GetDragListMessage());
8433 T* pT = static_cast<T*>(this);
8434 LPDRAGLISTINFO lpDragListInfo = (LPDRAGLISTINFO)lParam;
8435 LRESULT lRet = 0;
8436 switch(lpDragListInfo->uNotification)
8437 {
8438 case DL_BEGINDRAG:
8439 lRet = (LPARAM)pT->OnBeginDrag((int)wParam, lpDragListInfo->hWnd, lpDragListInfo->ptCursor);
8440 break;
8441 case DL_CANCELDRAG:
8442 pT->OnCancelDrag((int)wParam, lpDragListInfo->hWnd, lpDragListInfo->ptCursor);
8443 break;
8444 case DL_DRAGGING:
8445 lRet = (LPARAM)pT->OnDragging((int)wParam, lpDragListInfo->hWnd, lpDragListInfo->ptCursor);
8446 break;
8447 case DL_DROPPED:
8448 pT->OnDropped((int)wParam, lpDragListInfo->hWnd, lpDragListInfo->ptCursor);
8449 break;
8450 default:
8451 ATLTRACE2(atlTraceUI, 0, _T("Unknown DragListBox notification\n"));
8452 bHandled = FALSE; // don't handle it
8453 break;
8454 }
8455 return lRet;
8456 }
8457
8458 // Overrideables
8459 BOOL OnBeginDrag(int /*nCtlID*/, HWND /*hWndDragList*/, POINT /*ptCursor*/)
8460 {
8461 return TRUE; // allow dragging
8462 }
8463
8464 void OnCancelDrag(int /*nCtlID*/, HWND /*hWndDragList*/, POINT /*ptCursor*/)
8465 {
8466 // nothing to do
8467 }
8468
8469 int OnDragging(int /*nCtlID*/, HWND /*hWndDragList*/, POINT /*ptCursor*/)
8470 {
8471 return 0; // don't change cursor
8472 }
8473
8474 void OnDropped(int /*nCtlID*/, HWND /*hWndDragList*/, POINT /*ptCursor*/)
8475 {
8476 // nothing to do
8477 }
8478 };
8479
8480 #endif // _WIN32_WCE
8481
8482
8483 ///////////////////////////////////////////////////////////////////////////////
8484 // CReBarCtrl
8485
8486 template <class TBase>
8487 class CReBarCtrlT : public TBase
8488 {
8489 public:
8490 // Constructors
8491 CReBarCtrlT(HWND hWnd = NULL) : TBase(hWnd)
8492 { }
8493
8494 CReBarCtrlT< TBase >& operator =(HWND hWnd)
8495 {
8496 m_hWnd = hWnd;
8497 return *this;
8498 }
8499
8500 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
8501 DWORD dwStyle = 0, DWORD dwExStyle = 0,
8502 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
8503 {
8504 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
8505 }
8506
8507 // Attributes
8508 static LPCTSTR GetWndClassName()
8509 {
8510 return REBARCLASSNAME;
8511 }
8512
8513 UINT GetBandCount() const
8514 {
8515 ATLASSERT(::IsWindow(m_hWnd));
8516 return (UINT)::SendMessage(m_hWnd, RB_GETBANDCOUNT, 0, 0L);
8517 }
8518
8519 BOOL GetBandInfo(int nBand, LPREBARBANDINFO lprbbi) const
8520 {
8521 ATLASSERT(::IsWindow(m_hWnd));
8522 return (BOOL)::SendMessage(m_hWnd, RB_GETBANDINFO, nBand, (LPARAM)lprbbi);
8523 }
8524
8525 BOOL SetBandInfo(int nBand, LPREBARBANDINFO lprbbi)
8526 {
8527 ATLASSERT(::IsWindow(m_hWnd));
8528 return (BOOL)::SendMessage(m_hWnd, RB_SETBANDINFO, nBand, (LPARAM)lprbbi);
8529 }
8530
8531 BOOL GetBarInfo(LPREBARINFO lprbi) const
8532 {
8533 ATLASSERT(::IsWindow(m_hWnd));
8534 return (BOOL)::SendMessage(m_hWnd, RB_GETBARINFO, 0, (LPARAM)lprbi);
8535 }
8536
8537 BOOL SetBarInfo(LPREBARINFO lprbi)
8538 {
8539 ATLASSERT(::IsWindow(m_hWnd));
8540 return (BOOL)::SendMessage(m_hWnd, RB_SETBARINFO, 0, (LPARAM)lprbi);
8541 }
8542
8543 CImageList GetImageList() const
8544 {
8545 ATLASSERT(::IsWindow(m_hWnd));
8546 REBARINFO rbi = { 0 };
8547 rbi.cbSize = sizeof(REBARINFO);
8548 rbi.fMask = RBIM_IMAGELIST;
8549 BOOL bRet = (BOOL)::SendMessage(m_hWnd, RB_GETBARINFO, 0, (LPARAM)&rbi);
8550 return CImageList((bRet != FALSE) ? rbi.himl : NULL);
8551 }
8552
8553 BOOL SetImageList(HIMAGELIST hImageList)
8554 {
8555 ATLASSERT(::IsWindow(m_hWnd));
8556 REBARINFO rbi = { 0 };
8557 rbi.cbSize = sizeof(REBARINFO);
8558 rbi.fMask = RBIM_IMAGELIST;
8559 rbi.himl = hImageList;
8560 return (BOOL)::SendMessage(m_hWnd, RB_SETBARINFO, 0, (LPARAM)&rbi);
8561 }
8562
8563 UINT GetRowCount() const
8564 {
8565 ATLASSERT(::IsWindow(m_hWnd));
8566 return (UINT)::SendMessage(m_hWnd, RB_GETROWCOUNT, 0, 0L);
8567 }
8568
8569 UINT GetRowHeight(int nBand) const
8570 {
8571 ATLASSERT(::IsWindow(m_hWnd));
8572 return (UINT)::SendMessage(m_hWnd, RB_GETROWHEIGHT, nBand, 0L);
8573 }
8574
8575 #if (_WIN32_IE >= 0x0400)
8576 COLORREF GetTextColor() const
8577 {
8578 ATLASSERT(::IsWindow(m_hWnd));
8579 return (COLORREF)::SendMessage(m_hWnd, RB_GETTEXTCOLOR, 0, 0L);
8580 }
8581
8582 COLORREF SetTextColor(COLORREF clr)
8583 {
8584 ATLASSERT(::IsWindow(m_hWnd));
8585 return (COLORREF)::SendMessage(m_hWnd, RB_SETTEXTCOLOR, 0, (LPARAM)clr);
8586 }
8587
8588 COLORREF GetBkColor() const
8589 {
8590 ATLASSERT(::IsWindow(m_hWnd));
8591 return (COLORREF)::SendMessage(m_hWnd, RB_GETBKCOLOR, 0, 0L);
8592 }
8593
8594 COLORREF SetBkColor(COLORREF clr)
8595 {
8596 ATLASSERT(::IsWindow(m_hWnd));
8597 return (COLORREF)::SendMessage(m_hWnd, RB_SETBKCOLOR, 0, (LPARAM)clr);
8598 }
8599
8600 UINT GetBarHeight() const
8601 {
8602 ATLASSERT(::IsWindow(m_hWnd));
8603 return (UINT)::SendMessage(m_hWnd, RB_GETBARHEIGHT, 0, 0L);
8604 }
8605
8606 BOOL GetRect(int nBand, LPRECT lpRect) const
8607 {
8608 ATLASSERT(::IsWindow(m_hWnd));
8609 return (BOOL)::SendMessage(m_hWnd, RB_GETRECT, nBand, (LPARAM)lpRect);
8610 }
8611
8612 #ifndef _WIN32_WCE
8613 CToolTipCtrl GetToolTips() const
8614 {
8615 ATLASSERT(::IsWindow(m_hWnd));
8616 return CToolTipCtrl((HWND)::SendMessage(m_hWnd, RB_GETTOOLTIPS, 0, 0L));
8617 }
8618
8619 void SetToolTips(HWND hwndToolTip)
8620 {
8621 ATLASSERT(::IsWindow(m_hWnd));
8622 ::SendMessage(m_hWnd, RB_SETTOOLTIPS, (WPARAM)hwndToolTip, 0L);
8623 }
8624 #endif // !_WIN32_WCE
8625
8626 void GetBandBorders(int nBand, LPRECT lpRect) const
8627 {
8628 ATLASSERT(::IsWindow(m_hWnd));
8629 ATLASSERT(lpRect != NULL);
8630 ::SendMessage(m_hWnd, RB_GETBANDBORDERS, nBand, (LPARAM)lpRect);
8631 }
8632
8633 #ifndef _WIN32_WCE
8634 BOOL GetColorScheme(LPCOLORSCHEME lpColorScheme) const
8635 {
8636 ATLASSERT(::IsWindow(m_hWnd));
8637 ATLASSERT(lpColorScheme != NULL);
8638 return (BOOL)::SendMessage(m_hWnd, RB_GETCOLORSCHEME, 0, (LPARAM)lpColorScheme);
8639 }
8640
8641 void SetColorScheme(LPCOLORSCHEME lpColorScheme)
8642 {
8643 ATLASSERT(::IsWindow(m_hWnd));
8644 ATLASSERT(lpColorScheme != NULL);
8645 ::SendMessage(m_hWnd, RB_SETCOLORSCHEME, 0, (LPARAM)lpColorScheme);
8646 }
8647
8648 HPALETTE GetPalette() const
8649 {
8650 ATLASSERT(::IsWindow(m_hWnd));
8651 return (HPALETTE)::SendMessage(m_hWnd, RB_GETPALETTE, 0, 0L);
8652 }
8653
8654 HPALETTE SetPalette(HPALETTE hPalette)
8655 {
8656 ATLASSERT(::IsWindow(m_hWnd));
8657 return (HPALETTE)::SendMessage(m_hWnd, RB_SETPALETTE, 0, (LPARAM)hPalette);
8658 }
8659
8660 BOOL GetUnicodeFormat() const
8661 {
8662 ATLASSERT(::IsWindow(m_hWnd));
8663 return (BOOL)::SendMessage(m_hWnd, RB_GETUNICODEFORMAT, 0, 0L);
8664 }
8665
8666 BOOL SetUnicodeFormat(BOOL bUnicode = TRUE)
8667 {
8668 ATLASSERT(::IsWindow(m_hWnd));
8669 return (BOOL)::SendMessage(m_hWnd, RB_SETUNICODEFORMAT, bUnicode, 0L);
8670 }
8671 #endif // !_WIN32_WCE
8672 #endif // (_WIN32_IE >= 0x0400)
8673
8674 #if (_WIN32_WINNT >= 0x0501)
8675 // requires uxtheme.h to be included to use MARGINS struct
8676 #ifndef _UXTHEME_H_
8677 typedef struct _MARGINS* PMARGINS;
8678 #endif // !_UXTHEME_H_
8679 void GetBandMargins(PMARGINS pMargins) const
8680 {
8681 ATLASSERT(::IsWindow(m_hWnd));
8682 ::SendMessage(m_hWnd, RB_GETBANDMARGINS, 0, (LPARAM)pMargins);
8683 }
8684
8685 void SetWindowTheme(LPCWSTR lpstrTheme)
8686 {
8687 ATLASSERT(::IsWindow(m_hWnd));
8688 ::SendMessage(m_hWnd, RB_SETWINDOWTHEME, 0, (LPARAM)lpstrTheme);
8689 }
8690 #endif // (_WIN32_WINNT >= 0x0501)
8691
8692 #if (_WIN32_IE >= 0x0600)
8693 DWORD GetExtendedStyle() const
8694 {
8695 #ifndef RB_GETEXTENDEDSTYLE
8696 const UINT RB_GETEXTENDEDSTYLE = WM_USER + 42;
8697 #endif
8698 ATLASSERT(::IsWindow(m_hWnd));
8699 return (DWORD)::SendMessage(m_hWnd, RB_GETEXTENDEDSTYLE, 0, 0L);
8700 }
8701
8702 DWORD SetExtendedStyle(DWORD dwStyle, DWORD dwMask)
8703 {
8704 #ifndef RB_SETEXTENDEDSTYLE
8705 const UINT RB_SETEXTENDEDSTYLE = WM_USER + 41;
8706 #endif
8707 ATLASSERT(::IsWindow(m_hWnd));
8708 return (DWORD)::SendMessage(m_hWnd, RB_SETEXTENDEDSTYLE, dwMask, dwStyle);
8709 }
8710 #endif // (_WIN32_IE >= 0x0600)
8711
8712 // Operations
8713 BOOL InsertBand(int nBand, LPREBARBANDINFO lprbbi)
8714 {
8715 ATLASSERT(::IsWindow(m_hWnd));
8716 return (BOOL)::SendMessage(m_hWnd, RB_INSERTBAND, nBand, (LPARAM)lprbbi);
8717 }
8718
8719 BOOL AddBand(LPREBARBANDINFO lprbbi)
8720 {
8721 return InsertBand(-1, lprbbi);
8722 }
8723
8724 BOOL DeleteBand(int nBand)
8725 {
8726 ATLASSERT(::IsWindow(m_hWnd));
8727 return (BOOL)::SendMessage(m_hWnd, RB_DELETEBAND, nBand, 0L);
8728 }
8729
8730 ATL::CWindow SetNotifyWnd(HWND hWnd)
8731 {
8732 ATLASSERT(::IsWindow(m_hWnd));
8733 return ATL::CWindow((HWND)::SendMessage(m_hWnd, RB_SETPARENT, (WPARAM)hWnd, 0L));
8734 }
8735
8736 #if (_WIN32_IE >= 0x0400)
8737 void BeginDrag(int nBand, DWORD dwPos)
8738 {
8739 ATLASSERT(::IsWindow(m_hWnd));
8740 ::SendMessage(m_hWnd, RB_BEGINDRAG, nBand, dwPos);
8741 }
8742
8743 void BeginDrag(int nBand, int xPos, int yPos)
8744 {
8745 ATLASSERT(::IsWindow(m_hWnd));
8746 ::SendMessage(m_hWnd, RB_BEGINDRAG, nBand, MAKELPARAM(xPos, yPos));
8747 }
8748
8749 void EndDrag()
8750 {
8751 ATLASSERT(::IsWindow(m_hWnd));
8752 ::SendMessage(m_hWnd, RB_ENDDRAG, 0, 0L);
8753 }
8754
8755 void DragMove(DWORD dwPos)
8756 {
8757 ATLASSERT(::IsWindow(m_hWnd));
8758 ::SendMessage(m_hWnd, RB_DRAGMOVE, 0, dwPos);
8759 }
8760
8761 void DragMove(int xPos, int yPos)
8762 {
8763 ATLASSERT(::IsWindow(m_hWnd));
8764 ::SendMessage(m_hWnd, RB_DRAGMOVE, 0, MAKELPARAM(xPos, yPos));
8765 }
8766
8767 #ifndef _WIN32_WCE
8768 void GetDropTarget(IDropTarget** ppDropTarget) const
8769 {
8770 ATLASSERT(::IsWindow(m_hWnd));
8771 ::SendMessage(m_hWnd, RB_GETDROPTARGET, 0, (LPARAM)ppDropTarget);
8772 }
8773 #endif // !_WIN32_WCE
8774
8775 void MaximizeBand(int nBand, BOOL bIdeal = FALSE)
8776 {
8777 ATLASSERT(::IsWindow(m_hWnd));
8778 ::SendMessage(m_hWnd, RB_MAXIMIZEBAND, nBand, bIdeal);
8779 }
8780
8781 void MinimizeBand(int nBand)
8782 {
8783 ATLASSERT(::IsWindow(m_hWnd));
8784 ::SendMessage(m_hWnd, RB_MINIMIZEBAND, nBand, 0L);
8785 }
8786
8787 BOOL SizeToRect(LPRECT lpRect)
8788 {
8789 ATLASSERT(::IsWindow(m_hWnd));
8790 return (BOOL)::SendMessage(m_hWnd, RB_SIZETORECT, 0, (LPARAM)lpRect);
8791 }
8792
8793 int IdToIndex(UINT uBandID) const
8794 {
8795 ATLASSERT(::IsWindow(m_hWnd));
8796 return (int)::SendMessage(m_hWnd, RB_IDTOINDEX, uBandID, 0L);
8797 }
8798
8799 int HitTest(LPRBHITTESTINFO lprbht) const
8800 {
8801 ATLASSERT(::IsWindow(m_hWnd));
8802 return (int)::SendMessage(m_hWnd, RB_HITTEST, 0, (LPARAM)lprbht);
8803 }
8804
8805 BOOL ShowBand(int nBand, BOOL bShow)
8806 {
8807 ATLASSERT(::IsWindow(m_hWnd));
8808 return (BOOL)::SendMessage(m_hWnd, RB_SHOWBAND, nBand, bShow);
8809 }
8810
8811 #ifndef _WIN32_WCE
8812 BOOL MoveBand(int nBand, int nNewPos)
8813 {
8814 ATLASSERT(::IsWindow(m_hWnd));
8815 ATLASSERT(nNewPos >= 0 && nNewPos <= ((int)GetBandCount() - 1));
8816 return (BOOL)::SendMessage(m_hWnd, RB_MOVEBAND, nBand, nNewPos);
8817 }
8818 #endif // !_WIN32_WCE
8819 #endif // (_WIN32_IE >= 0x0400)
8820
8821 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
8822 void PushChevron(int nBand, LPARAM lAppValue)
8823 {
8824 ATLASSERT(::IsWindow(m_hWnd));
8825 ::SendMessage(m_hWnd, RB_PUSHCHEVRON, nBand, lAppValue);
8826 }
8827 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
8828
8829 // Extra operations
8830 #if (_WIN32_IE >= 0x0400)
8831 void LockBands(bool bLock)
8832 {
8833 int nBandCount = GetBandCount();
8834 for(int i =0; i < nBandCount; i++)
8835 {
8836 REBARBANDINFO rbbi = { RunTimeHelper::SizeOf_REBARBANDINFO() };
8837 rbbi.fMask = RBBIM_STYLE;
8838 BOOL bRet = GetBandInfo(i, &rbbi);
8839 ATLASSERT(bRet);
8840
8841 if((rbbi.fStyle & RBBS_GRIPPERALWAYS) == 0)
8842 {
8843 rbbi.fStyle |= RBBS_GRIPPERALWAYS;
8844 bRet = SetBandInfo(i, &rbbi);
8845 ATLASSERT(bRet);
8846 rbbi.fStyle &= ~RBBS_GRIPPERALWAYS;
8847 }
8848
8849 if(bLock)
8850 rbbi.fStyle |= RBBS_NOGRIPPER;
8851 else
8852 rbbi.fStyle &= ~RBBS_NOGRIPPER;
8853
8854 bRet = SetBandInfo(i, &rbbi);
8855 ATLASSERT(bRet);
8856 }
8857 }
8858 #endif // (_WIN32_IE >= 0x0400)
8859
8860 #if (_WIN32_WINNT >= 0x0600)
8861 BOOL SetBandWidth(int nBand, int cxWidth)
8862 {
8863 ATLASSERT(::IsWindow(m_hWnd));
8864 return (BOOL)::SendMessage(m_hWnd, RB_SETBANDWIDTH, nBand, cxWidth);
8865 }
8866 #endif // (_WIN32_WINNT >= 0x0600)
8867 };
8868
8869 typedef CReBarCtrlT<ATL::CWindow> CReBarCtrl;
8870
8871
8872 ///////////////////////////////////////////////////////////////////////////////
8873 // CComboBoxEx
8874
8875 #ifndef _WIN32_WCE
8876
8877 template <class TBase>
8878 class CComboBoxExT : public CComboBoxT< TBase >
8879 {
8880 public:
8881 // Constructors
8882 CComboBoxExT(HWND hWnd = NULL) : CComboBoxT< TBase >(hWnd)
8883 { }
8884
8885 CComboBoxExT< TBase >& operator =(HWND hWnd)
8886 {
8887 m_hWnd = hWnd;
8888 return *this;
8889 }
8890
8891 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
8892 DWORD dwStyle = 0, DWORD dwExStyle = 0,
8893 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
8894 {
8895 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
8896 }
8897
8898 // Attributes
8899 static LPCTSTR GetWndClassName()
8900 {
8901 return WC_COMBOBOXEX;
8902 }
8903
8904 CImageList GetImageList() const
8905 {
8906 ATLASSERT(::IsWindow(m_hWnd));
8907 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, CBEM_GETIMAGELIST, 0, 0L));
8908 }
8909
8910 CImageList SetImageList(HIMAGELIST hImageList)
8911 {
8912 ATLASSERT(::IsWindow(m_hWnd));
8913 return CImageList((HIMAGELIST)::SendMessage(m_hWnd, CBEM_SETIMAGELIST, 0, (LPARAM)hImageList));
8914 }
8915
8916 #if (_WIN32_IE >= 0x0400)
8917 DWORD GetExtendedStyle() const
8918 {
8919 ATLASSERT(::IsWindow(m_hWnd));
8920 return (DWORD)::SendMessage(m_hWnd, CBEM_GETEXTENDEDSTYLE, 0, 0L);
8921 }
8922
8923 DWORD SetExtendedStyle(DWORD dwExMask, DWORD dwExStyle)
8924 {
8925 ATLASSERT(::IsWindow(m_hWnd));
8926 return (DWORD)::SendMessage(m_hWnd, CBEM_SETEXTENDEDSTYLE, dwExMask, dwExStyle);
8927 }
8928
8929 BOOL GetUnicodeFormat() const
8930 {
8931 ATLASSERT(::IsWindow(m_hWnd));
8932 return (BOOL)::SendMessage(m_hWnd, CBEM_GETUNICODEFORMAT, 0, 0L);
8933 }
8934
8935 BOOL SetUnicodeFormat(BOOL bUnicode = TRUE)
8936 {
8937 ATLASSERT(::IsWindow(m_hWnd));
8938 return (BOOL)::SendMessage(m_hWnd, CBEM_SETUNICODEFORMAT, bUnicode, 0L);
8939 }
8940 #endif // (_WIN32_IE >= 0x0400)
8941
8942 #if (_WIN32_WINNT >= 0x0501)
8943 void SetWindowTheme(LPCWSTR lpstrTheme)
8944 {
8945 ATLASSERT(::IsWindow(m_hWnd));
8946 ::SendMessage(m_hWnd, CBEM_SETWINDOWTHEME, 0, (LPARAM)lpstrTheme);
8947 }
8948 #endif // (_WIN32_WINNT >= 0x0501)
8949
8950 // Operations
8951 int InsertItem(const COMBOBOXEXITEM* lpcCBItem)
8952 {
8953 ATLASSERT(::IsWindow(m_hWnd));
8954 return (int)::SendMessage(m_hWnd, CBEM_INSERTITEM, 0, (LPARAM)lpcCBItem);
8955 }
8956
8957 int InsertItem(UINT nMask, int nIndex, LPCTSTR lpszItem, int nImage, int nSelImage,
8958 int iIndent, int iOverlay, LPARAM lParam)
8959 {
8960 ATLASSERT(::IsWindow(m_hWnd));
8961 COMBOBOXEXITEM cbex = { 0 };
8962 cbex.mask = nMask;
8963 cbex.iItem = nIndex;
8964 cbex.pszText = (LPTSTR) lpszItem;
8965 cbex.iImage = nImage;
8966 cbex.iSelectedImage = nSelImage;
8967 cbex.iIndent = iIndent;
8968 cbex.iOverlay = iOverlay;
8969 cbex.lParam = lParam;
8970 return (int)::SendMessage(m_hWnd, CBEM_INSERTITEM, 0, (LPARAM)&cbex);
8971 }
8972
8973 int InsertItem(int nIndex, LPCTSTR lpszItem, int nImage, int nSelImage, int iIndent, LPARAM lParam = 0)
8974 {
8975 ATLASSERT(::IsWindow(m_hWnd));
8976 COMBOBOXEXITEM cbex = { 0 };
8977 cbex.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_INDENT | CBEIF_LPARAM;
8978 cbex.iItem = nIndex;
8979 cbex.pszText = (LPTSTR) lpszItem;
8980 cbex.iImage = nImage;
8981 cbex.iSelectedImage = nSelImage;
8982 cbex.iIndent = iIndent;
8983 cbex.lParam = lParam;
8984 return (int)::SendMessage(m_hWnd, CBEM_INSERTITEM, 0, (LPARAM)&cbex);
8985 }
8986
8987 int AddItem(UINT nMask, LPCTSTR lpszItem, int nImage, int nSelImage, int iIndent, int iOverlay, LPARAM lParam)
8988 {
8989 return InsertItem(nMask, -1, lpszItem, nImage, nSelImage, iIndent, iOverlay, lParam);
8990 }
8991
8992 int AddItem(LPCTSTR lpszItem, int nImage, int nSelImage, int iIndent, LPARAM lParam = 0)
8993 {
8994 return InsertItem(-1, lpszItem, nImage, nSelImage, iIndent, lParam);
8995 }
8996
8997 int DeleteItem(int nIndex)
8998 {
8999 ATLASSERT(::IsWindow(m_hWnd));
9000 return (int)::SendMessage(m_hWnd, CBEM_DELETEITEM, nIndex, 0L);
9001 }
9002
9003 BOOL GetItem(PCOMBOBOXEXITEM pCBItem) const
9004 {
9005 ATLASSERT(::IsWindow(m_hWnd));
9006 return (BOOL)::SendMessage(m_hWnd, CBEM_GETITEM, 0, (LPARAM)pCBItem);
9007 }
9008
9009 BOOL SetItem(const COMBOBOXEXITEM* lpcCBItem)
9010 {
9011 ATLASSERT(::IsWindow(m_hWnd));
9012 return (BOOL)::SendMessage(m_hWnd, CBEM_SETITEM, 0, (LPARAM)lpcCBItem);
9013 }
9014
9015 int SetItem(int nIndex, UINT nMask, LPCTSTR lpszItem, int nImage, int nSelImage,
9016 int iIndent, int iOverlay, LPARAM lParam)
9017 {
9018 ATLASSERT(::IsWindow(m_hWnd));
9019 COMBOBOXEXITEM cbex = { 0 };
9020 cbex.mask = nMask;
9021 cbex.iItem = nIndex;
9022 cbex.pszText = (LPTSTR) lpszItem;
9023 cbex.iImage = nImage;
9024 cbex.iSelectedImage = nSelImage;
9025 cbex.iIndent = iIndent;
9026 cbex.iOverlay = iOverlay;
9027 cbex.lParam = lParam;
9028 return (int)::SendMessage(m_hWnd, CBEM_SETITEM, 0, (LPARAM)&cbex);
9029 }
9030
9031 BOOL GetItemText(int nIndex, LPTSTR lpszItem, int nLen) const
9032 {
9033 ATLASSERT(::IsWindow(m_hWnd));
9034 ATLASSERT(lpszItem != NULL);
9035
9036 COMBOBOXEXITEM cbex = { 0 };
9037 cbex.mask = CBEIF_TEXT;
9038 cbex.iItem = nIndex;
9039 cbex.pszText = lpszItem;
9040 cbex.cchTextMax = nLen;
9041
9042 return (BOOL)::SendMessage(m_hWnd, CBEM_GETITEM, 0, (LPARAM)&cbex);
9043 }
9044
9045 #ifndef _ATL_NO_COM
9046 BOOL GetItemText(int nIndex, BSTR& bstrText) const
9047 {
9048 USES_CONVERSION;
9049 ATLASSERT(::IsWindow(m_hWnd));
9050 ATLASSERT(bstrText == NULL);
9051
9052 COMBOBOXEXITEM cbex = { 0 };
9053 cbex.mask = CBEIF_TEXT;
9054 cbex.iItem = nIndex;
9055
9056 LPTSTR lpstrText = NULL;
9057 BOOL bRet = FALSE;
9058 for(int nLen = 256; ; nLen *= 2)
9059 {
9060 ATLTRY(lpstrText = new TCHAR[nLen]);
9061 if(lpstrText == NULL)
9062 break;
9063 lpstrText[0] = NULL;
9064 cbex.pszText = lpstrText;
9065 cbex.cchTextMax = nLen;
9066 bRet = (BOOL)::SendMessage(m_hWnd, CBEM_GETITEM, 0, (LPARAM)&cbex);
9067 if(!bRet || (lstrlen(cbex.pszText) < nLen - 1))
9068 break;
9069 delete [] lpstrText;
9070 lpstrText = NULL;
9071 }
9072
9073 if(lpstrText != NULL)
9074 {
9075 if(bRet)
9076 bstrText = ::SysAllocString(T2OLE(lpstrText));
9077 delete [] lpstrText;
9078 }
9079
9080 return (bstrText != NULL) ? TRUE : FALSE;
9081 }
9082 #endif // !_ATL_NO_COM
9083
9084 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
9085 BOOL GetItemText(int nIndex, _CSTRING_NS::CString& strText) const
9086 {
9087 ATLASSERT(::IsWindow(m_hWnd));
9088
9089 COMBOBOXEXITEM cbex = { 0 };
9090 cbex.mask = CBEIF_TEXT;
9091 cbex.iItem = nIndex;
9092
9093 strText.Empty();
9094 BOOL bRet = FALSE;
9095 for(int nLen = 256; ; nLen *= 2)
9096 {
9097 cbex.pszText = strText.GetBufferSetLength(nLen);
9098 if(cbex.pszText == NULL)
9099 {
9100 bRet = FALSE;
9101 break;
9102 }
9103 cbex.cchTextMax = nLen;
9104 bRet = (BOOL)::SendMessage(m_hWnd, CBEM_GETITEM, 0, (LPARAM)&cbex);
9105 if(!bRet || (lstrlen(cbex.pszText) < nLen - 1))
9106 break;
9107 }
9108 strText.ReleaseBuffer();
9109 return bRet;
9110 }
9111 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
9112
9113 BOOL SetItemText(int nIndex, LPCTSTR lpszItem)
9114 {
9115 ATLASSERT(::IsWindow(m_hWnd));
9116 return SetItem(nIndex, CBEIF_TEXT, lpszItem, 0, 0, 0, 0, 0);
9117 }
9118
9119 CComboBox GetComboCtrl() const
9120 {
9121 ATLASSERT(::IsWindow(m_hWnd));
9122 return CComboBox((HWND)::SendMessage(m_hWnd, CBEM_GETCOMBOCONTROL, 0, 0L));
9123 }
9124
9125 CEdit GetEditCtrl() const
9126 {
9127 ATLASSERT(::IsWindow(m_hWnd));
9128 return CEdit((HWND)::SendMessage(m_hWnd, CBEM_GETEDITCONTROL, 0, 0L));
9129 }
9130
9131 BOOL HasEditChanged() const
9132 {
9133 ATLASSERT(::IsWindow(m_hWnd));
9134 return (BOOL)::SendMessage(m_hWnd, CBEM_HASEDITCHANGED, 0, 0L);
9135 }
9136
9137 // Non-functional
9138 int AddString(LPCTSTR /*lpszItem*/)
9139 {
9140 ATLASSERT(FALSE); // Not available in CComboBoxEx; use InsertItem
9141 return 0;
9142 }
9143
9144 int InsertString(int /*nIndex*/, LPCTSTR /*lpszString*/)
9145 {
9146 ATLASSERT(FALSE); // Not available in CComboBoxEx; use InsertItem
9147 return 0;
9148 }
9149
9150 int Dir(UINT /*attr*/, LPCTSTR /*lpszWildCard*/)
9151 {
9152 ATLASSERT(FALSE); // Not available in CComboBoxEx
9153 return 0;
9154 }
9155
9156 int FindString(int /*nStartAfter*/, LPCTSTR /*lpszString*/) const
9157 {
9158 ATLASSERT(FALSE); // Not available in CComboBoxEx; try FindStringExact
9159 return 0;
9160 }
9161 };
9162
9163 typedef CComboBoxExT<ATL::CWindow> CComboBoxEx;
9164
9165 #endif // !_WIN32_WCE
9166
9167
9168 ///////////////////////////////////////////////////////////////////////////////
9169 // CMonthCalendarCtrl
9170
9171 template <class TBase>
9172 class CMonthCalendarCtrlT : public TBase
9173 {
9174 public:
9175 // Constructors
9176 CMonthCalendarCtrlT(HWND hWnd = NULL) : TBase(hWnd)
9177 { }
9178
9179 CMonthCalendarCtrlT< TBase >& operator =(HWND hWnd)
9180 {
9181 m_hWnd = hWnd;
9182 return *this;
9183 }
9184
9185 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
9186 DWORD dwStyle = 0, DWORD dwExStyle = 0,
9187 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
9188 {
9189 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
9190 }
9191
9192 // Attributes
9193 static LPCTSTR GetWndClassName()
9194 {
9195 return MONTHCAL_CLASS;
9196 }
9197
9198 COLORREF GetColor(int nColorType) const
9199 {
9200 ATLASSERT(::IsWindow(m_hWnd));
9201 return (COLORREF)::SendMessage(m_hWnd, MCM_GETCOLOR, nColorType, 0L);
9202 }
9203
9204 COLORREF SetColor(int nColorType, COLORREF clr)
9205 {
9206 ATLASSERT(::IsWindow(m_hWnd));
9207 return (COLORREF)::SendMessage(m_hWnd, MCM_SETCOLOR, nColorType, clr);
9208 }
9209
9210 BOOL GetCurSel(LPSYSTEMTIME lpSysTime) const
9211 {
9212 ATLASSERT(::IsWindow(m_hWnd));
9213 return (BOOL)::SendMessage(m_hWnd, MCM_GETCURSEL, 0, (LPARAM)lpSysTime);
9214 }
9215
9216 BOOL SetCurSel(LPSYSTEMTIME lpSysTime)
9217 {
9218 ATLASSERT(::IsWindow(m_hWnd));
9219 return (BOOL)::SendMessage(m_hWnd, MCM_SETCURSEL, 0, (LPARAM)lpSysTime);
9220 }
9221
9222 int GetFirstDayOfWeek(BOOL* pbLocaleVal = NULL) const
9223 {
9224 ATLASSERT(::IsWindow(m_hWnd));
9225 DWORD dwRet = (DWORD)::SendMessage(m_hWnd, MCM_GETFIRSTDAYOFWEEK, 0, 0L);
9226 if(pbLocaleVal != NULL)
9227 *pbLocaleVal = (BOOL)HIWORD(dwRet);
9228 return (int)(short)LOWORD(dwRet);
9229 }
9230
9231 int SetFirstDayOfWeek(int nDay, BOOL* pbLocaleVal = NULL)
9232 {
9233 ATLASSERT(::IsWindow(m_hWnd));
9234 DWORD dwRet = (DWORD)::SendMessage(m_hWnd, MCM_SETFIRSTDAYOFWEEK, 0, nDay);
9235 if(pbLocaleVal != NULL)
9236 *pbLocaleVal = (BOOL)HIWORD(dwRet);
9237 return (int)(short)LOWORD(dwRet);
9238 }
9239
9240 int GetMaxSelCount() const
9241 {
9242 ATLASSERT(::IsWindow(m_hWnd));
9243 return (int)::SendMessage(m_hWnd, MCM_GETMAXSELCOUNT, 0, 0L);
9244 }
9245
9246 BOOL SetMaxSelCount(int nMax)
9247 {
9248 ATLASSERT(::IsWindow(m_hWnd));
9249 return (BOOL)::SendMessage(m_hWnd, MCM_SETMAXSELCOUNT, nMax, 0L);
9250 }
9251
9252 int GetMonthDelta() const
9253 {
9254 ATLASSERT(::IsWindow(m_hWnd));
9255 return (int)::SendMessage(m_hWnd, MCM_GETMONTHDELTA, 0, 0L);
9256 }
9257
9258 int SetMonthDelta(int nDelta)
9259 {
9260 ATLASSERT(::IsWindow(m_hWnd));
9261 return (int)::SendMessage(m_hWnd, MCM_SETMONTHDELTA, nDelta, 0L);
9262 }
9263
9264 DWORD GetRange(LPSYSTEMTIME lprgSysTimeArray) const
9265 {
9266 ATLASSERT(::IsWindow(m_hWnd));
9267 return (DWORD)::SendMessage(m_hWnd, MCM_GETRANGE, 0, (LPARAM)lprgSysTimeArray);
9268 }
9269
9270 BOOL SetRange(DWORD dwFlags, LPSYSTEMTIME lprgSysTimeArray)
9271 {
9272 ATLASSERT(::IsWindow(m_hWnd));
9273 return (BOOL)::SendMessage(m_hWnd, MCM_SETRANGE, dwFlags, (LPARAM)lprgSysTimeArray);
9274 }
9275
9276 BOOL GetSelRange(LPSYSTEMTIME lprgSysTimeArray) const
9277 {
9278 ATLASSERT(::IsWindow(m_hWnd));
9279 return (BOOL)::SendMessage(m_hWnd, MCM_GETSELRANGE, 0, (LPARAM)lprgSysTimeArray);
9280 }
9281
9282 BOOL SetSelRange(LPSYSTEMTIME lprgSysTimeArray)
9283 {
9284 ATLASSERT(::IsWindow(m_hWnd));
9285 return (BOOL)::SendMessage(m_hWnd, MCM_SETSELRANGE, 0, (LPARAM)lprgSysTimeArray);
9286 }
9287
9288 BOOL GetToday(LPSYSTEMTIME lpSysTime) const
9289 {
9290 ATLASSERT(::IsWindow(m_hWnd));
9291 return (BOOL)::SendMessage(m_hWnd, MCM_GETTODAY, 0, (LPARAM)lpSysTime);
9292 }
9293
9294 void SetToday(LPSYSTEMTIME lpSysTime)
9295 {
9296 ATLASSERT(::IsWindow(m_hWnd));
9297 ::SendMessage(m_hWnd, MCM_SETTODAY, 0, (LPARAM)lpSysTime);
9298 }
9299
9300 BOOL GetMinReqRect(LPRECT lpRectInfo) const
9301 {
9302 ATLASSERT(::IsWindow(m_hWnd));
9303 return (BOOL)::SendMessage(m_hWnd, MCM_GETMINREQRECT, 0, (LPARAM)lpRectInfo);
9304 }
9305
9306 int GetMaxTodayWidth() const
9307 {
9308 ATLASSERT(::IsWindow(m_hWnd));
9309 return (int)::SendMessage(m_hWnd, MCM_GETMAXTODAYWIDTH, 0, 0L);
9310 }
9311
9312 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
9313 BOOL GetUnicodeFormat() const
9314 {
9315 ATLASSERT(::IsWindow(m_hWnd));
9316 return (BOOL)::SendMessage(m_hWnd, MCM_GETUNICODEFORMAT, 0, 0L);
9317 }
9318
9319 BOOL SetUnicodeFormat(BOOL bUnicode = TRUE)
9320 {
9321 ATLASSERT(::IsWindow(m_hWnd));
9322 return (BOOL)::SendMessage(m_hWnd, MCM_SETUNICODEFORMAT, bUnicode, 0L);
9323 }
9324 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
9325
9326 #if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
9327 DWORD GetCurrentView() const
9328 {
9329 ATLASSERT(::IsWindow(m_hWnd));
9330 return (DWORD)::SendMessage(m_hWnd, MCM_GETCURRENTVIEW, 0, 0L);
9331 }
9332
9333 BOOL SetCurrentView(DWORD dwView)
9334 {
9335 ATLASSERT(::IsWindow(m_hWnd));
9336 return (BOOL)::SendMessage(m_hWnd, MCM_SETCURRENTVIEW, 0, dwView);
9337 }
9338
9339 DWORD GetCalendarCount() const
9340 {
9341 ATLASSERT(::IsWindow(m_hWnd));
9342 return (DWORD)::SendMessage(m_hWnd, MCM_GETCALENDARCOUNT, 0, 0L);
9343 }
9344
9345 BOOL GetCalendarGridInfo(PMCGRIDINFO pGridInfo) const
9346 {
9347 ATLASSERT(::IsWindow(m_hWnd));
9348 return (BOOL)::SendMessage(m_hWnd, MCM_GETCALENDARGRIDINFO, 0, (LPARAM)pGridInfo);
9349 }
9350
9351 CALID GetCALID() const
9352 {
9353 ATLASSERT(::IsWindow(m_hWnd));
9354 return (CALID)::SendMessage(m_hWnd, MCM_GETCALID, 0, 0L);
9355 }
9356
9357 void SetCALID(CALID calid)
9358 {
9359 ATLASSERT(::IsWindow(m_hWnd));
9360 ::SendMessage(m_hWnd, MCM_SETCALID, (LPARAM)calid, 0L);
9361 }
9362
9363 int GetCalendarBorder() const
9364 {
9365 ATLASSERT(::IsWindow(m_hWnd));
9366 return (int)::SendMessage(m_hWnd, MCM_GETCALENDARBORDER, 0, 0L);
9367 }
9368
9369 void SetCalendarBorder(int cxyBorder, BOOL bSet = TRUE)
9370 {
9371 ATLASSERT(::IsWindow(m_hWnd));
9372 ::SendMessage(m_hWnd, MCM_SETCALENDARBORDER, (WPARAM)bSet, (LPARAM)cxyBorder);
9373 }
9374 #endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
9375
9376 // Operations
9377 int GetMonthRange(DWORD dwFlags, LPSYSTEMTIME lprgSysTimeArray) const
9378 {
9379 ATLASSERT(::IsWindow(m_hWnd));
9380 return (int)::SendMessage(m_hWnd, MCM_GETMONTHRANGE, dwFlags, (LPARAM)lprgSysTimeArray);
9381 }
9382
9383 BOOL SetDayState(int nMonths, LPMONTHDAYSTATE lpDayStateArray)
9384 {
9385 ATLASSERT(::IsWindow(m_hWnd));
9386 return (BOOL)::SendMessage(m_hWnd, MCM_SETDAYSTATE, nMonths, (LPARAM)lpDayStateArray);
9387 }
9388
9389 DWORD HitTest(PMCHITTESTINFO pMCHitTest) const
9390 {
9391 ATLASSERT(::IsWindow(m_hWnd));
9392 return (DWORD)::SendMessage(m_hWnd, MCM_HITTEST, 0, (LPARAM)pMCHitTest);
9393 }
9394
9395 #if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
9396 void SizeRectToMin(LPRECT lpRect)
9397 {
9398 ATLASSERT(::IsWindow(m_hWnd));
9399 ::SendMessage(m_hWnd, MCM_SIZERECTTOMIN, 0, (LPARAM)lpRect);
9400 }
9401 #endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
9402 };
9403
9404 typedef CMonthCalendarCtrlT<ATL::CWindow> CMonthCalendarCtrl;
9405
9406
9407 ///////////////////////////////////////////////////////////////////////////////
9408 // CDateTimePickerCtrl
9409
9410 template <class TBase>
9411 class CDateTimePickerCtrlT : public TBase
9412 {
9413 public:
9414 // Constructors
9415 CDateTimePickerCtrlT(HWND hWnd = NULL) : TBase(hWnd)
9416 { }
9417
9418 CDateTimePickerCtrlT< TBase >& operator =(HWND hWnd)
9419 {
9420 m_hWnd = hWnd;
9421 return *this;
9422 }
9423
9424 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
9425 DWORD dwStyle = 0, DWORD dwExStyle = 0,
9426 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
9427 {
9428 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
9429 }
9430
9431 // Operations
9432 static LPCTSTR GetWndClassName()
9433 {
9434 return DATETIMEPICK_CLASS;
9435 }
9436
9437 BOOL SetFormat(LPCTSTR lpszFormat)
9438 {
9439 ATLASSERT(::IsWindow(m_hWnd));
9440 return (BOOL)::SendMessage(m_hWnd, DTM_SETFORMAT, 0, (LPARAM)lpszFormat);
9441 }
9442
9443 COLORREF GetMonthCalColor(int nColorType) const
9444 {
9445 ATLASSERT(::IsWindow(m_hWnd));
9446 return (COLORREF)::SendMessage(m_hWnd, DTM_GETMCCOLOR, nColorType, 0L);
9447 }
9448
9449 COLORREF SetMonthCalColor(int nColorType, COLORREF clr)
9450 {
9451 ATLASSERT(::IsWindow(m_hWnd));
9452 return (COLORREF)::SendMessage(m_hWnd, DTM_SETMCCOLOR, nColorType, clr);
9453 }
9454
9455 DWORD GetRange(LPSYSTEMTIME lpSysTimeArray) const
9456 {
9457 ATLASSERT(::IsWindow(m_hWnd));
9458 return (DWORD)::SendMessage(m_hWnd, DTM_GETRANGE, 0, (LPARAM)lpSysTimeArray);
9459 }
9460
9461 BOOL SetRange(DWORD dwFlags, LPSYSTEMTIME lpSysTimeArray)
9462 {
9463 ATLASSERT(::IsWindow(m_hWnd));
9464 return (BOOL)::SendMessage(m_hWnd, DTM_SETRANGE, dwFlags, (LPARAM)lpSysTimeArray);
9465 }
9466
9467 DWORD GetSystemTime(LPSYSTEMTIME lpSysTime) const
9468 {
9469 ATLASSERT(::IsWindow(m_hWnd));
9470 return (DWORD)::SendMessage(m_hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)lpSysTime);
9471 }
9472
9473 BOOL SetSystemTime(DWORD dwFlags, LPSYSTEMTIME lpSysTime)
9474 {
9475 ATLASSERT(::IsWindow(m_hWnd));
9476 return (BOOL)::SendMessage(m_hWnd, DTM_SETSYSTEMTIME, dwFlags, (LPARAM)lpSysTime);
9477 }
9478
9479 CMonthCalendarCtrl GetMonthCal() const
9480 {
9481 ATLASSERT(::IsWindow(m_hWnd));
9482 return CMonthCalendarCtrl((HWND)::SendMessage(m_hWnd, DTM_GETMONTHCAL, 0, 0L));
9483 }
9484
9485 #if (_WIN32_IE >= 0x0400)
9486 CFontHandle GetMonthCalFont() const
9487 {
9488 ATLASSERT(::IsWindow(m_hWnd));
9489 return CFontHandle((HFONT)::SendMessage(m_hWnd, DTM_GETMCFONT, 0, 0L));
9490 }
9491
9492 void SetMonthCalFont(HFONT hFont, BOOL bRedraw = TRUE)
9493 {
9494 ATLASSERT(::IsWindow(m_hWnd));
9495 ::SendMessage(m_hWnd, DTM_SETMCFONT, (WPARAM)hFont, MAKELPARAM(bRedraw, 0));
9496 }
9497 #endif // (_WIN32_IE >= 0x0400)
9498
9499 #if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
9500 DWORD GetMonthCalStyle() const
9501 {
9502 ATLASSERT(::IsWindow(m_hWnd));
9503 return (DWORD)::SendMessage(m_hWnd, DTM_GETMCSTYLE, 0, 0L);
9504 }
9505
9506 DWORD SetMonthCalStyle(DWORD dwStyle)
9507 {
9508 ATLASSERT(::IsWindow(m_hWnd));
9509 return (DWORD)::SendMessage(m_hWnd, DTM_SETMCSTYLE, 0, (LPARAM)dwStyle);
9510 }
9511
9512 void GetDateTimePickerInfo(LPDATETIMEPICKERINFO lpPickerInfo) const
9513 {
9514 ATLASSERT(::IsWindow(m_hWnd));
9515 ::SendMessage(m_hWnd, DTM_GETDATETIMEPICKERINFO, 0, (LPARAM)lpPickerInfo);
9516 }
9517
9518 BOOL GetIdealSize(LPSIZE lpSize) const
9519 {
9520 ATLASSERT(::IsWindow(m_hWnd));
9521 return (BOOL)::SendMessage(m_hWnd, DTM_GETIDEALSIZE, 0, (LPARAM)lpSize);
9522 }
9523
9524 void CloseMonthCal()
9525 {
9526 ATLASSERT(::IsWindow(m_hWnd));
9527 ::SendMessage(m_hWnd, DTM_CLOSEMONTHCAL, 0, 0L);
9528 }
9529 #endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
9530 };
9531
9532 typedef CDateTimePickerCtrlT<ATL::CWindow> CDateTimePickerCtrl;
9533
9534
9535 ///////////////////////////////////////////////////////////////////////////////
9536 // CFlatScrollBarImpl - support for flat scroll bars
9537
9538 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
9539
9540 template <class T>
9541 class CFlatScrollBarImpl
9542 {
9543 public:
9544 // Initialization
9545 BOOL FlatSB_Initialize()
9546 {
9547 T* pT = static_cast<T*>(this);
9548 ATLASSERT(::IsWindow(pT->m_hWnd));
9549 return ::InitializeFlatSB(pT->m_hWnd);
9550 }
9551
9552 HRESULT FlatSB_Uninitialize()
9553 {
9554 T* pT = static_cast<T*>(this);
9555 ATLASSERT(::IsWindow(pT->m_hWnd));
9556 return ::UninitializeFlatSB(pT->m_hWnd);
9557 }
9558
9559 // Flat scroll bar properties
9560 BOOL FlatSB_GetScrollProp(UINT uIndex, LPINT lpnValue) const
9561 {
9562 const T* pT = static_cast<const T*>(this);
9563 ATLASSERT(::IsWindow(pT->m_hWnd));
9564 return ::FlatSB_GetScrollProp(pT->m_hWnd, uIndex, lpnValue);
9565 }
9566
9567 BOOL FlatSB_SetScrollProp(UINT uIndex, int nValue, BOOL bRedraw = TRUE)
9568 {
9569 T* pT = static_cast<T*>(this);
9570 ATLASSERT(::IsWindow(pT->m_hWnd));
9571 return ::FlatSB_SetScrollProp(pT->m_hWnd, uIndex, nValue, bRedraw);
9572 }
9573
9574 // Attributes
9575 int FlatSB_GetScrollPos(int nBar) const
9576 {
9577 const T* pT = static_cast<const T*>(this);
9578 ATLASSERT(::IsWindow(pT->m_hWnd));
9579 return ::FlatSB_GetScrollPos(pT->m_hWnd, nBar);
9580 }
9581
9582 int FlatSB_SetScrollPos(int nBar, int nPos, BOOL bRedraw = TRUE)
9583 {
9584 T* pT = static_cast<T*>(this);
9585 ATLASSERT(::IsWindow(pT->m_hWnd));
9586 return ::FlatSB_SetScrollPos(pT->m_hWnd, nBar, nPos, bRedraw);
9587 }
9588
9589 BOOL FlatSB_GetScrollRange(int nBar, LPINT lpMinPos, LPINT lpMaxPos) const
9590 {
9591 const T* pT = static_cast<const T*>(this);
9592 ATLASSERT(::IsWindow(pT->m_hWnd));
9593 return ::FlatSB_GetScrollRange(pT->m_hWnd, nBar, lpMinPos, lpMaxPos);
9594 }
9595
9596 BOOL FlatSB_SetScrollRange(int nBar, int nMinPos, int nMaxPos, BOOL bRedraw = TRUE)
9597 {
9598 T* pT = static_cast<T*>(this);
9599 ATLASSERT(::IsWindow(pT->m_hWnd));
9600 return ::FlatSB_SetScrollRange(pT->m_hWnd, nBar, nMinPos, nMaxPos, bRedraw);
9601 }
9602
9603 BOOL FlatSB_GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo) const
9604 {
9605 const T* pT = static_cast<const T*>(this);
9606 ATLASSERT(::IsWindow(pT->m_hWnd));
9607 return ::FlatSB_GetScrollInfo(pT->m_hWnd, nBar, lpScrollInfo);
9608 }
9609
9610 int FlatSB_SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE)
9611 {
9612 T* pT = static_cast<T*>(this);
9613 ATLASSERT(::IsWindow(pT->m_hWnd));
9614 return ::FlatSB_SetScrollInfo(pT->m_hWnd, nBar, lpScrollInfo, bRedraw);
9615 }
9616
9617 // Operations
9618 BOOL FlatSB_ShowScrollBar(UINT nBar, BOOL bShow = TRUE)
9619 {
9620 T* pT = static_cast<T*>(this);
9621 ATLASSERT(::IsWindow(pT->m_hWnd));
9622 return ::FlatSB_ShowScrollBar(pT->m_hWnd, nBar, bShow);
9623 }
9624
9625 BOOL FlatSB_EnableScrollBar(UINT uSBFlags, UINT uArrowFlags = ESB_ENABLE_BOTH)
9626 {
9627 T* pT = static_cast<T*>(this);
9628 ATLASSERT(::IsWindow(pT->m_hWnd));
9629 return ::FlatSB_EnableScrollBar(pT->m_hWnd, uSBFlags, uArrowFlags);
9630 }
9631 };
9632
9633 template <class TBase>
9634 class CFlatScrollBarT : public TBase, public CFlatScrollBarImpl<CFlatScrollBarT< TBase > >
9635 {
9636 public:
9637 CFlatScrollBarT(HWND hWnd = NULL) : TBase(hWnd)
9638 { }
9639
9640 CFlatScrollBarT< TBase >& operator =(HWND hWnd)
9641 {
9642 m_hWnd = hWnd;
9643 return *this;
9644 }
9645 };
9646
9647 typedef CFlatScrollBarT<ATL::CWindow> CFlatScrollBar;
9648
9649 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
9650
9651
9652 ///////////////////////////////////////////////////////////////////////////////
9653 // CIPAddressCtrl
9654
9655 #if (_WIN32_IE >= 0x0400)
9656
9657 template <class TBase>
9658 class CIPAddressCtrlT : public TBase
9659 {
9660 public:
9661 // Constructors
9662 CIPAddressCtrlT(HWND hWnd = NULL) : TBase(hWnd)
9663 { }
9664
9665 CIPAddressCtrlT< TBase >& operator =(HWND hWnd)
9666 {
9667 m_hWnd = hWnd;
9668 return *this;
9669 }
9670
9671 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
9672 DWORD dwStyle = 0, DWORD dwExStyle = 0,
9673 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
9674 {
9675 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
9676 }
9677
9678 // Atteributes
9679 static LPCTSTR GetWndClassName()
9680 {
9681 return WC_IPADDRESS;
9682 }
9683
9684 BOOL IsBlank() const
9685 {
9686 ATLASSERT(::IsWindow(m_hWnd));
9687 return (BOOL)::SendMessage(m_hWnd, IPM_ISBLANK, 0, 0L);
9688 }
9689
9690 int GetAddress(LPDWORD lpdwAddress) const
9691 {
9692 ATLASSERT(::IsWindow(m_hWnd));
9693 return (int)::SendMessage(m_hWnd, IPM_GETADDRESS, 0, (LPARAM)lpdwAddress);
9694 }
9695
9696 void SetAddress(DWORD dwAddress)
9697 {
9698 ATLASSERT(::IsWindow(m_hWnd));
9699 ::SendMessage(m_hWnd, IPM_SETADDRESS, 0, dwAddress);
9700 }
9701
9702 void ClearAddress()
9703 {
9704 ATLASSERT(::IsWindow(m_hWnd));
9705 ::SendMessage(m_hWnd, IPM_CLEARADDRESS, 0, 0L);
9706 }
9707
9708 void SetRange(int nField, WORD wRange)
9709 {
9710 ATLASSERT(::IsWindow(m_hWnd));
9711 ::SendMessage(m_hWnd, IPM_SETRANGE, nField, wRange);
9712 }
9713
9714 void SetRange(int nField, BYTE nMin, BYTE nMax)
9715 {
9716 ATLASSERT(::IsWindow(m_hWnd));
9717 ::SendMessage(m_hWnd, IPM_SETRANGE, nField, MAKEIPRANGE(nMin, nMax));
9718 }
9719
9720 void SetFocus(int nField)
9721 {
9722 ATLASSERT(::IsWindow(m_hWnd));
9723 ::SendMessage(m_hWnd, IPM_SETFOCUS, nField, 0L);
9724 }
9725 };
9726
9727 typedef CIPAddressCtrlT<ATL::CWindow> CIPAddressCtrl;
9728
9729 #endif // (_WIN32_IE >= 0x0400)
9730
9731
9732 ///////////////////////////////////////////////////////////////////////////////
9733 // CPagerCtrl
9734
9735 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
9736
9737 template <class TBase>
9738 class CPagerCtrlT : public TBase
9739 {
9740 public:
9741 // Constructors
9742 CPagerCtrlT(HWND hWnd = NULL) : TBase(hWnd)
9743 { }
9744
9745 CPagerCtrlT< TBase >& operator =(HWND hWnd)
9746 {
9747 m_hWnd = hWnd;
9748 return *this;
9749 }
9750
9751 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
9752 DWORD dwStyle = 0, DWORD dwExStyle = 0,
9753 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
9754 {
9755 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
9756 }
9757
9758 // Attributes
9759 static LPCTSTR GetWndClassName()
9760 {
9761 return WC_PAGESCROLLER;
9762 }
9763
9764 int GetButtonSize() const
9765 {
9766 ATLASSERT(::IsWindow(m_hWnd));
9767 return (int)::SendMessage(m_hWnd, PGM_GETBUTTONSIZE, 0, 0L);
9768 }
9769
9770 int SetButtonSize(int nButtonSize)
9771 {
9772 ATLASSERT(::IsWindow(m_hWnd));
9773 return (int)::SendMessage(m_hWnd, PGM_SETBUTTONSIZE, 0, nButtonSize);
9774 }
9775
9776 DWORD GetButtonState(int nButton) const
9777 {
9778 ATLASSERT(::IsWindow(m_hWnd));
9779 ATLASSERT(nButton == PGB_TOPORLEFT || nButton == PGB_BOTTOMORRIGHT);
9780 return (DWORD)::SendMessage(m_hWnd, PGM_GETBUTTONSTATE, 0, nButton);
9781 }
9782
9783 COLORREF GetBkColor() const
9784 {
9785 ATLASSERT(::IsWindow(m_hWnd));
9786 return (COLORREF)::SendMessage(m_hWnd, PGM_GETBKCOLOR, 0, 0L);
9787 }
9788
9789 COLORREF SetBkColor(COLORREF clrBk)
9790 {
9791 ATLASSERT(::IsWindow(m_hWnd));
9792 return (COLORREF)::SendMessage(m_hWnd, PGM_SETBKCOLOR, 0, (LPARAM)clrBk);
9793 }
9794
9795 int GetBorder() const
9796 {
9797 ATLASSERT(::IsWindow(m_hWnd));
9798 return (int)::SendMessage(m_hWnd, PGM_GETBORDER, 0, 0L);
9799 }
9800
9801 int SetBorder(int nBorderSize)
9802 {
9803 ATLASSERT(::IsWindow(m_hWnd));
9804 return (int)::SendMessage(m_hWnd, PGM_SETBORDER, 0, nBorderSize);
9805 }
9806
9807 int GetPos() const
9808 {
9809 ATLASSERT(::IsWindow(m_hWnd));
9810 return (int)::SendMessage(m_hWnd, PGM_GETPOS, 0, 0L);
9811 }
9812
9813 int SetPos(int nPos)
9814 {
9815 ATLASSERT(::IsWindow(m_hWnd));
9816 return (int)::SendMessage(m_hWnd, PGM_SETPOS, 0, nPos);
9817 }
9818
9819 // Operations
9820 void SetChild(HWND hWndChild)
9821 {
9822 ATLASSERT(::IsWindow(m_hWnd));
9823 ::SendMessage(m_hWnd, PGM_SETCHILD, 0, (LPARAM)hWndChild);
9824 }
9825
9826 void ForwardMouse(BOOL bForward = TRUE)
9827 {
9828 ATLASSERT(::IsWindow(m_hWnd));
9829 ::SendMessage(m_hWnd, PGM_FORWARDMOUSE, bForward, 0L);
9830 }
9831
9832 void RecalcSize()
9833 {
9834 ATLASSERT(::IsWindow(m_hWnd));
9835 ::SendMessage(m_hWnd, PGM_RECALCSIZE, 0, 0L);
9836 }
9837
9838 void GetDropTarget(IDropTarget** ppDropTarget)
9839 {
9840 ATLASSERT(::IsWindow(m_hWnd));
9841 ATLASSERT(ppDropTarget != NULL);
9842 ::SendMessage(m_hWnd, PGM_GETDROPTARGET, 0, (LPARAM)ppDropTarget);
9843 }
9844 };
9845
9846 typedef CPagerCtrlT<ATL::CWindow> CPagerCtrl;
9847
9848 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
9849
9850
9851 ///////////////////////////////////////////////////////////////////////////////
9852 // CLinkCtrl - Windows SYSLINK control
9853
9854 #if (_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE)
9855
9856 template <class TBase>
9857 class CLinkCtrlT : public TBase
9858 {
9859 public:
9860 // Constructors
9861 CLinkCtrlT(HWND hWnd = NULL) : TBase(hWnd)
9862 { }
9863
9864 CLinkCtrlT< TBase >& operator =(HWND hWnd)
9865 {
9866 m_hWnd = hWnd;
9867 return *this;
9868 }
9869
9870 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
9871 DWORD dwStyle = 0, DWORD dwExStyle = 0,
9872 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
9873 {
9874 return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
9875 }
9876
9877 // Attributes
9878 static LPCTSTR GetWndClassName()
9879 {
9880 #ifdef _UNICODE
9881 return WC_LINK;
9882 #else // !_UNICODE
9883 return "SysLink";
9884 #endif // !_UNICODE
9885 }
9886
9887 int GetIdealHeight(int cxMaxWidth = 0) const
9888 {
9889 ATLASSERT(::IsWindow(m_hWnd));
9890 return (int)::SendMessage(m_hWnd, LM_GETIDEALHEIGHT, cxMaxWidth, 0L);
9891 }
9892
9893 BOOL GetItem(PLITEM pLItem) const
9894 {
9895 ATLASSERT(::IsWindow(m_hWnd));
9896 return (BOOL)::SendMessage(m_hWnd, LM_GETITEM, 0, (LPARAM)pLItem);
9897 }
9898
9899 BOOL SetItem(PLITEM pLItem)
9900 {
9901 ATLASSERT(::IsWindow(m_hWnd));
9902 return (BOOL)::SendMessage(m_hWnd, LM_SETITEM, 0, (LPARAM)pLItem);
9903 }
9904
9905 // Vista only
9906 int GetIdealSize(SIZE& size, int cxMaxWidth = 0) const
9907 {
9908 #ifndef LM_GETIDEALSIZE
9909 const UINT LM_GETIDEALSIZE = LM_GETIDEALHEIGHT;
9910 #endif
9911 ATLASSERT(::IsWindow(m_hWnd));
9912 return (int)::SendMessage(m_hWnd, LM_GETIDEALSIZE, cxMaxWidth, (LPARAM)&size);
9913 }
9914
9915 // Operations
9916 BOOL HitTest(PLHITTESTINFO pLHitTestInfo) const
9917 {
9918 ATLASSERT(::IsWindow(m_hWnd));
9919 return (BOOL)::SendMessage(m_hWnd, LM_HITTEST, 0, (LPARAM)pLHitTestInfo);
9920 }
9921 };
9922
9923 typedef CLinkCtrlT<ATL::CWindow> CLinkCtrl;
9924
9925 #endif // (_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE)
9926
9927
9928 ///////////////////////////////////////////////////////////////////////////////
9929 // CCustomDraw - MI class for custom-draw support
9930
9931 template <class T>
9932 class CCustomDraw
9933 {
9934 public:
9935 #if (_ATL_VER < 0x0700)
9936 BOOL m_bHandledCD;
9937
9938 BOOL IsMsgHandled() const
9939 {
9940 return m_bHandledCD;
9941 }
9942
9943 void SetMsgHandled(BOOL bHandled)
9944 {
9945 m_bHandledCD = bHandled;
9946 }
9947 #endif // !(_ATL_VER < 0x0700)
9948
9949 // Message map and handlers
9950 BEGIN_MSG_MAP(CCustomDraw< T >)
9951 NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw)
9952 ALT_MSG_MAP(1)
9953 REFLECTED_NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw)
9954 END_MSG_MAP()
9955
9956 // message handler
9957 LRESULT OnCustomDraw(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
9958 {
9959 T* pT = static_cast<T*>(this);
9960 pT->SetMsgHandled(TRUE);
9961 LPNMCUSTOMDRAW lpNMCustomDraw = (LPNMCUSTOMDRAW)pnmh;
9962 DWORD dwRet = 0;
9963 switch(lpNMCustomDraw->dwDrawStage)
9964 {
9965 case CDDS_PREPAINT:
9966 dwRet = pT->OnPrePaint(idCtrl, lpNMCustomDraw);
9967 break;
9968 case CDDS_POSTPAINT:
9969 dwRet = pT->OnPostPaint(idCtrl, lpNMCustomDraw);
9970 break;
9971 case CDDS_PREERASE:
9972 dwRet = pT->OnPreErase(idCtrl, lpNMCustomDraw);
9973 break;
9974 case CDDS_POSTERASE:
9975 dwRet = pT->OnPostErase(idCtrl, lpNMCustomDraw);
9976 break;
9977 case CDDS_ITEMPREPAINT:
9978 dwRet = pT->OnItemPrePaint(idCtrl, lpNMCustomDraw);
9979 break;
9980 case CDDS_ITEMPOSTPAINT:
9981 dwRet = pT->OnItemPostPaint(idCtrl, lpNMCustomDraw);
9982 break;
9983 case CDDS_ITEMPREERASE:
9984 dwRet = pT->OnItemPreErase(idCtrl, lpNMCustomDraw);
9985 break;
9986 case CDDS_ITEMPOSTERASE:
9987 dwRet = pT->OnItemPostErase(idCtrl, lpNMCustomDraw);
9988 break;
9989 #if (_WIN32_IE >= 0x0400)
9990 case (CDDS_ITEMPREPAINT | CDDS_SUBITEM):
9991 dwRet = pT->OnSubItemPrePaint(idCtrl, lpNMCustomDraw);
9992 break;
9993 #endif // (_WIN32_IE >= 0x0400)
9994 default:
9995 pT->SetMsgHandled(FALSE);
9996 break;
9997 }
9998 bHandled = pT->IsMsgHandled();
9999 return dwRet;
10000 }
10001
10002 // Overrideables
10003 DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
10004 {
10005 return CDRF_DODEFAULT;
10006 }
10007
10008 DWORD OnPostPaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
10009 {
10010 return CDRF_DODEFAULT;
10011 }
10012
10013 DWORD OnPreErase(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
10014 {
10015 return CDRF_DODEFAULT;
10016 }
10017
10018 DWORD OnPostErase(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
10019 {
10020 return CDRF_DODEFAULT;
10021 }
10022
10023 DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
10024 {
10025 return CDRF_DODEFAULT;
10026 }
10027
10028 DWORD OnItemPostPaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
10029 {
10030 return CDRF_DODEFAULT;
10031 }
10032
10033 DWORD OnItemPreErase(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
10034 {
10035 return CDRF_DODEFAULT;
10036 }
10037
10038 DWORD OnItemPostErase(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
10039 {
10040 return CDRF_DODEFAULT;
10041 }
10042
10043 #if (_WIN32_IE >= 0x0400)
10044 DWORD OnSubItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
10045 {
10046 return CDRF_DODEFAULT;
10047 }
10048 #endif // (_WIN32_IE >= 0x0400)
10049 };
10050
10051
10052 // --- Windows CE common controls ---
10053
10054 #ifdef _WIN32_WCE
10055
10056 ///////////////////////////////////////////////////////////////////////////////
10057 // CCECommandBarCtrl
10058
10059 template <class TBase>
10060 class CCECommandBarCtrlT : public TBase
10061 {
10062 public:
10063 // Constructors
10064 CCECommandBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) { }
10065
10066 CCECommandBarCtrlT< TBase >& operator=(HWND hWnd)
10067 {
10068 m_hWnd = hWnd;
10069 return *this;
10070 }
10071
10072 // Attributes
10073 BOOL IsVisible() const
10074 {
10075 return IsWindowVisible();
10076 }
10077
10078 int GetHeight() const
10079 {
10080 ATLASSERT(::IsWindow(m_hWnd));
10081 return ::CommandBar_Height(m_hWnd);
10082 }
10083
10084 HMENU GetMenu(WORD wButton) const
10085 {
10086 ATLASSERT(::IsWindow(m_hWnd));
10087 return ::CommandBar_GetMenu(m_hWnd, wButton);
10088 }
10089
10090 // Operations
10091 HWND Create(HWND hWndParent, int nCmdBarID)
10092 {
10093 m_hWnd = ::CommandBar_Create(ModuleHelper::GetModuleInstance(), hWndParent, nCmdBarID);
10094 ATLASSERT(::IsWindow(m_hWnd));
10095 return m_hWnd;
10096 }
10097
10098 void Destroy()
10099 {
10100 DestroyWindow();
10101 }
10102
10103 BOOL Show(BOOL bShow = TRUE)
10104 {
10105 ATLASSERT(::IsWindow(m_hWnd));
10106 return ::CommandBar_Show(m_hWnd, bShow);
10107 }
10108
10109 BOOL DrawMenuBar(WORD wButton)
10110 {
10111 ATLASSERT(::IsWindow(m_hWnd));
10112 return ::CommandBar_DrawMenuBar(m_hWnd, wButton);
10113 }
10114
10115 BOOL AddAdornments(DWORD dwFlags = 0)
10116 {
10117 ATLASSERT(::IsWindow(m_hWnd));
10118 return ::CommandBar_AddAdornments(m_hWnd, dwFlags, 0);
10119 }
10120
10121 int AddBitmap(int nBitmapID, int nNumImages)
10122 {
10123 ATLASSERT(::IsWindow(m_hWnd));
10124 return ::CommandBar_AddBitmap(m_hWnd, ModuleHelper::GetResourceInstance(), nBitmapID, nNumImages, 16, 16);
10125 }
10126
10127 BOOL AddButtons(UINT uNumButtons, LPTBBUTTON lpButtons)
10128 {
10129 ATLASSERT(::IsWindow(m_hWnd));
10130 return CommandBar_AddButtons(m_hWnd, uNumButtons, lpButtons);
10131 }
10132
10133 BOOL AddToolTips(UINT uNumToolTips, LPTSTR lpToolTips)
10134 {
10135 ATLASSERT(::IsWindow(m_hWnd));
10136 return CommandBar_AddToolTips(m_hWnd, uNumToolTips, lpToolTips);
10137 }
10138
10139 BOOL InsertButton(int nButton, LPTBBUTTON lpButton)
10140 {
10141 ATLASSERT(::IsWindow(m_hWnd));
10142 return CommandBar_InsertButton(m_hWnd, nButton, lpButton);
10143 }
10144
10145 HWND InsertComboBox(int nWidth, UINT dwStyle, WORD wComboBoxID, WORD wButton)
10146 {
10147 ATLASSERT(::IsWindow(m_hWnd));
10148 return ::CommandBar_InsertComboBox(m_hWnd, ModuleHelper::GetModuleInstance(), nWidth, dwStyle, wComboBoxID, wButton);
10149 }
10150
10151 BOOL InsertMenubar(WORD wMenuID, WORD wButton)
10152 {
10153 ATLASSERT(::IsWindow(m_hWnd));
10154 return ::CommandBar_InsertMenubar(m_hWnd, ModuleHelper::GetResourceInstance(), wMenuID, wButton);
10155 }
10156
10157 BOOL InsertMenubarEx(ATL::_U_STRINGorID menu, WORD wButton)
10158 {
10159 ATLASSERT(::IsWindow(m_hWnd));
10160 return ::CommandBar_InsertMenubarEx(m_hWnd, ModuleHelper::GetResourceInstance(), (LPTSTR)menu.m_lpstr, wButton);
10161 }
10162
10163 BOOL IsCommandBarMessage(LPMSG lpMsg)
10164 {
10165 ATLASSERT(::IsWindow(m_hWnd));
10166 return ::IsCommandBarMessage(m_hWnd, lpMsg);
10167 }
10168 };
10169
10170 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC MenuBar
10171 typedef CCECommandBarCtrlT<CToolBarCtrl> CMenuBarCtrl;
10172 #else
10173 typedef CCECommandBarCtrlT<CToolBarCtrl> CCECommandBarCtrl;
10174 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
10175
10176 ///////////////////////////////////////////////////////////////////////////////
10177 // CCECommandBandsCtrl
10178
10179 template <class TBase>
10180 class CCECommandBandsCtrlT : public TBase
10181 {
10182 public:
10183 // Constructors
10184 CCECommandBandsCtrlT(HWND hWnd = NULL) : TBase(hWnd) { }
10185
10186 CCECommandBandsCtrlT< TBase >& operator=(HWND hWnd)
10187 {
10188 m_hWnd = hWnd;
10189 return *this;
10190 }
10191
10192 // Attributes
10193 BOOL IsVisible() const
10194 {
10195 return IsWindowVisible();
10196 }
10197
10198 #if (_WIN32_IE >= 0x0400)
10199 UINT GetHeight() const
10200 {
10201 ATLASSERT(::IsWindow(m_hWnd));
10202 return CommandBands_Height(m_hWnd);
10203 }
10204 #endif // (_WIN32_IE >= 0x0400)
10205
10206 HWND GetCommandBar(UINT uBand) const
10207 {
10208 ATLASSERT(::IsWindow(m_hWnd));
10209 return ::CommandBands_GetCommandBar(m_hWnd, uBand);
10210 }
10211
10212 BOOL GetRestoreInformation(UINT uBand, LPCOMMANDBANDSRESTOREINFO pcbr) const
10213 {
10214 ATLASSERT(::IsWindow(m_hWnd));
10215 return ::CommandBands_GetRestoreInformation(m_hWnd, uBand, pcbr);
10216 }
10217
10218 // Operations
10219 HWND Create(HWND hWndParent, UINT wID, DWORD dwStyles, HIMAGELIST hImageList = NULL)
10220 {
10221 m_hWnd = ::CommandBands_Create(ModuleHelper::GetModuleInstance(), hWndParent, wID, dwStyles, hImageList);
10222 ATLASSERT(::IsWindow(m_hWnd));
10223 return m_hWnd;
10224 }
10225
10226 BOOL AddAdornments(DWORD dwFlags = 0, LPREBARBANDINFO prbbi = NULL)
10227 {
10228 ATLASSERT(::IsWindow(m_hWnd));
10229 return ::CommandBands_AddAdornments(m_hWnd, ModuleHelper::GetModuleInstance(), dwFlags, prbbi);
10230 }
10231
10232 BOOL AddBands(UINT uBandCount, LPREBARBANDINFO prbbi)
10233 {
10234 ATLASSERT(::IsWindow(m_hWnd));
10235 return ::CommandBands_AddBands(m_hWnd, ModuleHelper::GetModuleInstance(), uBandCount, prbbi);
10236 }
10237
10238 BOOL Show(BOOL bShow = TRUE)
10239 {
10240 ATLASSERT(::IsWindow(m_hWnd));
10241 return ::CommandBands_Show(m_hWnd, bShow);
10242 }
10243 };
10244
10245 typedef CCECommandBandsCtrlT<ATL::CWindow> CCECommandBandsCtrl;
10246
10247 #endif // _WIN32_WCE
10248
10249 }; // namespace WTL
10250
10251 #endif // __ATLCTRLS_H__
+0
-4211
src/third_party/wtl/Include/atlctrlw.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLCTRLW_H__
9 #define __ATLCTRLW_H__
10
11 #pragma once
12
13 #ifdef _WIN32_WCE
14 #error atlctrlw.h is not supported on Windows CE
15 #endif
16
17 #ifndef __ATLAPP_H__
18 #error atlctrlw.h requires atlapp.h to be included first
19 #endif
20
21 #ifndef __ATLCTRLS_H__
22 #error atlctrlw.h requires atlctrls.h to be included first
23 #endif
24
25 #if (_WIN32_IE < 0x0400)
26 #error atlctrlw.h requires _WIN32_IE >= 0x0400
27 #endif
28
29 // Define _WTL_CMDBAR_VISTA_MENUS as 0 to exclude Vista menus support
30 #if !defined(_WTL_CMDBAR_VISTA_MENUS) && (WINVER >= 0x0500) && (_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501)
31 #define _WTL_CMDBAR_VISTA_MENUS 1
32 #endif
33
34 #if _WTL_CMDBAR_VISTA_MENUS
35 #if !((_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501))
36 #error _WTL_CMDBAR_VISTA_MENUS requires (_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501)
37 #endif
38 #endif
39
40 // Note: Define _WTL_CMDBAR_VISTA_STD_MENUBAR to use Vista standard menubar look with Vista menus
41
42
43 ///////////////////////////////////////////////////////////////////////////////
44 // Classes in this file:
45 //
46 // CCommandBarCtrlImpl<T, TBase, TWinTraits>
47 // CCommandBarCtrl
48 // CMDICommandBarCtrlImpl<T, TBase, TWinTraits>
49 // CMDICommandBarCtrl
50
51
52 namespace WTL
53 {
54
55 ///////////////////////////////////////////////////////////////////////////////
56 // Command Bars
57
58 // Window Styles:
59 #define CBRWS_TOP CCS_TOP
60 #define CBRWS_BOTTOM CCS_BOTTOM
61 #define CBRWS_NORESIZE CCS_NORESIZE
62 #define CBRWS_NOPARENTALIGN CCS_NOPARENTALIGN
63 #define CBRWS_NODIVIDER CCS_NODIVIDER
64
65 // Extended styles
66 #define CBR_EX_TRANSPARENT 0x00000001L
67 #define CBR_EX_SHAREMENU 0x00000002L
68 #define CBR_EX_ALTFOCUSMODE 0x00000004L
69 #define CBR_EX_TRACKALWAYS 0x00000008L
70 #define CBR_EX_NOVISTAMENUS 0x00000010L
71
72 // standard command bar styles
73 #define ATL_SIMPLE_CMDBAR_PANE_STYLE \
74 (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CBRWS_NODIVIDER | CBRWS_NORESIZE | CBRWS_NOPARENTALIGN)
75
76 // Messages - support chevrons for frame windows
77 #define CBRM_GETCMDBAR (WM_USER + 301) // returns command bar HWND
78 #define CBRM_GETMENU (WM_USER + 302) // returns loaded or attached menu
79 #define CBRM_TRACKPOPUPMENU (WM_USER + 303) // displays a popup menu
80
81 typedef struct tagCBRPOPUPMENU
82 {
83 int cbSize;
84 HMENU hMenu; // popup menu do display
85 UINT uFlags; // TPM_* flags for ::TrackPopupMenuEx
86 int x;
87 int y;
88 LPTPMPARAMS lptpm; // ptr to TPMPARAMS for ::TrackPopupMenuEx
89 } CBRPOPUPMENU, *LPCBRPOPUPMENU;
90
91 // helper class
92 template <class T>
93 class CSimpleStack : public ATL::CSimpleArray< T >
94 {
95 public:
96 BOOL Push(T t)
97 {
98 #ifdef _CMDBAR_EXTRA_TRACE
99 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - STACK-PUSH (%8.8X) size = %i\n"), t, GetSize());
100 #endif
101 return Add(t);
102 }
103
104 T Pop()
105 {
106 int nLast = GetSize() - 1;
107 if(nLast < 0)
108 return NULL; // must be able to convert to NULL
109 T t = m_aT[nLast];
110 #ifdef _CMDBAR_EXTRA_TRACE
111 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - STACK-POP (%8.8X) size = %i\n"), t, GetSize());
112 #endif
113 if(!RemoveAt(nLast))
114 return NULL;
115 return t;
116 }
117
118 T GetCurrent()
119 {
120 int nLast = GetSize() - 1;
121 if(nLast < 0)
122 return NULL; // must be able to convert to NULL
123 return m_aT[nLast];
124 }
125 };
126
127
128 ///////////////////////////////////////////////////////////////////////////////
129 // CCommandBarCtrlBase - base class for the Command Bar implementation
130
131 class CCommandBarCtrlBase : public CToolBarCtrl
132 {
133 public:
134 struct _MsgHookData
135 {
136 HHOOK hMsgHook;
137 DWORD dwUsage;
138
139 _MsgHookData() : hMsgHook(NULL), dwUsage(0)
140 { }
141 };
142
143 typedef ATL::CSimpleMap<DWORD, _MsgHookData*> CMsgHookMap;
144 static CMsgHookMap* s_pmapMsgHook;
145
146 static HHOOK s_hCreateHook;
147 static bool s_bW2K; // For animation flag
148 static CCommandBarCtrlBase* s_pCurrentBar;
149 static bool s_bStaticInit;
150
151 CSimpleStack<HWND> m_stackMenuWnd;
152 CSimpleStack<HMENU> m_stackMenuHandle;
153
154 HWND m_hWndHook;
155 DWORD m_dwMagic;
156
157
158 CCommandBarCtrlBase() : m_hWndHook(NULL), m_dwMagic(1314)
159 {
160 // init static variables
161 if(!s_bStaticInit)
162 {
163 CStaticDataInitCriticalSectionLock lock;
164 if(FAILED(lock.Lock()))
165 {
166 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlBase::CCommandBarCtrlBase.\n"));
167 ATLASSERT(FALSE);
168 return;
169 }
170
171 if(!s_bStaticInit)
172 {
173 // Just in case...
174 AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES);
175 // Animation on Win2000 only
176 s_bW2K = !AtlIsOldWindows();
177 // done
178 s_bStaticInit = true;
179 }
180
181 lock.Unlock();
182 }
183 }
184
185 bool IsCommandBarBase() const { return m_dwMagic == 1314; }
186 };
187
188 __declspec(selectany) CCommandBarCtrlBase::CMsgHookMap* CCommandBarCtrlBase::s_pmapMsgHook = NULL;
189 __declspec(selectany) HHOOK CCommandBarCtrlBase::s_hCreateHook = NULL;
190 __declspec(selectany) CCommandBarCtrlBase* CCommandBarCtrlBase::s_pCurrentBar = NULL;
191 __declspec(selectany) bool CCommandBarCtrlBase::s_bW2K = false;
192 __declspec(selectany) bool CCommandBarCtrlBase::s_bStaticInit = false;
193
194
195 ///////////////////////////////////////////////////////////////////////////////
196 // CCommandBarCtrl - ATL implementation of Command Bars
197
198 template <class T, class TBase = CCommandBarCtrlBase, class TWinTraits = ATL::CControlWinTraits>
199 class ATL_NO_VTABLE CCommandBarCtrlImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >
200 {
201 public:
202 DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())
203
204 // Declarations
205 struct _MenuItemData // menu item data
206 {
207 DWORD dwMagic;
208 LPTSTR lpstrText;
209 UINT fType;
210 UINT fState;
211 int iButton;
212
213 _MenuItemData() { dwMagic = 0x1313; }
214 bool IsCmdBarMenuItem() { return (dwMagic == 0x1313); }
215 };
216
217 struct _ToolBarData // toolbar resource data
218 {
219 WORD wVersion;
220 WORD wWidth;
221 WORD wHeight;
222 WORD wItemCount;
223 //WORD aItems[wItemCount]
224
225 WORD* items()
226 { return (WORD*)(this+1); }
227 };
228
229 // Constants
230 enum _CmdBarDrawConstants
231 {
232 s_kcxGap = 1,
233 s_kcxTextMargin = 2,
234 s_kcxButtonMargin = 3,
235 s_kcyButtonMargin = 3
236 };
237
238 enum
239 {
240 _nMaxMenuItemTextLength = 100,
241 _chChevronShortcut = _T('/')
242 };
243
244 #ifndef DT_HIDEPREFIX
245 enum { DT_HIDEPREFIX = 0x00100000 };
246 #endif // !DT_HIDEPREFIX
247
248 // Data members
249 HMENU m_hMenu;
250 HIMAGELIST m_hImageList;
251 ATL::CSimpleValArray<WORD> m_arrCommand;
252
253 DWORD m_dwExtendedStyle; // Command Bar specific extended styles
254
255 ATL::CContainedWindow m_wndParent;
256
257 bool m_bMenuActive:1;
258 bool m_bAttachedMenu:1;
259 bool m_bImagesVisible:1;
260 bool m_bPopupItem:1;
261 bool m_bContextMenu:1;
262 bool m_bEscapePressed:1;
263 bool m_bSkipMsg:1;
264 bool m_bParentActive:1;
265 bool m_bFlatMenus:1;
266 bool m_bUseKeyboardCues:1;
267 bool m_bShowKeyboardCues:1;
268 bool m_bAllowKeyboardCues:1;
269 bool m_bKeyboardInput:1;
270 bool m_bAlphaImages:1;
271 bool m_bLayoutRTL:1;
272 bool m_bSkipPostDown:1;
273 bool m_bVistaMenus:1;
274
275 int m_nPopBtn;
276 int m_nNextPopBtn;
277
278 SIZE m_szBitmap;
279 SIZE m_szButton;
280
281 COLORREF m_clrMask;
282 CFont m_fontMenu; // used internally, only to measure text
283
284 UINT m_uSysKey;
285
286 HWND m_hWndFocus; // Alternate focus mode
287
288 int m_cxExtraSpacing;
289
290 #if _WTL_CMDBAR_VISTA_MENUS
291 ATL::CSimpleValArray<HBITMAP> m_arrVistaBitmap; // Bitmaps for Vista menus
292 #endif // _WTL_CMDBAR_VISTA_MENUS
293
294 // Constructor/destructor
295 CCommandBarCtrlImpl() :
296 m_hMenu(NULL),
297 m_hImageList(NULL),
298 m_wndParent(this, 1),
299 m_bMenuActive(false),
300 m_bAttachedMenu(false),
301 m_nPopBtn(-1),
302 m_nNextPopBtn(-1),
303 m_bPopupItem(false),
304 m_bImagesVisible(true),
305 m_bSkipMsg(false),
306 m_uSysKey(0),
307 m_hWndFocus(NULL),
308 m_bContextMenu(false),
309 m_bEscapePressed(false),
310 m_clrMask(RGB(192, 192, 192)),
311 m_dwExtendedStyle(CBR_EX_TRANSPARENT | CBR_EX_SHAREMENU | CBR_EX_TRACKALWAYS),
312 m_bParentActive(true),
313 m_bFlatMenus(false),
314 m_bUseKeyboardCues(false),
315 m_bShowKeyboardCues(false),
316 m_bAllowKeyboardCues(true),
317 m_bKeyboardInput(false),
318 m_cxExtraSpacing(0),
319 m_bAlphaImages(false),
320 m_bLayoutRTL(false),
321 m_bSkipPostDown(false),
322 m_bVistaMenus(false)
323 {
324 SetImageSize(16, 15); // default
325 }
326
327 ~CCommandBarCtrlImpl()
328 {
329 if(m_wndParent.IsWindow())
330 /*scary!*/ m_wndParent.UnsubclassWindow();
331
332 if(m_hMenu != NULL && (m_dwExtendedStyle & CBR_EX_SHAREMENU) == 0)
333 ::DestroyMenu(m_hMenu);
334
335 if(m_hImageList != NULL)
336 ::ImageList_Destroy(m_hImageList);
337 }
338
339 // Attributes
340 DWORD GetCommandBarExtendedStyle() const
341 {
342 return m_dwExtendedStyle;
343 }
344
345 DWORD SetCommandBarExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
346 {
347 DWORD dwPrevStyle = m_dwExtendedStyle;
348 if(dwMask == 0)
349 m_dwExtendedStyle = dwExtendedStyle;
350 else
351 m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
352 return dwPrevStyle;
353 }
354
355 CMenuHandle GetMenu() const
356 {
357 ATLASSERT(::IsWindow(m_hWnd));
358 return m_hMenu;
359 }
360
361 COLORREF GetImageMaskColor() const
362 {
363 return m_clrMask;
364 }
365
366 COLORREF SetImageMaskColor(COLORREF clrMask)
367 {
368 COLORREF clrOld = m_clrMask;
369 m_clrMask = clrMask;
370 return clrOld;
371 }
372
373 bool GetImagesVisible() const
374 {
375 return m_bImagesVisible;
376 }
377
378 bool SetImagesVisible(bool bVisible)
379 {
380 bool bOld = m_bImagesVisible;
381 m_bImagesVisible = bVisible;
382 return bOld;
383 }
384
385 void GetImageSize(SIZE& size) const
386 {
387 size = m_szBitmap;
388 }
389
390 bool SetImageSize(SIZE& size)
391 {
392 return SetImageSize(size.cx, size.cy);
393 }
394
395 bool SetImageSize(int cx, int cy)
396 {
397 if(m_hImageList != NULL)
398 {
399 if(::ImageList_GetImageCount(m_hImageList) == 0) // empty
400 {
401 ::ImageList_Destroy(m_hImageList);
402 m_hImageList = NULL;
403 }
404 else
405 {
406 return false; // can't set, image list exists
407 }
408 }
409
410 if(cx == 0 || cy == 0)
411 return false;
412
413 m_szBitmap.cx = cx;
414 m_szBitmap.cy = cy;
415 m_szButton.cx = m_szBitmap.cx + 2 * s_kcxButtonMargin;
416 m_szButton.cy = m_szBitmap.cy + 2 * s_kcyButtonMargin;
417
418 return true;
419 }
420
421 bool GetAlphaImages() const
422 {
423 return m_bAlphaImages;
424 }
425
426 bool SetAlphaImages(bool bAlphaImages)
427 {
428 if(m_hImageList != NULL)
429 {
430 if(::ImageList_GetImageCount(m_hImageList) == 0) // empty
431 {
432 ::ImageList_Destroy(m_hImageList);
433 m_hImageList = NULL;
434 }
435 else
436 {
437 return false; // can't set, image list exists
438 }
439 }
440
441 m_bAlphaImages = bAlphaImages;
442 return true;
443 }
444
445 HWND GetCmdBar() const
446 {
447 ATLASSERT(::IsWindow(m_hWnd));
448 return (HWND)::SendMessage(m_hWnd, CBRM_GETCMDBAR, 0, 0L);
449 }
450
451 // Methods
452 HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
453 DWORD dwStyle = 0, DWORD dwExStyle = 0,
454 UINT nID = 0, LPVOID lpCreateParam = NULL)
455 {
456 // These styles are required for command bars
457 dwStyle |= TBSTYLE_LIST | TBSTYLE_FLAT;
458 #if (_MSC_VER >= 1300)
459 return ATL::CWindowImpl< T, TBase, TWinTraits >::Create(hWndParent, rcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam);
460 #else // !(_MSC_VER >= 1300)
461 typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass;
462 return _baseClass::Create(hWndParent, rcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam);
463 #endif // !(_MSC_VER >= 1300)
464 }
465
466 BOOL AttachToWindow(HWND hWnd)
467 {
468 ATLASSERT(m_hWnd == NULL);
469 ATLASSERT(::IsWindow(hWnd));
470 BOOL bRet = SubclassWindow(hWnd);
471 if(bRet)
472 {
473 m_bAttachedMenu = true;
474 T* pT = static_cast<T*>(this);
475 pT->GetSystemSettings();
476 }
477 return bRet;
478 }
479
480 BOOL LoadMenu(ATL::_U_STRINGorID menu)
481 {
482 ATLASSERT(::IsWindow(m_hWnd));
483
484 if(m_bAttachedMenu) // doesn't work in this mode
485 return FALSE;
486 if(menu.m_lpstr == NULL)
487 return FALSE;
488
489 HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), menu.m_lpstr);
490 if(hMenu == NULL)
491 return FALSE;
492
493 return AttachMenu(hMenu);
494 }
495
496 BOOL AttachMenu(HMENU hMenu)
497 {
498 ATLASSERT(::IsWindow(m_hWnd));
499 ATLASSERT(hMenu == NULL || ::IsMenu(hMenu));
500 if(hMenu != NULL && !::IsMenu(hMenu))
501 return FALSE;
502
503 #if _WTL_CMDBAR_VISTA_MENUS
504 // remove Vista bitmaps if used
505 if(m_bVistaMenus && (m_hMenu != NULL))
506 {
507 T* pT = static_cast<T*>(this);
508 pT->_RemoveVistaBitmapsFromMenu();
509 }
510 #endif // _WTL_CMDBAR_VISTA_MENUS
511
512 // destroy old menu, if needed, and set new one
513 if(m_hMenu != NULL && (m_dwExtendedStyle & CBR_EX_SHAREMENU) == 0)
514 ::DestroyMenu(m_hMenu);
515
516 m_hMenu = hMenu;
517
518 if(m_bAttachedMenu) // Nothing else in this mode
519 return TRUE;
520
521 // Build buttons according to menu
522 SetRedraw(FALSE);
523
524 // Clear all buttons
525 int nCount = GetButtonCount();
526 for(int i = 0; i < nCount; i++)
527 ATLVERIFY(DeleteButton(0) != FALSE);
528
529 // Add buttons for each menu item
530 if(m_hMenu != NULL)
531 {
532 int nItems = ::GetMenuItemCount(m_hMenu);
533
534 T* pT = static_cast<T*>(this);
535 pT; // avoid level 4 warning
536 TCHAR szString[pT->_nMaxMenuItemTextLength] = { 0 };
537 for(int i = 0; i < nItems; i++)
538 {
539 CMenuItemInfo mii;
540 mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU;
541 mii.fType = MFT_STRING;
542 mii.dwTypeData = szString;
543 mii.cch = pT->_nMaxMenuItemTextLength;
544 BOOL bRet = ::GetMenuItemInfo(m_hMenu, i, TRUE, &mii);
545 ATLASSERT(bRet);
546 // If we have more than the buffer, we assume we have bitmaps bits
547 if(lstrlen(szString) > pT->_nMaxMenuItemTextLength - 1)
548 {
549 mii.fType = MFT_BITMAP;
550 ::SetMenuItemInfo(m_hMenu, i, TRUE, &mii);
551 szString[0] = 0;
552 }
553
554 // NOTE: Command Bar currently supports only drop-down menu items
555 ATLASSERT(mii.hSubMenu != NULL);
556
557 TBBUTTON btn = { 0 };
558 btn.iBitmap = 0;
559 btn.idCommand = i;
560 btn.fsState = (BYTE)(((mii.fState & MFS_DISABLED) == 0) ? TBSTATE_ENABLED : 0);
561 btn.fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE | BTNS_DROPDOWN;
562 btn.dwData = 0;
563 btn.iString = 0;
564
565 bRet = InsertButton(-1, &btn);
566 ATLASSERT(bRet);
567
568 TBBUTTONINFO bi = { 0 };
569 bi.cbSize = sizeof(TBBUTTONINFO);
570 bi.dwMask = TBIF_TEXT;
571 bi.pszText = szString;
572
573 bRet = SetButtonInfo(i, &bi);
574 ATLASSERT(bRet);
575 }
576 }
577
578 SetRedraw(TRUE);
579 Invalidate();
580 UpdateWindow();
581
582 return TRUE;
583 }
584
585 BOOL LoadImages(ATL::_U_STRINGorID image)
586 {
587 return _LoadImagesHelper(image, false);
588 }
589
590 BOOL LoadMappedImages(UINT nIDImage, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0)
591 {
592 return _LoadImagesHelper(nIDImage, true, nFlags , lpColorMap, nMapSize);
593 }
594
595 BOOL _LoadImagesHelper(ATL::_U_STRINGorID image, bool bMapped, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0)
596 {
597 ATLASSERT(::IsWindow(m_hWnd));
598 HINSTANCE hInstance = ModuleHelper::GetResourceInstance();
599
600 HRSRC hRsrc = ::FindResource(hInstance, image.m_lpstr, (LPTSTR)RT_TOOLBAR);
601 if(hRsrc == NULL)
602 return FALSE;
603
604 HGLOBAL hGlobal = ::LoadResource(hInstance, hRsrc);
605 if(hGlobal == NULL)
606 return FALSE;
607
608 _ToolBarData* pData = (_ToolBarData*)::LockResource(hGlobal);
609 if(pData == NULL)
610 return FALSE;
611 ATLASSERT(pData->wVersion == 1);
612
613 WORD* pItems = pData->items();
614 int nItems = pData->wItemCount;
615
616 // Set internal data
617 SetImageSize(pData->wWidth, pData->wHeight);
618
619 // Create image list if needed
620 if(m_hImageList == NULL)
621 {
622 // Check if the bitmap is 32-bit (alpha channel) bitmap (valid for Windows XP only)
623 T* pT = static_cast<T*>(this);
624 m_bAlphaImages = AtlIsAlphaBitmapResource(image);
625
626 if(!pT->CreateInternalImageList(pData->wItemCount))
627 return FALSE;
628 }
629
630 #if _WTL_CMDBAR_VISTA_MENUS
631 int nOldImageCount = ::ImageList_GetImageCount(m_hImageList);
632 #endif // _WTL_CMDBAR_VISTA_MENUS
633
634 // Add bitmap to our image list
635 CBitmap bmp;
636 if(bMapped)
637 {
638 ATLASSERT(HIWORD(PtrToUlong(image.m_lpstr)) == 0); // if mapped, must be a numeric ID
639 int nIDImage = (int)(short)LOWORD(PtrToUlong(image.m_lpstr));
640 bmp.LoadMappedBitmap(nIDImage, (WORD)nFlags, lpColorMap, nMapSize);
641 }
642 else
643 {
644 if(m_bAlphaImages)
645 bmp = (HBITMAP)::LoadImage(ModuleHelper::GetResourceInstance(), image.m_lpstr, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
646 else
647 bmp.LoadBitmap(image.m_lpstr);
648 }
649 ATLASSERT(bmp.m_hBitmap != NULL);
650 if(bmp.m_hBitmap == NULL)
651 return FALSE;
652 if(::ImageList_AddMasked(m_hImageList, bmp, m_clrMask) == -1)
653 return FALSE;
654
655 // Fill the array with command IDs
656 for(int i = 0; i < nItems; i++)
657 {
658 if(pItems[i] != 0)
659 m_arrCommand.Add(pItems[i]);
660 }
661
662 int nImageCount = ::ImageList_GetImageCount(m_hImageList);
663 ATLASSERT(nImageCount == m_arrCommand.GetSize());
664 if(nImageCount != m_arrCommand.GetSize())
665 return FALSE;
666
667 #if _WTL_CMDBAR_VISTA_MENUS
668 if(RunTimeHelper::IsVista())
669 {
670 T* pT = static_cast<T*>(this);
671 pT->_AddVistaBitmapsFromImageList(nOldImageCount, nImageCount - nOldImageCount);
672 ATLASSERT(nImageCount == m_arrVistaBitmap.GetSize());
673 }
674 #endif // _WTL_CMDBAR_VISTA_MENUS
675
676 return TRUE;
677 }
678
679 BOOL AddBitmap(ATL::_U_STRINGorID bitmap, int nCommandID)
680 {
681 ATLASSERT(::IsWindow(m_hWnd));
682 CBitmap bmp;
683 bmp.LoadBitmap(bitmap.m_lpstr);
684 if(bmp.m_hBitmap == NULL)
685 return FALSE;
686 return AddBitmap(bmp, nCommandID);
687 }
688
689 BOOL AddBitmap(HBITMAP hBitmap, UINT nCommandID)
690 {
691 ATLASSERT(::IsWindow(m_hWnd));
692 T* pT = static_cast<T*>(this);
693 // Create image list if it doesn't exist
694 if(m_hImageList == NULL)
695 {
696 if(!pT->CreateInternalImageList(1))
697 return FALSE;
698 }
699 // check bitmap size
700 CBitmapHandle bmp = hBitmap;
701 SIZE size = { 0, 0 };
702 bmp.GetSize(size);
703 if(size.cx != m_szBitmap.cx || size.cy != m_szBitmap.cy)
704 {
705 ATLASSERT(FALSE); // must match size!
706 return FALSE;
707 }
708 // add bitmap
709 int nRet = ::ImageList_AddMasked(m_hImageList, hBitmap, m_clrMask);
710 if(nRet == -1)
711 return FALSE;
712 BOOL bRet = m_arrCommand.Add((WORD)nCommandID);
713 ATLASSERT(::ImageList_GetImageCount(m_hImageList) == m_arrCommand.GetSize());
714 #if _WTL_CMDBAR_VISTA_MENUS
715 if(RunTimeHelper::IsVista())
716 {
717 pT->_AddVistaBitmapFromImageList(m_arrCommand.GetSize() - 1);
718 ATLASSERT(m_arrVistaBitmap.GetSize() == m_arrCommand.GetSize());
719 }
720 #endif // _WTL_CMDBAR_VISTA_MENUS
721 return bRet;
722 }
723
724 BOOL AddIcon(ATL::_U_STRINGorID icon, UINT nCommandID)
725 {
726 ATLASSERT(::IsWindow(m_hWnd));
727 HICON hIcon = ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr);
728 if(hIcon == NULL)
729 return FALSE;
730 return AddIcon(hIcon, nCommandID);
731 }
732
733 BOOL AddIcon(HICON hIcon, UINT nCommandID)
734 {
735 ATLASSERT(::IsWindow(m_hWnd));
736 T* pT = static_cast<T*>(this);
737 // create image list if it doesn't exist
738 if(m_hImageList == NULL)
739 {
740 if(!pT->CreateInternalImageList(1))
741 return FALSE;
742 }
743
744 int nRet = ::ImageList_AddIcon(m_hImageList, hIcon);
745 if(nRet == -1)
746 return FALSE;
747 BOOL bRet = m_arrCommand.Add((WORD)nCommandID);
748 ATLASSERT(::ImageList_GetImageCount(m_hImageList) == m_arrCommand.GetSize());
749 #if _WTL_CMDBAR_VISTA_MENUS
750 if(RunTimeHelper::IsVista())
751 {
752 pT->_AddVistaBitmapFromImageList(m_arrCommand.GetSize() - 1);
753 ATLASSERT(m_arrVistaBitmap.GetSize() == m_arrCommand.GetSize());
754 }
755 #endif // _WTL_CMDBAR_VISTA_MENUS
756 return bRet;
757 }
758
759 BOOL ReplaceBitmap(ATL::_U_STRINGorID bitmap, int nCommandID)
760 {
761 ATLASSERT(::IsWindow(m_hWnd));
762 CBitmap bmp;
763 bmp.LoadBitmap(bitmap.m_lpstr);
764 if(bmp.m_hBitmap == NULL)
765 return FALSE;
766 return ReplaceBitmap(bmp, nCommandID);
767 }
768
769 BOOL ReplaceBitmap(HBITMAP hBitmap, UINT nCommandID)
770 {
771 ATLASSERT(::IsWindow(m_hWnd));
772 BOOL bRet = FALSE;
773 for(int i = 0; i < m_arrCommand.GetSize(); i++)
774 {
775 if(m_arrCommand[i] == nCommandID)
776 {
777 bRet = ::ImageList_Remove(m_hImageList, i);
778 if(bRet)
779 {
780 m_arrCommand.RemoveAt(i);
781 #if _WTL_CMDBAR_VISTA_MENUS
782 if(RunTimeHelper::IsVista())
783 {
784 if(m_arrVistaBitmap[i] != NULL)
785 ::DeleteObject(m_arrVistaBitmap[i]);
786 m_arrVistaBitmap.RemoveAt(i);
787 }
788 #endif // _WTL_CMDBAR_VISTA_MENUS
789 }
790 break;
791 }
792 }
793 if(bRet)
794 bRet = AddBitmap(hBitmap, nCommandID);
795 return bRet;
796 }
797
798 BOOL ReplaceIcon(ATL::_U_STRINGorID icon, UINT nCommandID)
799 {
800 ATLASSERT(::IsWindow(m_hWnd));
801 HICON hIcon = ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr);
802 if(hIcon == NULL)
803 return FALSE;
804 return ReplaceIcon(hIcon, nCommandID);
805 }
806
807 BOOL ReplaceIcon(HICON hIcon, UINT nCommandID)
808 {
809 ATLASSERT(::IsWindow(m_hWnd));
810 BOOL bRet = FALSE;
811 for(int i = 0; i < m_arrCommand.GetSize(); i++)
812 {
813 if(m_arrCommand[i] == nCommandID)
814 {
815 bRet = (::ImageList_ReplaceIcon(m_hImageList, i, hIcon) != -1);
816 #if _WTL_CMDBAR_VISTA_MENUS
817 if(RunTimeHelper::IsVista() && bRet != FALSE)
818 {
819 T* pT = static_cast<T*>(this);
820 pT->_ReplaceVistaBitmapFromImageList(i);
821 }
822 #endif // _WTL_CMDBAR_VISTA_MENUS
823 break;
824 }
825 }
826 return bRet;
827 }
828
829 BOOL RemoveImage(int nCommandID)
830 {
831 ATLASSERT(::IsWindow(m_hWnd));
832
833 BOOL bRet = FALSE;
834 for(int i = 0; i < m_arrCommand.GetSize(); i++)
835 {
836 if(m_arrCommand[i] == nCommandID)
837 {
838 bRet = ::ImageList_Remove(m_hImageList, i);
839 if(bRet)
840 {
841 m_arrCommand.RemoveAt(i);
842 #if _WTL_CMDBAR_VISTA_MENUS
843 if(RunTimeHelper::IsVista())
844 {
845 if(m_arrVistaBitmap[i] != NULL)
846 ::DeleteObject(m_arrVistaBitmap[i]);
847 m_arrVistaBitmap.RemoveAt(i);
848 }
849 #endif // _WTL_CMDBAR_VISTA_MENUS
850 }
851 break;
852 }
853 }
854 return bRet;
855 }
856
857 BOOL RemoveAllImages()
858 {
859 ATLASSERT(::IsWindow(m_hWnd));
860
861 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Removing all images\n"));
862 BOOL bRet = ::ImageList_RemoveAll(m_hImageList);
863 if(bRet)
864 {
865 m_arrCommand.RemoveAll();
866 #if _WTL_CMDBAR_VISTA_MENUS
867 for(int i = 0; i < m_arrVistaBitmap.GetSize(); i++)
868 {
869 if(m_arrVistaBitmap[i] != NULL)
870 ::DeleteObject(m_arrVistaBitmap[i]);
871 }
872 m_arrVistaBitmap.RemoveAll();
873 #endif // _WTL_CMDBAR_VISTA_MENUS
874 }
875 return bRet;
876 }
877
878 BOOL TrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y, LPTPMPARAMS lpParams = NULL)
879 {
880 ATLASSERT(::IsWindow(m_hWnd));
881 ATLASSERT(::IsMenu(hMenu));
882 if(!::IsMenu(hMenu))
883 return FALSE;
884 m_bContextMenu = true;
885 if(m_bUseKeyboardCues)
886 m_bShowKeyboardCues = m_bKeyboardInput;
887 T* pT = static_cast<T*>(this);
888 return pT->DoTrackPopupMenu(hMenu, uFlags, x, y, lpParams);
889 }
890
891 BOOL SetMDIClient(HWND /*hWndMDIClient*/)
892 {
893 // Use CMDICommandBarCtrl for MDI support
894 ATLASSERT(FALSE);
895 return FALSE;
896 }
897
898 // Message map and handlers
899 BEGIN_MSG_MAP(CCommandBarCtrlImpl)
900 MESSAGE_HANDLER(WM_CREATE, OnCreate)
901 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
902 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
903 MESSAGE_HANDLER(WM_INITMENU, OnInitMenu)
904 MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup)
905 MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect)
906 MESSAGE_HANDLER(GetAutoPopupMessage(), OnInternalAutoPopup)
907 MESSAGE_HANDLER(GetGetBarMessage(), OnInternalGetBar)
908 MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
909 MESSAGE_HANDLER(WM_MENUCHAR, OnMenuChar)
910 MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus)
911
912 MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
913 MESSAGE_HANDLER(WM_KEYUP, OnKeyUp)
914 MESSAGE_HANDLER(WM_CHAR, OnChar)
915 MESSAGE_HANDLER(WM_SYSKEYDOWN, OnSysKeyDown)
916 MESSAGE_HANDLER(WM_SYSKEYUP, OnSysKeyUp)
917 MESSAGE_HANDLER(WM_SYSCHAR, OnSysChar)
918 // public API handlers - these stay to support chevrons in atlframe.h
919 MESSAGE_HANDLER(CBRM_GETMENU, OnAPIGetMenu)
920 MESSAGE_HANDLER(CBRM_TRACKPOPUPMENU, OnAPITrackPopupMenu)
921 MESSAGE_HANDLER(CBRM_GETCMDBAR, OnAPIGetCmdBar)
922
923 MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem)
924 MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem)
925
926 MESSAGE_HANDLER(WM_FORWARDMSG, OnForwardMsg)
927 ALT_MSG_MAP(1) // Parent window messages
928 NOTIFY_CODE_HANDLER(TBN_HOTITEMCHANGE, OnParentHotItemChange)
929 NOTIFY_CODE_HANDLER(TBN_DROPDOWN, OnParentDropDown)
930 MESSAGE_HANDLER(WM_INITMENUPOPUP, OnParentInitMenuPopup)
931 MESSAGE_HANDLER(GetGetBarMessage(), OnParentInternalGetBar)
932 MESSAGE_HANDLER(WM_SYSCOMMAND, OnParentSysCommand)
933 MESSAGE_HANDLER(CBRM_GETMENU, OnParentAPIGetMenu)
934 MESSAGE_HANDLER(WM_MENUCHAR, OnParentMenuChar)
935 MESSAGE_HANDLER(CBRM_TRACKPOPUPMENU, OnParentAPITrackPopupMenu)
936 MESSAGE_HANDLER(CBRM_GETCMDBAR, OnParentAPIGetCmdBar)
937 MESSAGE_HANDLER(WM_SETTINGCHANGE, OnParentSettingChange)
938
939 MESSAGE_HANDLER(WM_DRAWITEM, OnParentDrawItem)
940 MESSAGE_HANDLER(WM_MEASUREITEM, OnParentMeasureItem)
941
942 MESSAGE_HANDLER(WM_ACTIVATE, OnParentActivate)
943 NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnParentCustomDraw)
944 ALT_MSG_MAP(2) // MDI client window messages
945 // Use CMDICommandBarCtrl for MDI support
946 ALT_MSG_MAP(3) // Message hook messages
947 MESSAGE_HANDLER(WM_MOUSEMOVE, OnHookMouseMove)
948 MESSAGE_HANDLER(WM_SYSKEYDOWN, OnHookSysKeyDown)
949 MESSAGE_HANDLER(WM_SYSKEYUP, OnHookSysKeyUp)
950 MESSAGE_HANDLER(WM_SYSCHAR, OnHookSysChar)
951 MESSAGE_HANDLER(WM_KEYDOWN, OnHookKeyDown)
952 MESSAGE_HANDLER(WM_NEXTMENU, OnHookNextMenu)
953 MESSAGE_HANDLER(WM_CHAR, OnHookChar)
954 END_MSG_MAP()
955
956 LRESULT OnForwardMsg(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
957 {
958 LPMSG pMsg = (LPMSG)lParam;
959 if(pMsg->message >= WM_MOUSEFIRST && pMsg->message <= WM_MOUSELAST)
960 m_bKeyboardInput = false;
961 else if(pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
962 m_bKeyboardInput = true;
963 LRESULT lRet = 0;
964 ProcessWindowMessage(pMsg->hwnd, pMsg->message, pMsg->wParam, pMsg->lParam, lRet, 3);
965 return lRet;
966 }
967
968 LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
969 {
970 // Let the toolbar initialize itself
971 LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
972 // get and use system settings
973 T* pT = static_cast<T*>(this);
974 pT->GetSystemSettings();
975 // Parent init
976 ATL::CWindow wndParent = GetParent();
977 ATL::CWindow wndTopLevelParent = wndParent.GetTopLevelParent();
978 m_wndParent.SubclassWindow(wndTopLevelParent);
979 // Toolbar Init
980 SetButtonStructSize();
981 SetImageList(NULL);
982
983 // Create message hook if needed
984 CWindowCreateCriticalSectionLock lock;
985 if(FAILED(lock.Lock()))
986 {
987 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::OnCreate.\n"));
988 ATLASSERT(FALSE);
989 return -1;
990 }
991
992 if(s_pmapMsgHook == NULL)
993 {
994 ATLTRY(s_pmapMsgHook = new CMsgHookMap);
995 ATLASSERT(s_pmapMsgHook != NULL);
996 }
997
998 if(s_pmapMsgHook != NULL)
999 {
1000 DWORD dwThreadID = ::GetCurrentThreadId();
1001 _MsgHookData* pData = s_pmapMsgHook->Lookup(dwThreadID);
1002 if(pData == NULL)
1003 {
1004 ATLTRY(pData = new _MsgHookData);
1005 ATLASSERT(pData != NULL);
1006 HHOOK hMsgHook = ::SetWindowsHookEx(WH_GETMESSAGE, MessageHookProc, ModuleHelper::GetModuleInstance(), dwThreadID);
1007 ATLASSERT(hMsgHook != NULL);
1008 if(pData != NULL && hMsgHook != NULL)
1009 {
1010 pData->hMsgHook = hMsgHook;
1011 pData->dwUsage = 1;
1012 BOOL bRet = s_pmapMsgHook->Add(dwThreadID, pData);
1013 bRet;
1014 ATLASSERT(bRet);
1015 }
1016 }
1017 else
1018 {
1019 (pData->dwUsage)++;
1020 }
1021 }
1022 lock.Unlock();
1023
1024 // Get layout
1025 #if (WINVER >= 0x0500)
1026 m_bLayoutRTL = ((GetExStyle() & WS_EX_LAYOUTRTL) != 0);
1027 #endif // (WINVER >= 0x0500)
1028
1029 return lRet;
1030 }
1031
1032 LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
1033 {
1034 LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
1035
1036 #if _WTL_CMDBAR_VISTA_MENUS
1037 if(m_bVistaMenus && (m_hMenu != NULL))
1038 {
1039 T* pT = static_cast<T*>(this);
1040 pT->_RemoveVistaBitmapsFromMenu();
1041 }
1042
1043 for(int i = 0; i < m_arrVistaBitmap.GetSize(); i++)
1044 {
1045 if(m_arrVistaBitmap[i] != NULL)
1046 ::DeleteObject(m_arrVistaBitmap[i]);
1047 }
1048 #endif // _WTL_CMDBAR_VISTA_MENUS
1049
1050 if(m_bAttachedMenu) // nothing to do in this mode
1051 return lRet;
1052
1053 CWindowCreateCriticalSectionLock lock;
1054 if(FAILED(lock.Lock()))
1055 {
1056 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::OnDestroy.\n"));
1057 ATLASSERT(FALSE);
1058 return lRet;
1059 }
1060
1061 if(s_pmapMsgHook != NULL)
1062 {
1063 DWORD dwThreadID = ::GetCurrentThreadId();
1064 _MsgHookData* pData = s_pmapMsgHook->Lookup(dwThreadID);
1065 if(pData != NULL)
1066 {
1067 (pData->dwUsage)--;
1068 if(pData->dwUsage == 0)
1069 {
1070 BOOL bRet = ::UnhookWindowsHookEx(pData->hMsgHook);
1071 ATLASSERT(bRet);
1072 bRet = s_pmapMsgHook->Remove(dwThreadID);
1073 ATLASSERT(bRet);
1074 if(bRet)
1075 delete pData;
1076 }
1077
1078 if(s_pmapMsgHook->GetSize() == 0)
1079 {
1080 delete s_pmapMsgHook;
1081 s_pmapMsgHook = NULL;
1082 }
1083 }
1084 }
1085
1086 lock.Unlock();
1087
1088 return lRet;
1089 }
1090
1091 LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1092 {
1093 #ifdef _CMDBAR_EXTRA_TRACE
1094 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnKeyDown\n"));
1095 #endif
1096 if(m_bAttachedMenu) // nothing to do in this mode
1097 {
1098 bHandled = FALSE;
1099 return 1;
1100 }
1101
1102 bHandled = FALSE;
1103 // Simulate Alt+Space for the parent
1104 if(wParam == VK_SPACE)
1105 {
1106 m_wndParent.PostMessage(WM_SYSKEYDOWN, wParam, lParam | (1 << 29));
1107 bHandled = TRUE;
1108 }
1109 #if (_WIN32_IE >= 0x0500)
1110 else if(wParam == VK_LEFT || wParam == VK_RIGHT)
1111 {
1112 WPARAM wpNext = m_bLayoutRTL ? VK_LEFT : VK_RIGHT;
1113
1114 if(!m_bMenuActive)
1115 {
1116 T* pT = static_cast<T*>(this);
1117 int nBtn = GetHotItem();
1118 int nNextBtn = (wParam == wpNext) ? pT->GetNextMenuItem(nBtn) : pT->GetPreviousMenuItem(nBtn);
1119 if(nNextBtn == -2)
1120 {
1121 SetHotItem(-1);
1122 if(pT->DisplayChevronMenu())
1123 bHandled = TRUE;
1124 }
1125 }
1126 }
1127 #endif // (_WIN32_IE >= 0x0500)
1128 return 0;
1129 }
1130
1131 LRESULT OnKeyUp(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
1132 {
1133 #ifdef _CMDBAR_EXTRA_TRACE
1134 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnKeyUp\n"));
1135 #endif
1136 if(m_bAttachedMenu) // nothing to do in this mode
1137 {
1138 bHandled = FALSE;
1139 return 1;
1140 }
1141
1142 if(wParam != VK_SPACE)
1143 bHandled = FALSE;
1144
1145 return 0;
1146 }
1147
1148 LRESULT OnChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
1149 {
1150 #ifdef _CMDBAR_EXTRA_TRACE
1151 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnChar\n"));
1152 #endif
1153 if(m_bAttachedMenu) // nothing to do in this mode
1154 {
1155 bHandled = FALSE;
1156 return 1;
1157 }
1158
1159 if(wParam != VK_SPACE)
1160 bHandled = FALSE;
1161 else
1162 return 0;
1163 // Security
1164 if(!m_wndParent.IsWindowEnabled() || ::GetFocus() != m_hWnd)
1165 return 0;
1166
1167 // Handle mnemonic press when we have focus
1168 int nBtn = 0;
1169 if(wParam != VK_RETURN && !MapAccelerator((TCHAR)LOWORD(wParam), nBtn))
1170 {
1171 #if (_WIN32_IE >= 0x0500)
1172 if((TCHAR)LOWORD(wParam) != _chChevronShortcut)
1173 #endif // (_WIN32_IE >= 0x0500)
1174 ::MessageBeep(0);
1175 }
1176 else
1177 {
1178 #if (_WIN32_IE >= 0x0500)
1179 RECT rcClient = { 0 };
1180 GetClientRect(&rcClient);
1181 RECT rcBtn = { 0 };
1182 GetItemRect(nBtn, &rcBtn);
1183 TBBUTTON tbb = { 0 };
1184 GetButton(nBtn, &tbb);
1185 if((tbb.fsState & TBSTATE_ENABLED) != 0 && (tbb.fsState & TBSTATE_HIDDEN) == 0 && rcBtn.right <= rcClient.right)
1186 {
1187 #endif // (_WIN32_IE >= 0x0500)
1188 PostMessage(WM_KEYDOWN, VK_DOWN, 0L);
1189 if(wParam != VK_RETURN)
1190 SetHotItem(nBtn);
1191 #if (_WIN32_IE >= 0x0500)
1192 }
1193 else
1194 {
1195 ::MessageBeep(0);
1196 bHandled = TRUE;
1197 }
1198 #endif // (_WIN32_IE >= 0x0500)
1199 }
1200 return 0;
1201 }
1202
1203 LRESULT OnSysKeyDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
1204 {
1205 #ifdef _CMDBAR_EXTRA_TRACE
1206 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnSysKeyDown\n"));
1207 #endif
1208 bHandled = FALSE;
1209 return 0;
1210 }
1211
1212 LRESULT OnSysKeyUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
1213 {
1214 #ifdef _CMDBAR_EXTRA_TRACE
1215 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnSysKeyUp\n"));
1216 #endif
1217 bHandled = FALSE;
1218 return 0;
1219 }
1220
1221 LRESULT OnSysChar(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
1222 {
1223 #ifdef _CMDBAR_EXTRA_TRACE
1224 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnSysChar\n"));
1225 #endif
1226 bHandled = FALSE;
1227 return 0;
1228 }
1229
1230 LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
1231 {
1232 if(m_bAttachedMenu || (m_dwExtendedStyle & CBR_EX_TRANSPARENT))
1233 {
1234 bHandled = FALSE;
1235 return 0;
1236 }
1237
1238 CDCHandle dc = (HDC)wParam;
1239 RECT rect = { 0 };
1240 GetClientRect(&rect);
1241 dc.FillRect(&rect, COLOR_MENU);
1242
1243 return 1; // don't do the default erase
1244 }
1245
1246 LRESULT OnInitMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
1247 {
1248 int nIndex = GetHotItem();
1249 SendMessage(WM_MENUSELECT, MAKEWPARAM(nIndex, MF_POPUP|MF_HILITE), (LPARAM)m_hMenu);
1250 bHandled = FALSE;
1251 return 1;
1252 }
1253
1254 LRESULT OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1255 {
1256 if((BOOL)HIWORD(lParam)) // System menu, do nothing
1257 {
1258 bHandled = FALSE;
1259 return 1;
1260 }
1261
1262 if(!(m_bAttachedMenu || m_bMenuActive)) // Not attached or ours, do nothing
1263 {
1264 bHandled = FALSE;
1265 return 1;
1266 }
1267
1268 #ifdef _CMDBAR_EXTRA_TRACE
1269 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnInitMenuPopup\n"));
1270 #endif
1271 // forward to the parent or subclassed window, so it can handle update UI
1272 LRESULT lRet = 0;
1273 if(m_bAttachedMenu)
1274 lRet = DefWindowProc(uMsg, wParam, (lParam || m_bContextMenu) ? lParam : GetHotItem());
1275 else
1276 lRet = m_wndParent.DefWindowProc(uMsg, wParam, (lParam || m_bContextMenu) ? lParam : GetHotItem());
1277
1278 #if _WTL_CMDBAR_VISTA_MENUS
1279 // If Vista menus are active, just set bitmaps and return
1280 if(m_bVistaMenus)
1281 {
1282 CMenuHandle menu = (HMENU)wParam;
1283 ATLASSERT(menu.m_hMenu != NULL);
1284
1285 for(int i = 0; i < menu.GetMenuItemCount(); i++)
1286 {
1287 WORD nID = (WORD)menu.GetMenuItemID(i);
1288 int nIndex = m_arrCommand.Find(nID);
1289
1290 CMenuItemInfo mii;
1291 mii.fMask = MIIM_BITMAP;
1292 mii.hbmpItem = (m_bImagesVisible && (nIndex != -1)) ? m_arrVistaBitmap[nIndex] : NULL;
1293 menu.SetMenuItemInfo(i, TRUE, &mii);
1294 }
1295
1296 return lRet;
1297 }
1298 #endif // _WTL_CMDBAR_VISTA_MENUS
1299
1300 // Convert menu items to ownerdraw, add our data
1301 if(m_bImagesVisible)
1302 {
1303 CMenuHandle menuPopup = (HMENU)wParam;
1304 ATLASSERT(menuPopup.m_hMenu != NULL);
1305
1306 T* pT = static_cast<T*>(this);
1307 pT; // avoid level 4 warning
1308 TCHAR szString[pT->_nMaxMenuItemTextLength] = { 0 };
1309 BOOL bRet = FALSE;
1310 for(int i = 0; i < menuPopup.GetMenuItemCount(); i++)
1311 {
1312 CMenuItemInfo mii;
1313 mii.cch = pT->_nMaxMenuItemTextLength;
1314 mii.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE;
1315 mii.dwTypeData = szString;
1316 bRet = menuPopup.GetMenuItemInfo(i, TRUE, &mii);
1317 ATLASSERT(bRet);
1318
1319 if(!(mii.fType & MFT_OWNERDRAW)) // Not already an ownerdraw item
1320 {
1321 mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_STATE;
1322 _MenuItemData* pMI = NULL;
1323 ATLTRY(pMI = new _MenuItemData);
1324 ATLASSERT(pMI != NULL);
1325 if(pMI != NULL)
1326 {
1327 pMI->fType = mii.fType;
1328 pMI->fState = mii.fState;
1329 mii.fType |= MFT_OWNERDRAW;
1330 pMI->iButton = -1;
1331 for(int j = 0; j < m_arrCommand.GetSize(); j++)
1332 {
1333 if(m_arrCommand[j] == mii.wID)
1334 {
1335 pMI->iButton = j;
1336 break;
1337 }
1338 }
1339 int cchLen = lstrlen(szString) + 1;
1340 pMI->lpstrText = NULL;
1341 ATLTRY(pMI->lpstrText = new TCHAR[cchLen]);
1342 ATLASSERT(pMI->lpstrText != NULL);
1343 if(pMI->lpstrText != NULL)
1344 SecureHelper::strcpy_x(pMI->lpstrText, cchLen, szString);
1345 mii.dwItemData = (ULONG_PTR)pMI;
1346 bRet = menuPopup.SetMenuItemInfo(i, TRUE, &mii);
1347 ATLASSERT(bRet);
1348 }
1349 }
1350 }
1351
1352 // Add it to the list
1353 m_stackMenuHandle.Push(menuPopup.m_hMenu);
1354 }
1355
1356 return lRet;
1357 }
1358
1359 LRESULT OnMenuSelect(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1360 {
1361 if(!m_bAttachedMenu) // Not attached, do nothing, forward to parent
1362 {
1363 m_bPopupItem = (lParam != NULL) && ((HMENU)lParam != m_hMenu) && (HIWORD(wParam) & MF_POPUP);
1364 if(m_wndParent.IsWindow())
1365 m_wndParent.SendMessage(uMsg, wParam, lParam);
1366 bHandled = FALSE;
1367 return 1;
1368 }
1369
1370 // Check if a menu is closing, do a cleanup
1371 if(HIWORD(wParam) == 0xFFFF && lParam == NULL) // Menu closing
1372 {
1373 #ifdef _CMDBAR_EXTRA_TRACE
1374 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnMenuSelect - CLOSING!!!!\n"));
1375 #endif
1376 ATLASSERT(m_stackMenuWnd.GetSize() == 0);
1377 // Restore the menu items to the previous state for all menus that were converted
1378 if(m_bImagesVisible)
1379 {
1380 HMENU hMenu = NULL;
1381 while((hMenu = m_stackMenuHandle.Pop()) != NULL)
1382 {
1383 CMenuHandle menuPopup = hMenu;
1384 ATLASSERT(menuPopup.m_hMenu != NULL);
1385 // Restore state and delete menu item data
1386 BOOL bRet = FALSE;
1387 for(int i = 0; i < menuPopup.GetMenuItemCount(); i++)
1388 {
1389 CMenuItemInfo mii;
1390 mii.fMask = MIIM_DATA | MIIM_TYPE;
1391 bRet = menuPopup.GetMenuItemInfo(i, TRUE, &mii);
1392 ATLASSERT(bRet);
1393
1394 _MenuItemData* pMI = (_MenuItemData*)mii.dwItemData;
1395 if(pMI != NULL && pMI->IsCmdBarMenuItem())
1396 {
1397 mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_STATE;
1398 mii.fType = pMI->fType;
1399 mii.dwTypeData = pMI->lpstrText;
1400 mii.cch = lstrlen(pMI->lpstrText);
1401 mii.dwItemData = NULL;
1402
1403 bRet = menuPopup.SetMenuItemInfo(i, TRUE, &mii);
1404 ATLASSERT(bRet);
1405
1406 delete [] pMI->lpstrText;
1407 pMI->dwMagic = 0x6666;
1408 delete pMI;
1409 }
1410 }
1411 }
1412 }
1413 }
1414
1415 bHandled = FALSE;
1416 return 1;
1417 }
1418
1419 LRESULT OnInternalAutoPopup(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1420 {
1421 int nIndex = (int)wParam;
1422 T* pT = static_cast<T*>(this);
1423 pT->DoPopupMenu(nIndex, false);
1424 return 0;
1425 }
1426
1427 LRESULT OnInternalGetBar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1428 {
1429 // Let's make sure we're not embedded in another process
1430 if((LPVOID)wParam != NULL)
1431 *((DWORD*)wParam) = GetCurrentProcessId();
1432 if(IsWindowVisible())
1433 return (LRESULT)static_cast<CCommandBarCtrlBase*>(this);
1434 else
1435 return NULL;
1436 }
1437
1438 LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1439 {
1440 #ifndef SPI_SETKEYBOARDCUES
1441 const UINT SPI_SETKEYBOARDCUES = 0x100B;
1442 #endif // !SPI_SETKEYBOARDCUES
1443 #ifndef SPI_GETFLATMENU
1444 const UINT SPI_SETFLATMENU = 0x1023;
1445 #endif // !SPI_GETFLATMENU
1446
1447 if(wParam == SPI_SETNONCLIENTMETRICS || wParam == SPI_SETKEYBOARDCUES || wParam == SPI_SETFLATMENU)
1448 {
1449 T* pT = static_cast<T*>(this);
1450 pT->GetSystemSettings();
1451 }
1452
1453 return 0;
1454 }
1455
1456 LRESULT OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
1457 {
1458 LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
1459
1460 LPWINDOWPOS lpWP = (LPWINDOWPOS)lParam;
1461 int cyMin = ::GetSystemMetrics(SM_CYMENU);
1462 if(lpWP->cy < cyMin)
1463 lpWP->cy = cyMin;
1464
1465 return lRet;
1466 }
1467
1468 LRESULT OnMenuChar(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1469 {
1470 #ifdef _CMDBAR_EXTRA_TRACE
1471 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnMenuChar\n"));
1472 #endif
1473 bHandled = TRUE;
1474 T* pT = static_cast<T*>(this);
1475
1476 LRESULT lRet;
1477 if(m_bMenuActive && LOWORD(wParam) != 0x0D)
1478 lRet = 0;
1479 else
1480 lRet = MAKELRESULT(1, 1);
1481
1482 if(m_bMenuActive && HIWORD(wParam) == MF_POPUP)
1483 {
1484 // Convert character to lower/uppercase and possibly Unicode, using current keyboard layout
1485 TCHAR ch = (TCHAR)LOWORD(wParam);
1486 CMenuHandle menu = (HMENU)lParam;
1487 int nCount = ::GetMenuItemCount(menu);
1488 int nRetCode = MNC_EXECUTE;
1489 BOOL bRet = FALSE;
1490 TCHAR szString[pT->_nMaxMenuItemTextLength] = { 0 };
1491 WORD wMnem = 0;
1492 bool bFound = false;
1493 for(int i = 0; i < nCount; i++)
1494 {
1495 CMenuItemInfo mii;
1496 mii.cch = pT->_nMaxMenuItemTextLength;
1497 mii.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE;
1498 mii.dwTypeData = szString;
1499 bRet = menu.GetMenuItemInfo(i, TRUE, &mii);
1500 if(!bRet || (mii.fType & MFT_SEPARATOR))
1501 continue;
1502 _MenuItemData* pmd = (_MenuItemData*)mii.dwItemData;
1503 if(pmd != NULL && pmd->IsCmdBarMenuItem())
1504 {
1505 LPTSTR p = pmd->lpstrText;
1506
1507 if(p != NULL)
1508 {
1509 while(*p && *p != _T('&'))
1510 p = ::CharNext(p);
1511 if(p != NULL && *p)
1512 {
1513 DWORD dwP = MAKELONG(*(++p), 0);
1514 DWORD dwC = MAKELONG(ch, 0);
1515 if(::CharLower((LPTSTR)ULongToPtr(dwP)) == ::CharLower((LPTSTR)ULongToPtr(dwC)))
1516 {
1517 if(!bFound)
1518 {
1519 wMnem = (WORD)i;
1520 bFound = true;
1521 }
1522 else
1523 {
1524 nRetCode = MNC_SELECT;
1525 break;
1526 }
1527 }
1528 }
1529 }
1530 }
1531 }
1532 if(bFound)
1533 {
1534 if(nRetCode == MNC_EXECUTE)
1535 {
1536 PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L);
1537 pT->GiveFocusBack();
1538 }
1539 bHandled = TRUE;
1540 lRet = MAKELRESULT(wMnem, nRetCode);
1541 }
1542 }
1543 else if(!m_bMenuActive)
1544 {
1545 int nBtn = 0;
1546 if(!MapAccelerator((TCHAR)LOWORD(wParam), nBtn))
1547 {
1548 bHandled = FALSE;
1549 PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L);
1550 pT->GiveFocusBack();
1551
1552 #if (_WIN32_IE >= 0x0500)
1553 // check if we should display chevron menu
1554 if((TCHAR)LOWORD(wParam) == pT->_chChevronShortcut)
1555 {
1556 if(pT->DisplayChevronMenu())
1557 bHandled = TRUE;
1558 }
1559 #endif // (_WIN32_IE >= 0x0500)
1560 }
1561 else if(m_wndParent.IsWindowEnabled())
1562 {
1563 #if (_WIN32_IE >= 0x0500)
1564 RECT rcClient = { 0 };
1565 GetClientRect(&rcClient);
1566 RECT rcBtn = { 0 };
1567 GetItemRect(nBtn, &rcBtn);
1568 TBBUTTON tbb = { 0 };
1569 GetButton(nBtn, &tbb);
1570 if((tbb.fsState & TBSTATE_ENABLED) != 0 && (tbb.fsState & TBSTATE_HIDDEN) == 0 && rcBtn.right <= rcClient.right)
1571 {
1572 #endif // (_WIN32_IE >= 0x0500)
1573 if(m_bUseKeyboardCues && !m_bShowKeyboardCues)
1574 {
1575 m_bAllowKeyboardCues = true;
1576 ShowKeyboardCues(true);
1577 }
1578 pT->TakeFocus();
1579 PostMessage(WM_KEYDOWN, VK_DOWN, 0L);
1580 SetHotItem(nBtn);
1581 #if (_WIN32_IE >= 0x0500)
1582 }
1583 else
1584 {
1585 ::MessageBeep(0);
1586 }
1587 #endif // (_WIN32_IE >= 0x0500)
1588 }
1589 }
1590
1591 return lRet;
1592 }
1593
1594 LRESULT OnKillFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
1595 {
1596 if(m_bUseKeyboardCues && m_bShowKeyboardCues)
1597 ShowKeyboardCues(false);
1598
1599 bHandled = FALSE;
1600 return 1;
1601 }
1602
1603 LRESULT OnDrawItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
1604 {
1605 LPDRAWITEMSTRUCT lpDrawItemStruct = (LPDRAWITEMSTRUCT)lParam;
1606 _MenuItemData* pmd = (_MenuItemData*)lpDrawItemStruct->itemData;
1607 if(lpDrawItemStruct->CtlType == ODT_MENU && pmd != NULL && pmd->IsCmdBarMenuItem())
1608 {
1609 T* pT = static_cast<T*>(this);
1610 pT->DrawItem(lpDrawItemStruct);
1611 }
1612 else
1613 {
1614 bHandled = FALSE;
1615 }
1616 return (LRESULT)TRUE;
1617 }
1618
1619 LRESULT OnMeasureItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
1620 {
1621 LPMEASUREITEMSTRUCT lpMeasureItemStruct = (LPMEASUREITEMSTRUCT)lParam;
1622 _MenuItemData* pmd = (_MenuItemData*)lpMeasureItemStruct->itemData;
1623 if(lpMeasureItemStruct->CtlType == ODT_MENU && pmd != NULL && pmd->IsCmdBarMenuItem())
1624 {
1625 T* pT = static_cast<T*>(this);
1626 pT->MeasureItem(lpMeasureItemStruct);
1627 }
1628 else
1629 {
1630 bHandled = FALSE;
1631 }
1632 return (LRESULT)TRUE;
1633 }
1634
1635 // API message handlers
1636 LRESULT OnAPIGetMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1637 {
1638 return (LRESULT)m_hMenu;
1639 }
1640
1641 LRESULT OnAPITrackPopupMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
1642 {
1643 if(lParam == NULL)
1644 return FALSE;
1645 LPCBRPOPUPMENU lpCBRPopupMenu = (LPCBRPOPUPMENU)lParam;
1646 if(lpCBRPopupMenu->cbSize != sizeof(CBRPOPUPMENU))
1647 return FALSE;
1648
1649 T* pT = static_cast<T*>(this);
1650 return pT->TrackPopupMenu(lpCBRPopupMenu->hMenu, lpCBRPopupMenu->uFlags, lpCBRPopupMenu->x, lpCBRPopupMenu->y, lpCBRPopupMenu->lptpm);
1651 }
1652
1653 LRESULT OnAPIGetCmdBar(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1654 {
1655 return (LRESULT)m_hWnd;
1656 }
1657
1658 // Parent window message handlers
1659 LRESULT OnParentHotItemChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
1660 {
1661 LPNMTBHOTITEM lpNMHT = (LPNMTBHOTITEM)pnmh;
1662
1663 // Check if this comes from us
1664 if(pnmh->hwndFrom != m_hWnd)
1665 {
1666 bHandled = FALSE;
1667 return 0;
1668 }
1669
1670 bool bBlockTracking = false;
1671 if((m_dwExtendedStyle & CBR_EX_TRACKALWAYS) == 0)
1672 {
1673 DWORD dwProcessID;
1674 ::GetWindowThreadProcessId(::GetActiveWindow(), &dwProcessID);
1675 bBlockTracking = (::GetCurrentProcessId() != dwProcessID);
1676 }
1677
1678 if((!m_wndParent.IsWindowEnabled() || bBlockTracking) && (lpNMHT->dwFlags & HICF_MOUSE))
1679 {
1680 return 1;
1681 }
1682 else
1683 {
1684 #ifndef HICF_LMOUSE
1685 const DWORD HICF_LMOUSE = 0x00000080; // left mouse button selected
1686 #endif
1687 bHandled = FALSE;
1688
1689 // Send WM_MENUSELECT to the app if it needs to display a status text
1690 if(!(lpNMHT->dwFlags & HICF_MOUSE)
1691 && !(lpNMHT->dwFlags & HICF_ACCELERATOR)
1692 && !(lpNMHT->dwFlags & HICF_LMOUSE))
1693 {
1694 if(lpNMHT->dwFlags & HICF_ENTERING)
1695 m_wndParent.SendMessage(WM_MENUSELECT, 0, (LPARAM)m_hMenu);
1696 if(lpNMHT->dwFlags & HICF_LEAVING)
1697 m_wndParent.SendMessage(WM_MENUSELECT, MAKEWPARAM(0, 0xFFFF), NULL);
1698 }
1699
1700 return 0;
1701 }
1702 }
1703
1704 LRESULT OnParentDropDown(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
1705 {
1706 // Check if this comes from us
1707 if(pnmh->hwndFrom != m_hWnd)
1708 {
1709 bHandled = FALSE;
1710 return 1;
1711 }
1712
1713 T* pT = static_cast<T*>(this);
1714 if(::GetFocus() != m_hWnd)
1715 pT->TakeFocus();
1716 LPNMTOOLBAR pNMToolBar = (LPNMTOOLBAR)pnmh;
1717 int nIndex = CommandToIndex(pNMToolBar->iItem);
1718 m_bContextMenu = false;
1719 m_bEscapePressed = false;
1720 pT->DoPopupMenu(nIndex, true);
1721
1722 return TBDDRET_DEFAULT;
1723 }
1724
1725 LRESULT OnParentInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1726 {
1727 return OnInitMenuPopup(uMsg, wParam, lParam, bHandled);
1728 }
1729
1730 LRESULT OnParentInternalGetBar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1731 {
1732 return OnInternalGetBar(uMsg, wParam, lParam, bHandled);
1733 }
1734
1735 LRESULT OnParentSysCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
1736 {
1737 bHandled = FALSE;
1738 if((m_uSysKey == VK_MENU
1739 || (m_uSysKey == VK_F10 && !(::GetKeyState(VK_SHIFT) & 0x80))
1740 || m_uSysKey == VK_SPACE)
1741 && wParam == SC_KEYMENU)
1742 {
1743 T* pT = static_cast<T*>(this);
1744 if(::GetFocus() == m_hWnd)
1745 {
1746 pT->GiveFocusBack(); // exit menu "loop"
1747 PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L);
1748 }
1749 else if(m_uSysKey != VK_SPACE && !m_bSkipMsg)
1750 {
1751 if(m_bUseKeyboardCues && !m_bShowKeyboardCues && m_bAllowKeyboardCues)
1752 ShowKeyboardCues(true);
1753
1754 pT->TakeFocus(); // enter menu "loop"
1755 bHandled = TRUE;
1756 }
1757 else if(m_uSysKey != VK_SPACE)
1758 {
1759 bHandled = TRUE;
1760 }
1761 }
1762 m_bSkipMsg = false;
1763 return 0;
1764 }
1765
1766 LRESULT OnParentAPIGetMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1767 {
1768 return OnAPIGetMenu(uMsg, wParam, lParam, bHandled);
1769 }
1770
1771 LRESULT OnParentMenuChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1772 {
1773 return OnMenuChar(uMsg, wParam, lParam, bHandled);
1774 }
1775
1776 LRESULT OnParentAPITrackPopupMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1777 {
1778 return OnAPITrackPopupMenu(uMsg, wParam, lParam, bHandled);
1779 }
1780
1781 LRESULT OnParentAPIGetCmdBar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1782 {
1783 return OnAPIGetCmdBar(uMsg, wParam, lParam, bHandled);
1784 }
1785
1786 LRESULT OnParentSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1787 {
1788 OnSettingChange(uMsg, wParam, lParam, bHandled);
1789 bHandled = FALSE;
1790 return 1;
1791 }
1792
1793 LRESULT OnParentDrawItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1794 {
1795 return OnDrawItem(uMsg, wParam, lParam, bHandled);
1796 }
1797
1798 LRESULT OnParentMeasureItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1799 {
1800 return OnMeasureItem(uMsg, wParam, lParam, bHandled);
1801 }
1802
1803 LRESULT OnParentActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
1804 {
1805 m_bParentActive = (LOWORD(wParam) != WA_INACTIVE);
1806 if(!m_bParentActive && m_bUseKeyboardCues && m_bShowKeyboardCues)
1807 {
1808 ShowKeyboardCues(false); // this will repaint our window
1809 }
1810 else
1811 {
1812 Invalidate();
1813 UpdateWindow();
1814 }
1815 bHandled = FALSE;
1816 return 1;
1817 }
1818
1819 LRESULT OnParentCustomDraw(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
1820 {
1821 LRESULT lRet = CDRF_DODEFAULT;
1822 bHandled = FALSE;
1823 if(pnmh->hwndFrom == m_hWnd)
1824 {
1825 LPNMTBCUSTOMDRAW lpTBCustomDraw = (LPNMTBCUSTOMDRAW)pnmh;
1826 if(lpTBCustomDraw->nmcd.dwDrawStage == CDDS_PREPAINT)
1827 {
1828 lRet = CDRF_NOTIFYITEMDRAW;
1829 bHandled = TRUE;
1830 }
1831 else if(lpTBCustomDraw->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
1832 {
1833 #if _WTL_CMDBAR_VISTA_MENUS && defined(_WTL_CMDBAR_VISTA_STD_MENUBAR)
1834 if(m_bVistaMenus)
1835 {
1836 ::SetRectEmpty(&lpTBCustomDraw->rcText);
1837 lRet = CDRF_NOTIFYPOSTPAINT;
1838 bHandled = TRUE;
1839 }
1840 else
1841 #endif // _WTL_CMDBAR_VISTA_MENUS && defined(_WTL_CMDBAR_VISTA_STD_MENUBAR)
1842 {
1843 if(m_bFlatMenus)
1844 {
1845 #ifndef COLOR_MENUHILIGHT
1846 const int COLOR_MENUHILIGHT = 29;
1847 #endif // !COLOR_MENUHILIGHT
1848 bool bDisabled = ((lpTBCustomDraw->nmcd.uItemState & CDIS_DISABLED) == CDIS_DISABLED);
1849 if(!bDisabled && ((lpTBCustomDraw->nmcd.uItemState & CDIS_HOT) == CDIS_HOT ||
1850 (lpTBCustomDraw->nmcd.uItemState & CDIS_SELECTED) == CDIS_SELECTED))
1851 {
1852 ::FillRect(lpTBCustomDraw->nmcd.hdc, &lpTBCustomDraw->nmcd.rc, ::GetSysColorBrush(COLOR_MENUHILIGHT));
1853 ::FrameRect(lpTBCustomDraw->nmcd.hdc, &lpTBCustomDraw->nmcd.rc, ::GetSysColorBrush(COLOR_HIGHLIGHT));
1854 lpTBCustomDraw->clrText = ::GetSysColor(m_bParentActive ? COLOR_HIGHLIGHTTEXT : COLOR_GRAYTEXT);
1855 }
1856 else if(bDisabled || !m_bParentActive)
1857 {
1858 lpTBCustomDraw->clrText = ::GetSysColor(COLOR_GRAYTEXT);
1859 }
1860
1861 _ParentCustomDrawHelper(lpTBCustomDraw);
1862
1863 lRet = CDRF_SKIPDEFAULT;
1864 bHandled = TRUE;
1865 }
1866 else if(!m_bParentActive)
1867 {
1868 lpTBCustomDraw->clrText = ::GetSysColor(COLOR_GRAYTEXT);
1869 bHandled = TRUE;
1870 }
1871 }
1872 }
1873 #if _WTL_CMDBAR_VISTA_MENUS && defined(_WTL_CMDBAR_VISTA_STD_MENUBAR)
1874 else if (lpTBCustomDraw->nmcd.dwDrawStage == CDDS_ITEMPOSTPAINT)
1875 {
1876 bool bDisabled = ((lpTBCustomDraw->nmcd.uItemState & CDIS_DISABLED) == CDIS_DISABLED);
1877 if(bDisabled || !m_bParentActive)
1878 lpTBCustomDraw->clrText = ::GetSysColor(COLOR_GRAYTEXT);
1879
1880 _ParentCustomDrawHelper(lpTBCustomDraw);
1881
1882 lRet = CDRF_SKIPDEFAULT;
1883 bHandled = TRUE;
1884 }
1885 #endif // _WTL_CMDBAR_VISTA_MENUS && defined(_WTL_CMDBAR_VISTA_STD_MENUBAR)
1886 }
1887 return lRet;
1888 }
1889
1890 void _ParentCustomDrawHelper(LPNMTBCUSTOMDRAW lpTBCustomDraw)
1891 {
1892 CDCHandle dc = lpTBCustomDraw->nmcd.hdc;
1893 dc.SetTextColor(lpTBCustomDraw->clrText);
1894 dc.SetBkMode(lpTBCustomDraw->nStringBkMode);
1895
1896 HFONT hFont = GetFont();
1897 HFONT hFontOld = NULL;
1898 if(hFont != NULL)
1899 hFontOld = dc.SelectFont(hFont);
1900
1901 const int cchText = 200;
1902 TCHAR szText[cchText] = { 0 };
1903 TBBUTTONINFO tbbi = { 0 };
1904 tbbi.cbSize = sizeof(TBBUTTONINFO);
1905 tbbi.dwMask = TBIF_TEXT;
1906 tbbi.pszText = szText;
1907 tbbi.cchText = cchText;
1908 GetButtonInfo((int)lpTBCustomDraw->nmcd.dwItemSpec, &tbbi);
1909
1910 dc.DrawText(szText, -1, &lpTBCustomDraw->nmcd.rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER | (m_bShowKeyboardCues ? 0 : DT_HIDEPREFIX));
1911
1912 if(hFont != NULL)
1913 dc.SelectFont(hFontOld);
1914 }
1915
1916 // Message hook handlers
1917 LRESULT OnHookMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
1918 {
1919 static POINT s_point = { -1, -1 };
1920 DWORD dwPoint = ::GetMessagePos();
1921 POINT point = { GET_X_LPARAM(dwPoint), GET_Y_LPARAM(dwPoint) };
1922
1923 bHandled = FALSE;
1924 if(m_bMenuActive)
1925 {
1926 if(::WindowFromPoint(point) == m_hWnd)
1927 {
1928 ScreenToClient(&point);
1929 int nHit = HitTest(&point);
1930
1931 if((point.x != s_point.x || point.y != s_point.y) && nHit >= 0 && nHit < ::GetMenuItemCount(m_hMenu) && nHit != m_nPopBtn && m_nPopBtn != -1)
1932 {
1933 TBBUTTON tbb = { 0 };
1934 GetButton(nHit, &tbb);
1935 if((tbb.fsState & TBSTATE_ENABLED) != 0)
1936 {
1937 m_nNextPopBtn = nHit | 0xFFFF0000;
1938 HWND hWndMenu = m_stackMenuWnd.GetCurrent();
1939 ATLASSERT(hWndMenu != NULL);
1940
1941 // this one is needed to close a menu if mouse button was down
1942 ::PostMessage(hWndMenu, WM_LBUTTONUP, 0, MAKELPARAM(point.x, point.y));
1943 // this one closes a popup menu
1944 ::PostMessage(hWndMenu, WM_KEYDOWN, VK_ESCAPE, 0L);
1945
1946 bHandled = TRUE;
1947 }
1948 }
1949 }
1950 }
1951 else
1952 {
1953 ScreenToClient(&point);
1954 }
1955
1956 s_point = point;
1957 return 0;
1958 }
1959
1960 LRESULT OnHookSysKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
1961 {
1962 bHandled = FALSE;
1963 #ifdef _CMDBAR_EXTRA_TRACE
1964 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_SYSKEYDOWN (0x%2.2X)\n"), wParam);
1965 #endif
1966
1967 if(wParam == VK_MENU && m_bParentActive && m_bUseKeyboardCues && !m_bShowKeyboardCues && m_bAllowKeyboardCues)
1968 ShowKeyboardCues(true);
1969
1970 if(wParam != VK_SPACE && !m_bMenuActive && ::GetFocus() == m_hWnd)
1971 {
1972 m_bAllowKeyboardCues = false;
1973 PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L);
1974 T* pT = static_cast<T*>(this);
1975 pT->GiveFocusBack();
1976 m_bSkipMsg = true;
1977 }
1978 else
1979 {
1980 if(wParam == VK_SPACE && m_bUseKeyboardCues && m_bShowKeyboardCues)
1981 {
1982 m_bAllowKeyboardCues = true;
1983 ShowKeyboardCues(false);
1984 }
1985 m_uSysKey = (UINT)wParam;
1986 }
1987 return 0;
1988 }
1989
1990 LRESULT OnHookSysKeyUp(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
1991 {
1992 if(!m_bAllowKeyboardCues)
1993 m_bAllowKeyboardCues = true;
1994 bHandled = FALSE;
1995 wParam;
1996 #ifdef _CMDBAR_EXTRA_TRACE
1997 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_SYSKEYUP (0x%2.2X)\n"), wParam);
1998 #endif
1999 return 0;
2000 }
2001
2002 LRESULT OnHookSysChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
2003 {
2004 bHandled = FALSE;
2005 #ifdef _CMDBAR_EXTRA_TRACE
2006 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_SYSCHAR (0x%2.2X)\n"), wParam);
2007 #endif
2008
2009 if(!m_bMenuActive && m_hWndHook != m_hWnd && wParam != VK_SPACE)
2010 bHandled = TRUE;
2011 return 0;
2012 }
2013
2014 LRESULT OnHookKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
2015 {
2016 #ifdef _CMDBAR_EXTRA_TRACE
2017 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_KEYDOWN (0x%2.2X)\n"), wParam);
2018 #endif
2019 bHandled = FALSE;
2020 T* pT = static_cast<T*>(this);
2021
2022 if(wParam == VK_ESCAPE && m_stackMenuWnd.GetSize() <= 1)
2023 {
2024 if(m_bMenuActive && !m_bContextMenu)
2025 {
2026 int nHot = GetHotItem();
2027 if(nHot == -1)
2028 nHot = m_nPopBtn;
2029 if(nHot == -1)
2030 nHot = 0;
2031 SetHotItem(nHot);
2032 bHandled = TRUE;
2033 pT->TakeFocus();
2034 m_bEscapePressed = true; // To keep focus
2035 m_bSkipPostDown = false;
2036 }
2037 else if(::GetFocus() == m_hWnd && m_wndParent.IsWindow())
2038 {
2039 SetHotItem(-1);
2040 pT->GiveFocusBack();
2041 bHandled = TRUE;
2042 }
2043 }
2044 else if(wParam == VK_RETURN || wParam == VK_UP || wParam == VK_DOWN)
2045 {
2046 if(!m_bMenuActive && ::GetFocus() == m_hWnd && m_wndParent.IsWindow())
2047 {
2048 int nHot = GetHotItem();
2049 if(nHot != -1)
2050 {
2051 if(wParam != VK_RETURN)
2052 {
2053 if(!m_bSkipPostDown)
2054 {
2055 // IE4 only: WM_KEYDOWN doesn't generate TBN_DROPDOWN, we need to simulate a mouse click
2056 #if (_WIN32_IE < 0x0500)
2057 DWORD dwMajor = 0, dwMinor = 0;
2058 ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor);
2059 if(dwMajor <= 4 || (dwMajor == 5 && dwMinor < 80))
2060 {
2061 RECT rect = { 0 };
2062 GetItemRect(nHot, &rect);
2063 PostMessage(WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(rect.left, rect.top));
2064 }
2065 #endif // (_WIN32_IE < 0x0500)
2066 PostMessage(WM_KEYDOWN, VK_DOWN, 0L);
2067 m_bSkipPostDown = true;
2068 }
2069 else
2070 {
2071 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - skipping posting another VK_DOWN\n"));
2072 m_bSkipPostDown = false;
2073 }
2074 }
2075 }
2076 else
2077 {
2078 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Can't find hot button\n"));
2079 }
2080 }
2081 if(wParam == VK_RETURN && m_bMenuActive)
2082 {
2083 PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L);
2084 m_nNextPopBtn = -1;
2085 pT->GiveFocusBack();
2086 }
2087 }
2088 else if(wParam == VK_LEFT || wParam == VK_RIGHT)
2089 {
2090 WPARAM wpNext = m_bLayoutRTL ? VK_LEFT : VK_RIGHT;
2091 WPARAM wpPrev = m_bLayoutRTL ? VK_RIGHT : VK_LEFT;
2092
2093 if(m_bMenuActive && !m_bContextMenu && !(wParam == wpNext && m_bPopupItem))
2094 {
2095 bool bAction = false;
2096 if(wParam == wpPrev && s_pCurrentBar->m_stackMenuWnd.GetSize() == 1)
2097 {
2098 m_nNextPopBtn = pT->GetPreviousMenuItem(m_nPopBtn);
2099 if(m_nNextPopBtn != -1)
2100 bAction = true;
2101 }
2102 else if(wParam == wpNext)
2103 {
2104 m_nNextPopBtn = pT->GetNextMenuItem(m_nPopBtn);
2105 if(m_nNextPopBtn != -1)
2106 bAction = true;
2107 }
2108 HWND hWndMenu = m_stackMenuWnd.GetCurrent();
2109 ATLASSERT(hWndMenu != NULL);
2110
2111 // Close the popup menu
2112 if(bAction)
2113 {
2114 ::PostMessage(hWndMenu, WM_KEYDOWN, VK_ESCAPE, 0L);
2115 if(wParam == wpNext)
2116 {
2117 int cItem = m_stackMenuWnd.GetSize() - 1;
2118 while(cItem >= 0)
2119 {
2120 hWndMenu = m_stackMenuWnd[cItem];
2121 if(hWndMenu != NULL)
2122 ::PostMessage(hWndMenu, WM_KEYDOWN, VK_ESCAPE, 0L);
2123 cItem--;
2124 }
2125 }
2126 #if (_WIN32_IE >= 0x0500)
2127 if(m_nNextPopBtn == -2)
2128 {
2129 m_nNextPopBtn = -1;
2130 pT->DisplayChevronMenu();
2131 }
2132 #endif // (_WIN32_IE >= 0x0500)
2133 bHandled = TRUE;
2134 }
2135 }
2136 }
2137 return 0;
2138 }
2139
2140 LRESULT OnHookNextMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
2141 {
2142 #ifdef _CMDBAR_EXTRA_TRACE
2143 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_NEXTMENU\n"));
2144 #endif
2145 bHandled = FALSE;
2146 return 1;
2147 }
2148
2149 LRESULT OnHookChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
2150 {
2151 #ifdef _CMDBAR_EXTRA_TRACE
2152 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_CHAR (0x%2.2X)\n"), wParam);
2153 #endif
2154 bHandled = (wParam == VK_ESCAPE);
2155 return 0;
2156 }
2157
2158 // Implementation - ownerdraw overrideables and helpers
2159 void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
2160 {
2161 T* pT = static_cast<T*>(this);
2162 if(m_bFlatMenus)
2163 pT->DrawItemFlat(lpDrawItemStruct);
2164 else
2165 pT->DrawItem3D(lpDrawItemStruct);
2166
2167 }
2168
2169 void DrawItem3D(LPDRAWITEMSTRUCT lpDrawItemStruct)
2170 {
2171 _MenuItemData* pmd = (_MenuItemData*)lpDrawItemStruct->itemData;
2172 CDCHandle dc = lpDrawItemStruct->hDC;
2173 const RECT& rcItem = lpDrawItemStruct->rcItem;
2174 T* pT = static_cast<T*>(this);
2175
2176 if(pmd->fType & MFT_SEPARATOR)
2177 {
2178 // draw separator
2179 RECT rc = rcItem;
2180 rc.top += (rc.bottom - rc.top) / 2; // vertical center
2181 dc.DrawEdge(&rc, EDGE_ETCHED, BF_TOP); // draw separator line
2182 }
2183 else // not a separator
2184 {
2185 BOOL bDisabled = lpDrawItemStruct->itemState & ODS_GRAYED;
2186 BOOL bSelected = lpDrawItemStruct->itemState & ODS_SELECTED;
2187 BOOL bChecked = lpDrawItemStruct->itemState & ODS_CHECKED;
2188 BOOL bHasImage = FALSE;
2189
2190 if(LOWORD(lpDrawItemStruct->itemID) == (WORD)-1)
2191 bSelected = FALSE;
2192 RECT rcButn = { rcItem.left, rcItem.top, rcItem.left + m_szButton.cx, rcItem.top + m_szButton.cy }; // button rect
2193 ::OffsetRect(&rcButn, 0, ((rcItem.bottom - rcItem.top) - (rcButn.bottom - rcButn.top)) / 2); // center vertically
2194
2195 int iButton = pmd->iButton;
2196 if(iButton >= 0)
2197 {
2198 bHasImage = TRUE;
2199
2200 // calc drawing point
2201 SIZE sz = { rcButn.right - rcButn.left - m_szBitmap.cx, rcButn.bottom - rcButn.top - m_szBitmap.cy };
2202 sz.cx /= 2;
2203 sz.cy /= 2;
2204 POINT point = { rcButn.left + sz.cx, rcButn.top + sz.cy };
2205
2206 // fill background depending on state
2207 if(!bChecked || (bSelected && !bDisabled))
2208 {
2209 if(!bDisabled)
2210 dc.FillRect(&rcButn, (bChecked && !bSelected) ? COLOR_3DLIGHT : COLOR_MENU);
2211 else
2212 dc.FillRect(&rcButn, COLOR_MENU);
2213 }
2214 else
2215 {
2216 COLORREF crTxt = dc.SetTextColor(::GetSysColor(COLOR_BTNFACE));
2217 COLORREF crBk = dc.SetBkColor(::GetSysColor(COLOR_BTNHILIGHT));
2218 CBrush hbr(CDCHandle::GetHalftoneBrush());
2219 dc.SetBrushOrg(rcButn.left, rcButn.top);
2220 dc.FillRect(&rcButn, hbr);
2221 dc.SetTextColor(crTxt);
2222 dc.SetBkColor(crBk);
2223 }
2224
2225 // draw disabled or normal
2226 if(!bDisabled)
2227 {
2228 // draw pushed-in or popped-out edge
2229 if(bSelected || bChecked)
2230 {
2231 RECT rc2 = rcButn;
2232 dc.DrawEdge(&rc2, bChecked ? BDR_SUNKENOUTER : BDR_RAISEDINNER, BF_RECT);
2233 }
2234 // draw the image
2235 ::ImageList_Draw(m_hImageList, iButton, dc, point.x, point.y, ILD_TRANSPARENT);
2236 }
2237 else
2238 {
2239 HBRUSH hBrushBackground = bChecked ? NULL : ::GetSysColorBrush(COLOR_MENU);
2240 pT->DrawBitmapDisabled(dc, iButton, point, hBrushBackground);
2241 }
2242 }
2243 else
2244 {
2245 // no image - look for custom checked/unchecked bitmaps
2246 CMenuItemInfo info;
2247 info.fMask = MIIM_CHECKMARKS | MIIM_TYPE;
2248 ::GetMenuItemInfo((HMENU)lpDrawItemStruct->hwndItem, lpDrawItemStruct->itemID, MF_BYCOMMAND, &info);
2249 if(bChecked || info.hbmpUnchecked != NULL)
2250 {
2251 BOOL bRadio = ((info.fType & MFT_RADIOCHECK) != 0);
2252 bHasImage = pT->DrawCheckmark(dc, rcButn, bSelected, bDisabled, bRadio, bChecked ? info.hbmpChecked : info.hbmpUnchecked);
2253 }
2254 }
2255
2256 // draw item text
2257 int cxButn = m_szButton.cx;
2258 COLORREF colorBG = ::GetSysColor(bSelected ? COLOR_HIGHLIGHT : COLOR_MENU);
2259 if(bSelected || lpDrawItemStruct->itemAction == ODA_SELECT)
2260 {
2261 RECT rcBG = rcItem;
2262 if(bHasImage)
2263 rcBG.left += cxButn + s_kcxGap;
2264 dc.FillRect(&rcBG, bSelected ? COLOR_HIGHLIGHT : COLOR_MENU);
2265 }
2266
2267 // calc text rectangle and colors
2268 RECT rcText = rcItem;
2269 rcText.left += cxButn + s_kcxGap + s_kcxTextMargin;
2270 rcText.right -= cxButn;
2271 dc.SetBkMode(TRANSPARENT);
2272 COLORREF colorText = ::GetSysColor(bDisabled ? (bSelected ? COLOR_GRAYTEXT : COLOR_3DSHADOW) : (bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT));
2273
2274 // font already selected by Windows
2275 if(bDisabled && (!bSelected || colorText == colorBG))
2276 {
2277 // disabled - draw shadow text shifted down and right 1 pixel (unles selected)
2278 RECT rcDisabled = rcText;
2279 ::OffsetRect(&rcDisabled, 1, 1);
2280 pT->DrawMenuText(dc, rcDisabled, pmd->lpstrText, ::GetSysColor(COLOR_3DHILIGHT));
2281 }
2282 pT->DrawMenuText(dc, rcText, pmd->lpstrText, colorText); // finally!
2283 }
2284 }
2285
2286 void DrawItemFlat(LPDRAWITEMSTRUCT lpDrawItemStruct)
2287 {
2288 _MenuItemData* pmd = (_MenuItemData*)lpDrawItemStruct->itemData;
2289 CDCHandle dc = lpDrawItemStruct->hDC;
2290 const RECT& rcItem = lpDrawItemStruct->rcItem;
2291 T* pT = static_cast<T*>(this);
2292
2293 #ifndef COLOR_MENUHILIGHT
2294 const int COLOR_MENUHILIGHT = 29;
2295 #endif // !COLOR_MENUHILIGHT
2296
2297 BOOL bDisabled = lpDrawItemStruct->itemState & ODS_GRAYED;
2298 BOOL bSelected = lpDrawItemStruct->itemState & ODS_SELECTED;
2299 BOOL bChecked = lpDrawItemStruct->itemState & ODS_CHECKED;
2300
2301 // paint background
2302 if(bSelected || lpDrawItemStruct->itemAction == ODA_SELECT)
2303 {
2304 if(bSelected)
2305 {
2306 dc.FillRect(&rcItem, ::GetSysColorBrush(COLOR_MENUHILIGHT));
2307 dc.FrameRect(&rcItem, ::GetSysColorBrush(COLOR_HIGHLIGHT));
2308 }
2309 else
2310 {
2311 dc.FillRect(&rcItem, ::GetSysColorBrush(COLOR_MENU));
2312 }
2313 }
2314
2315 if(pmd->fType & MFT_SEPARATOR)
2316 {
2317 // draw separator
2318 RECT rc = rcItem;
2319 rc.top += (rc.bottom - rc.top) / 2; // vertical center
2320 dc.DrawEdge(&rc, EDGE_ETCHED, BF_TOP); // draw separator line
2321 }
2322 else // not a separator
2323 {
2324 if(LOWORD(lpDrawItemStruct->itemID) == (WORD)-1)
2325 bSelected = FALSE;
2326 RECT rcButn = { rcItem.left, rcItem.top, rcItem.left + m_szButton.cx, rcItem.top + m_szButton.cy }; // button rect
2327 ::OffsetRect(&rcButn, 0, ((rcItem.bottom - rcItem.top) - (rcButn.bottom - rcButn.top)) / 2); // center vertically
2328
2329 // draw background and border for checked items
2330 if(bChecked)
2331 {
2332 RECT rcCheck = rcButn;
2333 ::InflateRect(&rcCheck, -1, -1);
2334 if(bSelected)
2335 dc.FillRect(&rcCheck, ::GetSysColorBrush(COLOR_MENU));
2336 dc.FrameRect(&rcCheck, ::GetSysColorBrush(COLOR_HIGHLIGHT));
2337 }
2338
2339 int iButton = pmd->iButton;
2340 if(iButton >= 0)
2341 {
2342 // calc drawing point
2343 SIZE sz = { rcButn.right - rcButn.left - m_szBitmap.cx, rcButn.bottom - rcButn.top - m_szBitmap.cy };
2344 sz.cx /= 2;
2345 sz.cy /= 2;
2346 POINT point = { rcButn.left + sz.cx, rcButn.top + sz.cy };
2347
2348 // draw disabled or normal
2349 if(!bDisabled)
2350 {
2351 ::ImageList_Draw(m_hImageList, iButton, dc, point.x, point.y, ILD_TRANSPARENT);
2352 }
2353 else
2354 {
2355 HBRUSH hBrushBackground = ::GetSysColorBrush((bSelected && !(bDisabled && bChecked)) ? COLOR_MENUHILIGHT : COLOR_MENU);
2356 HBRUSH hBrushDisabledImage = ::GetSysColorBrush(COLOR_3DSHADOW);
2357 pT->DrawBitmapDisabled(dc, iButton, point, hBrushBackground, hBrushBackground, hBrushDisabledImage);
2358 }
2359 }
2360 else
2361 {
2362 // no image - look for custom checked/unchecked bitmaps
2363 CMenuItemInfo info;
2364 info.fMask = MIIM_CHECKMARKS | MIIM_TYPE;
2365 ::GetMenuItemInfo((HMENU)lpDrawItemStruct->hwndItem, lpDrawItemStruct->itemID, MF_BYCOMMAND, &info);
2366 if(bChecked || info.hbmpUnchecked != NULL)
2367 {
2368 BOOL bRadio = ((info.fType & MFT_RADIOCHECK) != 0);
2369 pT->DrawCheckmark(dc, rcButn, bSelected, bDisabled, bRadio, bChecked ? info.hbmpChecked : info.hbmpUnchecked);
2370 }
2371 }
2372
2373 // draw item text
2374 int cxButn = m_szButton.cx;
2375 // calc text rectangle and colors
2376 RECT rcText = rcItem;
2377 rcText.left += cxButn + s_kcxGap + s_kcxTextMargin;
2378 rcText.right -= cxButn;
2379 dc.SetBkMode(TRANSPARENT);
2380 COLORREF colorText = ::GetSysColor(bDisabled ? (bSelected ? COLOR_GRAYTEXT : COLOR_3DSHADOW) : (bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT));
2381
2382 pT->DrawMenuText(dc, rcText, pmd->lpstrText, colorText); // finally!
2383 }
2384 }
2385
2386 void DrawMenuText(CDCHandle& dc, RECT& rc, LPCTSTR lpstrText, COLORREF color)
2387 {
2388 int nTab = -1;
2389 const int nLen = lstrlen(lpstrText);
2390 for(int i = 0; i < nLen; i++)
2391 {
2392 if(lpstrText[i] == _T('\t'))
2393 {
2394 nTab = i;
2395 break;
2396 }
2397 }
2398 dc.SetTextColor(color);
2399 dc.DrawText(lpstrText, nTab, &rc, DT_SINGLELINE | DT_LEFT | DT_VCENTER | (m_bShowKeyboardCues ? 0 : DT_HIDEPREFIX));
2400 if(nTab != -1)
2401 dc.DrawText(&lpstrText[nTab + 1], -1, &rc, DT_SINGLELINE | DT_RIGHT | DT_VCENTER | (m_bShowKeyboardCues ? 0 : DT_HIDEPREFIX));
2402 }
2403
2404 void DrawBitmapDisabled(CDCHandle& dc, int nImage, POINT point,
2405 HBRUSH hBrushBackground = ::GetSysColorBrush(COLOR_3DFACE),
2406 HBRUSH hBrush3DEffect = ::GetSysColorBrush(COLOR_3DHILIGHT),
2407 HBRUSH hBrushDisabledImage = ::GetSysColorBrush(COLOR_3DSHADOW))
2408 {
2409 #if (_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501)
2410 if(m_bAlphaImages)
2411 {
2412 IMAGELISTDRAWPARAMS ildp = { 0 };
2413 ildp.cbSize = sizeof(IMAGELISTDRAWPARAMS);
2414 ildp.himl = m_hImageList;
2415 ildp.i = nImage;
2416 ildp.hdcDst = dc;
2417 ildp.x = point.x;
2418 ildp.y = point.y;
2419 ildp.cx = 0;
2420 ildp.cy = 0;
2421 ildp.xBitmap = 0;
2422 ildp.yBitmap = 0;
2423 ildp.fStyle = ILD_TRANSPARENT;
2424 ildp.fState = ILS_SATURATE;
2425 ildp.Frame = 0;
2426 ::ImageList_DrawIndirect(&ildp);
2427 }
2428 else
2429 #endif // (_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501)
2430 {
2431 // create memory DC
2432 CDC dcMem;
2433 dcMem.CreateCompatibleDC(dc);
2434 // create mono or color bitmap
2435 CBitmap bmp;
2436 bmp.CreateCompatibleBitmap(dc, m_szBitmap.cx, m_szBitmap.cy);
2437 ATLASSERT(bmp.m_hBitmap != NULL);
2438 // draw image into memory DC--fill BG white first
2439 HBITMAP hBmpOld = dcMem.SelectBitmap(bmp);
2440 dcMem.PatBlt(0, 0, m_szBitmap.cx, m_szBitmap.cy, WHITENESS);
2441 // If white is the text color, we can't use the normal painting since
2442 // it would blend with the WHITENESS, but the mask is OK
2443 UINT uDrawStyle = (::GetSysColor(COLOR_BTNTEXT) == RGB(255, 255, 255)) ? ILD_MASK : ILD_NORMAL;
2444 ::ImageList_Draw(m_hImageList, nImage, dcMem, 0, 0, uDrawStyle);
2445 dc.DitherBlt(point.x, point.y, m_szBitmap.cx, m_szBitmap.cy, dcMem, NULL, 0, 0, hBrushBackground, hBrush3DEffect, hBrushDisabledImage);
2446 dcMem.SelectBitmap(hBmpOld); // restore
2447 }
2448 }
2449
2450 // old name
2451 BOOL Draw3DCheckmark(CDCHandle& dc, const RECT& rc, BOOL bSelected, BOOL bDisabled, BOOL bRadio, HBITMAP hBmpCheck)
2452 {
2453 return DrawCheckmark(dc, rc, bSelected, bDisabled, bRadio, hBmpCheck);
2454 }
2455
2456 BOOL DrawCheckmark(CDCHandle& dc, const RECT& rc, BOOL bSelected, BOOL bDisabled, BOOL bRadio, HBITMAP hBmpCheck)
2457 {
2458 // get checkmark bitmap, if none, use Windows standard
2459 SIZE size = { 0, 0 };
2460 CBitmapHandle bmp = hBmpCheck;
2461 if(hBmpCheck != NULL)
2462 {
2463 bmp.GetSize(size);
2464 }
2465 else
2466 {
2467 size.cx = ::GetSystemMetrics(SM_CXMENUCHECK);
2468 size.cy = ::GetSystemMetrics(SM_CYMENUCHECK);
2469 bmp.CreateCompatibleBitmap(dc, size.cx, size.cy);
2470 ATLASSERT(bmp.m_hBitmap != NULL);
2471 }
2472 // center bitmap in caller's rectangle
2473 RECT rcDest = rc;
2474 if((rc.right - rc.left) > size.cx)
2475 {
2476 rcDest.left = rc.left + (rc.right - rc.left - size.cx) / 2;
2477 rcDest.right = rcDest.left + size.cx;
2478 }
2479 if((rc.bottom - rc.top) > size.cy)
2480 {
2481 rcDest.top = rc.top + (rc.bottom - rc.top - size.cy) / 2;
2482 rcDest.bottom = rcDest.top + size.cy;
2483 }
2484 // paint background
2485 if(!m_bFlatMenus)
2486 {
2487 if(bSelected && !bDisabled)
2488 {
2489 dc.FillRect(&rcDest, COLOR_MENU);
2490 }
2491 else
2492 {
2493 COLORREF clrTextOld = dc.SetTextColor(::GetSysColor(COLOR_BTNFACE));
2494 COLORREF clrBkOld = dc.SetBkColor(::GetSysColor(COLOR_BTNHILIGHT));
2495 CBrush hbr(CDCHandle::GetHalftoneBrush());
2496 dc.SetBrushOrg(rcDest.left, rcDest.top);
2497 dc.FillRect(&rcDest, hbr);
2498 dc.SetTextColor(clrTextOld);
2499 dc.SetBkColor(clrBkOld);
2500 }
2501 }
2502
2503 // create source image
2504 CDC dcSource;
2505 dcSource.CreateCompatibleDC(dc);
2506 HBITMAP hBmpOld = dcSource.SelectBitmap(bmp);
2507 // set colors
2508 const COLORREF clrBlack = RGB(0, 0, 0);
2509 const COLORREF clrWhite = RGB(255, 255, 255);
2510 COLORREF clrTextOld = dc.SetTextColor(clrBlack);
2511 COLORREF clrBkOld = dc.SetBkColor(clrWhite);
2512 // create mask
2513 CDC dcMask;
2514 dcMask.CreateCompatibleDC(dc);
2515 CBitmap bmpMask;
2516 bmpMask.CreateBitmap(size.cx, size.cy, 1, 1, NULL);
2517 HBITMAP hBmpOld1 = dcMask.SelectBitmap(bmpMask);
2518
2519 // draw the checkmark transparently
2520 int cx = rcDest.right - rcDest.left;
2521 int cy = rcDest.bottom - rcDest.top;
2522 if(hBmpCheck != NULL)
2523 {
2524 // build mask based on transparent color
2525 dcSource.SetBkColor(m_clrMask);
2526 dcMask.SetBkColor(clrBlack);
2527 dcMask.SetTextColor(clrWhite);
2528 dcMask.BitBlt(0, 0, size.cx, size.cy, dcSource, 0, 0, SRCCOPY);
2529 // draw bitmap using the mask
2530 dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcSource, 0, 0, SRCINVERT);
2531 dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcMask, 0, 0, SRCAND);
2532 dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcSource, 0, 0, SRCINVERT);
2533 }
2534 else
2535 {
2536 const DWORD ROP_DSno = 0x00BB0226L;
2537 const DWORD ROP_DSa = 0x008800C6L;
2538 const DWORD ROP_DSo = 0x00EE0086L;
2539 const DWORD ROP_DSna = 0x00220326L;
2540
2541 // draw mask
2542 RECT rcSource = { 0, 0, __min(size.cx, rc.right - rc.left), __min(size.cy, rc.bottom - rc.top) };
2543 dcMask.DrawFrameControl(&rcSource, DFC_MENU, bRadio ? DFCS_MENUBULLET : DFCS_MENUCHECK);
2544
2545 // draw shadow if disabled
2546 if(!m_bFlatMenus && bDisabled)
2547 {
2548 // offset by one pixel
2549 int x = rcDest.left + 1;
2550 int y = rcDest.top + 1;
2551 // paint source bitmap
2552 const int nColor = COLOR_3DHILIGHT;
2553 dcSource.FillRect(&rcSource, nColor);
2554 // draw checkmark - special case black and white colors
2555 COLORREF clrCheck = ::GetSysColor(nColor);
2556 if(clrCheck == clrWhite)
2557 {
2558 dc.BitBlt(x, y, cx, cy, dcMask, 0, 0, ROP_DSno);
2559 dc.BitBlt(x, y, cx, cy, dcSource, 0, 0, ROP_DSa);
2560 }
2561 else
2562 {
2563 if(clrCheck != clrBlack)
2564 {
2565 ATLASSERT(dcSource.GetTextColor() == clrBlack);
2566 ATLASSERT(dcSource.GetBkColor() == clrWhite);
2567 dcSource.BitBlt(0, 0, size.cx, size.cy, dcMask, 0, 0, ROP_DSna);
2568 }
2569 dc.BitBlt(x, y, cx, cy, dcMask, 0, 0, ROP_DSa);
2570 dc.BitBlt(x, y, cx, cy, dcSource, 0, 0, ROP_DSo);
2571 }
2572 }
2573
2574 // paint source bitmap
2575 const int nColor = bDisabled ? COLOR_BTNSHADOW : COLOR_MENUTEXT;
2576 dcSource.FillRect(&rcSource, nColor);
2577 // draw checkmark - special case black and white colors
2578 COLORREF clrCheck = ::GetSysColor(nColor);
2579 if(clrCheck == clrWhite)
2580 {
2581 dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcMask, 0, 0, ROP_DSno);
2582 dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcSource, 0, 0, ROP_DSa);
2583 }
2584 else
2585 {
2586 if(clrCheck != clrBlack)
2587 {
2588 ATLASSERT(dcSource.GetTextColor() == clrBlack);
2589 ATLASSERT(dcSource.GetBkColor() == clrWhite);
2590 dcSource.BitBlt(0, 0, size.cx, size.cy, dcMask, 0, 0, ROP_DSna);
2591 }
2592 dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcMask, 0, 0, ROP_DSa);
2593 dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcSource, 0, 0, ROP_DSo);
2594 }
2595 }
2596 // restore all
2597 dc.SetTextColor(clrTextOld);
2598 dc.SetBkColor(clrBkOld);
2599 dcSource.SelectBitmap(hBmpOld);
2600 dcMask.SelectBitmap(hBmpOld1);
2601 if(hBmpCheck == NULL)
2602 bmp.DeleteObject();
2603 // draw pushed-in hilight
2604 if(!m_bFlatMenus && !bDisabled)
2605 {
2606 if(rc.right - rc.left > size.cx)
2607 ::InflateRect(&rcDest, 1,1); // inflate checkmark by one pixel all around
2608 dc.DrawEdge(&rcDest, BDR_SUNKENOUTER, BF_RECT);
2609 }
2610
2611 return TRUE;
2612 }
2613
2614 void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
2615 {
2616 _MenuItemData* pmd = (_MenuItemData*)lpMeasureItemStruct->itemData;
2617
2618 if(pmd->fType & MFT_SEPARATOR) // separator - use half system height and zero width
2619 {
2620 lpMeasureItemStruct->itemHeight = ::GetSystemMetrics(SM_CYMENU) / 2;
2621 lpMeasureItemStruct->itemWidth = 0;
2622 }
2623 else
2624 {
2625 // compute size of text - use DrawText with DT_CALCRECT
2626 CWindowDC dc(NULL);
2627 CFont fontBold;
2628 HFONT hOldFont = NULL;
2629 if(pmd->fState & MFS_DEFAULT)
2630 {
2631 // need bold version of font
2632 LOGFONT lf = { 0 };
2633 m_fontMenu.GetLogFont(lf);
2634 lf.lfWeight += 200;
2635 fontBold.CreateFontIndirect(&lf);
2636 ATLASSERT(fontBold.m_hFont != NULL);
2637 hOldFont = dc.SelectFont(fontBold);
2638 }
2639 else
2640 {
2641 hOldFont = dc.SelectFont(m_fontMenu);
2642 }
2643
2644 RECT rcText = { 0 };
2645 dc.DrawText(pmd->lpstrText, -1, &rcText, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT);
2646 int cx = rcText.right - rcText.left;
2647 dc.SelectFont(hOldFont);
2648
2649 LOGFONT lf = { 0 };
2650 m_fontMenu.GetLogFont(lf);
2651 int cy = lf.lfHeight;
2652 if(cy < 0)
2653 cy = -cy;
2654 const int cyMargin = 8;
2655 cy += cyMargin;
2656
2657 // height of item is the bigger of these two
2658 lpMeasureItemStruct->itemHeight = __max(cy, (int)m_szButton.cy);
2659
2660 // width is width of text plus a bunch of stuff
2661 cx += 2 * s_kcxTextMargin; // L/R margin for readability
2662 cx += s_kcxGap; // space between button and menu text
2663 cx += 2 * m_szButton.cx; // button width (L=button; R=empty margin)
2664 cx += m_cxExtraSpacing; // extra between item text and accelerator keys
2665
2666 // Windows adds 1 to returned value
2667 cx -= ::GetSystemMetrics(SM_CXMENUCHECK) - 1;
2668 lpMeasureItemStruct->itemWidth = cx; // done deal
2669 }
2670 }
2671
2672 // Implementation - Hook procs
2673 static LRESULT CALLBACK CreateHookProc(int nCode, WPARAM wParam, LPARAM lParam)
2674 {
2675 const int cchClassName = 7;
2676 TCHAR szClassName[cchClassName] = { 0 };
2677
2678 if(nCode == HCBT_CREATEWND)
2679 {
2680 HWND hWndMenu = (HWND)wParam;
2681 #ifdef _CMDBAR_EXTRA_TRACE
2682 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - HCBT_CREATEWND (HWND = %8.8X)\n"), hWndMenu);
2683 #endif
2684
2685 ::GetClassName(hWndMenu, szClassName, cchClassName);
2686 if(!lstrcmp(_T("#32768"), szClassName))
2687 s_pCurrentBar->m_stackMenuWnd.Push(hWndMenu);
2688 }
2689 else if(nCode == HCBT_DESTROYWND)
2690 {
2691 HWND hWndMenu = (HWND)wParam;
2692 #ifdef _CMDBAR_EXTRA_TRACE
2693 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - HCBT_DESTROYWND (HWND = %8.8X)\n"), hWndMenu);
2694 #endif
2695
2696 ::GetClassName(hWndMenu, szClassName, cchClassName);
2697 if(!lstrcmp(_T("#32768"), szClassName))
2698 {
2699 ATLASSERT(hWndMenu == s_pCurrentBar->m_stackMenuWnd.GetCurrent());
2700 s_pCurrentBar->m_stackMenuWnd.Pop();
2701 }
2702 }
2703
2704 return ::CallNextHookEx(s_hCreateHook, nCode, wParam, lParam);
2705 }
2706
2707 static LRESULT CALLBACK MessageHookProc(int nCode, WPARAM wParam, LPARAM lParam)
2708 {
2709 LPMSG pMsg = (LPMSG)lParam;
2710
2711 if(nCode == HC_ACTION && wParam == PM_REMOVE && pMsg->message != GetGetBarMessage() && pMsg->message != WM_FORWARDMSG)
2712 {
2713 CCommandBarCtrlBase* pCmdBar = NULL;
2714 HWND hWnd = pMsg->hwnd;
2715 DWORD dwPID = 0;
2716 while(pCmdBar == NULL && hWnd != NULL)
2717 {
2718 pCmdBar = (CCommandBarCtrlBase*)::SendMessage(hWnd, GetGetBarMessage(), (WPARAM)&dwPID, 0L);
2719 hWnd = ::GetParent(hWnd);
2720 }
2721
2722 if(pCmdBar != NULL && dwPID == GetCurrentProcessId())
2723 {
2724 pCmdBar->m_hWndHook = pMsg->hwnd;
2725 ATLASSERT(pCmdBar->IsCommandBarBase());
2726
2727 if(::IsWindow(pCmdBar->m_hWnd))
2728 pCmdBar->SendMessage(WM_FORWARDMSG, 0, (LPARAM)pMsg);
2729 else
2730 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook skipping message, can't find command bar!\n"));
2731 }
2732 }
2733
2734 LRESULT lRet = 0;
2735 ATLASSERT(s_pmapMsgHook != NULL);
2736 if(s_pmapMsgHook != NULL)
2737 {
2738 DWORD dwThreadID = ::GetCurrentThreadId();
2739 _MsgHookData* pData = s_pmapMsgHook->Lookup(dwThreadID);
2740 if(pData != NULL)
2741 {
2742 lRet = ::CallNextHookEx(pData->hMsgHook, nCode, wParam, lParam);
2743 }
2744 }
2745 return lRet;
2746 }
2747
2748 // Implementation
2749 void DoPopupMenu(int nIndex, bool bAnimate)
2750 {
2751 #ifdef _CMDBAR_EXTRA_TRACE
2752 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - DoPopupMenu, bAnimate = %s\n"), bAnimate ? "true" : "false");
2753 #endif
2754
2755 // Menu animation flags
2756 #ifndef TPM_VERPOSANIMATION
2757 const UINT TPM_VERPOSANIMATION = 0x1000L;
2758 #endif
2759 #ifndef TPM_NOANIMATION
2760 const UINT TPM_NOANIMATION = 0x4000L;
2761 #endif
2762 T* pT = static_cast<T*>(this);
2763
2764 // get popup menu and it's position
2765 RECT rect = { 0 };
2766 GetItemRect(nIndex, &rect);
2767 POINT pt = { rect.left, rect.bottom };
2768 MapWindowPoints(NULL, &pt, 1);
2769 MapWindowPoints(NULL, &rect);
2770 TPMPARAMS TPMParams = { 0 };
2771 TPMParams.cbSize = sizeof(TPMPARAMS);
2772 TPMParams.rcExclude = rect;
2773 HMENU hMenuPopup = ::GetSubMenu(m_hMenu, nIndex);
2774 ATLASSERT(hMenuPopup != NULL);
2775
2776 // get button ID
2777 TBBUTTON tbb = { 0 };
2778 GetButton(nIndex, &tbb);
2779 int nCmdID = tbb.idCommand;
2780
2781 m_nPopBtn = nIndex; // remember current button's index
2782
2783 // press button and display popup menu
2784 PressButton(nCmdID, TRUE);
2785 SetHotItem(nCmdID);
2786 pT->DoTrackPopupMenu(hMenuPopup, TPM_LEFTBUTTON | TPM_VERTICAL | TPM_LEFTALIGN | TPM_TOPALIGN |
2787 (s_bW2K ? (bAnimate ? TPM_VERPOSANIMATION : TPM_NOANIMATION) : 0), pt.x, pt.y, &TPMParams);
2788 PressButton(nCmdID, FALSE);
2789 if(::GetFocus() != m_hWnd)
2790 SetHotItem(-1);
2791
2792 m_nPopBtn = -1; // restore
2793
2794 // eat next message if click is on the same button
2795 MSG msg = { 0 };
2796 if(::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE) && ::PtInRect(&rect, msg.pt))
2797 ::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_REMOVE);
2798
2799 // check if another popup menu should be displayed
2800 if(m_nNextPopBtn != -1)
2801 {
2802 PostMessage(GetAutoPopupMessage(), m_nNextPopBtn & 0xFFFF);
2803 if(!(m_nNextPopBtn & 0xFFFF0000) && !m_bPopupItem)
2804 PostMessage(WM_KEYDOWN, VK_DOWN, 0);
2805 m_nNextPopBtn = -1;
2806 }
2807 else
2808 {
2809 m_bContextMenu = false;
2810 // If user didn't hit escape, give focus back
2811 if(!m_bEscapePressed)
2812 {
2813 if(m_bUseKeyboardCues && m_bShowKeyboardCues)
2814 m_bAllowKeyboardCues = false;
2815 pT->GiveFocusBack();
2816 }
2817 else
2818 {
2819 SetHotItem(nCmdID);
2820 SetAnchorHighlight(TRUE);
2821 }
2822 }
2823 }
2824
2825 BOOL DoTrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y, LPTPMPARAMS lpParams = NULL)
2826 {
2827 CMenuHandle menuPopup = hMenu;
2828
2829 CWindowCreateCriticalSectionLock lock;
2830 if(FAILED(lock.Lock()))
2831 {
2832 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::DoTrackPopupMenu.\n"));
2833 ATLASSERT(FALSE);
2834 return FALSE;
2835 }
2836
2837 ATLASSERT(s_hCreateHook == NULL);
2838
2839 s_pCurrentBar = static_cast<CCommandBarCtrlBase*>(this);
2840
2841 s_hCreateHook = ::SetWindowsHookEx(WH_CBT, CreateHookProc, ModuleHelper::GetModuleInstance(), GetCurrentThreadId());
2842 ATLASSERT(s_hCreateHook != NULL);
2843
2844 m_bPopupItem = false;
2845 m_bMenuActive = true;
2846
2847 BOOL bTrackRet = menuPopup.TrackPopupMenuEx(uFlags, x, y, m_hWnd, lpParams);
2848 m_bMenuActive = false;
2849
2850 ::UnhookWindowsHookEx(s_hCreateHook);
2851
2852 s_hCreateHook = NULL;
2853 s_pCurrentBar = NULL;
2854
2855 lock.Unlock();
2856
2857 // cleanup - convert menus back to original state
2858 #ifdef _CMDBAR_EXTRA_TRACE
2859 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - TrackPopupMenu - cleanup\n"));
2860 #endif
2861
2862 ATLASSERT(m_stackMenuWnd.GetSize() == 0);
2863
2864 UpdateWindow();
2865 ATL::CWindow wndTL = GetTopLevelParent();
2866 wndTL.UpdateWindow();
2867
2868 // restore the menu items to the previous state for all menus that were converted
2869 if(m_bImagesVisible)
2870 {
2871 HMENU hMenuSav = NULL;
2872 while((hMenuSav = m_stackMenuHandle.Pop()) != NULL)
2873 {
2874 menuPopup = hMenuSav;
2875 BOOL bRet = FALSE;
2876 // restore state and delete menu item data
2877 for(int i = 0; i < menuPopup.GetMenuItemCount(); i++)
2878 {
2879 CMenuItemInfo mii;
2880 mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_ID;
2881 bRet = menuPopup.GetMenuItemInfo(i, TRUE, &mii);
2882 ATLASSERT(bRet);
2883
2884 _MenuItemData* pMI = (_MenuItemData*)mii.dwItemData;
2885 if(pMI != NULL && pMI->IsCmdBarMenuItem())
2886 {
2887 mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_STATE;
2888 mii.fType = pMI->fType;
2889 mii.fState = pMI->fState;
2890 mii.dwTypeData = pMI->lpstrText;
2891 mii.cch = lstrlen(pMI->lpstrText);
2892 mii.dwItemData = NULL;
2893
2894 bRet = menuPopup.SetMenuItemInfo(i, TRUE, &mii);
2895 // this one triggers WM_MEASUREITEM
2896 menuPopup.ModifyMenu(i, MF_BYPOSITION | mii.fType | mii.fState, mii.wID, pMI->lpstrText);
2897 ATLASSERT(bRet);
2898
2899 delete [] pMI->lpstrText;
2900 delete pMI;
2901 }
2902 }
2903 }
2904 }
2905 return bTrackRet;
2906 }
2907
2908 int GetPreviousMenuItem(int nBtn) const
2909 {
2910 if(nBtn == -1)
2911 return -1;
2912 #if (_WIN32_IE >= 0x0500)
2913 RECT rcClient = { 0 };
2914 GetClientRect(&rcClient);
2915 #endif // (_WIN32_IE >= 0x0500)
2916 int nNextBtn;
2917 for(nNextBtn = nBtn - 1; nNextBtn != nBtn; nNextBtn--)
2918 {
2919 if(nNextBtn < 0)
2920 nNextBtn = ::GetMenuItemCount(m_hMenu) - 1;
2921 TBBUTTON tbb = { 0 };
2922 GetButton(nNextBtn, &tbb);
2923 #if (_WIN32_IE >= 0x0500)
2924 RECT rcBtn = { 0 };
2925 GetItemRect(nNextBtn, &rcBtn);
2926 if(rcBtn.right > rcClient.right)
2927 {
2928 nNextBtn = -2; // chevron
2929 break;
2930 }
2931 #endif // (_WIN32_IE >= 0x0500)
2932 if((tbb.fsState & TBSTATE_ENABLED) != 0 && (tbb.fsState & TBSTATE_HIDDEN) == 0)
2933 break;
2934 }
2935 return (nNextBtn != nBtn) ? nNextBtn : -1;
2936 }
2937
2938 int GetNextMenuItem(int nBtn) const
2939 {
2940 if(nBtn == -1)
2941 return -1;
2942 #if (_WIN32_IE >= 0x0500)
2943 RECT rcClient = { 0 };
2944 GetClientRect(&rcClient);
2945 #endif // (_WIN32_IE >= 0x0500)
2946 int nNextBtn = 0;
2947 int nCount = ::GetMenuItemCount(m_hMenu);
2948 for(nNextBtn = nBtn + 1; nNextBtn != nBtn; nNextBtn++)
2949 {
2950 if(nNextBtn >= nCount)
2951 nNextBtn = 0;
2952 TBBUTTON tbb = { 0 };
2953 GetButton(nNextBtn, &tbb);
2954 #if (_WIN32_IE >= 0x0500)
2955 RECT rcBtn = { 0 };
2956 GetItemRect(nNextBtn, &rcBtn);
2957 if(rcBtn.right > rcClient.right)
2958 {
2959 nNextBtn = -2; // chevron
2960 break;
2961 }
2962 #endif // (_WIN32_IE >= 0x0500)
2963 if((tbb.fsState & TBSTATE_ENABLED) != 0 && (tbb.fsState & TBSTATE_HIDDEN) == 0)
2964 break;
2965 }
2966 return (nNextBtn != nBtn) ? nNextBtn : -1;
2967 }
2968
2969 #if (_WIN32_IE >= 0x0500)
2970 bool DisplayChevronMenu()
2971 {
2972 // assume we are in a rebar
2973 HWND hWndReBar = GetParent();
2974 int nCount = (int)::SendMessage(hWndReBar, RB_GETBANDCOUNT, 0, 0L);
2975 bool bRet = false;
2976 for(int i = 0; i < nCount; i++)
2977 {
2978 REBARBANDINFO rbbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_STYLE };
2979 BOOL bRetBandInfo = (BOOL)::SendMessage(hWndReBar, RB_GETBANDINFO, i, (LPARAM)&rbbi);
2980 if(bRetBandInfo && rbbi.hwndChild == m_hWnd)
2981 {
2982 if((rbbi.fStyle & RBBS_USECHEVRON) != 0)
2983 {
2984 ::PostMessage(hWndReBar, RB_PUSHCHEVRON, i, 0L);
2985 PostMessage(WM_KEYDOWN, VK_DOWN, 0L);
2986 bRet = true;
2987 }
2988 break;
2989 }
2990 }
2991 return bRet;
2992 }
2993 #endif // (_WIN32_IE >= 0x0500)
2994
2995 void GetSystemSettings()
2996 {
2997 // refresh our font
2998 NONCLIENTMETRICS info = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() };
2999 BOOL bRet = ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);
3000 ATLASSERT(bRet);
3001 if(bRet)
3002 {
3003 LOGFONT logfont = { 0 };
3004 if(m_fontMenu.m_hFont != NULL)
3005 m_fontMenu.GetLogFont(logfont);
3006 if(logfont.lfHeight != info.lfMenuFont.lfHeight ||
3007 logfont.lfWidth != info.lfMenuFont.lfWidth ||
3008 logfont.lfEscapement != info.lfMenuFont.lfEscapement ||
3009 logfont.lfOrientation != info.lfMenuFont.lfOrientation ||
3010 logfont.lfWeight != info.lfMenuFont.lfWeight ||
3011 logfont.lfItalic != info.lfMenuFont.lfItalic ||
3012 logfont.lfUnderline != info.lfMenuFont.lfUnderline ||
3013 logfont.lfStrikeOut != info.lfMenuFont.lfStrikeOut ||
3014 logfont.lfCharSet != info.lfMenuFont.lfCharSet ||
3015 logfont.lfOutPrecision != info.lfMenuFont.lfOutPrecision ||
3016 logfont.lfClipPrecision != info.lfMenuFont.lfClipPrecision ||
3017 logfont.lfQuality != info.lfMenuFont.lfQuality ||
3018 logfont.lfPitchAndFamily != info.lfMenuFont.lfPitchAndFamily ||
3019 lstrcmp(logfont.lfFaceName, info.lfMenuFont.lfFaceName) != 0)
3020 {
3021 HFONT hFontMenu = ::CreateFontIndirect(&info.lfMenuFont);
3022 ATLASSERT(hFontMenu != NULL);
3023 if(hFontMenu != NULL)
3024 {
3025 if(m_fontMenu.m_hFont != NULL)
3026 m_fontMenu.DeleteObject();
3027 m_fontMenu.Attach(hFontMenu);
3028 SetFont(m_fontMenu);
3029 AddStrings(_T("NS\0")); // for proper item height
3030 AutoSize();
3031 }
3032 }
3033 }
3034
3035 // check if we need extra spacing for menu item text
3036 CWindowDC dc(m_hWnd);
3037 HFONT hFontOld = dc.SelectFont(m_fontMenu);
3038 RECT rcText = { 0 };
3039 dc.DrawText(_T("\t"), -1, &rcText, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT);
3040 if((rcText.right - rcText.left) < 4)
3041 {
3042 ::SetRectEmpty(&rcText);
3043 dc.DrawText(_T("x"), -1, &rcText, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT);
3044 m_cxExtraSpacing = rcText.right - rcText.left;
3045 }
3046 else
3047 {
3048 m_cxExtraSpacing = 0;
3049 }
3050 dc.SelectFont(hFontOld);
3051
3052 // get Windows version
3053 #ifndef _versionhelpers_H_INCLUDED_
3054 OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) };
3055 ::GetVersionEx(&ovi);
3056 #endif // !_versionhelpers_H_INCLUDED_
3057
3058 // query keyboard cues mode (Windows 2000 or later)
3059 #ifdef _versionhelpers_H_INCLUDED_
3060 if(::IsWindowsVersionOrGreater(5, 0, 0))
3061 #else // !_versionhelpers_H_INCLUDED_
3062 if (ovi.dwMajorVersion >= 5)
3063 #endif // _versionhelpers_H_INCLUDED_
3064 {
3065 #ifndef SPI_GETKEYBOARDCUES
3066 const UINT SPI_GETKEYBOARDCUES = 0x100A;
3067 #endif // !SPI_GETKEYBOARDCUES
3068 BOOL bRetVal = TRUE;
3069 bRet = ::SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &bRetVal, 0);
3070 m_bUseKeyboardCues = (bRet && !bRetVal);
3071 m_bAllowKeyboardCues = true;
3072 ShowKeyboardCues(!m_bUseKeyboardCues);
3073 }
3074
3075 // query flat menu mode (Windows XP or later)
3076 #ifdef _versionhelpers_H_INCLUDED_
3077 if(::IsWindowsXPOrGreater())
3078 #else // !_versionhelpers_H_INCLUDED_
3079 if ((ovi.dwMajorVersion == 5 && ovi.dwMinorVersion >= 1) || (ovi.dwMajorVersion > 5))
3080 #endif // _versionhelpers_H_INCLUDED_
3081 {
3082 #ifndef SPI_GETFLATMENU
3083 const UINT SPI_GETFLATMENU = 0x1022;
3084 #endif // !SPI_GETFLATMENU
3085 BOOL bRetVal = FALSE;
3086 bRet = ::SystemParametersInfo(SPI_GETFLATMENU, 0, &bRetVal, 0);
3087 m_bFlatMenus = (bRet && bRetVal);
3088 }
3089
3090 #if _WTL_CMDBAR_VISTA_MENUS
3091 // check if we should use Vista menus
3092 bool bVistaMenus = (((m_dwExtendedStyle & CBR_EX_NOVISTAMENUS) == 0) && RunTimeHelper::IsVista() && RunTimeHelper::IsThemeAvailable());
3093 if(!bVistaMenus && m_bVistaMenus && (m_hMenu != NULL) && (m_arrCommand.GetSize() > 0))
3094 {
3095 T* pT = static_cast<T*>(this);
3096 pT->_RemoveVistaBitmapsFromMenu();
3097 }
3098
3099 m_bVistaMenus = bVistaMenus;
3100 #endif // _WTL_CMDBAR_VISTA_MENUS
3101
3102 #ifdef _CMDBAR_EXTRA_TRACE
3103 ATLTRACE2(atlTraceUI, 0, _T("CmdBar - GetSystemSettings:\n m_bFlatMenus = %s\n m_bUseKeyboardCues = %s m_bVistaMenus = %s\n"),
3104 m_bFlatMenus ? "true" : "false", m_bUseKeyboardCues ? "true" : "false", m_bVistaMenus ? "true" : "false");
3105 #endif
3106 }
3107
3108 // Implementation - alternate focus mode support
3109 void TakeFocus()
3110 {
3111 if((m_dwExtendedStyle & CBR_EX_ALTFOCUSMODE) && m_hWndFocus == NULL)
3112 m_hWndFocus = ::GetFocus();
3113 SetFocus();
3114 }
3115
3116 void GiveFocusBack()
3117 {
3118 if(m_bParentActive)
3119 {
3120 if((m_dwExtendedStyle & CBR_EX_ALTFOCUSMODE) && ::IsWindow(m_hWndFocus))
3121 ::SetFocus(m_hWndFocus);
3122 else if(!(m_dwExtendedStyle & CBR_EX_ALTFOCUSMODE) && m_wndParent.IsWindow())
3123 m_wndParent.SetFocus();
3124 }
3125 m_hWndFocus = NULL;
3126 SetAnchorHighlight(FALSE);
3127 if(m_bUseKeyboardCues && m_bShowKeyboardCues)
3128 ShowKeyboardCues(false);
3129 m_bSkipPostDown = false;
3130 }
3131
3132 void ShowKeyboardCues(bool bShow)
3133 {
3134 m_bShowKeyboardCues = bShow;
3135 SetDrawTextFlags(DT_HIDEPREFIX, m_bShowKeyboardCues ? 0 : DT_HIDEPREFIX);
3136 Invalidate();
3137 UpdateWindow();
3138 }
3139
3140 // Implementation - internal message helpers
3141 static UINT GetAutoPopupMessage()
3142 {
3143 static UINT uAutoPopupMessage = 0;
3144 if(uAutoPopupMessage == 0)
3145 {
3146 CStaticDataInitCriticalSectionLock lock;
3147 if(FAILED(lock.Lock()))
3148 {
3149 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::GetAutoPopupMessage.\n"));
3150 ATLASSERT(FALSE);
3151 return 0;
3152 }
3153
3154 if(uAutoPopupMessage == 0)
3155 uAutoPopupMessage = ::RegisterWindowMessage(_T("WTL_CmdBar_InternalAutoPopupMsg"));
3156
3157 lock.Unlock();
3158 }
3159 ATLASSERT(uAutoPopupMessage != 0);
3160 return uAutoPopupMessage;
3161 }
3162
3163 static UINT GetGetBarMessage()
3164 {
3165 static UINT uGetBarMessage = 0;
3166 if(uGetBarMessage == 0)
3167 {
3168 CStaticDataInitCriticalSectionLock lock;
3169 if(FAILED(lock.Lock()))
3170 {
3171 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::GetGetBarMessage.\n"));
3172 ATLASSERT(FALSE);
3173 return 0;
3174 }
3175
3176 if(uGetBarMessage == 0)
3177 uGetBarMessage = ::RegisterWindowMessage(_T("WTL_CmdBar_InternalGetBarMsg"));
3178
3179 lock.Unlock();
3180 }
3181 ATLASSERT(uGetBarMessage != 0);
3182 return uGetBarMessage;
3183 }
3184
3185 // Implementation
3186 bool CreateInternalImageList(int cImages)
3187 {
3188 UINT uFlags = (m_bAlphaImages ? ILC_COLOR32 : ILC_COLOR24) | ILC_MASK;
3189 m_hImageList = ::ImageList_Create(m_szBitmap.cx, m_szBitmap.cy, uFlags, cImages, 1);
3190 ATLASSERT(m_hImageList != NULL);
3191 return (m_hImageList != NULL);
3192 }
3193
3194 // Implementation - support for Vista menus
3195 #if _WTL_CMDBAR_VISTA_MENUS
3196 void _AddVistaBitmapsFromImageList(int nStartIndex, int nCount)
3197 {
3198 // Create display compatible memory DC
3199 CClientDC dc(NULL);
3200 CDC dcMem;
3201 dcMem.CreateCompatibleDC(dc);
3202 HBITMAP hBitmapSave = dcMem.GetCurrentBitmap();
3203
3204 T* pT = static_cast<T*>(this);
3205 // Create bitmaps for all menu items
3206 for(int i = 0; i < nCount; i++)
3207 {
3208 HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nStartIndex + i, dc, dcMem);
3209 dcMem.SelectBitmap(hBitmapSave);
3210 m_arrVistaBitmap.Add(hBitmap);
3211 }
3212 }
3213
3214 void _AddVistaBitmapFromImageList(int nIndex)
3215 {
3216 // Create display compatible memory DC
3217 CClientDC dc(NULL);
3218 CDC dcMem;
3219 dcMem.CreateCompatibleDC(dc);
3220 HBITMAP hBitmapSave = dcMem.GetCurrentBitmap();
3221
3222 // Create bitmap for menu item
3223 T* pT = static_cast<T*>(this);
3224 HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nIndex, dc, dcMem);
3225
3226 // Select saved bitmap back and add bitmap to the array
3227 dcMem.SelectBitmap(hBitmapSave);
3228 m_arrVistaBitmap.Add(hBitmap);
3229 }
3230
3231 void _ReplaceVistaBitmapFromImageList(int nIndex)
3232 {
3233 // Delete existing bitmap
3234 if(m_arrVistaBitmap[nIndex] != NULL)
3235 ::DeleteObject(m_arrVistaBitmap[nIndex]);
3236
3237 // Create display compatible memory DC
3238 CClientDC dc(NULL);
3239 CDC dcMem;
3240 dcMem.CreateCompatibleDC(dc);
3241 HBITMAP hBitmapSave = dcMem.GetCurrentBitmap();
3242
3243 // Create bitmap for menu item
3244 T* pT = static_cast<T*>(this);
3245 HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nIndex, dc, dcMem);
3246
3247 // Select saved bitmap back and replace bitmap in the array
3248 dcMem.SelectBitmap(hBitmapSave);
3249 m_arrVistaBitmap.SetAtIndex(nIndex, hBitmap);
3250 }
3251
3252 HBITMAP _CreateVistaBitmapHelper(int nIndex, HDC hDCSource, HDC hDCTarget)
3253 {
3254 // Create 32-bit bitmap
3255 BITMAPINFO bi = { 0 };
3256 bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3257 bi.bmiHeader.biWidth = m_szBitmap.cx;
3258 bi.bmiHeader.biHeight = m_szBitmap.cy;
3259 bi.bmiHeader.biPlanes = 1;
3260 bi.bmiHeader.biBitCount = 32;
3261 bi.bmiHeader.biCompression = BI_RGB;
3262 bi.bmiHeader.biSizeImage = 0;
3263 bi.bmiHeader.biXPelsPerMeter = 0;
3264 bi.bmiHeader.biYPelsPerMeter = 0;
3265 bi.bmiHeader.biClrUsed = 0;
3266 bi.bmiHeader.biClrImportant = 0;
3267 HBITMAP hBitmap = ::CreateDIBSection(hDCSource, &bi, DIB_RGB_COLORS, NULL, NULL, 0);
3268 ATLASSERT(hBitmap != NULL);
3269
3270 // Select bitmap into target DC and draw from image list to it
3271 if(hBitmap != NULL)
3272 {
3273 ::SelectObject(hDCTarget, hBitmap);
3274
3275 IMAGELISTDRAWPARAMS ildp = { 0 };
3276 ildp.cbSize = sizeof(IMAGELISTDRAWPARAMS);
3277 ildp.himl = m_hImageList;
3278 ildp.i = nIndex;
3279 ildp.hdcDst = hDCTarget;
3280 ildp.x = 0;
3281 ildp.y = 0;
3282 ildp.cx = 0;
3283 ildp.cy = 0;
3284 ildp.xBitmap = 0;
3285 ildp.yBitmap = 0;
3286 ildp.fStyle = ILD_TRANSPARENT;
3287 ildp.fState = ILS_ALPHA;
3288 ildp.Frame = 255;
3289 ::ImageList_DrawIndirect(&ildp);
3290 }
3291
3292 return hBitmap;
3293 }
3294
3295 void _RemoveVistaBitmapsFromMenu()
3296 {
3297 CMenuHandle menu = m_hMenu;
3298 for(int i = 0; i < m_arrCommand.GetSize(); i++)
3299 {
3300 CMenuItemInfo mii;
3301 mii.fMask = MIIM_BITMAP;
3302 mii.hbmpItem = NULL;
3303 menu.SetMenuItemInfo(m_arrCommand[i], FALSE, &mii);
3304 }
3305 }
3306 #endif // _WTL_CMDBAR_VISTA_MENUS
3307 };
3308
3309
3310 class CCommandBarCtrl : public CCommandBarCtrlImpl<CCommandBarCtrl>
3311 {
3312 public:
3313 DECLARE_WND_SUPERCLASS(_T("WTL_CommandBar"), GetWndClassName())
3314 };
3315
3316
3317 ///////////////////////////////////////////////////////////////////////////////
3318 // CMDICommandBarCtrl - ATL implementation of Command Bars for MDI apps
3319
3320 template <class T, class TBase = CCommandBarCtrlBase, class TWinTraits = ATL::CControlWinTraits>
3321 class ATL_NO_VTABLE CMDICommandBarCtrlImpl : public CCommandBarCtrlImpl< T, TBase, TWinTraits>
3322 {
3323 public:
3324 // Data members
3325 ATL::CContainedWindow m_wndMDIClient;
3326 bool m_bChildMaximized;
3327 HWND m_hWndChildMaximized;
3328 HICON m_hIconChildMaximized;
3329 int m_nBtnPressed;
3330 int m_nBtnWasPressed;
3331
3332 int m_cxyOffset; // offset between nonclient elements
3333 int m_cxIconWidth; // small icon width
3334 int m_cyIconHeight; // small icon height
3335 int m_cxBtnWidth; // nonclient button width
3336 int m_cyBtnHeight; // nonclient button height
3337 int m_cxLeft; // left nonclient area width
3338 int m_cxRight; // right nonclient area width
3339
3340 // Theme declarations and data members
3341 #ifndef _WTL_NO_AUTO_THEME
3342 #ifndef _UXTHEME_H_
3343 typedef HANDLE HTHEME;
3344 #endif // !_UXTHEME_H_
3345 typedef HTHEME (STDAPICALLTYPE *PFN_OpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
3346 typedef HRESULT (STDAPICALLTYPE *PFN_CloseThemeData)(HTHEME hTheme);
3347 typedef HRESULT (STDAPICALLTYPE *PFN_DrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
3348 typedef HRESULT (STDAPICALLTYPE *PFN_DrawThemeParentBackground)(HWND hwnd, HDC hdc, OPTIONAL RECT* prc);
3349
3350 HMODULE m_hThemeDLL;
3351 HTHEME m_hTheme;
3352 PFN_DrawThemeBackground m_pfnDrawThemeBackground;
3353 PFN_DrawThemeParentBackground m_pfnDrawThemeParentBackground;
3354 #endif // !_WTL_NO_AUTO_THEME
3355
3356 // Constructor/destructor
3357 CMDICommandBarCtrlImpl() :
3358 m_wndMDIClient(this, 2), m_bChildMaximized(false),
3359 m_hWndChildMaximized(NULL), m_hIconChildMaximized(NULL),
3360 m_nBtnPressed(-1), m_nBtnWasPressed(-1),
3361 #ifndef _WTL_NO_AUTO_THEME
3362 m_hThemeDLL(NULL), m_hTheme(NULL), m_pfnDrawThemeBackground(NULL), m_pfnDrawThemeParentBackground(NULL),
3363 #endif // !_WTL_NO_AUTO_THEME
3364 m_cxyOffset(2),
3365 m_cxIconWidth(16), m_cyIconHeight(16),
3366 m_cxBtnWidth(16), m_cyBtnHeight(14),
3367 m_cxLeft(20), m_cxRight(55)
3368 { }
3369
3370 ~CMDICommandBarCtrlImpl()
3371 {
3372 if(m_wndMDIClient.IsWindow())
3373 /*scary!*/ m_wndMDIClient.UnsubclassWindow();
3374 }
3375
3376 // Operations
3377 BOOL SetMDIClient(HWND hWndMDIClient)
3378 {
3379 ATLASSERT(::IsWindow(m_hWnd));
3380 ATLASSERT(::IsWindow(hWndMDIClient));
3381 if(!::IsWindow(hWndMDIClient))
3382 return FALSE;
3383
3384 #ifdef _DEBUG
3385 // BLOCK: Test if the passed window is MDICLIENT
3386 {
3387 LPCTSTR lpszMDIClientClass = _T("MDICLIENT");
3388 const int nNameLen = 9 + 1; // "MDICLIENT" + NULL
3389 TCHAR szClassName[nNameLen] = { 0 };
3390 ::GetClassName(hWndMDIClient, szClassName, nNameLen);
3391 ATLASSERT(lstrcmpi(szClassName, lpszMDIClientClass) == 0);
3392 }
3393 #endif // _DEBUG
3394
3395 if(m_wndMDIClient.IsWindow())
3396 /*scary!*/ m_wndMDIClient.UnsubclassWindow();
3397
3398 return m_wndMDIClient.SubclassWindow(hWndMDIClient);
3399 }
3400
3401 // Message maps
3402 typedef CCommandBarCtrlImpl< T, TBase, TWinTraits > _baseClass;
3403 BEGIN_MSG_MAP(CMDICommandBarCtrlImpl)
3404 MESSAGE_HANDLER(WM_CREATE, OnCreate)
3405 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
3406 #ifndef _WTL_NO_AUTO_THEME
3407 MESSAGE_HANDLER(_GetThemeChangedMsg(), OnThemeChanged)
3408 #endif // !_WTL_NO_AUTO_THEME
3409 MESSAGE_HANDLER(WM_SIZE, OnSize)
3410 MESSAGE_HANDLER(WM_NCCALCSIZE, OnNcCalcSize)
3411 MESSAGE_HANDLER(WM_NCPAINT, OnNcPaint)
3412 MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest)
3413 MESSAGE_HANDLER(WM_NCLBUTTONDOWN, OnNcLButtonDown)
3414 MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
3415 MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
3416 MESSAGE_HANDLER(WM_NCLBUTTONDBLCLK, OnNcLButtonDblClk)
3417 MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged)
3418 CHAIN_MSG_MAP(_baseClass)
3419 ALT_MSG_MAP(1) // Parent window messages
3420 MESSAGE_HANDLER(WM_ACTIVATE, OnParentActivate)
3421 CHAIN_MSG_MAP_ALT(_baseClass, 1)
3422 ALT_MSG_MAP(2) // MDI client window messages
3423 MESSAGE_HANDLER(WM_MDISETMENU, OnMDISetMenu)
3424 // no chaining needed since this was moved from the base class here
3425 ALT_MSG_MAP(3) // Message hook messages
3426 MESSAGE_RANGE_HANDLER(0, 0xFFFF, OnAllHookMessages)
3427 CHAIN_MSG_MAP_ALT(_baseClass, 3)
3428 END_MSG_MAP()
3429
3430 // Additional MDI message handlers
3431 LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3432 {
3433 LRESULT lRet = _baseClass::OnCreate(uMsg, wParam, lParam, bHandled);
3434 if(lRet == (LRESULT)-1)
3435 return lRet;
3436
3437 #ifndef _WTL_NO_AUTO_THEME
3438 // this will fail if theming is not supported
3439 m_hThemeDLL = ::LoadLibrary(_T("uxtheme.dll"));
3440 if(m_hThemeDLL != NULL)
3441 {
3442 m_pfnDrawThemeBackground = (PFN_DrawThemeBackground)::GetProcAddress(m_hThemeDLL, "DrawThemeBackground");
3443 ATLASSERT(m_pfnDrawThemeBackground != NULL);
3444 if(m_pfnDrawThemeBackground != NULL)
3445 {
3446 T* pT = static_cast<T*>(this);
3447 pT->_OpenThemeData();
3448 }
3449 else
3450 {
3451 ::FreeLibrary(m_hThemeDLL);
3452 m_hThemeDLL = NULL;
3453 }
3454 m_pfnDrawThemeParentBackground = (PFN_DrawThemeParentBackground)::GetProcAddress(m_hThemeDLL, "DrawThemeParentBackground");
3455 ATLASSERT(m_pfnDrawThemeParentBackground != NULL);
3456 }
3457 #endif // !_WTL_NO_AUTO_THEME
3458
3459 return lRet;
3460 }
3461
3462 LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3463 {
3464 LRESULT lRet = _baseClass::OnDestroy(uMsg, wParam, lParam, bHandled);
3465
3466 #ifndef _WTL_NO_AUTO_THEME
3467 if(m_hThemeDLL != NULL)
3468 {
3469 T* pT = static_cast<T*>(this);
3470 pT->_CloseThemeData();
3471 ::FreeLibrary(m_hThemeDLL);
3472 m_hThemeDLL = NULL;
3473 }
3474 #endif // !_WTL_NO_AUTO_THEME
3475
3476 return lRet;
3477 }
3478
3479 #ifndef _WTL_NO_AUTO_THEME
3480 LRESULT OnThemeChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
3481 {
3482 if(m_hThemeDLL != NULL)
3483 {
3484 T* pT = static_cast<T*>(this);
3485 pT->_CloseThemeData();
3486 pT->_OpenThemeData();
3487 }
3488 return 0;
3489 }
3490 #endif // !_WTL_NO_AUTO_THEME
3491
3492 LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
3493 {
3494 LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
3495 T* pT = static_cast<T*>(this);
3496 pT->_AdjustBtnSize(GET_Y_LPARAM(lParam));
3497 return lRet;
3498 }
3499
3500 LRESULT OnNcCalcSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
3501 {
3502 LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
3503
3504 if(m_bChildMaximized && (BOOL)wParam)
3505 {
3506 LPNCCALCSIZE_PARAMS lpParams = (LPNCCALCSIZE_PARAMS)lParam;
3507 if(m_bLayoutRTL)
3508 {
3509 lpParams->rgrc[0].left += m_cxRight;
3510 lpParams->rgrc[0].right -= m_cxLeft;
3511 }
3512 else
3513 {
3514 lpParams->rgrc[0].left += m_cxLeft;
3515 lpParams->rgrc[0].right -= m_cxRight;
3516 }
3517 }
3518
3519 return lRet;
3520 }
3521
3522 LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
3523 {
3524 LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
3525
3526 if(!m_bChildMaximized)
3527 return lRet;
3528
3529 ATLASSERT(m_hWndChildMaximized != NULL && m_hIconChildMaximized != NULL);
3530
3531 // get DC and window rectangle
3532 CWindowDC dc(m_hWnd);
3533 RECT rect = { 0 };
3534 GetWindowRect(&rect);
3535 int cxWidth = rect.right - rect.left;
3536 int cyHeight = rect.bottom - rect.top;
3537
3538 // paint left side nonclient background and draw icon
3539 ::SetRect(&rect, 0, 0, m_cxLeft, cyHeight);
3540 #ifndef _WTL_NO_AUTO_THEME
3541 if(m_hTheme != NULL)
3542 {
3543 if(m_pfnDrawThemeParentBackground != NULL)
3544 m_pfnDrawThemeParentBackground(m_hWnd, dc, &rect);
3545 else
3546 dc.FillRect(&rect, COLOR_WINDOW);
3547 }
3548 else
3549 #endif // !_WTL_NO_AUTO_THEME
3550 {
3551 if((m_dwExtendedStyle & CBR_EX_TRANSPARENT) != 0)
3552 dc.FillRect(&rect, COLOR_3DFACE);
3553 else
3554 dc.FillRect(&rect, COLOR_MENU);
3555 }
3556
3557 RECT rcIcon = { 0 };
3558 T* pT = static_cast<T*>(this);
3559 pT->_CalcIconRect(cxWidth, cyHeight, rcIcon);
3560 dc.DrawIconEx(rcIcon.left, rcIcon.top, m_hIconChildMaximized, m_cxIconWidth, m_cyIconHeight);
3561
3562 // paint right side nonclient background
3563 ::SetRect(&rect, cxWidth - m_cxRight, 0, cxWidth, cyHeight);
3564 #ifndef _WTL_NO_AUTO_THEME
3565 if(m_hTheme != NULL)
3566 {
3567 if(m_pfnDrawThemeParentBackground != NULL)
3568 {
3569 // this is to account for the left non-client area
3570 POINT ptOrg = { 0, 0 };
3571 dc.GetViewportOrg(&ptOrg);
3572 dc.SetViewportOrg(ptOrg.x + m_cxLeft, ptOrg.y);
3573 ::OffsetRect(&rect, -m_cxLeft, 0);
3574
3575 m_pfnDrawThemeParentBackground(m_hWnd, dc, &rect);
3576
3577 // restore
3578 dc.SetViewportOrg(ptOrg);
3579 ::OffsetRect(&rect, m_cxLeft, 0);
3580 }
3581 else
3582 {
3583 dc.FillRect(&rect, COLOR_3DFACE);
3584 }
3585 }
3586 else
3587 #endif // !_WTL_NO_AUTO_THEME
3588 {
3589 if((m_dwExtendedStyle & CBR_EX_TRANSPARENT) != 0)
3590 dc.FillRect(&rect, COLOR_3DFACE);
3591 else
3592 dc.FillRect(&rect, COLOR_MENU);
3593 }
3594
3595 // draw buttons
3596 RECT arrRect[3] = { 0 };
3597 pT->_CalcBtnRects(cxWidth, cyHeight, arrRect);
3598 pT->_DrawMDIButton(dc, arrRect, -1); // draw all buttons
3599
3600 return lRet;
3601 }
3602
3603 LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
3604 {
3605 LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
3606 if(m_bChildMaximized)
3607 {
3608 RECT rect = { 0 };
3609 GetWindowRect(&rect);
3610 POINT pt = { GET_X_LPARAM(lParam) - rect.left, GET_Y_LPARAM(lParam) - rect.top };
3611 if(m_bLayoutRTL)
3612 {
3613 if((pt.x < m_cxRight) || (pt.x > ((rect.right - rect.left) - m_cxLeft)))
3614 lRet = HTBORDER;
3615 }
3616 else
3617 {
3618 if((pt.x < m_cxLeft) || (pt.x > ((rect.right - rect.left) - m_cxRight)))
3619 lRet = HTBORDER;
3620 }
3621 }
3622 return lRet;
3623 }
3624
3625 LRESULT OnNcLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
3626 {
3627 if(!m_bChildMaximized)
3628 {
3629 bHandled = FALSE;
3630 return 1;
3631 }
3632
3633 ATLASSERT(_DebugCheckChild());
3634
3635 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
3636 RECT rect = { 0 };
3637 GetWindowRect(&rect);
3638 pt.x -= rect.left;
3639 pt.y -= rect.top;
3640
3641 RECT rcIcon = { 0 };
3642 T* pT = static_cast<T*>(this);
3643 pT->_CalcIconRect(rect.right - rect.left, rect.bottom - rect.top, rcIcon, m_bLayoutRTL);
3644 RECT arrRect[3] = { 0 };
3645 pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect, m_bLayoutRTL);
3646
3647 if(::PtInRect(&rcIcon, pt))
3648 {
3649 #ifdef _CMDBAR_EXTRA_TRACE
3650 ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonDown: icon\n"));
3651 #endif
3652 #ifndef TPM_VERPOSANIMATION
3653 const UINT TPM_VERPOSANIMATION = 0x1000L; // Menu animation flag
3654 #endif
3655 CMenuHandle menu = ::GetSystemMenu(m_hWndChildMaximized, FALSE);
3656 UINT uRet = (UINT)menu.TrackPopupMenu(TPM_LEFTBUTTON | TPM_VERTICAL | TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD |
3657 (s_bW2K ? TPM_VERPOSANIMATION : 0), m_bLayoutRTL ? rect.right : rect.left, rect.bottom, m_hWndChildMaximized);
3658
3659 // eat next message if click is on the same button
3660 ::OffsetRect(&rcIcon, rect.left, rect.top);
3661 MSG msg = { 0 };
3662 if(::PeekMessage(&msg, m_hWnd, WM_NCLBUTTONDOWN, WM_NCLBUTTONDOWN, PM_NOREMOVE) && ::PtInRect(&rcIcon, msg.pt))
3663 ::PeekMessage(&msg, m_hWnd, WM_NCLBUTTONDOWN, WM_NCLBUTTONDOWN, PM_REMOVE);
3664
3665 if(uRet != 0)
3666 ::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, uRet, 0L);
3667 }
3668 else if(::PtInRect(&arrRect[0], pt))
3669 {
3670 #ifdef _CMDBAR_EXTRA_TRACE
3671 ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonDown: close button\n"));
3672 #endif
3673 m_nBtnWasPressed = m_nBtnPressed = 0;
3674 }
3675 else if(::PtInRect(&arrRect[1], pt))
3676 {
3677 #ifdef _CMDBAR_EXTRA_TRACE
3678 ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonDown: restore button\n"));
3679 #endif
3680 m_nBtnWasPressed = m_nBtnPressed = 1;
3681 }
3682 else if(::PtInRect(&arrRect[2], pt))
3683 {
3684 #ifdef _CMDBAR_EXTRA_TRACE
3685 ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonDown: minimize button\n"));
3686 #endif
3687 m_nBtnWasPressed = m_nBtnPressed = 2;
3688 }
3689 else
3690 {
3691 bHandled = FALSE;
3692 }
3693
3694 // draw the button state if it was pressed
3695 if(m_nBtnPressed != -1)
3696 {
3697 SetCapture();
3698 CWindowDC dc(m_hWnd);
3699 pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect);
3700 pT->_DrawMDIButton(dc, arrRect, m_nBtnPressed);
3701 }
3702
3703 return 0;
3704 }
3705
3706 LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
3707 {
3708 if(!m_bChildMaximized || ::GetCapture() != m_hWnd || m_nBtnWasPressed == -1)
3709 {
3710 bHandled = FALSE;
3711 return 1;
3712 }
3713
3714 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
3715 ClientToScreen(&pt);
3716 RECT rect = { 0 };
3717 GetWindowRect(&rect);
3718 pt.x -= rect.left;
3719 pt.y -= rect.top;
3720 RECT arrRect[3] = { 0 };
3721 T* pT = static_cast<T*>(this);
3722 pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect, m_bLayoutRTL);
3723 int nOldBtnPressed = m_nBtnPressed;
3724 m_nBtnPressed = ::PtInRect(&arrRect[m_nBtnWasPressed], pt) ? m_nBtnWasPressed : -1;
3725 if(nOldBtnPressed != m_nBtnPressed)
3726 {
3727 CWindowDC dc(m_hWnd);
3728 pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect);
3729 pT->_DrawMDIButton(dc, arrRect, (m_nBtnPressed != -1) ? m_nBtnPressed : nOldBtnPressed);
3730 }
3731
3732 return 0;
3733 }
3734
3735 LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
3736 {
3737 if(!m_bChildMaximized || ::GetCapture() != m_hWnd || m_nBtnWasPressed == -1)
3738 {
3739 bHandled = FALSE;
3740 return 1;
3741 }
3742
3743 ATLASSERT(_DebugCheckChild());
3744
3745 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
3746 ClientToScreen(&pt);
3747 RECT rect = { 0 };
3748 GetWindowRect(&rect);
3749 pt.x -= rect.left;
3750 pt.y -= rect.top;
3751
3752 int nBtn = m_nBtnWasPressed;
3753 ReleaseCapture();
3754
3755 RECT arrRect[3] = { 0 };
3756 T* pT = static_cast<T*>(this);
3757 pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect, m_bLayoutRTL);
3758 if(::PtInRect(&arrRect[nBtn], pt))
3759 {
3760 switch(nBtn)
3761 {
3762 case 0: // close
3763 #ifdef _CMDBAR_EXTRA_TRACE
3764 ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonUp: close button\n"));
3765 #endif
3766 ::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, SC_CLOSE, 0L);
3767 break;
3768 case 1: // restore
3769 #ifdef _CMDBAR_EXTRA_TRACE
3770 ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonUp: restore button\n"));
3771 #endif
3772 ::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, SC_RESTORE, 0L);
3773 break;
3774 case 2: // minimize
3775 #ifdef _CMDBAR_EXTRA_TRACE
3776 ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonUp: minimize button\n"));
3777 #endif
3778 ::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, SC_MINIMIZE, 0L);
3779 break;
3780 default:
3781 break;
3782 }
3783 }
3784
3785 return 0;
3786 }
3787
3788 LRESULT OnNcLButtonDblClk(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
3789 {
3790 if(!m_bChildMaximized || m_nBtnWasPressed != -1)
3791 {
3792 bHandled = FALSE;
3793 return 1;
3794 }
3795
3796 ATLASSERT(_DebugCheckChild());
3797
3798 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
3799 RECT rect = { 0 };
3800 GetWindowRect(&rect);
3801 pt.x -= rect.left;
3802 pt.y -= rect.top;
3803
3804 RECT rcIcon = { 0 };
3805 T* pT = static_cast<T*>(this);
3806 pT->_CalcIconRect(rect.right - rect.left, rect.bottom - rect.top, rcIcon, m_bLayoutRTL);
3807 RECT arrRect[3] = { 0 };
3808 pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect, m_bLayoutRTL);
3809
3810 if(::PtInRect(&rcIcon, pt))
3811 {
3812 CMenuHandle menu = ::GetSystemMenu(m_hWndChildMaximized, FALSE);
3813 UINT uDefID = menu.GetMenuDefaultItem();
3814 if(uDefID == (UINT)-1)
3815 uDefID = SC_CLOSE;
3816 ::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, uDefID, 0L);
3817 }
3818
3819 return 0;
3820 }
3821
3822 LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
3823 {
3824 if(m_bChildMaximized)
3825 {
3826 if(m_nBtnPressed != -1)
3827 {
3828 ATLASSERT(m_nBtnPressed == m_nBtnWasPressed); // must be
3829 m_nBtnPressed = -1;
3830 RECT rect = { 0 };
3831 GetWindowRect(&rect);
3832 RECT arrRect[3] = { 0 };
3833 T* pT = static_cast<T*>(this);
3834 pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect);
3835 CWindowDC dc(m_hWnd);
3836 pT->_DrawMDIButton(dc, arrRect, m_nBtnWasPressed);
3837 }
3838 m_nBtnWasPressed = -1;
3839 }
3840 else
3841 {
3842 bHandled = FALSE;
3843 }
3844 return 0;
3845 }
3846
3847 // Parent window message handlers
3848 LRESULT OnParentActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
3849 {
3850 m_bParentActive = (LOWORD(wParam) != WA_INACTIVE);
3851 RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW);
3852 bHandled = FALSE;
3853 return 1;
3854 }
3855
3856 // MDI client window message handlers
3857 LRESULT OnMDISetMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
3858 {
3859 m_wndMDIClient.DefWindowProc(uMsg, NULL, lParam);
3860 HMENU hOldMenu = GetMenu();
3861 BOOL bRet = AttachMenu((HMENU)wParam);
3862 bRet; // avoid level 4 warning
3863 ATLASSERT(bRet);
3864
3865 #if (_WIN32_IE >= 0x0400)
3866 T* pT = static_cast<T*>(this);
3867 pT->UpdateRebarBandIdealSize();
3868 #endif // (_WIN32_IE >= 0x0400)
3869
3870 return (LRESULT)hOldMenu;
3871 }
3872
3873 // All messages from the message hook
3874 LRESULT OnAllHookMessages(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3875 {
3876 T* pT = static_cast<T*>(this);
3877 pT->_ProcessAllHookMessages(uMsg, wParam, lParam);
3878
3879 bHandled = FALSE;
3880 return 1;
3881 }
3882
3883 // Overrideables
3884 // override this to provide different ideal size
3885 void UpdateRebarBandIdealSize()
3886 {
3887 // assuming we are in a rebar, change ideal size to our size
3888 // we hope that if we are not in a rebar, nCount will be 0
3889 int nCount = (int)::SendMessage(GetParent(), RB_GETBANDCOUNT, 0, 0L);
3890 for(int i = 0; i < nCount; i++)
3891 {
3892 REBARBANDINFO rbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE };
3893 ::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi);
3894 if(rbi.hwndChild == m_hWnd)
3895 {
3896 rbi.fMask = RBBIM_IDEALSIZE;
3897 rbi.cxIdeal = m_bChildMaximized ? m_cxLeft + m_cxRight : 0;
3898 int nBtnCount = GetButtonCount();
3899 if(nBtnCount > 0)
3900 {
3901 RECT rect = { 0 };
3902 GetItemRect(nBtnCount - 1, &rect);
3903 rbi.cxIdeal += rect.right;
3904 }
3905 ::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi);
3906 break;
3907 }
3908 }
3909 }
3910
3911 // all hook messages - check for the maximized MDI child window change
3912 void _ProcessAllHookMessages(UINT uMsg, WPARAM /*wParam*/, LPARAM /*lParam*/)
3913 {
3914 if(uMsg == WM_MDIGETACTIVE || uMsg == WM_MDISETMENU)
3915 return;
3916
3917 BOOL bMaximized = FALSE;
3918 HWND hWndChild = (HWND)::SendMessage(m_wndMDIClient, WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized);
3919 bool bMaxOld = m_bChildMaximized;
3920 m_bChildMaximized = (hWndChild != NULL && bMaximized);
3921 HICON hIconOld = m_hIconChildMaximized;
3922
3923 if(m_bChildMaximized)
3924 {
3925 if(m_hWndChildMaximized != hWndChild)
3926 {
3927 ATL::CWindow wnd = m_hWndChildMaximized = hWndChild;
3928 m_hIconChildMaximized = wnd.GetIcon(FALSE);
3929 if(m_hIconChildMaximized == NULL)
3930 {
3931 m_hIconChildMaximized = wnd.GetIcon(TRUE);
3932 if(m_hIconChildMaximized == NULL)
3933 {
3934 // no icon set with WM_SETICON, get the class one
3935 // need conditional code because types don't match in winuser.h
3936 #ifdef _WIN64
3937 m_hIconChildMaximized = (HICON)::GetClassLongPtr(wnd, GCLP_HICONSM);
3938 #else
3939 m_hIconChildMaximized = (HICON)LongToHandle(::GetClassLongPtr(wnd, GCLP_HICONSM));
3940 #endif
3941 }
3942 }
3943 }
3944 }
3945 else
3946 {
3947 m_hWndChildMaximized = NULL;
3948 m_hIconChildMaximized = NULL;
3949 }
3950
3951 if(bMaxOld != m_bChildMaximized)
3952 {
3953 #ifdef _CMDBAR_EXTRA_TRACE
3954 ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - All messages hook change: m_bChildMaximized = %s\n"), m_bChildMaximized ? "true" : "false");
3955 #endif
3956 // assuming we are in a rebar, change our size to accomodate new state
3957 // we hope that if we are not in a rebar, nCount will be 0
3958 int nCount = (int)::SendMessage(GetParent(), RB_GETBANDCOUNT, 0, 0L);
3959 int cxDiff = (m_bChildMaximized ? 1 : -1) * (m_cxLeft + m_cxRight);
3960 for(int i = 0; i < nCount; i++)
3961 {
3962 #if (_WIN32_IE >= 0x0500)
3963 REBARBANDINFO rbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_STYLE };
3964 ::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi);
3965 if(rbi.hwndChild == m_hWnd)
3966 {
3967 if((rbi.fStyle & RBBS_USECHEVRON) != 0)
3968 {
3969 rbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE;
3970 rbi.cxMinChild += cxDiff;
3971 rbi.cxIdeal += cxDiff;
3972 ::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi);
3973 }
3974 break;
3975 }
3976 #elif (_WIN32_IE >= 0x0400)
3977 REBARBANDINFO rbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE };
3978 ::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi);
3979 if(rbi.hwndChild == m_hWnd)
3980 {
3981 rbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE;
3982 rbi.cxMinChild += cxDiff;
3983 rbi.cxIdeal += cxDiff;
3984 ::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi);
3985 break;
3986 }
3987 #else // (_WIN32_IE < 0x0400)
3988 REBARBANDINFO rbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_CHILDSIZE };
3989 ::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi);
3990 if(rbi.hwndChild == m_hWnd)
3991 {
3992 rbi.fMask = RBBIM_CHILDSIZE;
3993 rbi.cxMinChild += cxDiff;
3994 ::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi);
3995 break;
3996 }
3997 #endif // (_WIN32_IE < 0x0400)
3998 }
3999 }
4000
4001 if(bMaxOld != m_bChildMaximized || hIconOld != m_hIconChildMaximized)
4002 {
4003 // force size change and redraw everything
4004 RECT rect = { 0 };
4005 GetWindowRect(&rect);
4006 ::MapWindowPoints(NULL, GetParent(), (LPPOINT)&rect, 2);
4007 SetRedraw(FALSE);
4008 SetWindowPos(NULL, 0, 0, 1, 1, SWP_NOZORDER | SWP_NOMOVE);
4009 SetWindowPos(NULL, &rect, SWP_NOZORDER | SWP_NOMOVE);
4010 SetRedraw(TRUE);
4011 RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW);
4012 }
4013 }
4014
4015 // Implementation
4016 void GetSystemSettings()
4017 {
4018 #ifdef _CMDBAR_EXTRA_TRACE
4019 ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - GetSystemSettings\n"));
4020 #endif
4021 _baseClass::GetSystemSettings();
4022
4023 NONCLIENTMETRICS info = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() };
4024 BOOL bRet = ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);
4025 ATLASSERT(bRet);
4026 if(bRet)
4027 {
4028 m_cxIconWidth = ::GetSystemMetrics(SM_CXSMICON);
4029 m_cyIconHeight = ::GetSystemMetrics(SM_CYSMICON);
4030 m_cxLeft = m_cxIconWidth;
4031
4032 #ifndef _WTL_NO_AUTO_THEME
4033 if(m_hTheme != NULL)
4034 {
4035 m_cxBtnWidth = info.iCaptionWidth - 2 * m_cxyOffset;
4036 m_cyBtnHeight = info.iCaptionHeight - 2 * m_cxyOffset;
4037 m_cxRight = 3 * m_cxBtnWidth;
4038 }
4039 else
4040 #endif // !_WTL_NO_AUTO_THEME
4041 {
4042 m_cxBtnWidth = info.iCaptionWidth - m_cxyOffset;
4043 m_cyBtnHeight = info.iCaptionHeight - 2 * m_cxyOffset;
4044 m_cxRight = 3 * m_cxBtnWidth + m_cxyOffset;
4045 }
4046 }
4047
4048 RECT rect = { 0 };
4049 GetClientRect(&rect);
4050 T* pT = static_cast<T*>(this);
4051 pT->_AdjustBtnSize(rect.bottom);
4052 }
4053
4054 void _AdjustBtnSize(int cyHeight)
4055 {
4056 if(cyHeight > 1 && m_cyBtnHeight > cyHeight)
4057 {
4058 #ifndef _WTL_NO_AUTO_THEME
4059 if(m_hTheme != NULL)
4060 {
4061 m_cyBtnHeight = cyHeight;
4062 m_cxBtnWidth = cyHeight;
4063 m_cxRight = 3 * m_cxBtnWidth;
4064 }
4065 else
4066 #endif // !_WTL_NO_AUTO_THEME
4067 {
4068 m_cyBtnHeight = cyHeight;
4069 m_cxBtnWidth = cyHeight + m_cxyOffset;
4070 m_cxRight = 3 * m_cxBtnWidth + m_cxyOffset;
4071 }
4072 }
4073 }
4074
4075 void _CalcIconRect(int cxWidth, int cyHeight, RECT& rect, bool bInvertX = false) const
4076 {
4077 int xStart = (m_cxLeft - m_cxIconWidth) / 2;
4078 if(xStart < 0)
4079 xStart = 0;
4080 int yStart = (cyHeight - m_cyIconHeight) / 2;
4081 if(yStart < 0)
4082 yStart = 0;
4083
4084 if(bInvertX)
4085 ::SetRect(&rect, cxWidth - (xStart + m_cxBtnWidth), yStart, cxWidth - xStart, yStart + m_cyBtnHeight);
4086 else
4087 ::SetRect(&rect, xStart, yStart, xStart + m_cxBtnWidth, yStart + m_cyBtnHeight);
4088 }
4089
4090 void _CalcBtnRects(int cxWidth, int cyHeight, RECT arrRect[3], bool bInvertX = false) const
4091 {
4092 int yStart = (cyHeight - m_cyBtnHeight) / 2;
4093 if(yStart < 0)
4094 yStart = 0;
4095
4096 RECT rcBtn = { cxWidth - m_cxBtnWidth, yStart, cxWidth, yStart + m_cyBtnHeight };
4097 int nDirection = -1;
4098 if(bInvertX)
4099 {
4100 ::SetRect(&rcBtn, 0, yStart, m_cxBtnWidth, yStart + m_cyBtnHeight);
4101 nDirection = 1;
4102 }
4103
4104 arrRect[0] = rcBtn;
4105 #ifndef _WTL_NO_AUTO_THEME
4106 if(m_hTheme != NULL)
4107 ::OffsetRect(&rcBtn, nDirection * m_cxBtnWidth, 0);
4108 else
4109 #endif // !_WTL_NO_AUTO_THEME
4110 ::OffsetRect(&rcBtn, nDirection * (m_cxBtnWidth + m_cxyOffset), 0);
4111 arrRect[1] = rcBtn;
4112 ::OffsetRect(&rcBtn, nDirection * m_cxBtnWidth, 0);
4113 arrRect[2] = rcBtn;
4114 }
4115
4116 void _DrawMDIButton(CWindowDC& dc, LPRECT pRects, int nBtn)
4117 {
4118 #ifndef _WTL_NO_AUTO_THEME
4119 if(m_hTheme != NULL)
4120 {
4121 #if !defined(TMSCHEMA_H) && !defined(__VSSYM32_H__)
4122 const int WP_MDICLOSEBUTTON = 20;
4123 const int CBS_NORMAL = 1;
4124 const int CBS_PUSHED = 3;
4125 const int CBS_DISABLED = 4;
4126 const int WP_MDIRESTOREBUTTON = 22;
4127 const int RBS_NORMAL = 1;
4128 const int RBS_PUSHED = 3;
4129 const int RBS_DISABLED = 4;
4130 const int WP_MDIMINBUTTON = 16;
4131 const int MINBS_NORMAL = 1;
4132 const int MINBS_PUSHED = 3;
4133 const int MINBS_DISABLED = 4;
4134 #endif // !defined(TMSCHEMA_H) && !defined(__VSSYM32_H__)
4135 if(nBtn == -1 || nBtn == 0)
4136 m_pfnDrawThemeBackground(m_hTheme, dc, WP_MDICLOSEBUTTON, m_bParentActive ? ((m_nBtnPressed == 0) ? CBS_PUSHED : CBS_NORMAL) : CBS_DISABLED, &pRects[0], NULL);
4137 if(nBtn == -1 || nBtn == 1)
4138 m_pfnDrawThemeBackground(m_hTheme, dc, WP_MDIRESTOREBUTTON, m_bParentActive ? ((m_nBtnPressed == 1) ? RBS_PUSHED : RBS_NORMAL) : RBS_DISABLED, &pRects[1], NULL);
4139 if(nBtn == -1 || nBtn == 2)
4140 m_pfnDrawThemeBackground(m_hTheme, dc, WP_MDIMINBUTTON, m_bParentActive ? ((m_nBtnPressed == 2) ? MINBS_PUSHED : MINBS_NORMAL) : MINBS_DISABLED, &pRects[2], NULL);
4141 }
4142 else
4143 #endif // !_WTL_NO_AUTO_THEME
4144 {
4145 if(nBtn == -1 || nBtn == 0)
4146 dc.DrawFrameControl(&pRects[0], DFC_CAPTION, DFCS_CAPTIONCLOSE | ((m_nBtnPressed == 0) ? DFCS_PUSHED : 0));
4147 if(nBtn == -1 || nBtn == 1)
4148 dc.DrawFrameControl(&pRects[1], DFC_CAPTION, DFCS_CAPTIONRESTORE | ((m_nBtnPressed == 1) ? DFCS_PUSHED : 0));
4149 if(nBtn == -1 || nBtn == 2)
4150 dc.DrawFrameControl(&pRects[2], DFC_CAPTION, DFCS_CAPTIONMIN | ((m_nBtnPressed == 2) ? DFCS_PUSHED : 0));
4151 }
4152 }
4153
4154 #ifndef _WTL_NO_AUTO_THEME
4155 static UINT _GetThemeChangedMsg()
4156 {
4157 #ifndef WM_THEMECHANGED
4158 static const UINT WM_THEMECHANGED = 0x031A;
4159 #endif // !WM_THEMECHANGED
4160 return WM_THEMECHANGED;
4161 }
4162
4163 void _OpenThemeData()
4164 {
4165 ATLASSERT(m_hThemeDLL != NULL);
4166
4167 PFN_OpenThemeData pfnOpenThemeData = (PFN_OpenThemeData)::GetProcAddress(m_hThemeDLL, "OpenThemeData");
4168 ATLASSERT(pfnOpenThemeData != NULL);
4169 if(pfnOpenThemeData != NULL)
4170 m_hTheme = pfnOpenThemeData(m_hWnd, L"Window");
4171 }
4172
4173 void _CloseThemeData()
4174 {
4175 ATLASSERT(m_hThemeDLL != NULL);
4176
4177 if(m_hTheme == NULL)
4178 return; // nothing to do
4179
4180 PFN_CloseThemeData pfnCloseThemeData = (PFN_CloseThemeData)::GetProcAddress(m_hThemeDLL, "CloseThemeData");
4181 ATLASSERT(pfnCloseThemeData != NULL);
4182 if(pfnCloseThemeData != NULL)
4183 {
4184 pfnCloseThemeData(m_hTheme);
4185 m_hTheme = NULL;
4186 }
4187 }
4188 #endif // !_WTL_NO_AUTO_THEME
4189
4190 bool _DebugCheckChild()
4191 {
4192 #ifdef _DEBUG
4193 BOOL bMaximized = FALSE;
4194 HWND hWndChild = (HWND)::SendMessage(m_wndMDIClient, WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized);
4195 return (bMaximized && hWndChild == m_hWndChildMaximized);
4196 #else // !_DEBUG
4197 return true;
4198 #endif // !_DEBUG
4199 }
4200 };
4201
4202 class CMDICommandBarCtrl : public CMDICommandBarCtrlImpl<CMDICommandBarCtrl>
4203 {
4204 public:
4205 DECLARE_WND_SUPERCLASS(_T("WTL_MDICommandBar"), GetWndClassName())
4206 };
4207
4208 }; // namespace WTL
4209
4210 #endif // __ATLCTRLW_H__
+0
-5120
src/third_party/wtl/Include/atlctrlx.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLCTRLX_H__
9 #define __ATLCTRLX_H__
10
11 #pragma once
12
13 #ifndef __ATLAPP_H__
14 #error atlctrlx.h requires atlapp.h to be included first
15 #endif
16
17 #ifndef __ATLCTRLS_H__
18 #error atlctrlx.h requires atlctrls.h to be included first
19 #endif
20
21 #ifndef WM_UPDATEUISTATE
22 #define WM_UPDATEUISTATE 0x0128
23 #endif // !WM_UPDATEUISTATE
24
25
26 ///////////////////////////////////////////////////////////////////////////////
27 // Classes in this file:
28 //
29 // CBitmapButtonImpl<T, TBase, TWinTraits>
30 // CBitmapButton
31 // CCheckListViewCtrlImpl<T, TBase, TWinTraits>
32 // CCheckListViewCtrl
33 // CHyperLinkImpl<T, TBase, TWinTraits>
34 // CHyperLink
35 // CWaitCursor
36 // CCustomWaitCursor
37 // CMultiPaneStatusBarCtrlImpl<T, TBase>
38 // CMultiPaneStatusBarCtrl
39 // CPaneContainerImpl<T, TBase, TWinTraits>
40 // CPaneContainer
41 // CSortListViewImpl<T>
42 // CSortListViewCtrlImpl<T, TBase, TWinTraits>
43 // CSortListViewCtrl
44 // CTabViewImpl<T, TBase, TWinTraits>
45 // CTabView
46
47 namespace WTL
48 {
49
50 ///////////////////////////////////////////////////////////////////////////////
51 // CBitmapButton - bitmap button implementation
52
53 #ifndef _WIN32_WCE
54
55 // bitmap button extended styles
56 #define BMPBTN_HOVER 0x00000001
57 #define BMPBTN_AUTO3D_SINGLE 0x00000002
58 #define BMPBTN_AUTO3D_DOUBLE 0x00000004
59 #define BMPBTN_AUTOSIZE 0x00000008
60 #define BMPBTN_SHAREIMAGELISTS 0x00000010
61 #define BMPBTN_AUTOFIRE 0x00000020
62 #define BMPBTN_CHECK 0x00000040
63 #define BMPBTN_AUTOCHECK 0x00000080
64
65 // Note: BMPBTN_CHECK/BMPBTN_AUTOCHECK disables BN_DOUBLECLICKED,
66 // BMPBTN_AUTOFIRE doesn't work with BMPBTN_CHECK/BMPBTN_AUTOCHECK
67
68 template <class T, class TBase = CButton, class TWinTraits = ATL::CControlWinTraits>
69 class ATL_NO_VTABLE CBitmapButtonImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >
70 {
71 public:
72 DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())
73
74 enum
75 {
76 _nImageNormal = 0,
77 _nImagePushed,
78 _nImageFocusOrHover,
79 _nImageDisabled,
80
81 _nImageCount = 4,
82 };
83
84 enum
85 {
86 ID_TIMER_FIRST = 1000,
87 ID_TIMER_REPEAT = 1001
88 };
89
90 // Bitmap button specific extended styles
91 DWORD m_dwExtendedStyle;
92
93 CImageList m_ImageList;
94 int m_nImage[_nImageCount];
95
96 CToolTipCtrl m_tip;
97 LPTSTR m_lpstrToolTipText;
98
99 // Internal states
100 unsigned m_fMouseOver:1;
101 unsigned m_fFocus:1;
102 unsigned m_fPressed:1;
103 unsigned m_fChecked:1;
104
105
106 // Constructor/Destructor
107 CBitmapButtonImpl(DWORD dwExtendedStyle = BMPBTN_AUTOSIZE, HIMAGELIST hImageList = NULL) :
108 m_dwExtendedStyle(dwExtendedStyle), m_ImageList(hImageList),
109 m_lpstrToolTipText(NULL),
110 m_fMouseOver(0), m_fFocus(0), m_fPressed(0), m_fChecked(0)
111 {
112 m_nImage[_nImageNormal] = -1;
113 m_nImage[_nImagePushed] = -1;
114 m_nImage[_nImageFocusOrHover] = -1;
115 m_nImage[_nImageDisabled] = -1;
116
117 #ifdef _DEBUG
118 if(((m_dwExtendedStyle & BMPBTN_AUTOFIRE) != 0) && IsCheckMode())
119 ATLTRACE2(atlTraceUI, 0, _T("CBitmapButtonImpl - Check mode and BMPBTN_AUTOFIRE cannot be used together, BMPBTN_AUTOFIRE will be ignored.\n"));
120 #endif // _DEBUG
121 }
122
123 ~CBitmapButtonImpl()
124 {
125 if((m_dwExtendedStyle & BMPBTN_SHAREIMAGELISTS) == 0)
126 m_ImageList.Destroy();
127 delete [] m_lpstrToolTipText;
128 }
129
130 // overridden to provide proper initialization
131 BOOL SubclassWindow(HWND hWnd)
132 {
133 #if (_MSC_VER >= 1300)
134 BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits >::SubclassWindow(hWnd);
135 #else // !(_MSC_VER >= 1300)
136 typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass;
137 BOOL bRet = _baseClass::SubclassWindow(hWnd);
138 #endif // !(_MSC_VER >= 1300)
139 if(bRet != FALSE)
140 {
141 T* pT = static_cast<T*>(this);
142 pT->Init();
143 }
144
145 return bRet;
146 }
147
148 // Attributes
149 DWORD GetBitmapButtonExtendedStyle() const
150 {
151 return m_dwExtendedStyle;
152 }
153
154 DWORD SetBitmapButtonExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
155 {
156 DWORD dwPrevStyle = m_dwExtendedStyle;
157 if(dwMask == 0)
158 m_dwExtendedStyle = dwExtendedStyle;
159 else
160 m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
161
162 #ifdef _DEBUG
163 if(((m_dwExtendedStyle & BMPBTN_AUTOFIRE) != 0) && IsCheckMode())
164 ATLTRACE2(atlTraceUI, 0, _T("CBitmapButtonImpl - Check mode and BMPBTN_AUTOFIRE cannot be used together, BMPBTN_AUTOFIRE will be ignored.\n"));
165 #endif // _DEBUG
166
167 return dwPrevStyle;
168 }
169
170 HIMAGELIST GetImageList() const
171 {
172 return m_ImageList;
173 }
174
175 HIMAGELIST SetImageList(HIMAGELIST hImageList)
176 {
177 HIMAGELIST hImageListPrev = m_ImageList;
178 m_ImageList = hImageList;
179 if((m_dwExtendedStyle & BMPBTN_AUTOSIZE) != 0 && ::IsWindow(m_hWnd))
180 SizeToImage();
181
182 return hImageListPrev;
183 }
184
185 int GetToolTipTextLength() const
186 {
187 return (m_lpstrToolTipText == NULL) ? -1 : lstrlen(m_lpstrToolTipText);
188 }
189
190 bool GetToolTipText(LPTSTR lpstrText, int nLength) const
191 {
192 ATLASSERT(lpstrText != NULL);
193 if(m_lpstrToolTipText == NULL)
194 return false;
195
196 errno_t nRet = SecureHelper::strncpy_x(lpstrText, nLength, m_lpstrToolTipText, _TRUNCATE);
197
198 return (nRet == 0 || nRet == STRUNCATE);
199 }
200
201 bool SetToolTipText(LPCTSTR lpstrText)
202 {
203 if(m_lpstrToolTipText != NULL)
204 {
205 delete [] m_lpstrToolTipText;
206 m_lpstrToolTipText = NULL;
207 }
208
209 if(lpstrText == NULL)
210 {
211 if(m_tip.IsWindow())
212 m_tip.Activate(FALSE);
213 return true;
214 }
215
216 int cchLen = lstrlen(lpstrText) + 1;
217 ATLTRY(m_lpstrToolTipText = new TCHAR[cchLen]);
218 if(m_lpstrToolTipText == NULL)
219 return false;
220
221 SecureHelper::strcpy_x(m_lpstrToolTipText, cchLen, lpstrText);
222 if(m_tip.IsWindow())
223 {
224 m_tip.Activate(TRUE);
225 m_tip.AddTool(m_hWnd, m_lpstrToolTipText);
226 }
227
228 return true;
229 }
230
231 bool GetCheck() const
232 {
233 return (m_fChecked == 1);
234 }
235
236 void SetCheck(bool bCheck, bool bUpdate = true)
237 {
238 m_fChecked = bCheck ? 1 : 0;
239
240 if(bUpdate)
241 {
242 Invalidate();
243 UpdateWindow();
244 }
245 }
246
247 // Operations
248 void SetImages(int nNormal, int nPushed = -1, int nFocusOrHover = -1, int nDisabled = -1)
249 {
250 if(nNormal != -1)
251 m_nImage[_nImageNormal] = nNormal;
252 if(nPushed != -1)
253 m_nImage[_nImagePushed] = nPushed;
254 if(nFocusOrHover != -1)
255 m_nImage[_nImageFocusOrHover] = nFocusOrHover;
256 if(nDisabled != -1)
257 m_nImage[_nImageDisabled] = nDisabled;
258 }
259
260 BOOL SizeToImage()
261 {
262 ATLASSERT(::IsWindow(m_hWnd) && m_ImageList.m_hImageList != NULL);
263 int cx = 0;
264 int cy = 0;
265 if(!m_ImageList.GetIconSize(cx, cy))
266 return FALSE;
267 return ResizeClient(cx, cy);
268 }
269
270 // Overrideables
271 void DoPaint(CDCHandle dc)
272 {
273 ATLASSERT(m_ImageList.m_hImageList != NULL); // image list must be set
274 ATLASSERT(m_nImage[0] != -1); // main bitmap must be set
275
276 // set bitmap according to the current button state
277 bool bHover = IsHoverMode();
278 bool bPressed = (m_fPressed == 1) || (IsCheckMode() && (m_fChecked == 1));
279 int nImage = -1;
280 if(!IsWindowEnabled())
281 nImage = m_nImage[_nImageDisabled];
282 else if(bPressed)
283 nImage = m_nImage[_nImagePushed];
284 else if((!bHover && (m_fFocus == 1)) || (bHover && (m_fMouseOver == 1)))
285 nImage = m_nImage[_nImageFocusOrHover];
286
287 // if none is set, use default one
288 if(nImage == -1)
289 nImage = m_nImage[_nImageNormal];
290
291 // draw the button image
292 bool bAuto3D = (m_dwExtendedStyle & (BMPBTN_AUTO3D_SINGLE | BMPBTN_AUTO3D_DOUBLE)) != 0;
293 int xyPos = (bPressed && bAuto3D && (m_nImage[_nImagePushed] == -1)) ? 1 : 0;
294 m_ImageList.Draw(dc, nImage, xyPos, xyPos, ILD_NORMAL);
295
296 // draw 3D border if required
297 if(bAuto3D)
298 {
299 RECT rect = { 0 };
300 GetClientRect(&rect);
301
302 if(bPressed)
303 dc.DrawEdge(&rect, ((m_dwExtendedStyle & BMPBTN_AUTO3D_SINGLE) != 0) ? BDR_SUNKENOUTER : EDGE_SUNKEN, BF_RECT);
304 else if(!bHover || (m_fMouseOver == 1))
305 dc.DrawEdge(&rect, ((m_dwExtendedStyle & BMPBTN_AUTO3D_SINGLE) != 0) ? BDR_RAISEDINNER : EDGE_RAISED, BF_RECT);
306
307 if(!bHover && (m_fFocus == 1))
308 {
309 ::InflateRect(&rect, -2 * ::GetSystemMetrics(SM_CXEDGE), -2 * ::GetSystemMetrics(SM_CYEDGE));
310 dc.DrawFocusRect(&rect);
311 }
312 }
313 }
314
315 // Message map and handlers
316 BEGIN_MSG_MAP(CBitmapButtonImpl)
317 MESSAGE_HANDLER(WM_CREATE, OnCreate)
318 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
319 MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage)
320 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
321 MESSAGE_HANDLER(WM_PAINT, OnPaint)
322 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
323 MESSAGE_HANDLER(WM_SETFOCUS, OnFocus)
324 MESSAGE_HANDLER(WM_KILLFOCUS, OnFocus)
325 MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
326 MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDblClk)
327 MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
328 MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged)
329 MESSAGE_HANDLER(WM_ENABLE, OnEnable)
330 MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
331 MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave)
332 MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
333 MESSAGE_HANDLER(WM_KEYUP, OnKeyUp)
334 MESSAGE_HANDLER(WM_TIMER, OnTimer)
335 MESSAGE_HANDLER(WM_UPDATEUISTATE, OnUpdateUiState)
336 END_MSG_MAP()
337
338 LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
339 {
340 T* pT = static_cast<T*>(this);
341 pT->Init();
342
343 bHandled = FALSE;
344 return 1;
345 }
346
347 LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
348 {
349 if(m_tip.IsWindow())
350 {
351 m_tip.DestroyWindow();
352 m_tip.m_hWnd = NULL;
353 }
354 bHandled = FALSE;
355 return 1;
356 }
357
358 LRESULT OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
359 {
360 MSG msg = { m_hWnd, uMsg, wParam, lParam };
361 if(m_tip.IsWindow())
362 m_tip.RelayEvent(&msg);
363 bHandled = FALSE;
364 return 1;
365 }
366
367 LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
368 {
369 return 1; // no background needed
370 }
371
372 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
373 {
374 T* pT = static_cast<T*>(this);
375 if(wParam != NULL)
376 {
377 pT->DoPaint((HDC)wParam);
378 }
379 else
380 {
381 CPaintDC dc(m_hWnd);
382 pT->DoPaint(dc.m_hDC);
383 }
384 return 0;
385 }
386
387 LRESULT OnFocus(UINT uMsg, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
388 {
389 m_fFocus = (uMsg == WM_SETFOCUS) ? 1 : 0;
390 Invalidate();
391 UpdateWindow();
392 bHandled = FALSE;
393 return 1;
394 }
395
396 LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
397 {
398 LRESULT lRet = 0;
399 if(IsHoverMode())
400 SetCapture();
401 else
402 lRet = DefWindowProc(uMsg, wParam, lParam);
403 if(::GetCapture() == m_hWnd)
404 {
405 m_fPressed = 1;
406 Invalidate();
407 UpdateWindow();
408 }
409 if(((m_dwExtendedStyle & BMPBTN_AUTOFIRE) != 0) && !IsCheckMode())
410 {
411 int nElapse = 250;
412 int nDelay = 0;
413 if(::SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &nDelay, 0))
414 nElapse += nDelay * 250; // all milli-seconds
415 SetTimer(ID_TIMER_FIRST, nElapse);
416 }
417 return lRet;
418 }
419
420 LRESULT OnLButtonDblClk(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
421 {
422 LRESULT lRet = 0;
423 if(!IsHoverMode() && !IsCheckMode())
424 lRet = DefWindowProc(uMsg, wParam, lParam);
425 if(::GetCapture() != m_hWnd)
426 SetCapture();
427 if(m_fPressed == 0)
428 {
429 m_fPressed = 1;
430 Invalidate();
431 UpdateWindow();
432 }
433 return lRet;
434 }
435
436 LRESULT OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
437 {
438 if(((m_dwExtendedStyle & BMPBTN_AUTOCHECK) != 0) && (m_fPressed == 1))
439 SetCheck(!GetCheck(), false);
440
441 LRESULT lRet = 0;
442 if(!IsHoverMode() && !IsCheckMode())
443 lRet = DefWindowProc(uMsg, wParam, lParam);
444 if(::GetCapture() == m_hWnd)
445 {
446 if((IsHoverMode() || IsCheckMode()) && (m_fPressed == 1))
447 ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd);
448 ::ReleaseCapture();
449 }
450 return lRet;
451 }
452
453 LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
454 {
455 if(m_fPressed == 1)
456 {
457 m_fPressed = 0;
458 Invalidate();
459 UpdateWindow();
460 }
461 bHandled = FALSE;
462 return 1;
463 }
464
465 LRESULT OnEnable(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
466 {
467 Invalidate();
468 UpdateWindow();
469 bHandled = FALSE;
470 return 1;
471 }
472
473 LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
474 {
475 if(::GetCapture() == m_hWnd)
476 {
477 POINT ptCursor = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
478 ClientToScreen(&ptCursor);
479 RECT rect = { 0 };
480 GetWindowRect(&rect);
481 unsigned int uPressed = ::PtInRect(&rect, ptCursor) ? 1 : 0;
482 if(m_fPressed != uPressed)
483 {
484 m_fPressed = uPressed;
485 Invalidate();
486 UpdateWindow();
487 }
488 }
489 else if(IsHoverMode() && m_fMouseOver == 0)
490 {
491 m_fMouseOver = 1;
492 Invalidate();
493 UpdateWindow();
494 StartTrackMouseLeave();
495 }
496 bHandled = FALSE;
497 return 1;
498 }
499
500 LRESULT OnMouseLeave(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
501 {
502 if(m_fMouseOver == 1)
503 {
504 m_fMouseOver = 0;
505 Invalidate();
506 UpdateWindow();
507 }
508 return 0;
509 }
510
511 LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
512 {
513 if(wParam == VK_SPACE && IsHoverMode())
514 return 0; // ignore if in hover mode
515 if(wParam == VK_SPACE && m_fPressed == 0)
516 {
517 m_fPressed = 1;
518 Invalidate();
519 UpdateWindow();
520 }
521 bHandled = FALSE;
522 return 1;
523 }
524
525 LRESULT OnKeyUp(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
526 {
527 if(wParam == VK_SPACE && IsHoverMode())
528 return 0; // ignore if in hover mode
529 if(wParam == VK_SPACE && m_fPressed == 1)
530 {
531 m_fPressed = 0;
532 if((m_dwExtendedStyle & BMPBTN_AUTOCHECK) != 0)
533 SetCheck(!GetCheck(), false);
534 Invalidate();
535 UpdateWindow();
536 }
537 bHandled = FALSE;
538 return 1;
539 }
540
541 LRESULT OnTimer(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
542 {
543 ATLASSERT((m_dwExtendedStyle & BMPBTN_AUTOFIRE) != 0);
544 switch(wParam) // timer ID
545 {
546 case ID_TIMER_FIRST:
547 KillTimer(ID_TIMER_FIRST);
548 if(m_fPressed == 1)
549 {
550 ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd);
551 int nElapse = 250;
552 int nRepeat = 40;
553 if(::SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &nRepeat, 0))
554 nElapse = 10000 / (10 * nRepeat + 25); // milli-seconds, approximated
555 SetTimer(ID_TIMER_REPEAT, nElapse);
556 }
557 break;
558 case ID_TIMER_REPEAT:
559 if(m_fPressed == 1)
560 ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd);
561 else if(::GetCapture() != m_hWnd)
562 KillTimer(ID_TIMER_REPEAT);
563 break;
564 default: // not our timer
565 break;
566 }
567 return 0;
568 }
569
570 LRESULT OnUpdateUiState(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
571 {
572 // If the control is subclassed or superclassed, this message can cause
573 // repainting without WM_PAINT. We don't use this state, so just do nothing.
574 return 0;
575 }
576
577 // Implementation
578 void Init()
579 {
580 // We need this style to prevent Windows from painting the button
581 ModifyStyle(0, BS_OWNERDRAW);
582
583 // create a tool tip
584 m_tip.Create(m_hWnd);
585 ATLASSERT(m_tip.IsWindow());
586 if(m_tip.IsWindow() && m_lpstrToolTipText != NULL)
587 {
588 m_tip.Activate(TRUE);
589 m_tip.AddTool(m_hWnd, m_lpstrToolTipText);
590 }
591
592 if(m_ImageList.m_hImageList != NULL && (m_dwExtendedStyle & BMPBTN_AUTOSIZE) != 0)
593 SizeToImage();
594 }
595
596 BOOL StartTrackMouseLeave()
597 {
598 TRACKMOUSEEVENT tme = { 0 };
599 tme.cbSize = sizeof(tme);
600 tme.dwFlags = TME_LEAVE;
601 tme.hwndTrack = m_hWnd;
602 return _TrackMouseEvent(&tme);
603 }
604
605 bool IsHoverMode() const
606 {
607 return ((m_dwExtendedStyle & BMPBTN_HOVER) != 0);
608 }
609
610 bool IsCheckMode() const
611 {
612 return ((m_dwExtendedStyle & (BMPBTN_CHECK | BMPBTN_AUTOCHECK)) != 0);
613 }
614 };
615
616 class CBitmapButton : public CBitmapButtonImpl<CBitmapButton>
617 {
618 public:
619 DECLARE_WND_SUPERCLASS(_T("WTL_BitmapButton"), GetWndClassName())
620
621 CBitmapButton(DWORD dwExtendedStyle = BMPBTN_AUTOSIZE, HIMAGELIST hImageList = NULL) :
622 CBitmapButtonImpl<CBitmapButton>(dwExtendedStyle, hImageList)
623 { }
624 };
625
626 #endif // !_WIN32_WCE
627
628
629 ///////////////////////////////////////////////////////////////////////////////
630 // CCheckListCtrlView - list view control with check boxes
631
632 template <DWORD t_dwStyle, DWORD t_dwExStyle, DWORD t_dwExListViewStyle>
633 class CCheckListViewCtrlImplTraits
634 {
635 public:
636 static DWORD GetWndStyle(DWORD dwStyle)
637 {
638 return (dwStyle == 0) ? t_dwStyle : dwStyle;
639 }
640
641 static DWORD GetWndExStyle(DWORD dwExStyle)
642 {
643 return (dwExStyle == 0) ? t_dwExStyle : dwExStyle;
644 }
645
646 static DWORD GetExtendedLVStyle()
647 {
648 return t_dwExListViewStyle;
649 }
650 };
651
652 typedef CCheckListViewCtrlImplTraits<WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS, WS_EX_CLIENTEDGE, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT> CCheckListViewCtrlTraits;
653
654 template <class T, class TBase = CListViewCtrl, class TWinTraits = CCheckListViewCtrlTraits>
655 class ATL_NO_VTABLE CCheckListViewCtrlImpl : public ATL::CWindowImpl<T, TBase, TWinTraits >
656 {
657 public:
658 DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())
659
660 // Attributes
661 static DWORD GetExtendedLVStyle()
662 {
663 return TWinTraits::GetExtendedLVStyle();
664 }
665
666 // Operations
667 BOOL SubclassWindow(HWND hWnd)
668 {
669 #if (_MSC_VER >= 1300)
670 BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits >::SubclassWindow(hWnd);
671 #else // !(_MSC_VER >= 1300)
672 typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass;
673 BOOL bRet = _baseClass::SubclassWindow(hWnd);
674 #endif // !(_MSC_VER >= 1300)
675 if(bRet != FALSE)
676 {
677 T* pT = static_cast<T*>(this);
678 pT->Init();
679 }
680
681 return bRet;
682 }
683
684 void CheckSelectedItems(int nCurrItem)
685 {
686 // first check if this item is selected
687 LVITEM lvi = { 0 };
688 lvi.iItem = nCurrItem;
689 lvi.iSubItem = 0;
690 lvi.mask = LVIF_STATE;
691 lvi.stateMask = LVIS_SELECTED;
692 GetItem(&lvi);
693 // if item is not selected, don't do anything
694 if(!(lvi.state & LVIS_SELECTED))
695 return;
696 // new check state will be reverse of the current state,
697 BOOL bCheck = !GetCheckState(nCurrItem);
698 int nItem = -1;
699 int nOldItem = -1;
700 while((nItem = GetNextItem(nOldItem, LVNI_SELECTED)) != -1)
701 {
702 if(nItem != nCurrItem)
703 SetCheckState(nItem, bCheck);
704 nOldItem = nItem;
705 }
706 }
707
708 // Implementation
709 void Init()
710 {
711 T* pT = static_cast<T*>(this);
712 pT; // avoid level 4 warning
713 ATLASSERT((pT->GetExtendedLVStyle() & LVS_EX_CHECKBOXES) != 0);
714 SetExtendedListViewStyle(pT->GetExtendedLVStyle());
715 }
716
717 // Message map and handlers
718 BEGIN_MSG_MAP(CCheckListViewCtrlImpl)
719 MESSAGE_HANDLER(WM_CREATE, OnCreate)
720 MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
721 MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDown)
722 MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
723 END_MSG_MAP()
724
725 LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
726 {
727 // first let list view control initialize everything
728 LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
729 if(lRet == 0)
730 {
731 T* pT = static_cast<T*>(this);
732 pT->Init();
733 }
734
735 return lRet;
736 }
737
738 LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
739 {
740 POINT ptMsg = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
741 LVHITTESTINFO lvh = { 0 };
742 lvh.pt = ptMsg;
743 if(HitTest(&lvh) != -1 && lvh.flags == LVHT_ONITEMSTATEICON && ::GetKeyState(VK_CONTROL) >= 0)
744 {
745 T* pT = static_cast<T*>(this);
746 pT->CheckSelectedItems(lvh.iItem);
747 }
748 bHandled = FALSE;
749 return 1;
750 }
751
752 LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
753 {
754 if(wParam == VK_SPACE)
755 {
756 int nCurrItem = GetNextItem(-1, LVNI_FOCUSED);
757 if(nCurrItem != -1 && ::GetKeyState(VK_CONTROL) >= 0)
758 {
759 T* pT = static_cast<T*>(this);
760 pT->CheckSelectedItems(nCurrItem);
761 }
762 }
763 bHandled = FALSE;
764 return 1;
765 }
766 };
767
768 class CCheckListViewCtrl : public CCheckListViewCtrlImpl<CCheckListViewCtrl>
769 {
770 public:
771 DECLARE_WND_SUPERCLASS(_T("WTL_CheckListView"), GetWndClassName())
772 };
773
774
775 ///////////////////////////////////////////////////////////////////////////////
776 // CHyperLink - hyper link control implementation
777
778 #if (WINVER < 0x0500) && !defined(_WIN32_WCE)
779 __declspec(selectany) struct
780 {
781 enum { cxWidth = 32, cyHeight = 32 };
782 int xHotSpot;
783 int yHotSpot;
784 unsigned char arrANDPlane[cxWidth * cyHeight / 8];
785 unsigned char arrXORPlane[cxWidth * cyHeight / 8];
786 } _AtlHyperLink_CursorData =
787 {
788 5, 0,
789 {
790 0xF9, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF,
791 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0xF0, 0x01, 0xFF, 0xFF,
792 0xF0, 0x00, 0xFF, 0xFF, 0x10, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x7F, 0xFF,
793 0x80, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x7F, 0xFF,
794 0xE0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF,
795 0xF8, 0x01, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
796 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
797 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
798 },
799 {
800 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
801 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0xC0, 0x00, 0x00, 0x06, 0xD8, 0x00, 0x00,
802 0x06, 0xDA, 0x00, 0x00, 0x06, 0xDB, 0x00, 0x00, 0x67, 0xFB, 0x00, 0x00, 0x77, 0xFF, 0x00, 0x00,
803 0x37, 0xFF, 0x00, 0x00, 0x17, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0x00, 0x00,
804 0x0F, 0xFE, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00,
805 0x03, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
806 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
807 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
808 }
809 };
810 #endif // (WINVER < 0x0500) && !defined(_WIN32_WCE)
811
812 #define HLINK_UNDERLINED 0x00000000
813 #define HLINK_NOTUNDERLINED 0x00000001
814 #define HLINK_UNDERLINEHOVER 0x00000002
815 #define HLINK_COMMANDBUTTON 0x00000004
816 #define HLINK_NOTIFYBUTTON 0x0000000C
817 #define HLINK_USETAGS 0x00000010
818 #define HLINK_USETAGSBOLD 0x00000030
819 #define HLINK_NOTOOLTIP 0x00000040
820 #define HLINK_AUTOCREATELINKFONT 0x00000080
821 #define HLINK_SINGLELINE 0x00000100
822
823 // Notes:
824 // - HLINK_USETAGS and HLINK_USETAGSBOLD are always left-aligned
825 // - When HLINK_USETAGSBOLD is used, the underlined styles will be ignored
826
827 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
828 class ATL_NO_VTABLE CHyperLinkImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >
829 {
830 public:
831 LPTSTR m_lpstrLabel;
832 LPTSTR m_lpstrHyperLink;
833
834 HCURSOR m_hCursor;
835 HFONT m_hFontLink;
836 HFONT m_hFontNormal;
837
838 RECT m_rcLink;
839 #ifndef _WIN32_WCE
840 CToolTipCtrl m_tip;
841 #endif // !_WIN32_WCE
842
843 COLORREF m_clrLink;
844 COLORREF m_clrVisited;
845
846 DWORD m_dwExtendedStyle; // Hyper Link specific extended styles
847
848 bool m_bPaintLabel:1;
849 bool m_bVisited:1;
850 bool m_bHover:1;
851 bool m_bInternalLinkFont:1;
852 bool m_bInternalNormalFont:1;
853
854
855 // Constructor/Destructor
856 CHyperLinkImpl(DWORD dwExtendedStyle = HLINK_UNDERLINED) :
857 m_lpstrLabel(NULL), m_lpstrHyperLink(NULL),
858 m_hCursor(NULL), m_hFontLink(NULL), m_hFontNormal(NULL),
859 m_clrLink(RGB(0, 0, 255)), m_clrVisited(RGB(128, 0, 128)),
860 m_dwExtendedStyle(dwExtendedStyle),
861 m_bPaintLabel(true), m_bVisited(false),
862 m_bHover(false), m_bInternalLinkFont(false), m_bInternalNormalFont(false)
863 {
864 ::SetRectEmpty(&m_rcLink);
865 }
866
867 ~CHyperLinkImpl()
868 {
869 delete [] m_lpstrLabel;
870 delete [] m_lpstrHyperLink;
871 #if (WINVER < 0x0500) && !defined(_WIN32_WCE)
872 // It was created, not loaded, so we have to destroy it
873 if(m_hCursor != NULL)
874 ::DestroyCursor(m_hCursor);
875 #endif // (WINVER < 0x0500) && !defined(_WIN32_WCE)
876 }
877
878 // Attributes
879 DWORD GetHyperLinkExtendedStyle() const
880 {
881 return m_dwExtendedStyle;
882 }
883
884 DWORD SetHyperLinkExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
885 {
886 DWORD dwPrevStyle = m_dwExtendedStyle;
887 if(dwMask == 0)
888 m_dwExtendedStyle = dwExtendedStyle;
889 else
890 m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
891 return dwPrevStyle;
892 }
893
894 bool GetLabel(LPTSTR lpstrBuffer, int nLength) const
895 {
896 if(m_lpstrLabel == NULL)
897 return false;
898 ATLASSERT(lpstrBuffer != NULL);
899 if(nLength <= lstrlen(m_lpstrLabel))
900 return false;
901
902 SecureHelper::strcpy_x(lpstrBuffer, nLength, m_lpstrLabel);
903
904 return true;
905 }
906
907 bool SetLabel(LPCTSTR lpstrLabel)
908 {
909 delete [] m_lpstrLabel;
910 m_lpstrLabel = NULL;
911 int cchLen = lstrlen(lpstrLabel) + 1;
912 ATLTRY(m_lpstrLabel = new TCHAR[cchLen]);
913 if(m_lpstrLabel == NULL)
914 return false;
915
916 SecureHelper::strcpy_x(m_lpstrLabel, cchLen, lpstrLabel);
917 T* pT = static_cast<T*>(this);
918 pT->CalcLabelRect();
919
920 if(m_hWnd != NULL)
921 SetWindowText(lpstrLabel); // Set this for accessibility
922
923 return true;
924 }
925
926 bool GetHyperLink(LPTSTR lpstrBuffer, int nLength) const
927 {
928 if(m_lpstrHyperLink == NULL)
929 return false;
930 ATLASSERT(lpstrBuffer != NULL);
931 if(nLength <= lstrlen(m_lpstrHyperLink))
932 return false;
933
934 SecureHelper::strcpy_x(lpstrBuffer, nLength, m_lpstrHyperLink);
935
936 return true;
937 }
938
939 bool SetHyperLink(LPCTSTR lpstrLink)
940 {
941 delete [] m_lpstrHyperLink;
942 m_lpstrHyperLink = NULL;
943 int cchLen = lstrlen(lpstrLink) + 1;
944 ATLTRY(m_lpstrHyperLink = new TCHAR[cchLen]);
945 if(m_lpstrHyperLink == NULL)
946 return false;
947
948 SecureHelper::strcpy_x(m_lpstrHyperLink, cchLen, lpstrLink);
949 if(m_lpstrLabel == NULL)
950 {
951 T* pT = static_cast<T*>(this);
952 pT->CalcLabelRect();
953 }
954 #ifndef _WIN32_WCE
955 if(m_tip.IsWindow())
956 {
957 m_tip.Activate(TRUE);
958 m_tip.AddTool(m_hWnd, m_lpstrHyperLink, &m_rcLink, 1);
959 }
960 #endif // !_WIN32_WCE
961 return true;
962 }
963
964 HFONT GetLinkFont() const
965 {
966 return m_hFontLink;
967 }
968
969 void SetLinkFont(HFONT hFont)
970 {
971 if(m_bInternalLinkFont)
972 {
973 ::DeleteObject(m_hFontLink);
974 m_bInternalLinkFont = false;
975 }
976
977 m_hFontLink = hFont;
978
979 T* pT = static_cast<T*>(this);
980 pT->CalcLabelRect();
981 }
982
983 int GetIdealHeight() const
984 {
985 ATLASSERT(::IsWindow(m_hWnd));
986 if(m_lpstrLabel == NULL && m_lpstrHyperLink == NULL)
987 return -1;
988 if(!m_bPaintLabel)
989 return -1;
990
991 UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
992
993 CClientDC dc(m_hWnd);
994 RECT rect = { 0 };
995 GetClientRect(&rect);
996 HFONT hFontOld = dc.SelectFont(m_hFontNormal);
997 RECT rcText = rect;
998 dc.DrawText(_T("NS"), -1, &rcText, DT_LEFT | uFormat | DT_CALCRECT);
999 dc.SelectFont(m_hFontLink);
1000 RECT rcLink = rect;
1001 dc.DrawText(_T("NS"), -1, &rcLink, DT_LEFT | uFormat | DT_CALCRECT);
1002 dc.SelectFont(hFontOld);
1003 return __max(rcText.bottom - rcText.top, rcLink.bottom - rcLink.top);
1004 }
1005
1006 bool GetIdealSize(SIZE& size) const
1007 {
1008 int cx = 0, cy = 0;
1009 bool bRet = GetIdealSize(cx, cy);
1010 if(bRet)
1011 {
1012 size.cx = cx;
1013 size.cy = cy;
1014 }
1015 return bRet;
1016 }
1017
1018 bool GetIdealSize(int& cx, int& cy) const
1019 {
1020 ATLASSERT(::IsWindow(m_hWnd));
1021 if(m_lpstrLabel == NULL && m_lpstrHyperLink == NULL)
1022 return false;
1023 if(!m_bPaintLabel)
1024 return false;
1025
1026 CClientDC dc(m_hWnd);
1027 RECT rcClient = { 0 };
1028 GetClientRect(&rcClient);
1029 RECT rcAll = rcClient;
1030
1031 if(IsUsingTags())
1032 {
1033 // find tags and label parts
1034 LPTSTR lpstrLeft = NULL;
1035 int cchLeft = 0;
1036 LPTSTR lpstrLink = NULL;
1037 int cchLink = 0;
1038 LPTSTR lpstrRight = NULL;
1039 int cchRight = 0;
1040
1041 const T* pT = static_cast<const T*>(this);
1042 pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight);
1043
1044 // get label part rects
1045 UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
1046
1047 HFONT hFontOld = dc.SelectFont(m_hFontNormal);
1048 RECT rcLeft = rcClient;
1049 dc.DrawText(lpstrLeft, cchLeft, &rcLeft, DT_LEFT | uFormat | DT_CALCRECT);
1050
1051 dc.SelectFont(m_hFontLink);
1052 RECT rcLink = { rcLeft.right, rcLeft.top, rcClient.right, rcClient.bottom };
1053 dc.DrawText(lpstrLink, cchLink, &rcLink, DT_LEFT | uFormat | DT_CALCRECT);
1054
1055 dc.SelectFont(m_hFontNormal);
1056 RECT rcRight = { rcLink.right, rcLink.top, rcClient.right, rcClient.bottom };
1057 dc.DrawText(lpstrRight, cchRight, &rcRight, DT_LEFT | uFormat | DT_CALCRECT);
1058
1059 dc.SelectFont(hFontOld);
1060
1061 int cyMax = __max(rcLeft.bottom, __max(rcLink.bottom, rcRight.bottom));
1062 ::SetRect(&rcAll, rcLeft.left, rcLeft.top, rcRight.right, cyMax);
1063 }
1064 else
1065 {
1066 HFONT hOldFont = NULL;
1067 if(m_hFontLink != NULL)
1068 hOldFont = dc.SelectFont(m_hFontLink);
1069 LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink;
1070 DWORD dwStyle = GetStyle();
1071 UINT uFormat = DT_LEFT;
1072 if (dwStyle & SS_CENTER)
1073 uFormat = DT_CENTER;
1074 else if (dwStyle & SS_RIGHT)
1075 uFormat = DT_RIGHT;
1076 uFormat |= IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
1077 dc.DrawText(lpstrText, -1, &rcAll, uFormat | DT_CALCRECT);
1078 if(m_hFontLink != NULL)
1079 dc.SelectFont(hOldFont);
1080 if (dwStyle & SS_CENTER)
1081 {
1082 int dx = (rcClient.right - rcAll.right) / 2;
1083 ::OffsetRect(&rcAll, dx, 0);
1084 }
1085 else if (dwStyle & SS_RIGHT)
1086 {
1087 int dx = rcClient.right - rcAll.right;
1088 ::OffsetRect(&rcAll, dx, 0);
1089 }
1090 }
1091
1092 cx = rcAll.right - rcAll.left;
1093 cy = rcAll.bottom - rcAll.top;
1094
1095 return true;
1096 }
1097
1098 // for command buttons only
1099 bool GetToolTipText(LPTSTR lpstrBuffer, int nLength) const
1100 {
1101 ATLASSERT(IsCommandButton());
1102 return GetHyperLink(lpstrBuffer, nLength);
1103 }
1104
1105 bool SetToolTipText(LPCTSTR lpstrToolTipText)
1106 {
1107 ATLASSERT(IsCommandButton());
1108 return SetHyperLink(lpstrToolTipText);
1109 }
1110
1111 // Operations
1112 BOOL SubclassWindow(HWND hWnd)
1113 {
1114 ATLASSERT(m_hWnd == NULL);
1115 ATLASSERT(::IsWindow(hWnd));
1116 if(m_hFontNormal == NULL)
1117 m_hFontNormal = (HFONT)::SendMessage(hWnd, WM_GETFONT, 0, 0L);
1118
1119 #if (_MSC_VER >= 1300)
1120 BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits >::SubclassWindow(hWnd);
1121 #else // !(_MSC_VER >= 1300)
1122 typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass;
1123 BOOL bRet = _baseClass::SubclassWindow(hWnd);
1124 #endif // !(_MSC_VER >= 1300)
1125 if(bRet != FALSE)
1126 {
1127 T* pT = static_cast<T*>(this);
1128 pT->Init();
1129 }
1130
1131 return bRet;
1132 }
1133
1134 bool Navigate()
1135 {
1136 ATLASSERT(::IsWindow(m_hWnd));
1137 bool bRet = true;
1138 if(IsNotifyButton())
1139 {
1140 NMHDR nmhdr = { m_hWnd, (UINT_PTR)GetDlgCtrlID(), NM_CLICK };
1141 ::SendMessage(GetParent(), WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&nmhdr);
1142 }
1143 else if(IsCommandButton())
1144 {
1145 ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd);
1146 }
1147 else
1148 {
1149 ATLASSERT(m_lpstrHyperLink != NULL);
1150 #ifndef _WIN32_WCE
1151 DWORD_PTR dwRet = (DWORD_PTR)::ShellExecute(0, _T("open"), m_lpstrHyperLink, 0, 0, SW_SHOWNORMAL);
1152 bRet = (dwRet > 32);
1153 #else // CE specific
1154 SHELLEXECUTEINFO shExeInfo = { sizeof(SHELLEXECUTEINFO), 0, 0, L"open", m_lpstrHyperLink, 0, 0, SW_SHOWNORMAL, 0, 0, 0, 0, 0, 0, 0 };
1155 ::ShellExecuteEx(&shExeInfo);
1156 DWORD_PTR dwRet = (DWORD_PTR)shExeInfo.hInstApp;
1157 bRet = (dwRet == 0) || (dwRet > 32);
1158 #endif // _WIN32_WCE
1159 ATLASSERT(bRet);
1160 if(bRet)
1161 {
1162 m_bVisited = true;
1163 Invalidate();
1164 }
1165 }
1166 return bRet;
1167 }
1168
1169 void CreateLinkFontFromNormal()
1170 {
1171 if(m_bInternalLinkFont)
1172 {
1173 ::DeleteObject(m_hFontLink);
1174 m_bInternalLinkFont = false;
1175 }
1176
1177 CFontHandle font = (m_hFontNormal != NULL) ? m_hFontNormal : (HFONT)::GetStockObject(SYSTEM_FONT);
1178 LOGFONT lf = { 0 };
1179 font.GetLogFont(&lf);
1180
1181 if(IsUsingTagsBold())
1182 lf.lfWeight = FW_BOLD;
1183 else if(!IsNotUnderlined())
1184 lf.lfUnderline = TRUE;
1185
1186 m_hFontLink = ::CreateFontIndirect(&lf);
1187 m_bInternalLinkFont = true;
1188 ATLASSERT(m_hFontLink != NULL);
1189 }
1190
1191 // Message map and handlers
1192 BEGIN_MSG_MAP(CHyperLinkImpl)
1193 MESSAGE_HANDLER(WM_CREATE, OnCreate)
1194 #ifndef _WIN32_WCE
1195 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
1196 MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage)
1197 #endif // !_WIN32_WCE
1198 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
1199 MESSAGE_HANDLER(WM_PAINT, OnPaint)
1200 #ifndef _WIN32_WCE
1201 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
1202 #endif // !_WIN32_WCE
1203 MESSAGE_HANDLER(WM_SETFOCUS, OnFocus)
1204 MESSAGE_HANDLER(WM_KILLFOCUS, OnFocus)
1205 MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
1206 #ifndef _WIN32_WCE
1207 MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave)
1208 #endif // !_WIN32_WCE
1209 MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
1210 MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
1211 MESSAGE_HANDLER(WM_CHAR, OnChar)
1212 MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode)
1213 MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor)
1214 MESSAGE_HANDLER(WM_ENABLE, OnEnable)
1215 MESSAGE_HANDLER(WM_GETFONT, OnGetFont)
1216 MESSAGE_HANDLER(WM_SETFONT, OnSetFont)
1217 MESSAGE_HANDLER(WM_UPDATEUISTATE, OnUpdateUiState)
1218 MESSAGE_HANDLER(WM_SIZE, OnSize)
1219 END_MSG_MAP()
1220
1221 LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1222 {
1223 T* pT = static_cast<T*>(this);
1224 pT->Init();
1225 return 0;
1226 }
1227
1228 #ifndef _WIN32_WCE
1229 LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
1230 {
1231 if(m_tip.IsWindow())
1232 {
1233 m_tip.DestroyWindow();
1234 m_tip.m_hWnd = NULL;
1235 }
1236
1237 if(m_bInternalLinkFont)
1238 {
1239 ::DeleteObject(m_hFontLink);
1240 m_hFontLink = NULL;
1241 m_bInternalLinkFont = false;
1242 }
1243
1244 if(m_bInternalNormalFont)
1245 {
1246 ::DeleteObject(m_hFontNormal);
1247 m_hFontNormal = NULL;
1248 m_bInternalNormalFont = false;
1249 }
1250
1251 bHandled = FALSE;
1252 return 1;
1253 }
1254
1255 LRESULT OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1256 {
1257 MSG msg = { m_hWnd, uMsg, wParam, lParam };
1258 if(m_tip.IsWindow() && IsUsingToolTip())
1259 m_tip.RelayEvent(&msg);
1260 bHandled = FALSE;
1261 return 1;
1262 }
1263 #endif // !_WIN32_WCE
1264
1265 LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1266 {
1267 return 1; // no background painting needed (we do it all during WM_PAINT)
1268 }
1269
1270 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
1271 {
1272 if(!m_bPaintLabel)
1273 {
1274 bHandled = FALSE;
1275 return 1;
1276 }
1277
1278 T* pT = static_cast<T*>(this);
1279 if(wParam != NULL)
1280 {
1281 pT->DoEraseBackground((HDC)wParam);
1282 pT->DoPaint((HDC)wParam);
1283 }
1284 else
1285 {
1286 CPaintDC dc(m_hWnd);
1287 pT->DoEraseBackground(dc.m_hDC);
1288 pT->DoPaint(dc.m_hDC);
1289 }
1290
1291 return 0;
1292 }
1293
1294 LRESULT OnFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
1295 {
1296 if(m_bPaintLabel)
1297 Invalidate();
1298 else
1299 bHandled = FALSE;
1300 return 0;
1301 }
1302
1303 LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
1304 {
1305 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
1306 if((m_lpstrHyperLink != NULL || IsCommandButton()) && ::PtInRect(&m_rcLink, pt))
1307 {
1308 ::SetCursor(m_hCursor);
1309 if(IsUnderlineHover())
1310 {
1311 if(!m_bHover)
1312 {
1313 m_bHover = true;
1314 InvalidateRect(&m_rcLink);
1315 UpdateWindow();
1316 #ifndef _WIN32_WCE
1317 StartTrackMouseLeave();
1318 #endif // !_WIN32_WCE
1319 }
1320 }
1321 }
1322 else
1323 {
1324 if(IsUnderlineHover())
1325 {
1326 if(m_bHover)
1327 {
1328 m_bHover = false;
1329 InvalidateRect(&m_rcLink);
1330 UpdateWindow();
1331 }
1332 }
1333 bHandled = FALSE;
1334 }
1335 return 0;
1336 }
1337
1338 #ifndef _WIN32_WCE
1339 LRESULT OnMouseLeave(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1340 {
1341 if(IsUnderlineHover() && m_bHover)
1342 {
1343 m_bHover = false;
1344 InvalidateRect(&m_rcLink);
1345 UpdateWindow();
1346 }
1347 return 0;
1348 }
1349 #endif // !_WIN32_WCE
1350
1351 LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
1352 {
1353 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
1354 if(::PtInRect(&m_rcLink, pt))
1355 {
1356 SetFocus();
1357 SetCapture();
1358 }
1359 return 0;
1360 }
1361
1362 LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
1363 {
1364 if(GetCapture() == m_hWnd)
1365 {
1366 ReleaseCapture();
1367 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
1368 if(::PtInRect(&m_rcLink, pt))
1369 {
1370 T* pT = static_cast<T*>(this);
1371 pT->Navigate();
1372 }
1373 }
1374 return 0;
1375 }
1376
1377 LRESULT OnChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1378 {
1379 if(wParam == VK_RETURN || wParam == VK_SPACE)
1380 {
1381 T* pT = static_cast<T*>(this);
1382 pT->Navigate();
1383 }
1384 return 0;
1385 }
1386
1387 LRESULT OnGetDlgCode(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1388 {
1389 return DLGC_WANTCHARS;
1390 }
1391
1392 LRESULT OnSetCursor(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
1393 {
1394 POINT pt = { 0, 0 };
1395 GetCursorPos(&pt);
1396 ScreenToClient(&pt);
1397 if((m_lpstrHyperLink != NULL || IsCommandButton()) && ::PtInRect(&m_rcLink, pt))
1398 {
1399 return TRUE;
1400 }
1401 bHandled = FALSE;
1402 return FALSE;
1403 }
1404
1405 LRESULT OnEnable(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1406 {
1407 Invalidate();
1408 UpdateWindow();
1409 return 0;
1410 }
1411
1412 LRESULT OnGetFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1413 {
1414 return (LRESULT)m_hFontNormal;
1415 }
1416
1417 LRESULT OnSetFont(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
1418 {
1419 if(m_bInternalNormalFont)
1420 {
1421 ::DeleteObject(m_hFontNormal);
1422 m_bInternalNormalFont = false;
1423 }
1424
1425 bool bCreateLinkFont = m_bInternalLinkFont;
1426
1427 m_hFontNormal = (HFONT)wParam;
1428
1429 if(bCreateLinkFont || IsAutoCreateLinkFont())
1430 CreateLinkFontFromNormal();
1431
1432 T* pT = static_cast<T*>(this);
1433 pT->CalcLabelRect();
1434
1435 if((BOOL)lParam)
1436 {
1437 Invalidate();
1438 UpdateWindow();
1439 }
1440
1441 return 0;
1442 }
1443
1444 LRESULT OnUpdateUiState(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1445 {
1446 // If the control is subclassed or superclassed, this message can cause
1447 // repainting without WM_PAINT. We don't use this state, so just do nothing.
1448 return 0;
1449 }
1450
1451 LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1452 {
1453 T* pT = static_cast<T*>(this);
1454 pT->CalcLabelRect();
1455 pT->Invalidate();
1456 return 0;
1457 }
1458
1459 // Implementation
1460 void Init()
1461 {
1462 ATLASSERT(::IsWindow(m_hWnd));
1463
1464 // Check if we should paint a label
1465 const int cchBuff = 8;
1466 TCHAR szBuffer[cchBuff] = { 0 };
1467 if(::GetClassName(m_hWnd, szBuffer, cchBuff))
1468 {
1469 if(lstrcmpi(szBuffer, _T("static")) == 0)
1470 {
1471 ModifyStyle(0, SS_NOTIFY); // we need this
1472 DWORD dwStyle = GetStyle() & 0x000000FF;
1473 #ifndef _WIN32_WCE
1474 if(dwStyle == SS_ICON || dwStyle == SS_BLACKRECT || dwStyle == SS_GRAYRECT ||
1475 dwStyle == SS_WHITERECT || dwStyle == SS_BLACKFRAME || dwStyle == SS_GRAYFRAME ||
1476 dwStyle == SS_WHITEFRAME || dwStyle == SS_OWNERDRAW ||
1477 dwStyle == SS_BITMAP || dwStyle == SS_ENHMETAFILE)
1478 #else // CE specific
1479 if(dwStyle == SS_ICON || dwStyle == SS_BITMAP)
1480 #endif // _WIN32_WCE
1481 m_bPaintLabel = false;
1482 }
1483 }
1484
1485 // create or load a cursor
1486 #if (WINVER >= 0x0500) || defined(_WIN32_WCE)
1487 m_hCursor = ::LoadCursor(NULL, IDC_HAND);
1488 #else
1489 m_hCursor = ::CreateCursor(ModuleHelper::GetModuleInstance(), _AtlHyperLink_CursorData.xHotSpot, _AtlHyperLink_CursorData.yHotSpot, _AtlHyperLink_CursorData.cxWidth, _AtlHyperLink_CursorData.cyHeight, _AtlHyperLink_CursorData.arrANDPlane, _AtlHyperLink_CursorData.arrXORPlane);
1490 #endif
1491 ATLASSERT(m_hCursor != NULL);
1492
1493 // set fonts
1494 if(m_bPaintLabel)
1495 {
1496 if(m_hFontNormal == NULL)
1497 {
1498 m_hFontNormal = AtlCreateControlFont();
1499 m_bInternalNormalFont = true;
1500 }
1501
1502 if(m_hFontLink == NULL)
1503 CreateLinkFontFromNormal();
1504 }
1505
1506 #ifndef _WIN32_WCE
1507 // create a tool tip
1508 m_tip.Create(m_hWnd);
1509 ATLASSERT(m_tip.IsWindow());
1510 #endif // !_WIN32_WCE
1511
1512 // set label (defaults to window text)
1513 if(m_lpstrLabel == NULL)
1514 {
1515 int nLen = GetWindowTextLength();
1516 if(nLen > 0)
1517 {
1518 ATLTRY(m_lpstrLabel = new TCHAR[nLen + 1]);
1519 if(m_lpstrLabel != NULL)
1520 ATLVERIFY(GetWindowText(m_lpstrLabel, nLen + 1) > 0);
1521 }
1522 }
1523
1524 T* pT = static_cast<T*>(this);
1525 pT->CalcLabelRect();
1526
1527 // set hyperlink (defaults to label), or just activate tool tip if already set
1528 if(m_lpstrHyperLink == NULL && !IsCommandButton())
1529 {
1530 if(m_lpstrLabel != NULL)
1531 SetHyperLink(m_lpstrLabel);
1532 }
1533 #ifndef _WIN32_WCE
1534 else
1535 {
1536 m_tip.Activate(TRUE);
1537 m_tip.AddTool(m_hWnd, m_lpstrHyperLink, &m_rcLink, 1);
1538 }
1539 #endif // !_WIN32_WCE
1540
1541 // set link colors
1542 if(m_bPaintLabel)
1543 {
1544 CRegKeyEx rk;
1545 LONG lRet = rk.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Internet Explorer\\Settings"));
1546 if(lRet == ERROR_SUCCESS)
1547 {
1548 const int cchValue = 12;
1549 TCHAR szValue[cchValue] = { 0 };
1550 ULONG ulCount = cchValue;
1551 lRet = rk.QueryStringValue(_T("Anchor Color"), szValue, &ulCount);
1552 if(lRet == ERROR_SUCCESS)
1553 {
1554 COLORREF clr = pT->_ParseColorString(szValue);
1555 ATLASSERT(clr != CLR_INVALID);
1556 if(clr != CLR_INVALID)
1557 m_clrLink = clr;
1558 }
1559
1560 ulCount = cchValue;
1561 lRet = rk.QueryStringValue(_T("Anchor Color Visited"), szValue, &ulCount);
1562 if(lRet == ERROR_SUCCESS)
1563 {
1564 COLORREF clr = pT->_ParseColorString(szValue);
1565 ATLASSERT(clr != CLR_INVALID);
1566 if(clr != CLR_INVALID)
1567 m_clrVisited = clr;
1568 }
1569 }
1570 }
1571 }
1572
1573 static COLORREF _ParseColorString(LPTSTR lpstr)
1574 {
1575 int c[3] = { -1, -1, -1 };
1576 LPTSTR p = NULL;
1577 for(int i = 0; i < 2; i++)
1578 {
1579 for(p = lpstr; *p != _T('\0'); p = ::CharNext(p))
1580 {
1581 if(*p == _T(','))
1582 {
1583 *p = _T('\0');
1584 c[i] = MinCrtHelper::_atoi(lpstr);
1585 lpstr = &p[1];
1586 break;
1587 }
1588 }
1589 if(c[i] == -1)
1590 return CLR_INVALID;
1591 }
1592 if(*lpstr == _T('\0'))
1593 return CLR_INVALID;
1594 c[2] = MinCrtHelper::_atoi(lpstr);
1595
1596 return RGB(c[0], c[1], c[2]);
1597 }
1598
1599 bool CalcLabelRect()
1600 {
1601 if(!::IsWindow(m_hWnd))
1602 return false;
1603 if(m_lpstrLabel == NULL && m_lpstrHyperLink == NULL)
1604 return false;
1605
1606 CClientDC dc(m_hWnd);
1607 RECT rcClient = { 0 };
1608 GetClientRect(&rcClient);
1609 m_rcLink = rcClient;
1610 if(!m_bPaintLabel)
1611 return true;
1612
1613 if(IsUsingTags())
1614 {
1615 // find tags and label parts
1616 LPTSTR lpstrLeft = NULL;
1617 int cchLeft = 0;
1618 LPTSTR lpstrLink = NULL;
1619 int cchLink = 0;
1620 LPTSTR lpstrRight = NULL;
1621 int cchRight = 0;
1622
1623 T* pT = static_cast<T*>(this);
1624 pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight);
1625 ATLASSERT(lpstrLink != NULL);
1626 ATLASSERT(cchLink > 0);
1627
1628 // get label part rects
1629 HFONT hFontOld = dc.SelectFont(m_hFontNormal);
1630
1631 UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
1632
1633 RECT rcLeft = rcClient;
1634 if(lpstrLeft != NULL)
1635 dc.DrawText(lpstrLeft, cchLeft, &rcLeft, DT_LEFT | uFormat | DT_CALCRECT);
1636
1637 dc.SelectFont(m_hFontLink);
1638 RECT rcLink = rcClient;
1639 if(lpstrLeft != NULL)
1640 rcLink.left = rcLeft.right;
1641 dc.DrawText(lpstrLink, cchLink, &rcLink, DT_LEFT | uFormat | DT_CALCRECT);
1642
1643 dc.SelectFont(hFontOld);
1644
1645 m_rcLink = rcLink;
1646 }
1647 else
1648 {
1649 HFONT hOldFont = NULL;
1650 if(m_hFontLink != NULL)
1651 hOldFont = dc.SelectFont(m_hFontLink);
1652 LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink;
1653 DWORD dwStyle = GetStyle();
1654 UINT uFormat = DT_LEFT;
1655 if (dwStyle & SS_CENTER)
1656 uFormat = DT_CENTER;
1657 else if (dwStyle & SS_RIGHT)
1658 uFormat = DT_RIGHT;
1659 uFormat |= IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
1660 dc.DrawText(lpstrText, -1, &m_rcLink, uFormat | DT_CALCRECT);
1661 if(m_hFontLink != NULL)
1662 dc.SelectFont(hOldFont);
1663 if (dwStyle & SS_CENTER)
1664 {
1665 int dx = (rcClient.right - m_rcLink.right) / 2;
1666 ::OffsetRect(&m_rcLink, dx, 0);
1667 }
1668 else if (dwStyle & SS_RIGHT)
1669 {
1670 int dx = rcClient.right - m_rcLink.right;
1671 ::OffsetRect(&m_rcLink, dx, 0);
1672 }
1673 }
1674
1675 return true;
1676 }
1677
1678 void CalcLabelParts(LPTSTR& lpstrLeft, int& cchLeft, LPTSTR& lpstrLink, int& cchLink, LPTSTR& lpstrRight, int& cchRight) const
1679 {
1680 lpstrLeft = NULL;
1681 cchLeft = 0;
1682 lpstrLink = NULL;
1683 cchLink = 0;
1684 lpstrRight = NULL;
1685 cchRight = 0;
1686
1687 LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink;
1688 int cchText = lstrlen(lpstrText);
1689 bool bOutsideLink = true;
1690 for(int i = 0; i < cchText; i++)
1691 {
1692 if(lpstrText[i] != _T('<'))
1693 continue;
1694
1695 if(bOutsideLink)
1696 {
1697 if(::CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, &lpstrText[i], 3, _T("<A>"), 3) == CSTR_EQUAL)
1698 {
1699 if(i > 0)
1700 {
1701 lpstrLeft = lpstrText;
1702 cchLeft = i;
1703 }
1704 lpstrLink = &lpstrText[i + 3];
1705 bOutsideLink = false;
1706 }
1707 }
1708 else
1709 {
1710 if(::CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, &lpstrText[i], 4, _T("</A>"), 4) == CSTR_EQUAL)
1711 {
1712 cchLink = i - 3 - cchLeft;
1713 if(lpstrText[i + 4] != 0)
1714 {
1715 lpstrRight = &lpstrText[i + 4];
1716 cchRight = cchText - (i + 4);
1717 break;
1718 }
1719 }
1720 }
1721 }
1722
1723 }
1724
1725 void DoEraseBackground(CDCHandle dc)
1726 {
1727 HBRUSH hBrush = (HBRUSH)::SendMessage(GetParent(), WM_CTLCOLORSTATIC, (WPARAM)dc.m_hDC, (LPARAM)m_hWnd);
1728 if(hBrush != NULL)
1729 {
1730 RECT rect = { 0 };
1731 GetClientRect(&rect);
1732 dc.FillRect(&rect, hBrush);
1733 }
1734 }
1735
1736 void DoPaint(CDCHandle dc)
1737 {
1738 if(IsUsingTags())
1739 {
1740 // find tags and label parts
1741 LPTSTR lpstrLeft = NULL;
1742 int cchLeft = 0;
1743 LPTSTR lpstrLink = NULL;
1744 int cchLink = 0;
1745 LPTSTR lpstrRight = NULL;
1746 int cchRight = 0;
1747
1748 T* pT = static_cast<T*>(this);
1749 pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight);
1750
1751 // get label part rects
1752 RECT rcClient = { 0 };
1753 GetClientRect(&rcClient);
1754
1755 dc.SetBkMode(TRANSPARENT);
1756 HFONT hFontOld = dc.SelectFont(m_hFontNormal);
1757
1758 UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
1759
1760 if(lpstrLeft != NULL)
1761 dc.DrawText(lpstrLeft, cchLeft, &rcClient, DT_LEFT | uFormat);
1762
1763 COLORREF clrOld = dc.SetTextColor(IsWindowEnabled() ? (m_bVisited ? m_clrVisited : m_clrLink) : (::GetSysColor(COLOR_GRAYTEXT)));
1764 if(m_hFontLink != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover)))
1765 dc.SelectFont(m_hFontLink);
1766 else
1767 dc.SelectFont(m_hFontNormal);
1768
1769 dc.DrawText(lpstrLink, cchLink, &m_rcLink, DT_LEFT | uFormat);
1770
1771 dc.SetTextColor(clrOld);
1772 dc.SelectFont(m_hFontNormal);
1773 if(lpstrRight != NULL)
1774 {
1775 RECT rcRight = { m_rcLink.right, m_rcLink.top, rcClient.right, rcClient.bottom };
1776 dc.DrawText(lpstrRight, cchRight, &rcRight, DT_LEFT | uFormat);
1777 }
1778
1779 if(GetFocus() == m_hWnd)
1780 dc.DrawFocusRect(&m_rcLink);
1781
1782 dc.SelectFont(hFontOld);
1783 }
1784 else
1785 {
1786 dc.SetBkMode(TRANSPARENT);
1787 COLORREF clrOld = dc.SetTextColor(IsWindowEnabled() ? (m_bVisited ? m_clrVisited : m_clrLink) : (::GetSysColor(COLOR_GRAYTEXT)));
1788
1789 HFONT hFontOld = NULL;
1790 if(m_hFontLink != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover)))
1791 hFontOld = dc.SelectFont(m_hFontLink);
1792 else
1793 hFontOld = dc.SelectFont(m_hFontNormal);
1794
1795 LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink;
1796
1797 DWORD dwStyle = GetStyle();
1798 UINT uFormat = DT_LEFT;
1799 if (dwStyle & SS_CENTER)
1800 uFormat = DT_CENTER;
1801 else if (dwStyle & SS_RIGHT)
1802 uFormat = DT_RIGHT;
1803 uFormat |= IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
1804
1805 dc.DrawText(lpstrText, -1, &m_rcLink, uFormat);
1806
1807 if(GetFocus() == m_hWnd)
1808 dc.DrawFocusRect(&m_rcLink);
1809
1810 dc.SetTextColor(clrOld);
1811 dc.SelectFont(hFontOld);
1812 }
1813 }
1814
1815 #ifndef _WIN32_WCE
1816 BOOL StartTrackMouseLeave()
1817 {
1818 TRACKMOUSEEVENT tme = { 0 };
1819 tme.cbSize = sizeof(tme);
1820 tme.dwFlags = TME_LEAVE;
1821 tme.hwndTrack = m_hWnd;
1822 return _TrackMouseEvent(&tme);
1823 }
1824 #endif // !_WIN32_WCE
1825
1826 // Implementation helpers
1827 bool IsUnderlined() const
1828 {
1829 return ((m_dwExtendedStyle & (HLINK_NOTUNDERLINED | HLINK_UNDERLINEHOVER)) == 0);
1830 }
1831
1832 bool IsNotUnderlined() const
1833 {
1834 return ((m_dwExtendedStyle & HLINK_NOTUNDERLINED) != 0);
1835 }
1836
1837 bool IsUnderlineHover() const
1838 {
1839 return ((m_dwExtendedStyle & HLINK_UNDERLINEHOVER) != 0);
1840 }
1841
1842 bool IsCommandButton() const
1843 {
1844 return ((m_dwExtendedStyle & HLINK_COMMANDBUTTON) != 0);
1845 }
1846
1847 bool IsNotifyButton() const
1848 {
1849 return ((m_dwExtendedStyle & HLINK_NOTIFYBUTTON) == HLINK_NOTIFYBUTTON);
1850 }
1851
1852 bool IsUsingTags() const
1853 {
1854 return ((m_dwExtendedStyle & HLINK_USETAGS) != 0);
1855 }
1856
1857 bool IsUsingTagsBold() const
1858 {
1859 return ((m_dwExtendedStyle & HLINK_USETAGSBOLD) == HLINK_USETAGSBOLD);
1860 }
1861
1862 bool IsUsingToolTip() const
1863 {
1864 return ((m_dwExtendedStyle & HLINK_NOTOOLTIP) == 0);
1865 }
1866
1867 bool IsAutoCreateLinkFont() const
1868 {
1869 return ((m_dwExtendedStyle & HLINK_AUTOCREATELINKFONT) == HLINK_AUTOCREATELINKFONT);
1870 }
1871
1872 bool IsSingleLine() const
1873 {
1874 return ((m_dwExtendedStyle & HLINK_SINGLELINE) == HLINK_SINGLELINE);
1875 }
1876 };
1877
1878 class CHyperLink : public CHyperLinkImpl<CHyperLink>
1879 {
1880 public:
1881 DECLARE_WND_CLASS(_T("WTL_HyperLink"))
1882 };
1883
1884
1885 ///////////////////////////////////////////////////////////////////////////////
1886 // CWaitCursor - displays a wait cursor
1887
1888 class CWaitCursor
1889 {
1890 public:
1891 // Data
1892 HCURSOR m_hWaitCursor;
1893 HCURSOR m_hOldCursor;
1894 bool m_bInUse;
1895
1896 // Constructor/destructor
1897 CWaitCursor(bool bSet = true, LPCTSTR lpstrCursor = IDC_WAIT, bool bSys = true) : m_hOldCursor(NULL), m_bInUse(false)
1898 {
1899 HINSTANCE hInstance = bSys ? NULL : ModuleHelper::GetResourceInstance();
1900 m_hWaitCursor = ::LoadCursor(hInstance, lpstrCursor);
1901 ATLASSERT(m_hWaitCursor != NULL);
1902
1903 if(bSet)
1904 Set();
1905 }
1906
1907 ~CWaitCursor()
1908 {
1909 Restore();
1910 }
1911
1912 // Methods
1913 bool Set()
1914 {
1915 if(m_bInUse)
1916 return false;
1917 m_hOldCursor = ::SetCursor(m_hWaitCursor);
1918 m_bInUse = true;
1919 return true;
1920 }
1921
1922 bool Restore()
1923 {
1924 if(!m_bInUse)
1925 return false;
1926 ::SetCursor(m_hOldCursor);
1927 m_bInUse = false;
1928 return true;
1929 }
1930 };
1931
1932
1933 ///////////////////////////////////////////////////////////////////////////////
1934 // CCustomWaitCursor - for custom and animated cursors
1935
1936 class CCustomWaitCursor : public CWaitCursor
1937 {
1938 public:
1939 // Constructor/destructor
1940 CCustomWaitCursor(ATL::_U_STRINGorID cursor, bool bSet = true, HINSTANCE hInstance = NULL) :
1941 CWaitCursor(false, IDC_WAIT, true)
1942 {
1943 if(hInstance == NULL)
1944 hInstance = ModuleHelper::GetResourceInstance();
1945 m_hWaitCursor = (HCURSOR)::LoadImage(hInstance, cursor.m_lpstr, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE);
1946
1947 if(bSet)
1948 Set();
1949 }
1950
1951 ~CCustomWaitCursor()
1952 {
1953 Restore();
1954 #if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)))
1955 ::DestroyCursor(m_hWaitCursor);
1956 #endif // !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)))
1957 }
1958 };
1959
1960
1961 ///////////////////////////////////////////////////////////////////////////////
1962 // CMultiPaneStatusBarCtrl - Status Bar with multiple panes
1963
1964 template <class T, class TBase = CStatusBarCtrl>
1965 class ATL_NO_VTABLE CMultiPaneStatusBarCtrlImpl : public ATL::CWindowImpl< T, TBase >
1966 {
1967 public:
1968 DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())
1969
1970 // Data
1971 enum { m_cxPaneMargin = 3 };
1972
1973 int m_nPanes;
1974 int* m_pPane;
1975
1976 // Constructor/destructor
1977 CMultiPaneStatusBarCtrlImpl() : m_nPanes(0), m_pPane(NULL)
1978 { }
1979
1980 ~CMultiPaneStatusBarCtrlImpl()
1981 {
1982 delete [] m_pPane;
1983 }
1984
1985 // Methods
1986 HWND Create(HWND hWndParent, LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR)
1987 {
1988 #if (_MSC_VER >= 1300)
1989 return ATL::CWindowImpl< T, TBase >::Create(hWndParent, rcDefault, lpstrText, dwStyle, 0, nID);
1990 #else // !(_MSC_VER >= 1300)
1991 typedef ATL::CWindowImpl< T, TBase > _baseClass;
1992 return _baseClass::Create(hWndParent, rcDefault, lpstrText, dwStyle, 0, nID);
1993 #endif // !(_MSC_VER >= 1300)
1994 }
1995
1996 HWND Create(HWND hWndParent, UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR)
1997 {
1998 const int cchMax = 128; // max text length is 127 for status bars (+1 for null)
1999 TCHAR szText[cchMax] = { 0 };
2000 ::LoadString(ModuleHelper::GetResourceInstance(), nTextID, szText, cchMax);
2001 return Create(hWndParent, szText, dwStyle, nID);
2002 }
2003
2004 BOOL SetPanes(int* pPanes, int nPanes, bool bSetText = true)
2005 {
2006 ATLASSERT(::IsWindow(m_hWnd));
2007 ATLASSERT(nPanes > 0);
2008
2009 m_nPanes = nPanes;
2010 delete [] m_pPane;
2011 m_pPane = NULL;
2012
2013 ATLTRY(m_pPane = new int[nPanes]);
2014 ATLASSERT(m_pPane != NULL);
2015 if(m_pPane == NULL)
2016 return FALSE;
2017
2018 CTempBuffer<int, _WTL_STACK_ALLOC_THRESHOLD> buff;
2019 int* pPanesPos = buff.Allocate(nPanes);
2020 ATLASSERT(pPanesPos != NULL);
2021 if(pPanesPos == NULL)
2022 return FALSE;
2023
2024 SecureHelper::memcpy_x(m_pPane, nPanes * sizeof(int), pPanes, nPanes * sizeof(int));
2025
2026 // get status bar DC and set font
2027 CClientDC dc(m_hWnd);
2028 HFONT hOldFont = dc.SelectFont(GetFont());
2029
2030 // get status bar borders
2031 int arrBorders[3] = { 0 };
2032 GetBorders(arrBorders);
2033
2034 const int cchBuff = 128;
2035 TCHAR szBuff[cchBuff] = { 0 };
2036 SIZE size = { 0, 0 };
2037 int cxLeft = arrBorders[0];
2038
2039 // calculate right edge of each part
2040 for(int i = 0; i < nPanes; i++)
2041 {
2042 if(pPanes[i] == ID_DEFAULT_PANE)
2043 {
2044 // make very large, will be resized later
2045 pPanesPos[i] = INT_MAX / 2;
2046 }
2047 else
2048 {
2049 ::LoadString(ModuleHelper::GetResourceInstance(), pPanes[i], szBuff, cchBuff);
2050 dc.GetTextExtent(szBuff, lstrlen(szBuff), &size);
2051 T* pT = static_cast<T*>(this);
2052 pT;
2053 pPanesPos[i] = cxLeft + size.cx + arrBorders[2] + 2 * pT->m_cxPaneMargin;
2054 }
2055 cxLeft = pPanesPos[i];
2056 }
2057
2058 BOOL bRet = SetParts(nPanes, pPanesPos);
2059
2060 if(bRet && bSetText)
2061 {
2062 for(int i = 0; i < nPanes; i++)
2063 {
2064 if(pPanes[i] != ID_DEFAULT_PANE)
2065 {
2066 ::LoadString(ModuleHelper::GetResourceInstance(), pPanes[i], szBuff, cchBuff);
2067 SetPaneText(m_pPane[i], szBuff);
2068 }
2069 }
2070 }
2071
2072 dc.SelectFont(hOldFont);
2073 return bRet;
2074 }
2075
2076 bool GetPaneTextLength(int nPaneID, int* pcchLength = NULL, int* pnType = NULL) const
2077 {
2078 ATLASSERT(::IsWindow(m_hWnd));
2079 int nIndex = GetPaneIndexFromID(nPaneID);
2080 if(nIndex == -1)
2081 return false;
2082
2083 int nLength = GetTextLength(nIndex, pnType);
2084 if(pcchLength != NULL)
2085 *pcchLength = nLength;
2086
2087 return true;
2088 }
2089
2090 BOOL GetPaneText(int nPaneID, LPTSTR lpstrText, int* pcchLength = NULL, int* pnType = NULL) const
2091 {
2092 ATLASSERT(::IsWindow(m_hWnd));
2093 int nIndex = GetPaneIndexFromID(nPaneID);
2094 if(nIndex == -1)
2095 return FALSE;
2096
2097 int nLength = GetText(nIndex, lpstrText, pnType);
2098 if(pcchLength != NULL)
2099 *pcchLength = nLength;
2100
2101 return TRUE;
2102 }
2103
2104 BOOL SetPaneText(int nPaneID, LPCTSTR lpstrText, int nType = 0)
2105 {
2106 ATLASSERT(::IsWindow(m_hWnd));
2107 int nIndex = GetPaneIndexFromID(nPaneID);
2108 if(nIndex == -1)
2109 return FALSE;
2110
2111 return SetText(nIndex, lpstrText, nType);
2112 }
2113
2114 BOOL GetPaneRect(int nPaneID, LPRECT lpRect) const
2115 {
2116 ATLASSERT(::IsWindow(m_hWnd));
2117 int nIndex = GetPaneIndexFromID(nPaneID);
2118 if(nIndex == -1)
2119 return FALSE;
2120
2121 return GetRect(nIndex, lpRect);
2122 }
2123
2124 BOOL SetPaneWidth(int nPaneID, int cxWidth)
2125 {
2126 ATLASSERT(::IsWindow(m_hWnd));
2127 ATLASSERT(nPaneID != ID_DEFAULT_PANE); // Can't resize this one
2128 int nIndex = GetPaneIndexFromID(nPaneID);
2129 if(nIndex == -1)
2130 return FALSE;
2131
2132 // get pane positions
2133 CTempBuffer<int, _WTL_STACK_ALLOC_THRESHOLD> buff;
2134 int* pPanesPos = buff.Allocate(m_nPanes);
2135 if(pPanesPos == NULL)
2136 return FALSE;
2137 GetParts(m_nPanes, pPanesPos);
2138 // calculate offset
2139 int cxPaneWidth = pPanesPos[nIndex] - ((nIndex == 0) ? 0 : pPanesPos[nIndex - 1]);
2140 int cxOff = cxWidth - cxPaneWidth;
2141 // find variable width pane
2142 int nDef = m_nPanes;
2143 for(int i = 0; i < m_nPanes; i++)
2144 {
2145 if(m_pPane[i] == ID_DEFAULT_PANE)
2146 {
2147 nDef = i;
2148 break;
2149 }
2150 }
2151 // resize
2152 if(nIndex < nDef) // before default pane
2153 {
2154 for(int i = nIndex; i < nDef; i++)
2155 pPanesPos[i] += cxOff;
2156
2157 }
2158 else // after default one
2159 {
2160 for(int i = nDef; i < nIndex; i++)
2161 pPanesPos[i] -= cxOff;
2162 }
2163 // set pane postions
2164 return SetParts(m_nPanes, pPanesPos);
2165 }
2166
2167 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
2168 BOOL GetPaneTipText(int nPaneID, LPTSTR lpstrText, int nSize) const
2169 {
2170 ATLASSERT(::IsWindow(m_hWnd));
2171 int nIndex = GetPaneIndexFromID(nPaneID);
2172 if(nIndex == -1)
2173 return FALSE;
2174
2175 GetTipText(nIndex, lpstrText, nSize);
2176 return TRUE;
2177 }
2178
2179 BOOL SetPaneTipText(int nPaneID, LPCTSTR lpstrText)
2180 {
2181 ATLASSERT(::IsWindow(m_hWnd));
2182 int nIndex = GetPaneIndexFromID(nPaneID);
2183 if(nIndex == -1)
2184 return FALSE;
2185
2186 SetTipText(nIndex, lpstrText);
2187 return TRUE;
2188 }
2189 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
2190
2191 #if ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500))
2192 BOOL GetPaneIcon(int nPaneID, HICON& hIcon) const
2193 {
2194 ATLASSERT(::IsWindow(m_hWnd));
2195 int nIndex = GetPaneIndexFromID(nPaneID);
2196 if(nIndex == -1)
2197 return FALSE;
2198
2199 hIcon = GetIcon(nIndex);
2200 return TRUE;
2201 }
2202
2203 BOOL SetPaneIcon(int nPaneID, HICON hIcon)
2204 {
2205 ATLASSERT(::IsWindow(m_hWnd));
2206 int nIndex = GetPaneIndexFromID(nPaneID);
2207 if(nIndex == -1)
2208 return FALSE;
2209
2210 return SetIcon(nIndex, hIcon);
2211 }
2212 #endif // ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500))
2213
2214 // Message map and handlers
2215 BEGIN_MSG_MAP(CMultiPaneStatusBarCtrlImpl< T >)
2216 MESSAGE_HANDLER(WM_SIZE, OnSize)
2217 END_MSG_MAP()
2218
2219 LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
2220 {
2221 LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
2222 if(wParam != SIZE_MINIMIZED && m_nPanes > 0)
2223 {
2224 T* pT = static_cast<T*>(this);
2225 pT->UpdatePanesLayout();
2226 }
2227 return lRet;
2228 }
2229
2230 // Implementation
2231 BOOL UpdatePanesLayout()
2232 {
2233 // get pane positions
2234 CTempBuffer<int, _WTL_STACK_ALLOC_THRESHOLD> buff;
2235 int* pPanesPos = buff.Allocate(m_nPanes);
2236 ATLASSERT(pPanesPos != NULL);
2237 if(pPanesPos == NULL)
2238 return FALSE;
2239 int nRet = GetParts(m_nPanes, pPanesPos);
2240 ATLASSERT(nRet == m_nPanes);
2241 if(nRet != m_nPanes)
2242 return FALSE;
2243 // calculate offset
2244 RECT rcClient = { 0 };
2245 GetClientRect(&rcClient);
2246 int cxOff = rcClient.right - pPanesPos[m_nPanes - 1];
2247 #ifndef _WIN32_WCE
2248 // Move panes left if size grip box is present
2249 if((GetStyle() & SBARS_SIZEGRIP) != 0)
2250 cxOff -= ::GetSystemMetrics(SM_CXVSCROLL) + ::GetSystemMetrics(SM_CXEDGE);
2251 #endif // !_WIN32_WCE
2252 // find variable width pane
2253 int i;
2254 for(i = 0; i < m_nPanes; i++)
2255 {
2256 if(m_pPane[i] == ID_DEFAULT_PANE)
2257 break;
2258 }
2259 // resize all panes from the variable one to the right
2260 if((i < m_nPanes) && (pPanesPos[i] + cxOff) > ((i == 0) ? 0 : pPanesPos[i - 1]))
2261 {
2262 for(; i < m_nPanes; i++)
2263 pPanesPos[i] += cxOff;
2264 }
2265 // set pane postions
2266 return SetParts(m_nPanes, pPanesPos);
2267 }
2268
2269 int GetPaneIndexFromID(int nPaneID) const
2270 {
2271 for(int i = 0; i < m_nPanes; i++)
2272 {
2273 if(m_pPane[i] == nPaneID)
2274 return i;
2275 }
2276
2277 return -1; // not found
2278 }
2279 };
2280
2281 class CMultiPaneStatusBarCtrl : public CMultiPaneStatusBarCtrlImpl<CMultiPaneStatusBarCtrl>
2282 {
2283 public:
2284 DECLARE_WND_SUPERCLASS(_T("WTL_MultiPaneStatusBar"), GetWndClassName())
2285 };
2286
2287
2288 ///////////////////////////////////////////////////////////////////////////////
2289 // CPaneContainer - provides header with title and close button for panes
2290
2291 // pane container extended styles
2292 #define PANECNT_NOCLOSEBUTTON 0x00000001
2293 #define PANECNT_VERTICAL 0x00000002
2294 #define PANECNT_FLATBORDER 0x00000004
2295 #define PANECNT_NOBORDER 0x00000008
2296 #define PANECNT_DIVIDER 0x00000010
2297 #define PANECNT_GRADIENT 0x00000020
2298
2299 // Note: PANECNT_GRADIENT doesn't work with _ATL_NO_MSIMG
2300
2301 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
2302 class ATL_NO_VTABLE CPaneContainerImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CCustomDraw< T >
2303 {
2304 public:
2305 DECLARE_WND_CLASS_EX(NULL, 0, -1)
2306
2307 // Constants
2308 enum
2309 {
2310 m_cxyBorder = 2,
2311 m_cxyTextOffset = 4,
2312 m_cxyBtnOffset = 1,
2313
2314 m_cchTitle = 80,
2315
2316 m_cxImageTB = 13,
2317 m_cyImageTB = 11,
2318 m_cxyBtnAddTB = 7,
2319
2320 m_cxToolBar = m_cxImageTB + m_cxyBtnAddTB + m_cxyBorder + m_cxyBtnOffset,
2321
2322 m_xBtnImageLeft = 6,
2323 m_yBtnImageTop = 5,
2324 m_xBtnImageRight = 12,
2325 m_yBtnImageBottom = 11,
2326
2327 m_nCloseBtnID = ID_PANE_CLOSE
2328 };
2329
2330 // Data members
2331 CToolBarCtrl m_tb;
2332 ATL::CWindow m_wndClient;
2333 int m_cxyHeader;
2334 TCHAR m_szTitle[m_cchTitle];
2335 DWORD m_dwExtendedStyle; // Pane container specific extended styles
2336 HFONT m_hFont;
2337 bool m_bInternalFont;
2338
2339
2340 // Constructor
2341 CPaneContainerImpl() : m_cxyHeader(0), m_dwExtendedStyle(0), m_hFont(NULL), m_bInternalFont(false)
2342 {
2343 m_szTitle[0] = 0;
2344 }
2345
2346 // Attributes
2347 DWORD GetPaneContainerExtendedStyle() const
2348 {
2349 return m_dwExtendedStyle;
2350 }
2351
2352 DWORD SetPaneContainerExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
2353 {
2354 DWORD dwPrevStyle = m_dwExtendedStyle;
2355 if(dwMask == 0)
2356 m_dwExtendedStyle = dwExtendedStyle;
2357 else
2358 m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
2359 if(m_hWnd != NULL)
2360 {
2361 T* pT = static_cast<T*>(this);
2362 bool bUpdate = false;
2363
2364 if(((dwPrevStyle & PANECNT_NOCLOSEBUTTON) != 0) && ((m_dwExtendedStyle & PANECNT_NOCLOSEBUTTON) == 0)) // add close button
2365 {
2366 pT->CreateCloseButton();
2367 bUpdate = true;
2368 }
2369 else if(((dwPrevStyle & PANECNT_NOCLOSEBUTTON) == 0) && ((m_dwExtendedStyle & PANECNT_NOCLOSEBUTTON) != 0)) // remove close button
2370 {
2371 pT->DestroyCloseButton();
2372 bUpdate = true;
2373 }
2374
2375 if((dwPrevStyle & PANECNT_VERTICAL) != (m_dwExtendedStyle & PANECNT_VERTICAL)) // change orientation
2376 {
2377 pT->CalcSize();
2378 bUpdate = true;
2379 }
2380
2381 if((dwPrevStyle & (PANECNT_FLATBORDER | PANECNT_NOBORDER)) !=
2382 (m_dwExtendedStyle & (PANECNT_FLATBORDER | PANECNT_NOBORDER))) // change border
2383 {
2384 bUpdate = true;
2385 }
2386
2387 #if (!defined(_WIN32_WCE) && !defined(_ATL_NO_MSIMG)) || (_WIN32_WCE >= 420)
2388 if((dwPrevStyle & PANECNT_GRADIENT) != (m_dwExtendedStyle & PANECNT_GRADIENT)) // change background
2389 {
2390 bUpdate = true;
2391 }
2392 #endif // (!defined(_WIN32_WCE) && !defined(_ATL_NO_MSIMG)) || (_WIN32_WCE >= 420)
2393
2394 if(bUpdate)
2395 pT->UpdateLayout();
2396 }
2397 return dwPrevStyle;
2398 }
2399
2400 HWND GetClient() const
2401 {
2402 return m_wndClient;
2403 }
2404
2405 HWND SetClient(HWND hWndClient)
2406 {
2407 HWND hWndOldClient = m_wndClient;
2408 m_wndClient = hWndClient;
2409 if(m_hWnd != NULL)
2410 {
2411 T* pT = static_cast<T*>(this);
2412 pT->UpdateLayout();
2413 }
2414 return hWndOldClient;
2415 }
2416
2417 BOOL GetTitle(LPTSTR lpstrTitle, int cchLength) const
2418 {
2419 ATLASSERT(lpstrTitle != NULL);
2420
2421 errno_t nRet = SecureHelper::strncpy_x(lpstrTitle, cchLength, m_szTitle, _TRUNCATE);
2422
2423 return (nRet == 0 || nRet == STRUNCATE);
2424 }
2425
2426 BOOL SetTitle(LPCTSTR lpstrTitle)
2427 {
2428 ATLASSERT(lpstrTitle != NULL);
2429
2430 errno_t nRet = SecureHelper::strncpy_x(m_szTitle, m_cchTitle, lpstrTitle, _TRUNCATE);
2431 bool bRet = (nRet == 0 || nRet == STRUNCATE);
2432 if(bRet && m_hWnd != NULL)
2433 {
2434 T* pT = static_cast<T*>(this);
2435 pT->UpdateLayout();
2436 }
2437
2438 return bRet;
2439 }
2440
2441 int GetTitleLength() const
2442 {
2443 return lstrlen(m_szTitle);
2444 }
2445
2446 // Methods
2447 HWND Create(HWND hWndParent, LPCTSTR lpstrTitle = NULL, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
2448 DWORD dwExStyle = 0, UINT nID = 0, LPVOID lpCreateParam = NULL)
2449 {
2450 if(lpstrTitle != NULL)
2451 SecureHelper::strncpy_x(m_szTitle, m_cchTitle, lpstrTitle, _TRUNCATE);
2452 #if (_MSC_VER >= 1300)
2453 return ATL::CWindowImpl< T, TBase, TWinTraits >::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam);
2454 #else // !(_MSC_VER >= 1300)
2455 typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass;
2456 return _baseClass::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam);
2457 #endif // !(_MSC_VER >= 1300)
2458 }
2459
2460 HWND Create(HWND hWndParent, UINT uTitleID, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
2461 DWORD dwExStyle = 0, UINT nID = 0, LPVOID lpCreateParam = NULL)
2462 {
2463 if(uTitleID != 0U)
2464 ::LoadString(ModuleHelper::GetResourceInstance(), uTitleID, m_szTitle, m_cchTitle);
2465 #if (_MSC_VER >= 1300)
2466 return ATL::CWindowImpl< T, TBase, TWinTraits >::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam);
2467 #else // !(_MSC_VER >= 1300)
2468 typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass;
2469 return _baseClass::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam);
2470 #endif // !(_MSC_VER >= 1300)
2471 }
2472
2473 BOOL SubclassWindow(HWND hWnd)
2474 {
2475 #if (_MSC_VER >= 1300)
2476 BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits >::SubclassWindow(hWnd);
2477 #else // !(_MSC_VER >= 1300)
2478 typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass;
2479 BOOL bRet = _baseClass::SubclassWindow(hWnd);
2480 #endif // !(_MSC_VER >= 1300)
2481 if(bRet != FALSE)
2482 {
2483 T* pT = static_cast<T*>(this);
2484 pT->Init();
2485
2486 RECT rect = { 0 };
2487 GetClientRect(&rect);
2488 pT->UpdateLayout(rect.right, rect.bottom);
2489 }
2490
2491 return bRet;
2492 }
2493
2494 BOOL EnableCloseButton(BOOL bEnable)
2495 {
2496 ATLASSERT(::IsWindow(m_hWnd));
2497 T* pT = static_cast<T*>(this);
2498 pT; // avoid level 4 warning
2499 return (m_tb.m_hWnd != NULL) ? m_tb.EnableButton(pT->m_nCloseBtnID, bEnable) : FALSE;
2500 }
2501
2502 void UpdateLayout()
2503 {
2504 RECT rcClient = { 0 };
2505 GetClientRect(&rcClient);
2506 T* pT = static_cast<T*>(this);
2507 pT->UpdateLayout(rcClient.right, rcClient.bottom);
2508 }
2509
2510 // Message map and handlers
2511 BEGIN_MSG_MAP(CPaneContainerImpl)
2512 MESSAGE_HANDLER(WM_CREATE, OnCreate)
2513 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
2514 MESSAGE_HANDLER(WM_SIZE, OnSize)
2515 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
2516 MESSAGE_HANDLER(WM_GETFONT, OnGetFont)
2517 MESSAGE_HANDLER(WM_SETFONT, OnSetFont)
2518 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
2519 MESSAGE_HANDLER(WM_PAINT, OnPaint)
2520 #ifndef _WIN32_WCE
2521 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
2522 #endif // !_WIN32_WCE
2523 MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
2524 MESSAGE_HANDLER(WM_COMMAND, OnCommand)
2525 FORWARD_NOTIFICATIONS()
2526 END_MSG_MAP()
2527
2528 LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
2529 {
2530 T* pT = static_cast<T*>(this);
2531 pT->Init();
2532
2533 return 0;
2534 }
2535
2536 LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
2537 {
2538 if(m_bInternalFont)
2539 {
2540 ::DeleteObject(m_hFont);
2541 m_hFont = NULL;
2542 m_bInternalFont = false;
2543 }
2544
2545 return 0;
2546 }
2547
2548 LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
2549 {
2550 T* pT = static_cast<T*>(this);
2551 pT->UpdateLayout(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
2552 return 0;
2553 }
2554
2555 LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
2556 {
2557 if(m_wndClient.m_hWnd != NULL)
2558 m_wndClient.SetFocus();
2559 return 0;
2560 }
2561
2562 LRESULT OnGetFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
2563 {
2564 return (LRESULT)m_hFont;
2565 }
2566
2567 LRESULT OnSetFont(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
2568 {
2569 if(m_bInternalFont)
2570 {
2571 ::DeleteObject(m_hFont);
2572 m_bInternalFont = false;
2573 }
2574
2575 m_hFont = (HFONT)wParam;
2576
2577 T* pT = static_cast<T*>(this);
2578 pT->CalcSize();
2579
2580 if((BOOL)lParam != FALSE)
2581 pT->UpdateLayout();
2582
2583 return 0;
2584 }
2585
2586 LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
2587 {
2588 T* pT = static_cast<T*>(this);
2589 pT->DrawPaneTitleBackground((HDC)wParam);
2590
2591 return 1;
2592 }
2593
2594 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
2595 {
2596 T* pT = static_cast<T*>(this);
2597 if(wParam != NULL)
2598 {
2599 pT->DrawPaneTitle((HDC)wParam);
2600
2601 if(m_wndClient.m_hWnd == NULL) // no client window
2602 pT->DrawPane((HDC)wParam);
2603 }
2604 else
2605 {
2606 CPaintDC dc(m_hWnd);
2607 pT->DrawPaneTitle(dc.m_hDC);
2608
2609 if(m_wndClient.m_hWnd == NULL) // no client window
2610 pT->DrawPane(dc.m_hDC);
2611 }
2612
2613 return 0;
2614 }
2615
2616 LRESULT OnNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
2617 {
2618 if(m_tb.m_hWnd == NULL)
2619 {
2620 bHandled = FALSE;
2621 return 1;
2622 }
2623
2624 T* pT = static_cast<T*>(this);
2625 pT;
2626 LPNMHDR lpnmh = (LPNMHDR)lParam;
2627 LRESULT lRet = 0;
2628
2629 // pass toolbar custom draw notifications to the base class
2630 if(lpnmh->code == NM_CUSTOMDRAW && lpnmh->hwndFrom == m_tb.m_hWnd)
2631 lRet = CCustomDraw< T >::OnCustomDraw(0, lpnmh, bHandled);
2632 #ifndef _WIN32_WCE
2633 // tooltip notifications come with the tooltip window handle and button ID,
2634 // pass them to the parent if we don't handle them
2635 else if(lpnmh->code == TTN_GETDISPINFO && lpnmh->idFrom == pT->m_nCloseBtnID)
2636 bHandled = pT->GetToolTipText(lpnmh);
2637 #endif // !_WIN32_WCE
2638 // only let notifications not from the toolbar go to the parent
2639 else if(lpnmh->hwndFrom != m_tb.m_hWnd && lpnmh->idFrom != pT->m_nCloseBtnID)
2640 bHandled = FALSE;
2641
2642 return lRet;
2643 }
2644
2645 LRESULT OnCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2646 {
2647 // if command comes from the close button, substitute HWND of the pane container instead
2648 if(m_tb.m_hWnd != NULL && (HWND)lParam == m_tb.m_hWnd)
2649 return ::SendMessage(GetParent(), WM_COMMAND, wParam, (LPARAM)m_hWnd);
2650
2651 bHandled = FALSE;
2652 return 1;
2653 }
2654
2655 // Custom draw overrides
2656 DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
2657 {
2658 return CDRF_NOTIFYITEMDRAW; // we need per-item notifications
2659 }
2660
2661 DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
2662 {
2663 return CDRF_NOTIFYPOSTPAINT;
2664 }
2665
2666 DWORD OnItemPostPaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw)
2667 {
2668 CDCHandle dc = lpNMCustomDraw->hdc;
2669 #if (_WIN32_IE >= 0x0400)
2670 RECT& rc = lpNMCustomDraw->rc;
2671 #else // !(_WIN32_IE >= 0x0400)
2672 RECT rc = { 0 };
2673 m_tb.GetItemRect(0, &rc);
2674 #endif // !(_WIN32_IE >= 0x0400)
2675
2676 RECT rcImage = { m_xBtnImageLeft, m_yBtnImageTop, m_xBtnImageRight + 1, m_yBtnImageBottom + 1 };
2677 ::OffsetRect(&rcImage, rc.left, rc.top);
2678 T* pT = static_cast<T*>(this);
2679
2680 if((lpNMCustomDraw->uItemState & CDIS_DISABLED) != 0)
2681 {
2682 RECT rcShadow = rcImage;
2683 ::OffsetRect(&rcShadow, 1, 1);
2684 CPen pen1;
2685 pen1.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DHILIGHT));
2686 pT->DrawButtonImage(dc, rcShadow, pen1);
2687 CPen pen2;
2688 pen2.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DSHADOW));
2689 pT->DrawButtonImage(dc, rcImage, pen2);
2690 }
2691 else
2692 {
2693 if((lpNMCustomDraw->uItemState & CDIS_SELECTED) != 0)
2694 ::OffsetRect(&rcImage, 1, 1);
2695 CPen pen;
2696 pen.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNTEXT));
2697 pT->DrawButtonImage(dc, rcImage, pen);
2698 }
2699
2700 return CDRF_DODEFAULT; // continue with the default item painting
2701 }
2702
2703 // Implementation - overrideable methods
2704 void Init()
2705 {
2706 if(m_hFont == NULL)
2707 {
2708 // The same as AtlCreateControlFont() for horizontal pane
2709 #ifndef _WIN32_WCE
2710 LOGFONT lf = { 0 };
2711 ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE);
2712 if(IsVertical())
2713 lf.lfEscapement = 900; // 90 degrees
2714 m_hFont = ::CreateFontIndirect(&lf);
2715 #else // CE specific
2716 m_hFont = (HFONT)::GetStockObject(SYSTEM_FONT);
2717 if(IsVertical())
2718 {
2719 CLogFont lf(m_hFont);
2720 lf.lfEscapement = 900; // 90 degrees
2721 m_hFont = ::CreateFontIndirect(&lf);
2722 }
2723 #endif // _WIN32_WCE
2724 m_bInternalFont = true;
2725 }
2726
2727 T* pT = static_cast<T*>(this);
2728 pT->CalcSize();
2729
2730 if((m_dwExtendedStyle & PANECNT_NOCLOSEBUTTON) == 0)
2731 pT->CreateCloseButton();
2732 }
2733
2734 void UpdateLayout(int cxWidth, int cyHeight)
2735 {
2736 ATLASSERT(::IsWindow(m_hWnd));
2737 RECT rect = { 0 };
2738
2739 if(IsVertical())
2740 {
2741 ::SetRect(&rect, 0, 0, m_cxyHeader, cyHeight);
2742 if(m_tb.m_hWnd != NULL)
2743 m_tb.SetWindowPos(NULL, m_cxyBorder, m_cxyBorder + m_cxyBtnOffset, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
2744
2745 if(m_wndClient.m_hWnd != NULL)
2746 m_wndClient.SetWindowPos(NULL, m_cxyHeader, 0, cxWidth - m_cxyHeader, cyHeight, SWP_NOZORDER);
2747 else
2748 rect.right = cxWidth;
2749 }
2750 else
2751 {
2752 ::SetRect(&rect, 0, 0, cxWidth, m_cxyHeader);
2753 if(m_tb.m_hWnd != NULL)
2754 m_tb.SetWindowPos(NULL, rect.right - m_cxToolBar, m_cxyBorder + m_cxyBtnOffset, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
2755
2756 if(m_wndClient.m_hWnd != NULL)
2757 m_wndClient.SetWindowPos(NULL, 0, m_cxyHeader, cxWidth, cyHeight - m_cxyHeader, SWP_NOZORDER);
2758 else
2759 rect.bottom = cyHeight;
2760 }
2761
2762 InvalidateRect(&rect);
2763 }
2764
2765 void CreateCloseButton()
2766 {
2767 ATLASSERT(m_tb.m_hWnd == NULL);
2768 // create toolbar for the "x" button
2769 m_tb.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NORESIZE | CCS_NOPARENTALIGN | CCS_NOMOVEY | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT, 0);
2770 ATLASSERT(m_tb.IsWindow());
2771
2772 if(m_tb.m_hWnd != NULL)
2773 {
2774 T* pT = static_cast<T*>(this);
2775 pT; // avoid level 4 warning
2776
2777 m_tb.SetButtonStructSize();
2778
2779 TBBUTTON tbbtn = { 0 };
2780 tbbtn.idCommand = pT->m_nCloseBtnID;
2781 tbbtn.fsState = TBSTATE_ENABLED;
2782 tbbtn.fsStyle = BTNS_BUTTON;
2783 m_tb.AddButtons(1, &tbbtn);
2784
2785 m_tb.SetBitmapSize(m_cxImageTB, m_cyImageTB);
2786 m_tb.SetButtonSize(m_cxImageTB + m_cxyBtnAddTB, m_cyImageTB + m_cxyBtnAddTB);
2787
2788 if(IsVertical())
2789 m_tb.SetWindowPos(NULL, m_cxyBorder + m_cxyBtnOffset, m_cxyBorder + m_cxyBtnOffset, m_cxImageTB + m_cxyBtnAddTB, m_cyImageTB + m_cxyBtnAddTB + 1, SWP_NOZORDER | SWP_NOACTIVATE);
2790 else
2791 m_tb.SetWindowPos(NULL, 0, 0, m_cxImageTB + m_cxyBtnAddTB, m_cyImageTB + m_cxyBtnAddTB + 1, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
2792 }
2793 }
2794
2795 void DestroyCloseButton()
2796 {
2797 if(m_tb.m_hWnd != NULL)
2798 m_tb.DestroyWindow();
2799 }
2800
2801 void CalcSize()
2802 {
2803 T* pT = static_cast<T*>(this);
2804 CFontHandle font = pT->GetTitleFont();
2805 if(font.IsNull())
2806 font = (HFONT)::GetStockObject(SYSTEM_FONT);
2807 LOGFONT lf = { 0 };
2808 font.GetLogFont(lf);
2809 if(IsVertical())
2810 {
2811 m_cxyHeader = m_cxImageTB + m_cxyBtnAddTB + m_cxyBorder + 1;
2812 }
2813 else
2814 {
2815 int cyFont = abs(lf.lfHeight) + m_cxyBorder + 2 * m_cxyTextOffset;
2816 int cyBtn = m_cyImageTB + m_cxyBtnAddTB + m_cxyBorder + 2 * m_cxyBtnOffset + 1;
2817 m_cxyHeader = __max(cyFont, cyBtn);
2818 }
2819 }
2820
2821 HFONT GetTitleFont() const
2822 {
2823 return m_hFont;
2824 }
2825
2826 #ifndef _WIN32_WCE
2827 BOOL GetToolTipText(LPNMHDR /*lpnmh*/)
2828 {
2829 return FALSE;
2830 }
2831 #endif // !_WIN32_WCE
2832
2833 void DrawPaneTitle(CDCHandle dc)
2834 {
2835 RECT rect = { 0 };
2836 GetClientRect(&rect);
2837
2838 UINT uBorder = BF_LEFT | BF_TOP | BF_ADJUST;
2839 if(IsVertical())
2840 {
2841 rect.right = rect.left + m_cxyHeader;
2842 uBorder |= BF_BOTTOM;
2843 }
2844 else
2845 {
2846 rect.bottom = rect.top + m_cxyHeader;
2847 uBorder |= BF_RIGHT;
2848 }
2849
2850 if((m_dwExtendedStyle & PANECNT_NOBORDER) == 0)
2851 {
2852 if((m_dwExtendedStyle & PANECNT_FLATBORDER) != 0)
2853 uBorder |= BF_FLAT;
2854 dc.DrawEdge(&rect, EDGE_ETCHED, uBorder);
2855 }
2856
2857 if((m_dwExtendedStyle & PANECNT_DIVIDER) != 0)
2858 {
2859 uBorder = BF_FLAT | BF_ADJUST | (IsVertical() ? BF_RIGHT : BF_BOTTOM);
2860 dc.DrawEdge(&rect, BDR_SUNKENOUTER, uBorder);
2861 }
2862
2863 // draw title text
2864 dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
2865 dc.SetBkMode(TRANSPARENT);
2866 T* pT = static_cast<T*>(this);
2867 HFONT hFontOld = dc.SelectFont(pT->GetTitleFont());
2868 #if defined(_WIN32_WCE) && !defined(DT_END_ELLIPSIS)
2869 const UINT DT_END_ELLIPSIS = 0;
2870 #endif // defined(_WIN32_WCE) && !defined(DT_END_ELLIPSIS)
2871
2872 if(IsVertical())
2873 {
2874 rect.top += m_cxyTextOffset;
2875 rect.bottom -= m_cxyTextOffset;
2876 if(m_tb.m_hWnd != NULL)
2877 rect.top += m_cxToolBar;;
2878
2879 RECT rcCalc = { rect.left, rect.bottom, rect.right, rect.top };
2880 int cxFont = dc.DrawText(m_szTitle, -1, &rcCalc, DT_TOP | DT_SINGLELINE | DT_END_ELLIPSIS | DT_CALCRECT);
2881 RECT rcText = { 0 };
2882 rcText.left = (rect.right - rect.left - cxFont) / 2;
2883 rcText.right = rcText.left + (rect.bottom - rect.top);
2884 rcText.top = rect.bottom;
2885 rcText.bottom = rect.top;
2886 dc.DrawText(m_szTitle, -1, &rcText, DT_TOP | DT_SINGLELINE | DT_END_ELLIPSIS);
2887 }
2888 else
2889 {
2890 rect.left += m_cxyTextOffset;
2891 rect.right -= m_cxyTextOffset;
2892 if(m_tb.m_hWnd != NULL)
2893 rect.right -= m_cxToolBar;;
2894
2895 dc.DrawText(m_szTitle, -1, &rect, DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS);
2896 }
2897
2898 dc.SelectFont(hFontOld);
2899 }
2900
2901 void DrawPaneTitleBackground(CDCHandle dc)
2902 {
2903 RECT rect = { 0 };
2904 GetClientRect(&rect);
2905 if(IsVertical())
2906 rect.right = m_cxyHeader;
2907 else
2908 rect.bottom = m_cxyHeader;
2909
2910 #if (!defined(_WIN32_WCE) && !defined(_ATL_NO_MSIMG)) || (_WIN32_WCE >= 420)
2911 if((m_dwExtendedStyle & PANECNT_GRADIENT) != 0)
2912 dc.GradientFillRect(rect, ::GetSysColor(COLOR_WINDOW), ::GetSysColor(COLOR_3DFACE), IsVertical());
2913 else
2914 #endif // (!defined(_WIN32_WCE) && !defined(_ATL_NO_MSIMG)) || (_WIN32_WCE >= 420)
2915 dc.FillRect(&rect, COLOR_3DFACE);
2916 }
2917
2918 // called only if pane is empty
2919 void DrawPane(CDCHandle dc)
2920 {
2921 RECT rect = { 0 };
2922 GetClientRect(&rect);
2923 if(IsVertical())
2924 rect.left += m_cxyHeader;
2925 else
2926 rect.top += m_cxyHeader;
2927 if((GetExStyle() & WS_EX_CLIENTEDGE) == 0)
2928 dc.DrawEdge(&rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
2929 dc.FillRect(&rect, COLOR_APPWORKSPACE);
2930 }
2931
2932 // drawing helper - draws "x" button image
2933 void DrawButtonImage(CDCHandle dc, RECT& rcImage, HPEN hPen)
2934 {
2935 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
2936 HPEN hPenOld = dc.SelectPen(hPen);
2937
2938 dc.MoveTo(rcImage.left, rcImage.top);
2939 dc.LineTo(rcImage.right, rcImage.bottom);
2940 dc.MoveTo(rcImage.left + 1, rcImage.top);
2941 dc.LineTo(rcImage.right + 1, rcImage.bottom);
2942
2943 dc.MoveTo(rcImage.left, rcImage.bottom - 1);
2944 dc.LineTo(rcImage.right, rcImage.top - 1);
2945 dc.MoveTo(rcImage.left + 1, rcImage.bottom - 1);
2946 dc.LineTo(rcImage.right + 1, rcImage.top - 1);
2947
2948 dc.SelectPen(hPenOld);
2949 #else // (_WIN32_WCE < 400)
2950 rcImage;
2951 hPen;
2952 // no support for the "x" button image
2953 #endif // (_WIN32_WCE < 400)
2954 }
2955
2956 bool IsVertical() const
2957 {
2958 return ((m_dwExtendedStyle & PANECNT_VERTICAL) != 0);
2959 }
2960 };
2961
2962 class CPaneContainer : public CPaneContainerImpl<CPaneContainer>
2963 {
2964 public:
2965 DECLARE_WND_CLASS_EX(_T("WTL_PaneContainer"), 0, -1)
2966 };
2967
2968
2969 ///////////////////////////////////////////////////////////////////////////////
2970 // CSortListViewCtrl - implements sorting for a listview control
2971
2972 // sort listview extended styles
2973 #define SORTLV_USESHELLBITMAPS 0x00000001
2974
2975 // Notification sent to parent when sort column is changed by user clicking header.
2976 #define SLVN_SORTCHANGED LVN_LAST
2977
2978 // A LPNMSORTLISTVIEW is sent with the SLVN_SORTCHANGED notification
2979 typedef struct tagNMSORTLISTVIEW
2980 {
2981 NMHDR hdr;
2982 int iNewSortColumn;
2983 int iOldSortColumn;
2984 } NMSORTLISTVIEW, *LPNMSORTLISTVIEW;
2985
2986 // Column sort types. Can be set on a per-column basis with the SetColumnSortType method.
2987 enum
2988 {
2989 LVCOLSORT_NONE,
2990 LVCOLSORT_TEXT, // default
2991 LVCOLSORT_TEXTNOCASE,
2992 LVCOLSORT_LONG,
2993 LVCOLSORT_DOUBLE,
2994 LVCOLSORT_DECIMAL,
2995 LVCOLSORT_DATETIME,
2996 LVCOLSORT_DATE,
2997 LVCOLSORT_TIME,
2998 LVCOLSORT_CUSTOM,
2999 LVCOLSORT_LAST = LVCOLSORT_CUSTOM
3000 };
3001
3002
3003 template <class T>
3004 class CSortListViewImpl
3005 {
3006 public:
3007 enum
3008 {
3009 m_cchCmpTextMax = 32, // overrideable
3010 m_cxSortImage = 16,
3011 m_cySortImage = 15,
3012 m_cxSortArrow = 11,
3013 m_cySortArrow = 6,
3014 m_iSortUp = 0, // index of sort bitmaps
3015 m_iSortDown = 1,
3016 m_nShellSortUpID = 133
3017 };
3018
3019 // passed to LVCompare functions as lParam1 and lParam2
3020 struct LVCompareParam
3021 {
3022 int iItem;
3023 DWORD_PTR dwItemData;
3024 union
3025 {
3026 long lValue;
3027 double dblValue;
3028 DECIMAL decValue;
3029 LPCTSTR pszValue;
3030 };
3031 };
3032
3033 // passed to LVCompare functions as the lParamSort parameter
3034 struct LVSortInfo
3035 {
3036 T* pT;
3037 int iSortCol;
3038 bool bDescending;
3039 };
3040
3041 bool m_bSortDescending;
3042 bool m_bCommCtrl6;
3043 int m_iSortColumn;
3044 CBitmap m_bmSort[2];
3045 int m_fmtOldSortCol;
3046 HBITMAP m_hbmOldSortCol;
3047 DWORD m_dwSortLVExtendedStyle;
3048 ATL::CSimpleArray<WORD> m_arrColSortType;
3049 bool m_bUseWaitCursor;
3050
3051 CSortListViewImpl() :
3052 m_bSortDescending(false),
3053 m_bCommCtrl6(false),
3054 m_iSortColumn(-1),
3055 m_fmtOldSortCol(0),
3056 m_hbmOldSortCol(NULL),
3057 m_dwSortLVExtendedStyle(SORTLV_USESHELLBITMAPS),
3058 m_bUseWaitCursor(true)
3059 {
3060 #ifndef _WIN32_WCE
3061 DWORD dwMajor = 0;
3062 DWORD dwMinor = 0;
3063 HRESULT hRet = ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor);
3064 m_bCommCtrl6 = SUCCEEDED(hRet) && dwMajor >= 6;
3065 #endif // !_WIN32_WCE
3066 }
3067
3068 // Attributes
3069 void SetSortColumn(int iCol)
3070 {
3071 T* pT = static_cast<T*>(this);
3072 ATLASSERT(::IsWindow(pT->m_hWnd));
3073 CHeaderCtrl header = pT->GetHeader();
3074 ATLASSERT(header.m_hWnd != NULL);
3075 ATLASSERT(iCol >= -1 && iCol < m_arrColSortType.GetSize());
3076
3077 int iOldSortCol = m_iSortColumn;
3078 m_iSortColumn = iCol;
3079 if(m_bCommCtrl6)
3080 {
3081 #ifndef HDF_SORTUP
3082 const int HDF_SORTUP = 0x0400;
3083 #endif // HDF_SORTUP
3084 #ifndef HDF_SORTDOWN
3085 const int HDF_SORTDOWN = 0x0200;
3086 #endif // HDF_SORTDOWN
3087 const int nMask = HDF_SORTUP | HDF_SORTDOWN;
3088 HDITEM hditem = { HDI_FORMAT };
3089 if(iOldSortCol != iCol && iOldSortCol >= 0 && header.GetItem(iOldSortCol, &hditem))
3090 {
3091 hditem.fmt &= ~nMask;
3092 header.SetItem(iOldSortCol, &hditem);
3093 }
3094 if(iCol >= 0 && header.GetItem(iCol, &hditem))
3095 {
3096 hditem.fmt &= ~nMask;
3097 hditem.fmt |= m_bSortDescending ? HDF_SORTDOWN : HDF_SORTUP;
3098 header.SetItem(iCol, &hditem);
3099 }
3100 return;
3101 }
3102
3103 if(m_bmSort[m_iSortUp].IsNull())
3104 pT->CreateSortBitmaps();
3105
3106 // restore previous sort column's bitmap, if any, and format
3107 HDITEM hditem = { HDI_BITMAP | HDI_FORMAT };
3108 if(iOldSortCol != iCol && iOldSortCol >= 0)
3109 {
3110 hditem.hbm = m_hbmOldSortCol;
3111 hditem.fmt = m_fmtOldSortCol;
3112 header.SetItem(iOldSortCol, &hditem);
3113 }
3114
3115 // save new sort column's bitmap and format, and add our sort bitmap
3116 if(iCol >= 0 && header.GetItem(iCol, &hditem))
3117 {
3118 if(iOldSortCol != iCol)
3119 {
3120 m_fmtOldSortCol = hditem.fmt;
3121 m_hbmOldSortCol = hditem.hbm;
3122 }
3123 hditem.fmt &= ~HDF_IMAGE;
3124 hditem.fmt |= HDF_BITMAP | HDF_BITMAP_ON_RIGHT;
3125 int i = m_bSortDescending ? m_iSortDown : m_iSortUp;
3126 hditem.hbm = m_bmSort[i];
3127 header.SetItem(iCol, &hditem);
3128 }
3129 }
3130
3131 int GetSortColumn() const
3132 {
3133 return m_iSortColumn;
3134 }
3135
3136 void SetColumnSortType(int iCol, WORD wType)
3137 {
3138 ATLASSERT(iCol >= 0 && iCol < m_arrColSortType.GetSize());
3139 ATLASSERT(wType >= LVCOLSORT_NONE && wType <= LVCOLSORT_LAST);
3140 m_arrColSortType[iCol] = wType;
3141 }
3142
3143 WORD GetColumnSortType(int iCol) const
3144 {
3145 ATLASSERT((iCol >= 0) && iCol < m_arrColSortType.GetSize());
3146 return m_arrColSortType[iCol];
3147 }
3148
3149 int GetColumnCount() const
3150 {
3151 const T* pT = static_cast<const T*>(this);
3152 ATLASSERT(::IsWindow(pT->m_hWnd));
3153 CHeaderCtrl header = pT->GetHeader();
3154 return header.m_hWnd != NULL ? header.GetItemCount() : 0;
3155 }
3156
3157 bool IsSortDescending() const
3158 {
3159 return m_bSortDescending;
3160 }
3161
3162 DWORD GetSortListViewExtendedStyle() const
3163 {
3164 return m_dwSortLVExtendedStyle;
3165 }
3166
3167 DWORD SetSortListViewExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
3168 {
3169 DWORD dwPrevStyle = m_dwSortLVExtendedStyle;
3170 if(dwMask == 0)
3171 m_dwSortLVExtendedStyle = dwExtendedStyle;
3172 else
3173 m_dwSortLVExtendedStyle = (m_dwSortLVExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
3174 return dwPrevStyle;
3175 }
3176
3177 // Operations
3178 bool DoSortItems(int iCol, bool bDescending = false)
3179 {
3180 T* pT = static_cast<T*>(this);
3181 ATLASSERT(::IsWindow(pT->m_hWnd));
3182 ATLASSERT(iCol >= 0 && iCol < m_arrColSortType.GetSize());
3183
3184 WORD wType = m_arrColSortType[iCol];
3185 if(wType == LVCOLSORT_NONE)
3186 return false;
3187
3188 int nCount = pT->GetItemCount();
3189 if(nCount < 2)
3190 {
3191 m_bSortDescending = bDescending;
3192 SetSortColumn(iCol);
3193 return true;
3194 }
3195
3196 CWaitCursor waitCursor(false);
3197 if(m_bUseWaitCursor)
3198 waitCursor.Set();
3199
3200 LVCompareParam* pParam = NULL;
3201 ATLTRY(pParam = new LVCompareParam[nCount]);
3202 PFNLVCOMPARE pFunc = NULL;
3203 TCHAR pszTemp[pT->m_cchCmpTextMax] = { 0 };
3204 bool bStrValue = false;
3205
3206 switch(wType)
3207 {
3208 case LVCOLSORT_TEXT:
3209 pFunc = (PFNLVCOMPARE)pT->LVCompareText;
3210 case LVCOLSORT_TEXTNOCASE:
3211 if(pFunc == NULL)
3212 pFunc = (PFNLVCOMPARE)pT->LVCompareTextNoCase;
3213 case LVCOLSORT_CUSTOM:
3214 {
3215 if(pFunc == NULL)
3216 pFunc = (PFNLVCOMPARE)pT->LVCompareCustom;
3217
3218 for(int i = 0; i < nCount; i++)
3219 {
3220 pParam[i].iItem = i;
3221 pParam[i].dwItemData = pT->GetItemData(i);
3222 pParam[i].pszValue = new TCHAR[pT->m_cchCmpTextMax];
3223 pT->GetItemText(i, iCol, (LPTSTR)pParam[i].pszValue, pT->m_cchCmpTextMax);
3224 pT->SetItemData(i, (DWORD_PTR)&pParam[i]);
3225 }
3226 bStrValue = true;
3227 }
3228 break;
3229 case LVCOLSORT_LONG:
3230 {
3231 pFunc = (PFNLVCOMPARE)pT->LVCompareLong;
3232 for(int i = 0; i < nCount; i++)
3233 {
3234 pParam[i].iItem = i;
3235 pParam[i].dwItemData = pT->GetItemData(i);
3236 pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax);
3237 pParam[i].lValue = pT->StrToLong(pszTemp);
3238 pT->SetItemData(i, (DWORD_PTR)&pParam[i]);
3239 }
3240 }
3241 break;
3242 case LVCOLSORT_DOUBLE:
3243 {
3244 pFunc = (PFNLVCOMPARE)pT->LVCompareDouble;
3245 for(int i = 0; i < nCount; i++)
3246 {
3247 pParam[i].iItem = i;
3248 pParam[i].dwItemData = pT->GetItemData(i);
3249 pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax);
3250 pParam[i].dblValue = pT->StrToDouble(pszTemp);
3251 pT->SetItemData(i, (DWORD_PTR)&pParam[i]);
3252 }
3253 }
3254 break;
3255 case LVCOLSORT_DECIMAL:
3256 {
3257 pFunc = (PFNLVCOMPARE)pT->LVCompareDecimal;
3258 for(int i = 0; i < nCount; i++)
3259 {
3260 pParam[i].iItem = i;
3261 pParam[i].dwItemData = pT->GetItemData(i);
3262 pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax);
3263 pT->StrToDecimal(pszTemp, &pParam[i].decValue);
3264 pT->SetItemData(i, (DWORD_PTR)&pParam[i]);
3265 }
3266 }
3267 break;
3268 case LVCOLSORT_DATETIME:
3269 case LVCOLSORT_DATE:
3270 case LVCOLSORT_TIME:
3271 {
3272 pFunc = (PFNLVCOMPARE)pT->LVCompareDouble;
3273 DWORD dwFlags = LOCALE_NOUSEROVERRIDE;
3274 if(wType == LVCOLSORT_DATE)
3275 dwFlags |= VAR_DATEVALUEONLY;
3276 else if(wType == LVCOLSORT_TIME)
3277 dwFlags |= VAR_TIMEVALUEONLY;
3278 for(int i = 0; i < nCount; i++)
3279 {
3280 pParam[i].iItem = i;
3281 pParam[i].dwItemData = pT->GetItemData(i);
3282 pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax);
3283 pParam[i].dblValue = pT->DateStrToDouble(pszTemp, dwFlags);
3284 pT->SetItemData(i, (DWORD_PTR)&pParam[i]);
3285 }
3286 }
3287 break;
3288 default:
3289 ATLTRACE2(atlTraceUI, 0, _T("Unknown value for sort type in CSortListViewImpl::DoSortItems()\n"));
3290 break;
3291 } // switch(wType)
3292
3293 ATLASSERT(pFunc != NULL);
3294 LVSortInfo lvsi = { pT, iCol, bDescending };
3295 bool bRet = ((BOOL)pT->DefWindowProc(LVM_SORTITEMS, (WPARAM)&lvsi, (LPARAM)pFunc) != FALSE);
3296 for(int i = 0; i < nCount; i++)
3297 {
3298 DWORD_PTR dwItemData = pT->GetItemData(i);
3299 LVCompareParam* p = (LVCompareParam*)dwItemData;
3300 ATLASSERT(p != NULL);
3301 if(bStrValue)
3302 delete [] (TCHAR*)p->pszValue;
3303 pT->SetItemData(i, p->dwItemData);
3304 }
3305 delete [] pParam;
3306
3307 if(bRet)
3308 {
3309 m_bSortDescending = bDescending;
3310 SetSortColumn(iCol);
3311 }
3312
3313 if(m_bUseWaitCursor)
3314 waitCursor.Restore();
3315
3316 return bRet;
3317 }
3318
3319 void CreateSortBitmaps()
3320 {
3321 if((m_dwSortLVExtendedStyle & SORTLV_USESHELLBITMAPS) != 0)
3322 {
3323 bool bFree = false;
3324 LPCTSTR pszModule = _T("shell32.dll");
3325 HINSTANCE hShell = ::GetModuleHandle(pszModule);
3326
3327 if (hShell == NULL)
3328 {
3329 hShell = ::LoadLibrary(pszModule);
3330 bFree = true;
3331 }
3332
3333 if (hShell != NULL)
3334 {
3335 bool bSuccess = true;
3336 for(int i = m_iSortUp; i <= m_iSortDown; i++)
3337 {
3338 if(!m_bmSort[i].IsNull())
3339 m_bmSort[i].DeleteObject();
3340 m_bmSort[i] = (HBITMAP)::LoadImage(hShell, MAKEINTRESOURCE(m_nShellSortUpID + i),
3341 #ifndef _WIN32_WCE
3342 IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS);
3343 #else // CE specific
3344 IMAGE_BITMAP, 0, 0, 0);
3345 #endif // _WIN32_WCE
3346 if(m_bmSort[i].IsNull())
3347 {
3348 bSuccess = false;
3349 break;
3350 }
3351 }
3352 if(bFree)
3353 ::FreeLibrary(hShell);
3354 if(bSuccess)
3355 return;
3356 }
3357 }
3358
3359 T* pT = static_cast<T*>(this);
3360 for(int i = m_iSortUp; i <= m_iSortDown; i++)
3361 {
3362 if(!m_bmSort[i].IsNull())
3363 m_bmSort[i].DeleteObject();
3364
3365 CDC dcMem;
3366 CClientDC dc(::GetDesktopWindow());
3367 dcMem.CreateCompatibleDC(dc.m_hDC);
3368 m_bmSort[i].CreateCompatibleBitmap(dc.m_hDC, m_cxSortImage, m_cySortImage);
3369 HBITMAP hbmOld = dcMem.SelectBitmap(m_bmSort[i]);
3370 RECT rc = { 0, 0, m_cxSortImage, m_cySortImage };
3371 pT->DrawSortBitmap(dcMem.m_hDC, i, &rc);
3372 dcMem.SelectBitmap(hbmOld);
3373 dcMem.DeleteDC();
3374 }
3375 }
3376
3377 void NotifyParentSortChanged(int iNewSortCol, int iOldSortCol)
3378 {
3379 T* pT = static_cast<T*>(this);
3380 int nID = pT->GetDlgCtrlID();
3381 NMSORTLISTVIEW nm = { { pT->m_hWnd, (UINT_PTR)nID, SLVN_SORTCHANGED }, iNewSortCol, iOldSortCol };
3382 ::SendMessage(pT->GetParent(), WM_NOTIFY, (WPARAM)nID, (LPARAM)&nm);
3383 }
3384
3385 // Overrideables
3386 int CompareItemsCustom(LVCompareParam* /*pItem1*/, LVCompareParam* /*pItem2*/, int /*iSortCol*/)
3387 {
3388 // pItem1 and pItem2 contain valid iItem, dwItemData, and pszValue members.
3389 // If item1 > item2 return 1, if item1 < item2 return -1, else return 0.
3390 return 0;
3391 }
3392
3393 void DrawSortBitmap(CDCHandle dc, int iBitmap, LPRECT prc)
3394 {
3395 dc.FillRect(prc, ::GetSysColorBrush(COLOR_BTNFACE));
3396 HBRUSH hbrOld = dc.SelectBrush(::GetSysColorBrush(COLOR_BTNSHADOW));
3397 CPen pen;
3398 pen.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNSHADOW));
3399 HPEN hpenOld = dc.SelectPen(pen);
3400 POINT ptOrg = { (m_cxSortImage - m_cxSortArrow) / 2, (m_cySortImage - m_cySortArrow) / 2 };
3401 if(iBitmap == m_iSortUp)
3402 {
3403 POINT pts[3] =
3404 {
3405 { ptOrg.x + m_cxSortArrow / 2, ptOrg.y },
3406 { ptOrg.x, ptOrg.y + m_cySortArrow - 1 },
3407 { ptOrg.x + m_cxSortArrow - 1, ptOrg.y + m_cySortArrow - 1 }
3408 };
3409 dc.Polygon(pts, 3);
3410 }
3411 else
3412 {
3413 POINT pts[3] =
3414 {
3415 { ptOrg.x, ptOrg.y },
3416 { ptOrg.x + m_cxSortArrow / 2, ptOrg.y + m_cySortArrow - 1 },
3417 { ptOrg.x + m_cxSortArrow - 1, ptOrg.y }
3418 };
3419 dc.Polygon(pts, 3);
3420 }
3421 dc.SelectBrush(hbrOld);
3422 dc.SelectPen(hpenOld);
3423 }
3424
3425 double DateStrToDouble(LPCTSTR lpstr, DWORD dwFlags)
3426 {
3427 ATLASSERT(lpstr != NULL);
3428 if(lpstr == NULL || lpstr[0] == _T('\0'))
3429 return 0;
3430
3431 USES_CONVERSION;
3432 HRESULT hRet = E_FAIL;
3433 DATE dRet = 0;
3434 if (FAILED(hRet = ::VarDateFromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, dwFlags, &dRet)))
3435 {
3436 ATLTRACE2(atlTraceUI, 0, _T("VarDateFromStr failed with result of 0x%8.8X\n"), hRet);
3437 dRet = 0;
3438 }
3439 return dRet;
3440 }
3441
3442 long StrToLong(LPCTSTR lpstr)
3443 {
3444 ATLASSERT(lpstr != NULL);
3445 if(lpstr == NULL || lpstr[0] == _T('\0'))
3446 return 0;
3447
3448 USES_CONVERSION;
3449 HRESULT hRet = E_FAIL;
3450 long lRet = 0;
3451 if (FAILED(hRet = ::VarI4FromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, &lRet)))
3452 {
3453 ATLTRACE2(atlTraceUI, 0, _T("VarI4FromStr failed with result of 0x%8.8X\n"), hRet);
3454 lRet = 0;
3455 }
3456 return lRet;
3457 }
3458
3459 double StrToDouble(LPCTSTR lpstr)
3460 {
3461 ATLASSERT(lpstr != NULL);
3462 if(lpstr == NULL || lpstr[0] == _T('\0'))
3463 return 0;
3464
3465 USES_CONVERSION;
3466 HRESULT hRet = E_FAIL;
3467 double dblRet = 0;
3468 if (FAILED(hRet = ::VarR8FromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, &dblRet)))
3469 {
3470 ATLTRACE2(atlTraceUI, 0, _T("VarR8FromStr failed with result of 0x%8.8X\n"), hRet);
3471 dblRet = 0;
3472 }
3473 return dblRet;
3474 }
3475
3476 bool StrToDecimal(LPCTSTR lpstr, DECIMAL* pDecimal)
3477 {
3478 ATLASSERT(lpstr != NULL);
3479 ATLASSERT(pDecimal != NULL);
3480 if(lpstr == NULL || pDecimal == NULL)
3481 return false;
3482
3483 USES_CONVERSION;
3484 HRESULT hRet = E_FAIL;
3485 if (FAILED(hRet = ::VarDecFromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, pDecimal)))
3486 {
3487 ATLTRACE2(atlTraceUI, 0, _T("VarDecFromStr failed with result of 0x%8.8X\n"), hRet);
3488 pDecimal->Lo64 = 0;
3489 pDecimal->Hi32 = 0;
3490 pDecimal->signscale = 0;
3491 return false;
3492 }
3493 return true;
3494 }
3495
3496 // Overrideable PFNLVCOMPARE functions
3497 static int CALLBACK LVCompareText(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
3498 {
3499 ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL);
3500
3501 LVCompareParam* pParam1 = (LVCompareParam*)lParam1;
3502 LVCompareParam* pParam2 = (LVCompareParam*)lParam2;
3503 LVSortInfo* pInfo = (LVSortInfo*)lParamSort;
3504
3505 int nRet = lstrcmp(pParam1->pszValue, pParam2->pszValue);
3506 return pInfo->bDescending ? -nRet : nRet;
3507 }
3508
3509 static int CALLBACK LVCompareTextNoCase(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
3510 {
3511 ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL);
3512
3513 LVCompareParam* pParam1 = (LVCompareParam*)lParam1;
3514 LVCompareParam* pParam2 = (LVCompareParam*)lParam2;
3515 LVSortInfo* pInfo = (LVSortInfo*)lParamSort;
3516
3517 int nRet = lstrcmpi(pParam1->pszValue, pParam2->pszValue);
3518 return pInfo->bDescending ? -nRet : nRet;
3519 }
3520
3521 static int CALLBACK LVCompareLong(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
3522 {
3523 ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL);
3524
3525 LVCompareParam* pParam1 = (LVCompareParam*)lParam1;
3526 LVCompareParam* pParam2 = (LVCompareParam*)lParam2;
3527 LVSortInfo* pInfo = (LVSortInfo*)lParamSort;
3528
3529 int nRet = 0;
3530 if(pParam1->lValue > pParam2->lValue)
3531 nRet = 1;
3532 else if(pParam1->lValue < pParam2->lValue)
3533 nRet = -1;
3534 return pInfo->bDescending ? -nRet : nRet;
3535 }
3536
3537 static int CALLBACK LVCompareDouble(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
3538 {
3539 ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL);
3540
3541 LVCompareParam* pParam1 = (LVCompareParam*)lParam1;
3542 LVCompareParam* pParam2 = (LVCompareParam*)lParam2;
3543 LVSortInfo* pInfo = (LVSortInfo*)lParamSort;
3544
3545 int nRet = 0;
3546 if(pParam1->dblValue > pParam2->dblValue)
3547 nRet = 1;
3548 else if(pParam1->dblValue < pParam2->dblValue)
3549 nRet = -1;
3550 return pInfo->bDescending ? -nRet : nRet;
3551 }
3552
3553 static int CALLBACK LVCompareCustom(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
3554 {
3555 ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL);
3556
3557 LVCompareParam* pParam1 = (LVCompareParam*)lParam1;
3558 LVCompareParam* pParam2 = (LVCompareParam*)lParam2;
3559 LVSortInfo* pInfo = (LVSortInfo*)lParamSort;
3560
3561 int nRet = pInfo->pT->CompareItemsCustom(pParam1, pParam2, pInfo->iSortCol);
3562 return pInfo->bDescending ? -nRet : nRet;
3563 }
3564
3565 #ifndef _WIN32_WCE
3566 static int CALLBACK LVCompareDecimal(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
3567 {
3568 ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL);
3569
3570 LVCompareParam* pParam1 = (LVCompareParam*)lParam1;
3571 LVCompareParam* pParam2 = (LVCompareParam*)lParam2;
3572 LVSortInfo* pInfo = (LVSortInfo*)lParamSort;
3573
3574 int nRet = (int)::VarDecCmp(&pParam1->decValue, &pParam2->decValue);
3575 nRet--;
3576 return pInfo->bDescending ? -nRet : nRet;
3577 }
3578 #else
3579 // Compare mantissas, ignore sign and scale
3580 static int CompareMantissas(const DECIMAL& decLeft, const DECIMAL& decRight)
3581 {
3582 if (decLeft.Hi32 < decRight.Hi32)
3583 {
3584 return -1;
3585 }
3586 if (decLeft.Hi32 > decRight.Hi32)
3587 {
3588 return 1;
3589 }
3590 // Here, decLeft.Hi32 == decRight.Hi32
3591 if (decLeft.Lo64 < decRight.Lo64)
3592 {
3593 return -1;
3594 }
3595 if (decLeft.Lo64 > decRight.Lo64)
3596 {
3597 return 1;
3598 }
3599 return 0;
3600 }
3601
3602 // return values: VARCMP_LT, VARCMP_EQ, VARCMP_GT, VARCMP_NULL
3603 static HRESULT VarDecCmp(const DECIMAL* pdecLeft, const DECIMAL* pdecRight)
3604 {
3605 static const ULONG powersOfTen[] =
3606 {
3607 10ul,
3608 100ul,
3609 1000ul,
3610 10000ul,
3611 100000ul,
3612 1000000ul,
3613 10000000ul,
3614 100000000ul,
3615 1000000000ul
3616 };
3617 static const int largestPower = sizeof(powersOfTen) / sizeof(powersOfTen[0]);
3618 if (!pdecLeft || !pdecRight)
3619 {
3620 return VARCMP_NULL;
3621 }
3622
3623 // Degenerate case - at least one comparand is of the form
3624 // [+-]0*10^N (denormalized zero)
3625 bool bLeftZero = (!pdecLeft->Lo64 && !pdecLeft->Hi32);
3626 bool bRightZero = (!pdecRight->Lo64 && !pdecRight->Hi32);
3627 if (bLeftZero && bRightZero)
3628 {
3629 return VARCMP_EQ;
3630 }
3631 bool bLeftNeg = ((pdecLeft->sign & DECIMAL_NEG) != 0);
3632 bool bRightNeg = ((pdecRight->sign & DECIMAL_NEG) != 0);
3633 if (bLeftZero)
3634 {
3635 return (bRightNeg ? VARCMP_GT : VARCMP_LT);
3636 }
3637 // This also covers the case where the comparands have different signs
3638 if (bRightZero || bLeftNeg != bRightNeg)
3639 {
3640 return (bLeftNeg ? VARCMP_LT : VARCMP_GT);
3641 }
3642
3643 // Here both comparands have the same sign and need to be compared
3644 // on mantissa and scale. The result is obvious when
3645 // 1. Scales are equal (then compare mantissas)
3646 // 2. A number with smaller scale is also the one with larger mantissa
3647 // (then this number is obviously larger)
3648 // In the remaining case, we would multiply the number with smaller
3649 // scale by 10 and simultaneously increment its scale (which amounts to
3650 // adding trailing zeros after decimal point), until the numbers fall under
3651 // one of the two cases above
3652 DECIMAL temp;
3653 bool bInvert = bLeftNeg; // the final result needs to be inverted
3654 if (pdecLeft->scale < pdecRight->scale)
3655 {
3656 temp = *pdecLeft;
3657 }
3658 else
3659 {
3660 temp = *pdecRight;
3661 pdecRight = pdecLeft;
3662 bInvert = !bInvert;
3663 }
3664
3665 // Now temp is the number with smaller (or equal) scale, and
3666 // we can modify it freely without touching original parameters
3667 int comp;
3668 while ((comp = CompareMantissas(temp, *pdecRight)) < 0 &&
3669 temp.scale < pdecRight->scale)
3670 {
3671 // Multiply by an appropriate power of 10
3672 int scaleDiff = pdecRight->scale - temp.scale;
3673 if (scaleDiff > largestPower)
3674 {
3675 // Keep the multiplier representable in 32bit
3676 scaleDiff = largestPower;
3677 }
3678 DWORDLONG power = powersOfTen[scaleDiff - 1];
3679 // Multiply temp's mantissa by power
3680 DWORDLONG product = temp.Lo32 * power;
3681 ULONG carry = static_cast<ULONG>(product >> 32);
3682 temp.Lo32 = static_cast<ULONG>(product);
3683 product = temp.Mid32 * power + carry;
3684 carry = static_cast<ULONG>(product >> 32);
3685 temp.Mid32 = static_cast<ULONG>(product);
3686 product = temp.Hi32 * power + carry;
3687 if (static_cast<ULONG>(product >> 32))
3688 {
3689 // Multiplication overflowed - pdecLeft is clearly larger
3690 break;
3691 }
3692 temp.Hi32 = static_cast<ULONG>(product);
3693 temp.scale = (BYTE)(temp.scale + scaleDiff);
3694 }
3695 if (temp.scale < pdecRight->scale)
3696 {
3697 comp = 1;
3698 }
3699 if (bInvert)
3700 {
3701 comp = -comp;
3702 }
3703 return (comp > 0 ? VARCMP_GT : comp < 0 ? VARCMP_LT : VARCMP_EQ);
3704 }
3705
3706 static int CALLBACK LVCompareDecimal(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
3707 {
3708 ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL);
3709
3710 LVCompareParam* pParam1 = (LVCompareParam*)lParam1;
3711 LVCompareParam* pParam2 = (LVCompareParam*)lParam2;
3712 LVSortInfo* pInfo = (LVSortInfo*)lParamSort;
3713
3714 int nRet = (int)VarDecCmp(&pParam1->decValue, &pParam2->decValue);
3715 nRet--;
3716 return pInfo->bDescending ? -nRet : nRet;
3717 }
3718 #endif // !_WIN32_WCE
3719
3720 BEGIN_MSG_MAP(CSortListViewImpl)
3721 MESSAGE_HANDLER(LVM_INSERTCOLUMN, OnInsertColumn)
3722 MESSAGE_HANDLER(LVM_DELETECOLUMN, OnDeleteColumn)
3723 NOTIFY_CODE_HANDLER(HDN_ITEMCLICKA, OnHeaderItemClick)
3724 NOTIFY_CODE_HANDLER(HDN_ITEMCLICKW, OnHeaderItemClick)
3725 MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
3726 END_MSG_MAP()
3727
3728 LRESULT OnInsertColumn(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
3729 {
3730 T* pT = static_cast<T*>(this);
3731 LRESULT lRet = pT->DefWindowProc(uMsg, wParam, lParam);
3732 if(lRet == -1)
3733 return -1;
3734
3735 WORD wType = 0;
3736 m_arrColSortType.Add(wType);
3737 int nCount = m_arrColSortType.GetSize();
3738 ATLASSERT(nCount == GetColumnCount());
3739
3740 for(int i = nCount - 1; i > lRet; i--)
3741 m_arrColSortType[i] = m_arrColSortType[i - 1];
3742 m_arrColSortType[(int)lRet] = LVCOLSORT_TEXT;
3743
3744 if(lRet <= m_iSortColumn)
3745 m_iSortColumn++;
3746
3747 return lRet;
3748 }
3749
3750 LRESULT OnDeleteColumn(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
3751 {
3752 T* pT = static_cast<T*>(this);
3753 LRESULT lRet = pT->DefWindowProc(uMsg, wParam, lParam);
3754 if(lRet == 0)
3755 return 0;
3756
3757 int iCol = (int)wParam;
3758 if(m_iSortColumn == iCol)
3759 m_iSortColumn = -1;
3760 else if(m_iSortColumn > iCol)
3761 m_iSortColumn--;
3762 m_arrColSortType.RemoveAt(iCol);
3763
3764 return lRet;
3765 }
3766
3767 LRESULT OnHeaderItemClick(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
3768 {
3769 LPNMHEADER p = (LPNMHEADER)pnmh;
3770 if(p->iButton == 0)
3771 {
3772 int iOld = m_iSortColumn;
3773 bool bDescending = (m_iSortColumn == p->iItem) ? !m_bSortDescending : false;
3774 if(DoSortItems(p->iItem, bDescending))
3775 NotifyParentSortChanged(p->iItem, iOld);
3776 }
3777 bHandled = FALSE;
3778 return 0;
3779 }
3780
3781 LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
3782 {
3783 #ifndef _WIN32_WCE
3784 if(wParam == SPI_SETNONCLIENTMETRICS)
3785 GetSystemSettings();
3786 #else // CE specific
3787 wParam; // avoid level 4 warning
3788 GetSystemSettings();
3789 #endif // _WIN32_WCE
3790 bHandled = FALSE;
3791 return 0;
3792 }
3793
3794 void GetSystemSettings()
3795 {
3796 if(!m_bCommCtrl6 && !m_bmSort[m_iSortUp].IsNull())
3797 {
3798 T* pT = static_cast<T*>(this);
3799 pT->CreateSortBitmaps();
3800 if(m_iSortColumn != -1)
3801 SetSortColumn(m_iSortColumn);
3802 }
3803 }
3804
3805 };
3806
3807
3808 typedef ATL::CWinTraits<WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | LVS_REPORT | LVS_SHOWSELALWAYS , WS_EX_CLIENTEDGE> CSortListViewCtrlTraits;
3809
3810 template <class T, class TBase = CListViewCtrl, class TWinTraits = CSortListViewCtrlTraits>
3811 class ATL_NO_VTABLE CSortListViewCtrlImpl: public ATL::CWindowImpl<T, TBase, TWinTraits>, public CSortListViewImpl<T>
3812 {
3813 public:
3814 DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())
3815
3816 bool SortItems(int iCol, bool bDescending = false)
3817 {
3818 return DoSortItems(iCol, bDescending);
3819 }
3820
3821 BEGIN_MSG_MAP(CSortListViewCtrlImpl)
3822 MESSAGE_HANDLER(LVM_INSERTCOLUMN, CSortListViewImpl<T>::OnInsertColumn)
3823 MESSAGE_HANDLER(LVM_DELETECOLUMN, CSortListViewImpl<T>::OnDeleteColumn)
3824 NOTIFY_CODE_HANDLER(HDN_ITEMCLICKA, CSortListViewImpl<T>::OnHeaderItemClick)
3825 NOTIFY_CODE_HANDLER(HDN_ITEMCLICKW, CSortListViewImpl<T>::OnHeaderItemClick)
3826 MESSAGE_HANDLER(WM_SETTINGCHANGE, CSortListViewImpl<T>::OnSettingChange)
3827 END_MSG_MAP()
3828 };
3829
3830 class CSortListViewCtrl : public CSortListViewCtrlImpl<CSortListViewCtrl>
3831 {
3832 public:
3833 DECLARE_WND_SUPERCLASS(_T("WTL_SortListViewCtrl"), GetWndClassName())
3834 };
3835
3836
3837 ///////////////////////////////////////////////////////////////////////////////
3838 // CTabView - implements tab view window
3839
3840 // TabView Notifications
3841 #define TBVN_PAGEACTIVATED (0U-741)
3842 #define TBVN_CONTEXTMENU (0U-742)
3843
3844 // Notification data for TBVN_CONTEXTMENU
3845 struct TBVCONTEXTMENUINFO
3846 {
3847 NMHDR hdr;
3848 POINT pt;
3849 };
3850
3851 typedef TBVCONTEXTMENUINFO* LPTBVCONTEXTMENUINFO;
3852
3853
3854 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
3855 class ATL_NO_VTABLE CTabViewImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >
3856 {
3857 public:
3858 DECLARE_WND_CLASS_EX(NULL, 0, COLOR_APPWORKSPACE)
3859
3860 // Declarations and enums
3861 struct TABVIEWPAGE
3862 {
3863 HWND hWnd;
3864 LPTSTR lpstrTitle;
3865 LPVOID pData;
3866 };
3867
3868 struct TCITEMEXTRA
3869 {
3870 TCITEMHEADER tciheader;
3871 TABVIEWPAGE tvpage;
3872
3873 operator LPTCITEM() { return (LPTCITEM)this; }
3874 };
3875
3876 enum
3877 {
3878 m_nTabID = 1313,
3879 m_cxMoveMark = 6,
3880 m_cyMoveMark = 3,
3881 m_nMenuItemsMax = (ID_WINDOW_TABLAST - ID_WINDOW_TABFIRST + 1)
3882 };
3883
3884 // Data members
3885 ATL::CContainedWindowT<CTabCtrl> m_tab;
3886 int m_cyTabHeight;
3887
3888 int m_nActivePage;
3889
3890 int m_nInsertItem;
3891 POINT m_ptStartDrag;
3892
3893 CMenuHandle m_menu;
3894
3895 int m_cchTabTextLength;
3896
3897 int m_nMenuItemsCount;
3898
3899 ATL::CWindow m_wndTitleBar;
3900 LPTSTR m_lpstrTitleBarBase;
3901 int m_cchTitleBarLength;
3902
3903 CImageList m_ilDrag;
3904
3905 bool m_bDestroyPageOnRemove:1;
3906 bool m_bDestroyImageList:1;
3907 bool m_bActivePageMenuItem:1;
3908 bool m_bActiveAsDefaultMenuItem:1;
3909 bool m_bEmptyMenuItem:1;
3910 bool m_bWindowsMenuItem:1;
3911 bool m_bNoTabDrag:1;
3912 // internal
3913 bool m_bTabCapture:1;
3914 bool m_bTabDrag:1;
3915 bool m_bInternalFont:1;
3916
3917 // Constructor/destructor
3918 CTabViewImpl() :
3919 m_nActivePage(-1),
3920 m_cyTabHeight(0),
3921 m_tab(this, 1),
3922 m_nInsertItem(-1),
3923 m_cchTabTextLength(30),
3924 m_nMenuItemsCount(10),
3925 m_lpstrTitleBarBase(NULL),
3926 m_cchTitleBarLength(100),
3927 m_bDestroyPageOnRemove(true),
3928 m_bDestroyImageList(true),
3929 m_bActivePageMenuItem(true),
3930 m_bActiveAsDefaultMenuItem(false),
3931 m_bEmptyMenuItem(false),
3932 m_bWindowsMenuItem(false),
3933 m_bNoTabDrag(false),
3934 m_bTabCapture(false),
3935 m_bTabDrag(false),
3936 m_bInternalFont(false)
3937 {
3938 m_ptStartDrag.x = 0;
3939 m_ptStartDrag.y = 0;
3940 }
3941
3942 ~CTabViewImpl()
3943 {
3944 delete [] m_lpstrTitleBarBase;
3945 }
3946
3947 // Message filter function - to be called from PreTranslateMessage of the main window
3948 BOOL PreTranslateMessage(MSG* pMsg)
3949 {
3950 if(IsWindow() == FALSE)
3951 return FALSE;
3952
3953 BOOL bRet = FALSE;
3954
3955 // Check for TabView built-in accelerators (Ctrl+Tab/Ctrl+Shift+Tab - next/previous page)
3956 int nCount = GetPageCount();
3957 if(nCount > 0)
3958 {
3959 bool bControl = (::GetKeyState(VK_CONTROL) < 0);
3960 if((pMsg->message == WM_KEYDOWN) && (pMsg->wParam == VK_TAB) && bControl)
3961 {
3962 if(nCount > 1)
3963 {
3964 int nPage = m_nActivePage;
3965 bool bShift = (::GetKeyState(VK_SHIFT) < 0);
3966 if(bShift)
3967 nPage = (nPage > 0) ? (nPage - 1) : (nCount - 1);
3968 else
3969 nPage = ((nPage >= 0) && (nPage < (nCount - 1))) ? (nPage + 1) : 0;
3970
3971 SetActivePage(nPage);
3972 T* pT = static_cast<T*>(this);
3973 pT->OnPageActivated(m_nActivePage);
3974 }
3975
3976 bRet = TRUE;
3977 }
3978 }
3979
3980 // If we are doing drag-drop, check for Escape key that cancels it
3981 if(bRet == FALSE)
3982 {
3983 if(m_bTabCapture && pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
3984 {
3985 ::ReleaseCapture();
3986 bRet = TRUE;
3987 }
3988 }
3989
3990 // Pass the message to the active page
3991 if(bRet == FALSE)
3992 {
3993 if(m_nActivePage != -1)
3994 bRet = (BOOL)::SendMessage(GetPageHWND(m_nActivePage), WM_FORWARDMSG, 0, (LPARAM)pMsg);
3995 }
3996
3997 return bRet;
3998 }
3999
4000 // Attributes
4001 int GetPageCount() const
4002 {
4003 ATLASSERT(::IsWindow(m_hWnd));
4004 return m_tab.GetItemCount();
4005 }
4006
4007 int GetActivePage() const
4008 {
4009 return m_nActivePage;
4010 }
4011
4012 void SetActivePage(int nPage)
4013 {
4014 ATLASSERT(::IsWindow(m_hWnd));
4015 ATLASSERT(IsValidPageIndex(nPage));
4016
4017 T* pT = static_cast<T*>(this);
4018
4019 SetRedraw(FALSE);
4020
4021 if(m_nActivePage != -1)
4022 ::ShowWindow(GetPageHWND(m_nActivePage), FALSE);
4023 m_nActivePage = nPage;
4024 m_tab.SetCurSel(m_nActivePage);
4025 ::ShowWindow(GetPageHWND(m_nActivePage), TRUE);
4026
4027 pT->UpdateLayout();
4028
4029 SetRedraw(TRUE);
4030 RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
4031
4032 if(::GetFocus() != m_tab.m_hWnd)
4033 ::SetFocus(GetPageHWND(m_nActivePage));
4034
4035 pT->UpdateTitleBar();
4036 pT->UpdateMenu();
4037 }
4038
4039 HIMAGELIST GetImageList() const
4040 {
4041 ATLASSERT(::IsWindow(m_hWnd));
4042 return m_tab.GetImageList();
4043 }
4044
4045 HIMAGELIST SetImageList(HIMAGELIST hImageList)
4046 {
4047 ATLASSERT(::IsWindow(m_hWnd));
4048 return m_tab.SetImageList(hImageList);
4049 }
4050
4051 void SetWindowMenu(HMENU hMenu)
4052 {
4053 ATLASSERT(::IsWindow(m_hWnd));
4054
4055 m_menu = hMenu;
4056
4057 T* pT = static_cast<T*>(this);
4058 pT->UpdateMenu();
4059 }
4060
4061 void SetTitleBarWindow(HWND hWnd)
4062 {
4063 ATLASSERT(::IsWindow(m_hWnd));
4064
4065 delete [] m_lpstrTitleBarBase;
4066 m_lpstrTitleBarBase = NULL;
4067
4068 m_wndTitleBar = hWnd;
4069 if(hWnd == NULL)
4070 return;
4071
4072 int cchLen = m_wndTitleBar.GetWindowTextLength() + 1;
4073 ATLTRY(m_lpstrTitleBarBase = new TCHAR[cchLen]);
4074 if(m_lpstrTitleBarBase != NULL)
4075 {
4076 m_wndTitleBar.GetWindowText(m_lpstrTitleBarBase, cchLen);
4077 T* pT = static_cast<T*>(this);
4078 pT->UpdateTitleBar();
4079 }
4080 }
4081
4082 // Page attributes
4083 HWND GetPageHWND(int nPage) const
4084 {
4085 ATLASSERT(::IsWindow(m_hWnd));
4086 ATLASSERT(IsValidPageIndex(nPage));
4087
4088 TCITEMEXTRA tcix = { 0 };
4089 tcix.tciheader.mask = TCIF_PARAM;
4090 m_tab.GetItem(nPage, tcix);
4091
4092 return tcix.tvpage.hWnd;
4093 }
4094
4095 LPCTSTR GetPageTitle(int nPage) const
4096 {
4097 ATLASSERT(::IsWindow(m_hWnd));
4098 ATLASSERT(IsValidPageIndex(nPage));
4099
4100 TCITEMEXTRA tcix = { 0 };
4101 tcix.tciheader.mask = TCIF_PARAM;
4102 if(m_tab.GetItem(nPage, tcix) == FALSE)
4103 return NULL;
4104
4105 return tcix.tvpage.lpstrTitle;
4106 }
4107
4108 bool SetPageTitle(int nPage, LPCTSTR lpstrTitle)
4109 {
4110 ATLASSERT(::IsWindow(m_hWnd));
4111 ATLASSERT(IsValidPageIndex(nPage));
4112
4113 T* pT = static_cast<T*>(this);
4114
4115 int cchBuff = lstrlen(lpstrTitle) + 1;
4116 LPTSTR lpstrBuff = NULL;
4117 ATLTRY(lpstrBuff = new TCHAR[cchBuff]);
4118 if(lpstrBuff == NULL)
4119 return false;
4120
4121 SecureHelper::strcpy_x(lpstrBuff, cchBuff, lpstrTitle);
4122 TCITEMEXTRA tcix = { 0 };
4123 tcix.tciheader.mask = TCIF_PARAM;
4124 if(m_tab.GetItem(nPage, tcix) == FALSE)
4125 return false;
4126
4127 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
4128 LPTSTR lpstrTabText = buff.Allocate(m_cchTabTextLength + 1);
4129 if(lpstrTabText == NULL)
4130 return false;
4131
4132 delete [] tcix.tvpage.lpstrTitle;
4133
4134 pT->ShortenTitle(lpstrTitle, lpstrTabText, m_cchTabTextLength + 1);
4135
4136 tcix.tciheader.mask = TCIF_TEXT | TCIF_PARAM;
4137 tcix.tciheader.pszText = lpstrTabText;
4138 tcix.tvpage.lpstrTitle = lpstrBuff;
4139 if(m_tab.SetItem(nPage, tcix) == FALSE)
4140 return false;
4141
4142 pT->UpdateTitleBar();
4143 pT->UpdateMenu();
4144
4145 return true;
4146 }
4147
4148 LPVOID GetPageData(int nPage) const
4149 {
4150 ATLASSERT(::IsWindow(m_hWnd));
4151 ATLASSERT(IsValidPageIndex(nPage));
4152
4153 TCITEMEXTRA tcix = { 0 };
4154 tcix.tciheader.mask = TCIF_PARAM;
4155 m_tab.GetItem(nPage, tcix);
4156
4157 return tcix.tvpage.pData;
4158 }
4159
4160 LPVOID SetPageData(int nPage, LPVOID pData)
4161 {
4162 ATLASSERT(::IsWindow(m_hWnd));
4163 ATLASSERT(IsValidPageIndex(nPage));
4164
4165 TCITEMEXTRA tcix = { 0 };
4166 tcix.tciheader.mask = TCIF_PARAM;
4167 m_tab.GetItem(nPage, tcix);
4168 LPVOID pDataOld = tcix.tvpage.pData;
4169
4170 tcix.tvpage.pData = pData;
4171 m_tab.SetItem(nPage, tcix);
4172
4173 return pDataOld;
4174 }
4175
4176 int GetPageImage(int nPage) const
4177 {
4178 ATLASSERT(::IsWindow(m_hWnd));
4179 ATLASSERT(IsValidPageIndex(nPage));
4180
4181 TCITEMEXTRA tcix = { 0 };
4182 tcix.tciheader.mask = TCIF_IMAGE;
4183 m_tab.GetItem(nPage, tcix);
4184
4185 return tcix.tciheader.iImage;
4186 }
4187
4188 int SetPageImage(int nPage, int nImage)
4189 {
4190 ATLASSERT(::IsWindow(m_hWnd));
4191 ATLASSERT(IsValidPageIndex(nPage));
4192
4193 TCITEMEXTRA tcix = { 0 };
4194 tcix.tciheader.mask = TCIF_IMAGE;
4195 m_tab.GetItem(nPage, tcix);
4196 int nImageOld = tcix.tciheader.iImage;
4197
4198 tcix.tciheader.iImage = nImage;
4199 m_tab.SetItem(nPage, tcix);
4200
4201 return nImageOld;
4202 }
4203
4204 // Operations
4205 bool AddPage(HWND hWndView, LPCTSTR lpstrTitle, int nImage = -1, LPVOID pData = NULL)
4206 {
4207 return InsertPage(GetPageCount(), hWndView, lpstrTitle, nImage, pData);
4208 }
4209
4210 bool InsertPage(int nPage, HWND hWndView, LPCTSTR lpstrTitle, int nImage = -1, LPVOID pData = NULL)
4211 {
4212 ATLASSERT(::IsWindow(m_hWnd));
4213 ATLASSERT(nPage == GetPageCount() || IsValidPageIndex(nPage));
4214
4215 T* pT = static_cast<T*>(this);
4216
4217 int cchBuff = lstrlen(lpstrTitle) + 1;
4218 LPTSTR lpstrBuff = NULL;
4219 ATLTRY(lpstrBuff = new TCHAR[cchBuff]);
4220 if(lpstrBuff == NULL)
4221 return false;
4222
4223 SecureHelper::strcpy_x(lpstrBuff, cchBuff, lpstrTitle);
4224
4225 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
4226 LPTSTR lpstrTabText = buff.Allocate(m_cchTabTextLength + 1);
4227 if(lpstrTabText == NULL)
4228 return false;
4229
4230 pT->ShortenTitle(lpstrTitle, lpstrTabText, m_cchTabTextLength + 1);
4231
4232 SetRedraw(FALSE);
4233
4234 TCITEMEXTRA tcix = { 0 };
4235 tcix.tciheader.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM;
4236 tcix.tciheader.pszText = lpstrTabText;
4237 tcix.tciheader.iImage = nImage;
4238 tcix.tvpage.hWnd = hWndView;
4239 tcix.tvpage.lpstrTitle = lpstrBuff;
4240 tcix.tvpage.pData = pData;
4241 int nItem = m_tab.InsertItem(nPage, tcix);
4242 if(nItem == -1)
4243 {
4244 delete [] lpstrBuff;
4245 SetRedraw(TRUE);
4246 return false;
4247 }
4248
4249 // adjust active page index, if inserted before it
4250 if(nPage <= m_nActivePage)
4251 m_nActivePage++;
4252
4253 SetActivePage(nItem);
4254 pT->OnPageActivated(m_nActivePage);
4255
4256 if(GetPageCount() == 1)
4257 pT->ShowTabControl(true);
4258
4259 pT->UpdateLayout();
4260
4261 SetRedraw(TRUE);
4262 RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
4263
4264 return true;
4265 }
4266
4267 void RemovePage(int nPage)
4268 {
4269 ATLASSERT(::IsWindow(m_hWnd));
4270 ATLASSERT(IsValidPageIndex(nPage));
4271
4272 T* pT = static_cast<T*>(this);
4273
4274 SetRedraw(FALSE);
4275
4276 if(GetPageCount() == 1)
4277 pT->ShowTabControl(false);
4278
4279 if(m_bDestroyPageOnRemove)
4280 ::DestroyWindow(GetPageHWND(nPage));
4281 else
4282 ::ShowWindow(GetPageHWND(nPage), FALSE);
4283 LPTSTR lpstrTitle = (LPTSTR)GetPageTitle(nPage);
4284 delete [] lpstrTitle;
4285
4286 ATLVERIFY(m_tab.DeleteItem(nPage) != FALSE);
4287
4288 if(m_nActivePage == nPage)
4289 {
4290 m_nActivePage = -1;
4291
4292 if(nPage > 0)
4293 {
4294 SetActivePage(nPage - 1);
4295 }
4296 else if(GetPageCount() > 0)
4297 {
4298 SetActivePage(nPage);
4299 }
4300 else
4301 {
4302 SetRedraw(TRUE);
4303 Invalidate();
4304 UpdateWindow();
4305 pT->UpdateTitleBar();
4306 pT->UpdateMenu();
4307 }
4308 }
4309 else
4310 {
4311 nPage = (nPage < m_nActivePage) ? (m_nActivePage - 1) : m_nActivePage;
4312 m_nActivePage = -1;
4313 SetActivePage(nPage);
4314 }
4315
4316 pT->OnPageActivated(m_nActivePage);
4317 }
4318
4319 void RemoveAllPages()
4320 {
4321 ATLASSERT(::IsWindow(m_hWnd));
4322
4323 if(GetPageCount() == 0)
4324 return;
4325
4326 T* pT = static_cast<T*>(this);
4327
4328 SetRedraw(FALSE);
4329
4330 pT->ShowTabControl(false);
4331
4332 for(int i = 0; i < GetPageCount(); i++)
4333 {
4334 if(m_bDestroyPageOnRemove)
4335 ::DestroyWindow(GetPageHWND(i));
4336 else
4337 ::ShowWindow(GetPageHWND(i), FALSE);
4338 LPTSTR lpstrTitle = (LPTSTR)GetPageTitle(i);
4339 delete [] lpstrTitle;
4340 }
4341 m_tab.DeleteAllItems();
4342
4343 m_nActivePage = -1;
4344 pT->OnPageActivated(m_nActivePage);
4345
4346 SetRedraw(TRUE);
4347 Invalidate();
4348 UpdateWindow();
4349
4350 pT->UpdateTitleBar();
4351 pT->UpdateMenu();
4352 }
4353
4354 int PageIndexFromHwnd(HWND hWnd) const
4355 {
4356 int nIndex = -1;
4357
4358 for(int i = 0; i < GetPageCount(); i++)
4359 {
4360 if(GetPageHWND(i) == hWnd)
4361 {
4362 nIndex = i;
4363 break;
4364 }
4365 }
4366
4367 return nIndex;
4368 }
4369
4370 void BuildWindowMenu(HMENU hMenu, int nMenuItemsCount = 10, bool bEmptyMenuItem = true, bool bWindowsMenuItem = true, bool bActivePageMenuItem = true, bool bActiveAsDefaultMenuItem = false)
4371 {
4372 ATLASSERT(::IsWindow(m_hWnd));
4373
4374 CMenuHandle menu = hMenu;
4375 T* pT = static_cast<T*>(this);
4376 pT; // avoid level 4 warning
4377 int nFirstPos = 0;
4378
4379 // Find first menu item in our range
4380 #ifndef _WIN32_WCE
4381 for(nFirstPos = 0; nFirstPos < menu.GetMenuItemCount(); nFirstPos++)
4382 {
4383 UINT nID = menu.GetMenuItemID(nFirstPos);
4384 if((nID >= ID_WINDOW_TABFIRST && nID <= ID_WINDOW_TABLAST) || nID == ID_WINDOW_SHOWTABLIST)
4385 break;
4386 }
4387 #else // CE specific
4388 for(nFirstPos = 0; ; nFirstPos++)
4389 {
4390 CMenuItemInfo mii;
4391 mii.fMask = MIIM_ID;
4392 BOOL bRet = menu.GetMenuItemInfo(nFirstPos, TRUE, &mii);
4393 if(bRet == FALSE)
4394 break;
4395 if((mii.wID >= ID_WINDOW_TABFIRST && mii.wID <= ID_WINDOW_TABLAST) || mii.wID == ID_WINDOW_SHOWTABLIST)
4396 break;
4397 }
4398 #endif // _WIN32_WCE
4399
4400 // Remove all menu items for tab pages
4401 BOOL bRet = TRUE;
4402 while(bRet != FALSE)
4403 bRet = menu.DeleteMenu(nFirstPos, MF_BYPOSITION);
4404
4405 // Add separator if it's not already there
4406 int nPageCount = GetPageCount();
4407 if((bWindowsMenuItem || (nPageCount > 0)) && (nFirstPos > 0))
4408 {
4409 CMenuItemInfo mii;
4410 mii.fMask = MIIM_TYPE;
4411 menu.GetMenuItemInfo(nFirstPos - 1, TRUE, &mii);
4412 if((nFirstPos <= 0) || ((mii.fType & MFT_SEPARATOR) == 0))
4413 {
4414 menu.AppendMenu(MF_SEPARATOR);
4415 nFirstPos++;
4416 }
4417 }
4418
4419 // Add menu items for all pages
4420 if(nPageCount > 0)
4421 {
4422 // Append menu items for all pages
4423 const int cchPrefix = 3; // 2 digits + space
4424 nMenuItemsCount = __min(__min(nPageCount, nMenuItemsCount), (int)m_nMenuItemsMax);
4425 ATLASSERT(nMenuItemsCount < 100); // 2 digits only
4426 if(nMenuItemsCount >= 100)
4427 nMenuItemsCount = 99;
4428
4429 for(int i = 0; i < nMenuItemsCount; i++)
4430 {
4431 LPCTSTR lpstrTitle = GetPageTitle(i);
4432 int nLen = lstrlen(lpstrTitle);
4433 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
4434 LPTSTR lpstrText = buff.Allocate(cchPrefix + nLen + 1);
4435 ATLASSERT(lpstrText != NULL);
4436 if(lpstrText != NULL)
4437 {
4438 LPCTSTR lpstrFormat = (i < 9) ? _T("&%i %s") : _T("%i %s");
4439 SecureHelper::wsprintf_x(lpstrText, cchPrefix + nLen + 1, lpstrFormat, i + 1, lpstrTitle);
4440 menu.AppendMenu(MF_STRING, ID_WINDOW_TABFIRST + i, lpstrText);
4441 }
4442 }
4443
4444 // Mark active page
4445 if(bActivePageMenuItem && (m_nActivePage != -1))
4446 {
4447 #ifndef _WIN32_WCE
4448 if(bActiveAsDefaultMenuItem)
4449 {
4450 menu.SetMenuDefaultItem((UINT)-1, TRUE);
4451 menu.SetMenuDefaultItem(nFirstPos + m_nActivePage, TRUE);
4452 }
4453 else
4454 #else // CE specific
4455 bActiveAsDefaultMenuItem; // avoid level 4 warning
4456 #endif // _WIN32_WCE
4457 {
4458 menu.CheckMenuRadioItem(nFirstPos, nFirstPos + nMenuItemsCount, nFirstPos + m_nActivePage, MF_BYPOSITION);
4459 }
4460 }
4461 }
4462 else
4463 {
4464 if(bEmptyMenuItem)
4465 {
4466 menu.AppendMenu(MF_BYPOSITION | MF_STRING, ID_WINDOW_TABFIRST, pT->GetEmptyListText());
4467 menu.EnableMenuItem(ID_WINDOW_TABFIRST, MF_GRAYED);
4468 }
4469
4470 // Remove separator if nothing else is there
4471 if(!bEmptyMenuItem && !bWindowsMenuItem && (nFirstPos > 0))
4472 {
4473 CMenuItemInfo mii;
4474 mii.fMask = MIIM_TYPE;
4475 menu.GetMenuItemInfo(nFirstPos - 1, TRUE, &mii);
4476 if((mii.fType & MFT_SEPARATOR) != 0)
4477 menu.DeleteMenu(nFirstPos - 1, MF_BYPOSITION);
4478 }
4479 }
4480
4481 // Add "Windows..." menu item
4482 if(bWindowsMenuItem)
4483 menu.AppendMenu(MF_BYPOSITION | MF_STRING, ID_WINDOW_SHOWTABLIST, pT->GetWindowsMenuItemText());
4484 }
4485
4486 BOOL SubclassWindow(HWND hWnd)
4487 {
4488 #if (_MSC_VER >= 1300)
4489 BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits >::SubclassWindow(hWnd);
4490 #else // !(_MSC_VER >= 1300)
4491 typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass;
4492 BOOL bRet = _baseClass::SubclassWindow(hWnd);
4493 #endif // !(_MSC_VER >= 1300)
4494 if(bRet != FALSE)
4495 {
4496 T* pT = static_cast<T*>(this);
4497 pT->CreateTabControl();
4498 pT->UpdateLayout();
4499 }
4500
4501 return bRet;
4502 }
4503
4504 // Message map and handlers
4505 BEGIN_MSG_MAP(CTabViewImpl)
4506 MESSAGE_HANDLER(WM_CREATE, OnCreate)
4507 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
4508 MESSAGE_HANDLER(WM_SIZE, OnSize)
4509 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
4510 MESSAGE_HANDLER(WM_GETFONT, OnGetFont)
4511 MESSAGE_HANDLER(WM_SETFONT, OnSetFont)
4512 NOTIFY_HANDLER(m_nTabID, TCN_SELCHANGE, OnTabChanged)
4513 NOTIFY_ID_HANDLER(m_nTabID, OnTabNotification)
4514 #ifndef _WIN32_WCE
4515 NOTIFY_CODE_HANDLER(TTN_GETDISPINFO, OnTabGetDispInfo)
4516 #endif // !_WIN32_WCE
4517 FORWARD_NOTIFICATIONS()
4518 ALT_MSG_MAP(1) // tab control
4519 MESSAGE_HANDLER(WM_LBUTTONDOWN, OnTabLButtonDown)
4520 MESSAGE_HANDLER(WM_LBUTTONUP, OnTabLButtonUp)
4521 MESSAGE_HANDLER(WM_CAPTURECHANGED, OnTabCaptureChanged)
4522 MESSAGE_HANDLER(WM_MOUSEMOVE, OnTabMouseMove)
4523 MESSAGE_HANDLER(WM_RBUTTONUP, OnTabRButtonUp)
4524 MESSAGE_HANDLER(WM_SYSKEYDOWN, OnTabSysKeyDown)
4525 END_MSG_MAP()
4526
4527 LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
4528 {
4529 T* pT = static_cast<T*>(this);
4530 pT->CreateTabControl();
4531
4532 return 0;
4533 }
4534
4535 LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
4536 {
4537 RemoveAllPages();
4538
4539 if(m_bDestroyImageList)
4540 {
4541 CImageList il = m_tab.SetImageList(NULL);
4542 if(il.m_hImageList != NULL)
4543 il.Destroy();
4544 }
4545
4546 if(m_bInternalFont)
4547 {
4548 HFONT hFont = m_tab.GetFont();
4549 m_tab.SetFont(NULL, FALSE);
4550 ::DeleteObject(hFont);
4551 m_bInternalFont = false;
4552 }
4553
4554 return 0;
4555 }
4556
4557 LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
4558 {
4559 T* pT = static_cast<T*>(this);
4560 pT->UpdateLayout();
4561 return 0;
4562 }
4563
4564 LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
4565 {
4566 if(m_nActivePage != -1)
4567 ::SetFocus(GetPageHWND(m_nActivePage));
4568 return 0;
4569 }
4570
4571 LRESULT OnGetFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
4572 {
4573 return m_tab.SendMessage(WM_GETFONT);
4574 }
4575
4576 LRESULT OnSetFont(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
4577 {
4578 if(m_bInternalFont)
4579 {
4580 HFONT hFont = m_tab.GetFont();
4581 m_tab.SetFont(NULL, FALSE);
4582 ::DeleteObject(hFont);
4583 m_bInternalFont = false;
4584 }
4585
4586 m_tab.SendMessage(WM_SETFONT, wParam, lParam);
4587
4588 T* pT = static_cast<T*>(this);
4589 m_cyTabHeight = pT->CalcTabHeight();
4590
4591 if((BOOL)lParam != FALSE)
4592 pT->UpdateLayout();
4593
4594 return 0;
4595 }
4596
4597 LRESULT OnTabChanged(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
4598 {
4599 SetActivePage(m_tab.GetCurSel());
4600 T* pT = static_cast<T*>(this);
4601 pT->OnPageActivated(m_nActivePage);
4602
4603 return 0;
4604 }
4605
4606 LRESULT OnTabNotification(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
4607 {
4608 // nothing to do - this just blocks all tab control
4609 // notifications from being propagated further
4610 return 0;
4611 }
4612
4613 #ifndef _WIN32_WCE
4614 LRESULT OnTabGetDispInfo(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
4615 {
4616 LPNMTTDISPINFO pTTDI = (LPNMTTDISPINFO)pnmh;
4617 if(pTTDI->hdr.hwndFrom == m_tab.GetTooltips())
4618 {
4619 T* pT = static_cast<T*>(this);
4620 pT->UpdateTooltipText(pTTDI);
4621 }
4622 else
4623 {
4624 bHandled = FALSE;
4625 }
4626
4627 return 0;
4628 }
4629 #endif // !_WIN32_WCE
4630
4631 // Tab control message handlers
4632 LRESULT OnTabLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
4633 {
4634 if(!m_bNoTabDrag && (m_tab.GetItemCount() > 1))
4635 {
4636 m_bTabCapture = true;
4637 m_tab.SetCapture();
4638
4639 m_ptStartDrag.x = GET_X_LPARAM(lParam);
4640 m_ptStartDrag.y = GET_Y_LPARAM(lParam);
4641 }
4642
4643 bHandled = FALSE;
4644 return 0;
4645 }
4646
4647 LRESULT OnTabLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
4648 {
4649 if(m_bTabCapture)
4650 {
4651 if(m_bTabDrag)
4652 {
4653 TCHITTESTINFO hti = { 0 };
4654 hti.pt.x = GET_X_LPARAM(lParam);
4655 hti.pt.y = GET_Y_LPARAM(lParam);
4656 int nItem = m_tab.HitTest(&hti);
4657 if(nItem != -1)
4658 MovePage(m_nActivePage, nItem);
4659 }
4660
4661 ::ReleaseCapture();
4662 }
4663
4664 bHandled = FALSE;
4665 return 0;
4666 }
4667
4668 LRESULT OnTabCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
4669 {
4670 if(m_bTabCapture)
4671 {
4672 m_bTabCapture = false;
4673
4674 if(m_bTabDrag)
4675 {
4676 m_bTabDrag = false;
4677 T* pT = static_cast<T*>(this);
4678 pT->DrawMoveMark(-1);
4679
4680 #ifndef _WIN32_WCE
4681 m_ilDrag.DragLeave(GetDesktopWindow());
4682 #endif // !_WIN32_WCE
4683 m_ilDrag.EndDrag();
4684
4685 m_ilDrag.Destroy();
4686 m_ilDrag.m_hImageList = NULL;
4687 }
4688 }
4689
4690 bHandled = FALSE;
4691 return 0;
4692 }
4693
4694 LRESULT OnTabMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
4695 {
4696 bHandled = FALSE;
4697
4698 if(m_bTabCapture)
4699 {
4700 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
4701
4702 if(!m_bTabDrag)
4703 {
4704 #ifndef _WIN32_WCE
4705 if(abs(m_ptStartDrag.x - GET_X_LPARAM(lParam)) >= ::GetSystemMetrics(SM_CXDRAG) ||
4706 abs(m_ptStartDrag.y - GET_Y_LPARAM(lParam)) >= ::GetSystemMetrics(SM_CYDRAG))
4707 #else // CE specific
4708 if(abs(m_ptStartDrag.x - GET_X_LPARAM(lParam)) >= 4 ||
4709 abs(m_ptStartDrag.y - GET_Y_LPARAM(lParam)) >= 4)
4710 #endif // _WIN32_WCE
4711 {
4712 T* pT = static_cast<T*>(this);
4713 pT->GenerateDragImage(m_nActivePage);
4714
4715 int cxCursor = ::GetSystemMetrics(SM_CXCURSOR);
4716 int cyCursor = ::GetSystemMetrics(SM_CYCURSOR);
4717 m_ilDrag.BeginDrag(0, -(cxCursor / 2), -(cyCursor / 2));
4718 #ifndef _WIN32_WCE
4719 POINT ptEnter = m_ptStartDrag;
4720 m_tab.ClientToScreen(&ptEnter);
4721 m_ilDrag.DragEnter(GetDesktopWindow(), ptEnter);
4722 #endif // !_WIN32_WCE
4723
4724 m_bTabDrag = true;
4725 }
4726 }
4727
4728 if(m_bTabDrag)
4729 {
4730 TCHITTESTINFO hti = { 0 };
4731 hti.pt = pt;
4732 int nItem = m_tab.HitTest(&hti);
4733
4734 T* pT = static_cast<T*>(this);
4735 pT->SetMoveCursor(nItem != -1);
4736
4737 if(m_nInsertItem != nItem)
4738 pT->DrawMoveMark(nItem);
4739
4740 m_ilDrag.DragShowNolock((nItem != -1) ? TRUE : FALSE);
4741 m_tab.ClientToScreen(&pt);
4742 m_ilDrag.DragMove(pt);
4743
4744 bHandled = TRUE;
4745 }
4746 }
4747
4748 return 0;
4749 }
4750
4751 LRESULT OnTabRButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
4752 {
4753 TCHITTESTINFO hti = { 0 };
4754 hti.pt.x = GET_X_LPARAM(lParam);
4755 hti.pt.y = GET_Y_LPARAM(lParam);
4756 int nItem = m_tab.HitTest(&hti);
4757 if(nItem != -1)
4758 {
4759 T* pT = static_cast<T*>(this);
4760 pT->OnContextMenu(nItem, hti.pt);
4761 }
4762
4763 return 0;
4764 }
4765
4766 LRESULT OnTabSysKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
4767 {
4768 bool bShift = (::GetKeyState(VK_SHIFT) < 0);
4769 if(wParam == VK_F10 && bShift)
4770 {
4771 if(m_nActivePage != -1)
4772 {
4773 RECT rect = { 0 };
4774 m_tab.GetItemRect(m_nActivePage, &rect);
4775 POINT pt = { rect.left, rect.bottom };
4776 T* pT = static_cast<T*>(this);
4777 pT->OnContextMenu(m_nActivePage, pt);
4778 }
4779 }
4780 else
4781 {
4782 bHandled = FALSE;
4783 }
4784
4785 return 0;
4786 }
4787
4788 // Implementation helpers
4789 bool IsValidPageIndex(int nPage) const
4790 {
4791 return (nPage >= 0 && nPage < GetPageCount());
4792 }
4793
4794 bool MovePage(int nMovePage, int nInsertBeforePage)
4795 {
4796 ATLASSERT(IsValidPageIndex(nMovePage));
4797 ATLASSERT(IsValidPageIndex(nInsertBeforePage));
4798
4799 if(!IsValidPageIndex(nMovePage) || !IsValidPageIndex(nInsertBeforePage))
4800 return false;
4801
4802 if(nMovePage == nInsertBeforePage)
4803 return true; // nothing to do
4804
4805 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
4806 LPTSTR lpstrTabText = buff.Allocate(m_cchTabTextLength + 1);
4807 if(lpstrTabText == NULL)
4808 return false;
4809 TCITEMEXTRA tcix = { 0 };
4810 tcix.tciheader.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM;
4811 tcix.tciheader.pszText = lpstrTabText;
4812 tcix.tciheader.cchTextMax = m_cchTabTextLength + 1;
4813 BOOL bRet = m_tab.GetItem(nMovePage, tcix);
4814 ATLASSERT(bRet != FALSE);
4815 if(bRet == FALSE)
4816 return false;
4817
4818 int nInsertItem = (nInsertBeforePage > nMovePage) ? nInsertBeforePage + 1 : nInsertBeforePage;
4819 int nNewItem = m_tab.InsertItem(nInsertItem, tcix);
4820 ATLASSERT(nNewItem == nInsertItem);
4821 if(nNewItem != nInsertItem)
4822 {
4823 ATLVERIFY(m_tab.DeleteItem(nNewItem));
4824 return false;
4825 }
4826
4827 if(nMovePage > nInsertBeforePage)
4828 ATLVERIFY(m_tab.DeleteItem(nMovePage + 1) != FALSE);
4829 else if(nMovePage < nInsertBeforePage)
4830 ATLVERIFY(m_tab.DeleteItem(nMovePage) != FALSE);
4831
4832 SetActivePage(nInsertBeforePage);
4833 T* pT = static_cast<T*>(this);
4834 pT->OnPageActivated(m_nActivePage);
4835
4836 return true;
4837 }
4838
4839 // Implementation overrideables
4840 bool CreateTabControl()
4841 {
4842 #ifndef _WIN32_WCE
4843 m_tab.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_TOOLTIPS, 0, m_nTabID);
4844 #else // CE specific
4845 m_tab.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, m_nTabID);
4846 #endif // _WIN32_WCE
4847 ATLASSERT(m_tab.m_hWnd != NULL);
4848 if(m_tab.m_hWnd == NULL)
4849 return false;
4850
4851 m_tab.SetFont(AtlCreateControlFont());
4852 m_bInternalFont = true;
4853
4854 m_tab.SetItemExtra(sizeof(TABVIEWPAGE));
4855
4856 T* pT = static_cast<T*>(this);
4857 m_cyTabHeight = pT->CalcTabHeight();
4858
4859 return true;
4860 }
4861
4862 int CalcTabHeight()
4863 {
4864 int nCount = m_tab.GetItemCount();
4865 TCHAR szText[] = _T("NS");
4866 TCITEMEXTRA tcix = { 0 };
4867 tcix.tciheader.mask = TCIF_TEXT;
4868 tcix.tciheader.pszText = szText;
4869 int nIndex = m_tab.InsertItem(nCount, tcix);
4870
4871 RECT rect = { 0, 0, 1000, 1000 };
4872 m_tab.AdjustRect(FALSE, &rect);
4873
4874 RECT rcWnd = { 0, 0, 1000, rect.top };
4875 ::AdjustWindowRectEx(&rcWnd, m_tab.GetStyle(), FALSE, m_tab.GetExStyle());
4876
4877 int nHeight = rcWnd.bottom - rcWnd.top;
4878
4879 m_tab.DeleteItem(nIndex);
4880
4881 return nHeight;
4882 }
4883
4884 void ShowTabControl(bool bShow)
4885 {
4886 m_tab.ShowWindow(bShow ? SW_SHOWNOACTIVATE : SW_HIDE);
4887 T* pT = static_cast<T*>(this);
4888 pT->UpdateLayout();
4889 }
4890
4891 void UpdateLayout()
4892 {
4893 RECT rect = { 0 };
4894 GetClientRect(&rect);
4895
4896 int cyOffset = 0;
4897 if(m_tab.IsWindow() && ((m_tab.GetStyle() & WS_VISIBLE) != 0))
4898 {
4899 m_tab.SetWindowPos(NULL, 0, 0, rect.right - rect.left, m_cyTabHeight, SWP_NOZORDER);
4900 cyOffset = m_cyTabHeight;
4901 }
4902
4903 if(m_nActivePage != -1)
4904 ::SetWindowPos(GetPageHWND(m_nActivePage), NULL, 0, cyOffset, rect.right - rect.left, rect.bottom - rect.top - cyOffset, SWP_NOZORDER);
4905 }
4906
4907 void UpdateMenu()
4908 {
4909 if(m_menu.m_hMenu != NULL)
4910 BuildWindowMenu(m_menu, m_nMenuItemsCount, m_bEmptyMenuItem, m_bWindowsMenuItem, m_bActivePageMenuItem, m_bActiveAsDefaultMenuItem);
4911 }
4912
4913 void UpdateTitleBar()
4914 {
4915 if(!m_wndTitleBar.IsWindow() || m_lpstrTitleBarBase == NULL)
4916 return; // nothing to do
4917
4918 if(m_nActivePage != -1)
4919 {
4920 T* pT = static_cast<T*>(this);
4921 LPCTSTR lpstrTitle = pT->GetPageTitle(m_nActivePage);
4922 LPCTSTR lpstrDivider = pT->GetTitleDividerText();
4923 int cchBuffer = m_cchTitleBarLength + lstrlen(lpstrDivider) + lstrlen(m_lpstrTitleBarBase) + 1;
4924 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
4925 LPTSTR lpstrPageTitle = buff.Allocate(cchBuffer);
4926 ATLASSERT(lpstrPageTitle != NULL);
4927 if(lpstrPageTitle != NULL)
4928 {
4929 pT->ShortenTitle(lpstrTitle, lpstrPageTitle, m_cchTitleBarLength + 1);
4930 SecureHelper::strcat_x(lpstrPageTitle, cchBuffer, lpstrDivider);
4931 SecureHelper::strcat_x(lpstrPageTitle, cchBuffer, m_lpstrTitleBarBase);
4932 }
4933 else
4934 {
4935 lpstrPageTitle = m_lpstrTitleBarBase;
4936 }
4937
4938 m_wndTitleBar.SetWindowText(lpstrPageTitle);
4939 }
4940 else
4941 {
4942 m_wndTitleBar.SetWindowText(m_lpstrTitleBarBase);
4943 }
4944 }
4945
4946 void DrawMoveMark(int nItem)
4947 {
4948 T* pT = static_cast<T*>(this);
4949
4950 if(m_nInsertItem != -1)
4951 {
4952 RECT rect = { 0 };
4953 pT->GetMoveMarkRect(rect);
4954 m_tab.InvalidateRect(&rect);
4955 }
4956
4957 m_nInsertItem = nItem;
4958
4959 if(m_nInsertItem != -1)
4960 {
4961 CClientDC dc(m_tab.m_hWnd);
4962
4963 RECT rect = { 0 };
4964 pT->GetMoveMarkRect(rect);
4965
4966 CPen pen;
4967 pen.CreatePen(PS_SOLID, 1, ::GetSysColor(COLOR_WINDOWTEXT));
4968 CBrush brush;
4969 brush.CreateSolidBrush(::GetSysColor(COLOR_WINDOWTEXT));
4970
4971 HPEN hPenOld = dc.SelectPen(pen);
4972 HBRUSH hBrushOld = dc.SelectBrush(brush);
4973
4974 int x = rect.left;
4975 int y = rect.top;
4976 POINT ptsTop[3] = { { x, y }, { x + m_cxMoveMark, y }, { x + (m_cxMoveMark / 2), y + m_cyMoveMark } };
4977 dc.Polygon(ptsTop, 3);
4978
4979 y = rect.bottom - 1;
4980 POINT ptsBottom[3] = { { x, y }, { x + m_cxMoveMark, y }, { x + (m_cxMoveMark / 2), y - m_cyMoveMark } };
4981 dc.Polygon(ptsBottom, 3);
4982
4983 dc.SelectPen(hPenOld);
4984 dc.SelectBrush(hBrushOld);
4985 }
4986 }
4987
4988 void GetMoveMarkRect(RECT& rect) const
4989 {
4990 m_tab.GetClientRect(&rect);
4991
4992 RECT rcItem = { 0 };
4993 m_tab.GetItemRect(m_nInsertItem, &rcItem);
4994
4995 if(m_nInsertItem <= m_nActivePage)
4996 {
4997 rect.left = rcItem.left - m_cxMoveMark / 2 - 1;
4998 rect.right = rcItem.left + m_cxMoveMark / 2;
4999 }
5000 else
5001 {
5002 rect.left = rcItem.right - m_cxMoveMark / 2 - 1;
5003 rect.right = rcItem.right + m_cxMoveMark / 2;
5004 }
5005 }
5006
5007 void SetMoveCursor(bool bCanMove)
5008 {
5009 ::SetCursor(::LoadCursor(NULL, bCanMove ? IDC_ARROW : IDC_NO));
5010 }
5011
5012 void GenerateDragImage(int nItem)
5013 {
5014 ATLASSERT(IsValidPageIndex(nItem));
5015
5016 #ifndef _WIN32_WCE
5017 RECT rcItem = { 0 };
5018 m_tab.GetItemRect(nItem, &rcItem);
5019 ::InflateRect(&rcItem, 2, 2); // make bigger to cover selected item
5020 #else // CE specific
5021 nItem; // avoid level 4 warning
5022 RECT rcItem = { 0, 0, 40, 20 };
5023 #endif // _WIN32_WCE
5024
5025 ATLASSERT(m_ilDrag.m_hImageList == NULL);
5026 m_ilDrag.Create(rcItem.right - rcItem.left, rcItem.bottom - rcItem.top, ILC_COLORDDB | ILC_MASK, 1, 1);
5027
5028 CClientDC dc(m_hWnd);
5029 CDC dcMem;
5030 dcMem.CreateCompatibleDC(dc);
5031 ATLASSERT(dcMem.m_hDC != NULL);
5032 dcMem.SetViewportOrg(-rcItem.left, -rcItem.top);
5033
5034 CBitmap bmp;
5035 bmp.CreateCompatibleBitmap(dc, rcItem.right - rcItem.left, rcItem.bottom - rcItem.top);
5036 ATLASSERT(bmp.m_hBitmap != NULL);
5037
5038 HBITMAP hBmpOld = dcMem.SelectBitmap(bmp);
5039 #ifndef _WIN32_WCE
5040 m_tab.SendMessage(WM_PRINTCLIENT, (WPARAM)dcMem.m_hDC);
5041 #else // CE specific
5042 dcMem.Rectangle(&rcItem);
5043 #endif // _WIN32_WCE
5044 dcMem.SelectBitmap(hBmpOld);
5045
5046 ATLVERIFY(m_ilDrag.Add(bmp.m_hBitmap, RGB(255, 0, 255)) != -1);
5047 }
5048
5049 void ShortenTitle(LPCTSTR lpstrTitle, LPTSTR lpstrShortTitle, int cchShortTitle)
5050 {
5051 if(lstrlen(lpstrTitle) >= cchShortTitle)
5052 {
5053 LPCTSTR lpstrEllipsis = _T("...");
5054 int cchEllipsis = lstrlen(lpstrEllipsis);
5055 SecureHelper::strncpy_x(lpstrShortTitle, cchShortTitle, lpstrTitle, cchShortTitle - cchEllipsis - 1);
5056 SecureHelper::strcat_x(lpstrShortTitle, cchShortTitle, lpstrEllipsis);
5057 }
5058 else
5059 {
5060 SecureHelper::strcpy_x(lpstrShortTitle, cchShortTitle, lpstrTitle);
5061 }
5062 }
5063
5064 #ifndef _WIN32_WCE
5065 void UpdateTooltipText(LPNMTTDISPINFO pTTDI)
5066 {
5067 ATLASSERT(pTTDI != NULL);
5068 pTTDI->lpszText = (LPTSTR)GetPageTitle((int)pTTDI->hdr.idFrom);
5069 }
5070 #endif // !_WIN32_WCE
5071
5072 // Text for menu items and title bar - override to provide different strings
5073 static LPCTSTR GetEmptyListText()
5074 {
5075 return _T("(Empty)");
5076 }
5077
5078 static LPCTSTR GetWindowsMenuItemText()
5079 {
5080 return _T("&Windows...");
5081 }
5082
5083 static LPCTSTR GetTitleDividerText()
5084 {
5085 return _T(" - ");
5086 }
5087
5088 // Notifications - override to provide different behavior
5089 void OnPageActivated(int nPage)
5090 {
5091 NMHDR nmhdr = { 0 };
5092 nmhdr.hwndFrom = m_hWnd;
5093 nmhdr.idFrom = nPage;
5094 nmhdr.code = TBVN_PAGEACTIVATED;
5095 ::SendMessage(GetParent(), WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&nmhdr);
5096 }
5097
5098 void OnContextMenu(int nPage, POINT pt)
5099 {
5100 m_tab.ClientToScreen(&pt);
5101
5102 TBVCONTEXTMENUINFO cmi = { 0 };
5103 cmi.hdr.hwndFrom = m_hWnd;
5104 cmi.hdr.idFrom = nPage;
5105 cmi.hdr.code = TBVN_CONTEXTMENU;
5106 cmi.pt = pt;
5107 ::SendMessage(GetParent(), WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&cmi);
5108 }
5109 };
5110
5111 class CTabView : public CTabViewImpl<CTabView>
5112 {
5113 public:
5114 DECLARE_WND_CLASS_EX(_T("WTL_TabView"), 0, COLOR_APPWORKSPACE)
5115 };
5116
5117 }; // namespace WTL
5118
5119 #endif // __ATLCTRLX_H__
+0
-684
src/third_party/wtl/Include/atlddx.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLDDX_H__
9 #define __ATLDDX_H__
10
11 #pragma once
12
13 #ifndef __ATLAPP_H__
14 #error atlddx.h requires atlapp.h to be included first
15 #endif
16
17 #if defined(_ATL_USE_DDX_FLOAT) && defined(_ATL_MIN_CRT)
18 #error Cannot use floating point DDX with _ATL_MIN_CRT defined
19 #endif // defined(_ATL_USE_DDX_FLOAT) && defined(_ATL_MIN_CRT)
20
21 #ifdef _ATL_USE_DDX_FLOAT
22 #include <float.h>
23 #endif // _ATL_USE_DDX_FLOAT
24
25
26 ///////////////////////////////////////////////////////////////////////////////
27 // Classes in this file:
28 //
29 // CWinDataExchange<T>
30
31
32 namespace WTL
33 {
34
35 // Constants
36 #define DDX_LOAD FALSE
37 #define DDX_SAVE TRUE
38
39 // DDX map macros
40 #define BEGIN_DDX_MAP(thisClass) \
41 BOOL DoDataExchange(BOOL bSaveAndValidate = FALSE, UINT nCtlID = (UINT)-1) \
42 { \
43 (bSaveAndValidate); \
44 (nCtlID);
45
46 #define DDX_TEXT(nID, var) \
47 if(nCtlID == (UINT)-1 || nCtlID == nID) \
48 { \
49 if(!DDX_Text(nID, var, sizeof(var), bSaveAndValidate)) \
50 return FALSE; \
51 }
52
53 #define DDX_TEXT_LEN(nID, var, len) \
54 if(nCtlID == (UINT)-1 || nCtlID == nID) \
55 { \
56 if(!DDX_Text(nID, var, sizeof(var), bSaveAndValidate, TRUE, len)) \
57 return FALSE; \
58 }
59
60 #define DDX_INT(nID, var) \
61 if(nCtlID == (UINT)-1 || nCtlID == nID) \
62 { \
63 if(!DDX_Int(nID, var, TRUE, bSaveAndValidate)) \
64 return FALSE; \
65 }
66
67 #define DDX_INT_RANGE(nID, var, min, max) \
68 if(nCtlID == (UINT)-1 || nCtlID == nID) \
69 { \
70 if(!DDX_Int(nID, var, TRUE, bSaveAndValidate, TRUE, min, max)) \
71 return FALSE; \
72 }
73
74 #define DDX_UINT(nID, var) \
75 if(nCtlID == (UINT)-1 || nCtlID == nID) \
76 { \
77 if(!DDX_Int(nID, var, FALSE, bSaveAndValidate)) \
78 return FALSE; \
79 }
80
81 #define DDX_UINT_RANGE(nID, var, min, max) \
82 if(nCtlID == (UINT)-1 || nCtlID == nID) \
83 { \
84 if(!DDX_Int(nID, var, FALSE, bSaveAndValidate, TRUE, min, max)) \
85 return FALSE; \
86 }
87
88 #ifdef _ATL_USE_DDX_FLOAT
89 #define DDX_FLOAT(nID, var) \
90 if(nCtlID == (UINT)-1 || nCtlID == nID) \
91 { \
92 if(!DDX_Float(nID, var, bSaveAndValidate)) \
93 return FALSE; \
94 }
95
96 #define DDX_FLOAT_RANGE(nID, var, min, max) \
97 if(nCtlID == (UINT)-1 || nCtlID == nID) \
98 { \
99 if(!DDX_Float(nID, var, bSaveAndValidate, TRUE, min, max)) \
100 return FALSE; \
101 }
102 #define DDX_FLOAT_P(nID, var, precision) \
103 if(nCtlID == (UINT)-1 || nCtlID == nID) \
104 { \
105 if(!DDX_Float(nID, var, bSaveAndValidate, FALSE, 0, 0, precision)) \
106 return FALSE; \
107 }
108
109 #define DDX_FLOAT_P_RANGE(nID, var, min, max, precision) \
110 if(nCtlID == (UINT)-1 || nCtlID == nID) \
111 { \
112 if(!DDX_Float(nID, var, bSaveAndValidate, TRUE, min, max, precision)) \
113 return FALSE; \
114 }
115 #endif // _ATL_USE_DDX_FLOAT
116
117 #define DDX_CONTROL(nID, obj) \
118 if(nCtlID == (UINT)-1 || nCtlID == nID) \
119 DDX_Control(nID, obj, bSaveAndValidate);
120
121 #define DDX_CONTROL_HANDLE(nID, obj) \
122 if(nCtlID == (UINT)-1 || nCtlID == nID) \
123 DDX_Control_Handle(nID, obj, bSaveAndValidate);
124
125 #define DDX_CHECK(nID, var) \
126 if(nCtlID == (UINT)-1 || nCtlID == nID) \
127 DDX_Check(nID, var, bSaveAndValidate);
128
129 #define DDX_RADIO(nID, var) \
130 if(nCtlID == (UINT)-1 || nCtlID == nID) \
131 DDX_Radio(nID, var, bSaveAndValidate);
132
133 #define END_DDX_MAP() \
134 return TRUE; \
135 }
136
137 // DDX support for Tab, Combo, ListBox and ListView selection index
138 // Note: Specialized versions require atlctrls.h to be included first
139 #if (_MSC_VER >= 1300)
140
141 #define DDX_INDEX(CtrlClass, nID, var) \
142 if(nCtlID == (UINT)-1 || nCtlID == nID) \
143 DDX_Index<CtrlClass>(nID, var, bSaveAndValidate);
144
145 #ifdef __ATLCTRLS_H__
146 #define DDX_TAB_INDEX(nID, var) DDX_INDEX(WTL::CTabCtrl, nID, var)
147 #ifndef WIN32_PLATFORM_WFSP // No COMBOBOX on SmartPhones
148 #define DDX_COMBO_INDEX(nID, var) DDX_INDEX(WTL::CComboBox, nID, var)
149 #endif
150 #define DDX_LISTBOX_INDEX(nID, var) DDX_INDEX(WTL::CListBox, nID, var)
151 #define DDX_LISTVIEW_INDEX(nID, var) DDX_INDEX(WTL::CListViewCtrl, nID, var)
152 #endif // __ATLCTRLS_H__
153
154 #endif // (_MSC_VER >= 1300)
155
156
157 ///////////////////////////////////////////////////////////////////////////////
158 // CWinDataExchange - provides support for DDX
159
160 template <class T>
161 class CWinDataExchange
162 {
163 public:
164 // Data exchange method - override in your derived class
165 BOOL DoDataExchange(BOOL /*bSaveAndValidate*/ = FALSE, UINT /*nCtlID*/ = (UINT)-1)
166 {
167 // this one should never be called, override it in
168 // your derived class by implementing DDX map
169 ATLASSERT(FALSE);
170 return FALSE;
171 }
172
173 // Helpers for validation error reporting
174 enum _XDataType
175 {
176 ddxDataNull = 0,
177 ddxDataText = 1,
178 ddxDataInt = 2,
179 ddxDataFloat = 3,
180 ddxDataDouble = 4
181 };
182
183 struct _XTextData
184 {
185 int nLength;
186 int nMaxLength;
187 };
188
189 struct _XIntData
190 {
191 long nVal;
192 long nMin;
193 long nMax;
194 };
195
196 struct _XFloatData
197 {
198 double nVal;
199 double nMin;
200 double nMax;
201 };
202
203 struct _XData
204 {
205 _XDataType nDataType;
206 union
207 {
208 _XTextData textData;
209 _XIntData intData;
210 _XFloatData floatData;
211 };
212 };
213
214 // Text exchange
215 BOOL DDX_Text(UINT nID, LPTSTR lpstrText, int cbSize, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0)
216 {
217 T* pT = static_cast<T*>(this);
218 BOOL bSuccess = TRUE;
219
220 if(bSave)
221 {
222 HWND hWndCtrl = pT->GetDlgItem(nID);
223 int nRetLen = ::GetWindowText(hWndCtrl, lpstrText, cbSize / sizeof(TCHAR));
224 if(nRetLen < ::GetWindowTextLength(hWndCtrl))
225 bSuccess = FALSE;
226 }
227 else
228 {
229 ATLASSERT(!bValidate || (lstrlen(lpstrText) <= nLength));
230 bSuccess = pT->SetDlgItemText(nID, lpstrText);
231 }
232
233 if(!bSuccess)
234 {
235 pT->OnDataExchangeError(nID, bSave);
236 }
237 else if(bSave && bValidate) // validation
238 {
239 ATLASSERT(nLength > 0);
240 if(lstrlen(lpstrText) > nLength)
241 {
242 _XData data = { ddxDataText };
243 data.textData.nLength = lstrlen(lpstrText);
244 data.textData.nMaxLength = nLength;
245 pT->OnDataValidateError(nID, bSave, data);
246 bSuccess = FALSE;
247 }
248 }
249 return bSuccess;
250 }
251
252 BOOL DDX_Text(UINT nID, BSTR& bstrText, int /*cbSize*/, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0)
253 {
254 T* pT = static_cast<T*>(this);
255 BOOL bSuccess = TRUE;
256
257 if(bSave)
258 {
259 bSuccess = pT->GetDlgItemText(nID, bstrText);
260 }
261 else
262 {
263 USES_CONVERSION;
264 LPTSTR lpstrText = OLE2T(bstrText);
265 ATLASSERT(!bValidate || (lstrlen(lpstrText) <= nLength));
266 bSuccess = pT->SetDlgItemText(nID, lpstrText);
267 }
268
269 if(!bSuccess)
270 {
271 pT->OnDataExchangeError(nID, bSave);
272 }
273 else if(bSave && bValidate) // validation
274 {
275 ATLASSERT(nLength > 0);
276 if((int)::SysStringLen(bstrText) > nLength)
277 {
278 _XData data = { ddxDataText };
279 data.textData.nLength = (int)::SysStringLen(bstrText);
280 data.textData.nMaxLength = nLength;
281 pT->OnDataValidateError(nID, bSave, data);
282 bSuccess = FALSE;
283 }
284 }
285 return bSuccess;
286 }
287
288 BOOL DDX_Text(UINT nID, ATL::CComBSTR& bstrText, int /*cbSize*/, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0)
289 {
290 T* pT = static_cast<T*>(this);
291 BOOL bSuccess = TRUE;
292
293 if(bSave)
294 {
295 bSuccess = pT->GetDlgItemText(nID, (BSTR&)bstrText);
296 }
297 else
298 {
299 USES_CONVERSION;
300 LPTSTR lpstrText = OLE2T(bstrText);
301 ATLASSERT(!bValidate || (lstrlen(lpstrText) <= nLength));
302 bSuccess = pT->SetDlgItemText(nID, lpstrText);
303 }
304
305 if(!bSuccess)
306 {
307 pT->OnDataExchangeError(nID, bSave);
308 }
309 else if(bSave && bValidate) // validation
310 {
311 ATLASSERT(nLength > 0);
312 if((int)bstrText.Length() > nLength)
313 {
314 _XData data = { ddxDataText };
315 data.textData.nLength = (int)bstrText.Length();
316 data.textData.nMaxLength = nLength;
317 pT->OnDataValidateError(nID, bSave, data);
318 bSuccess = FALSE;
319 }
320 }
321 return bSuccess;
322 }
323
324 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
325 BOOL DDX_Text(UINT nID, _CSTRING_NS::CString& strText, int /*cbSize*/, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0)
326 {
327 T* pT = static_cast<T*>(this);
328 BOOL bSuccess = TRUE;
329
330 if(bSave)
331 {
332 HWND hWndCtrl = pT->GetDlgItem(nID);
333 int nLen = ::GetWindowTextLength(hWndCtrl);
334 int nRetLen = -1;
335 LPTSTR lpstr = strText.GetBufferSetLength(nLen);
336 if(lpstr != NULL)
337 {
338 nRetLen = ::GetWindowText(hWndCtrl, lpstr, nLen + 1);
339 strText.ReleaseBuffer();
340 }
341 if(nRetLen < nLen)
342 bSuccess = FALSE;
343 }
344 else
345 {
346 bSuccess = pT->SetDlgItemText(nID, strText);
347 }
348
349 if(!bSuccess)
350 {
351 pT->OnDataExchangeError(nID, bSave);
352 }
353 else if(bSave && bValidate) // validation
354 {
355 ATLASSERT(nLength > 0);
356 if(strText.GetLength() > nLength)
357 {
358 _XData data = { ddxDataText };
359 data.textData.nLength = strText.GetLength();
360 data.textData.nMaxLength = nLength;
361 pT->OnDataValidateError(nID, bSave, data);
362 bSuccess = FALSE;
363 }
364 }
365 return bSuccess;
366 }
367 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
368
369 // Numeric exchange
370 template <class Type>
371 BOOL DDX_Int(UINT nID, Type& nVal, BOOL bSigned, BOOL bSave, BOOL bValidate = FALSE, Type nMin = 0, Type nMax = 0)
372 {
373 T* pT = static_cast<T*>(this);
374 BOOL bSuccess = TRUE;
375
376 if(bSave)
377 {
378 nVal = (Type)pT->GetDlgItemInt(nID, &bSuccess, bSigned);
379 }
380 else
381 {
382 ATLASSERT(!bValidate || (nVal >= nMin && nVal <= nMax));
383 bSuccess = pT->SetDlgItemInt(nID, nVal, bSigned);
384 }
385
386 if(!bSuccess)
387 {
388 pT->OnDataExchangeError(nID, bSave);
389 }
390 else if(bSave && bValidate) // validation
391 {
392 ATLASSERT(nMin != nMax);
393 if(nVal < nMin || nVal > nMax)
394 {
395 _XData data = { ddxDataInt };
396 data.intData.nVal = (long)nVal;
397 data.intData.nMin = (long)nMin;
398 data.intData.nMax = (long)nMax;
399 pT->OnDataValidateError(nID, bSave, data);
400 bSuccess = FALSE;
401 }
402 }
403 return bSuccess;
404 }
405
406 // Float exchange
407 #ifdef _ATL_USE_DDX_FLOAT
408 static BOOL _AtlSimpleFloatParse(LPCTSTR lpszText, double& d)
409 {
410 ATLASSERT(lpszText != NULL);
411 while (*lpszText == _T(' ') || *lpszText == _T('\t'))
412 lpszText++;
413
414 TCHAR chFirst = lpszText[0];
415 d = _tcstod(lpszText, (LPTSTR*)&lpszText);
416 if (d == 0.0 && chFirst != _T('0'))
417 return FALSE; // could not convert
418 while (*lpszText == _T(' ') || *lpszText == _T('\t'))
419 lpszText++;
420
421 if (*lpszText != _T('\0'))
422 return FALSE; // not terminated properly
423
424 return TRUE;
425 }
426
427 BOOL DDX_Float(UINT nID, float& nVal, BOOL bSave, BOOL bValidate = FALSE, float nMin = 0.F, float nMax = 0.F, int nPrecision = FLT_DIG)
428 {
429 T* pT = static_cast<T*>(this);
430 BOOL bSuccess = TRUE;
431 const int cchBuff = 32;
432 TCHAR szBuff[cchBuff] = { 0 };
433
434 if(bSave)
435 {
436 pT->GetDlgItemText(nID, szBuff, cchBuff);
437 double d = 0;
438 if(_AtlSimpleFloatParse(szBuff, d))
439 nVal = (float)d;
440 else
441 bSuccess = FALSE;
442 }
443 else
444 {
445 ATLASSERT(!bValidate || (nVal >= nMin && nVal <= nMax));
446 SecureHelper::sprintf_x(szBuff, cchBuff, _T("%.*g"), nPrecision, nVal);
447 bSuccess = pT->SetDlgItemText(nID, szBuff);
448 }
449
450 if(!bSuccess)
451 {
452 pT->OnDataExchangeError(nID, bSave);
453 }
454 else if(bSave && bValidate) // validation
455 {
456 ATLASSERT(nMin != nMax);
457 if(nVal < nMin || nVal > nMax)
458 {
459 _XData data = { ddxDataFloat };
460 data.floatData.nVal = (double)nVal;
461 data.floatData.nMin = (double)nMin;
462 data.floatData.nMax = (double)nMax;
463 pT->OnDataValidateError(nID, bSave, data);
464 bSuccess = FALSE;
465 }
466 }
467 return bSuccess;
468 }
469
470 BOOL DDX_Float(UINT nID, double& nVal, BOOL bSave, BOOL bValidate = FALSE, double nMin = 0., double nMax = 0., int nPrecision = DBL_DIG)
471 {
472 T* pT = static_cast<T*>(this);
473 BOOL bSuccess = TRUE;
474 const int cchBuff = 32;
475 TCHAR szBuff[cchBuff] = { 0 };
476
477 if(bSave)
478 {
479 pT->GetDlgItemText(nID, szBuff, cchBuff);
480 double d = 0;
481 if(_AtlSimpleFloatParse(szBuff, d))
482 nVal = d;
483 else
484 bSuccess = FALSE;
485 }
486 else
487 {
488 ATLASSERT(!bValidate || (nVal >= nMin && nVal <= nMax));
489 SecureHelper::sprintf_x(szBuff, cchBuff, _T("%.*g"), nPrecision, nVal);
490 bSuccess = pT->SetDlgItemText(nID, szBuff);
491 }
492
493 if(!bSuccess)
494 {
495 pT->OnDataExchangeError(nID, bSave);
496 }
497 else if(bSave && bValidate) // validation
498 {
499 ATLASSERT(nMin != nMax);
500 if(nVal < nMin || nVal > nMax)
501 {
502 _XData data = { ddxDataFloat };
503 data.floatData.nVal = nVal;
504 data.floatData.nMin = nMin;
505 data.floatData.nMax = nMax;
506 pT->OnDataValidateError(nID, bSave, data);
507 bSuccess = FALSE;
508 }
509 }
510 return bSuccess;
511 }
512 #endif // _ATL_USE_DDX_FLOAT
513
514 // Full control subclassing (for CWindowImpl derived controls)
515 template <class TControl>
516 void DDX_Control(UINT nID, TControl& ctrl, BOOL bSave)
517 {
518 if(!bSave && ctrl.m_hWnd == NULL)
519 {
520 T* pT = static_cast<T*>(this);
521 ctrl.SubclassWindow(pT->GetDlgItem(nID));
522 }
523 }
524
525 // Simple control attaching (for HWND wrapper controls)
526 template <class TControl>
527 void DDX_Control_Handle(UINT nID, TControl& ctrl, BOOL bSave)
528 {
529 if(!bSave && ctrl.m_hWnd == NULL)
530 {
531 T* pT = static_cast<T*>(this);
532 ctrl = pT->GetDlgItem(nID);
533 }
534 }
535
536 // Control state
537 void DDX_Check(UINT nID, int& nValue, BOOL bSave)
538 {
539 T* pT = static_cast<T*>(this);
540 HWND hWndCtrl = pT->GetDlgItem(nID);
541 if(bSave)
542 {
543 nValue = (int)::SendMessage(hWndCtrl, BM_GETCHECK, 0, 0L);
544 ATLASSERT(nValue >= 0 && nValue <= 2);
545 }
546 else
547 {
548 if(nValue < 0 || nValue > 2)
549 {
550 ATLTRACE2(atlTraceUI, 0, _T("ATL: Warning - dialog data checkbox value (%d) out of range.\n"), nValue);
551 nValue = 0; // default to off
552 }
553 ::SendMessage(hWndCtrl, BM_SETCHECK, nValue, 0L);
554 }
555 }
556
557 // variant that supports bool (checked/not-checked, no intermediate state)
558 void DDX_Check(UINT nID, bool& bCheck, BOOL bSave)
559 {
560 int nValue = bCheck ? 1 : 0;
561 DDX_Check(nID, nValue, bSave);
562
563 if(bSave)
564 {
565 if(nValue == 2)
566 ATLTRACE2(atlTraceUI, 0, _T("ATL: Warning - checkbox state (%d) out of supported range.\n"), nValue);
567 bCheck = (nValue == 1);
568 }
569 }
570
571 void DDX_Radio(UINT nID, int& nValue, BOOL bSave)
572 {
573 T* pT = static_cast<T*>(this);
574 HWND hWndCtrl = pT->GetDlgItem(nID);
575 ATLASSERT(hWndCtrl != NULL);
576
577 // must be first in a group of auto radio buttons
578 ATLASSERT(::GetWindowLong(hWndCtrl, GWL_STYLE) & WS_GROUP);
579 ATLASSERT(::SendMessage(hWndCtrl, WM_GETDLGCODE, 0, 0L) & DLGC_RADIOBUTTON);
580
581 if(bSave)
582 nValue = -1; // value if none found
583
584 // walk all children in group
585 int nButton = 0;
586 do
587 {
588 if(::SendMessage(hWndCtrl, WM_GETDLGCODE, 0, 0L) & DLGC_RADIOBUTTON)
589 {
590 // control in group is a radio button
591 if(bSave)
592 {
593 if(::SendMessage(hWndCtrl, BM_GETCHECK, 0, 0L) != 0)
594 {
595 ATLASSERT(nValue == -1); // only set once
596 nValue = nButton;
597 }
598 }
599 else
600 {
601 // select button
602 ::SendMessage(hWndCtrl, BM_SETCHECK, (nButton == nValue), 0L);
603 }
604 nButton++;
605 }
606 else
607 {
608 ATLTRACE2(atlTraceUI, 0, _T("ATL: Warning - skipping non-radio button in group.\n"));
609 }
610 hWndCtrl = ::GetWindow(hWndCtrl, GW_HWNDNEXT);
611 }
612 while (hWndCtrl != NULL && !(GetWindowLong(hWndCtrl, GWL_STYLE) & WS_GROUP));
613 }
614
615 // DDX support for Tab, Combo, ListBox and ListView selection index
616 #if (_MSC_VER >= 1300)
617 template <class TCtrl>
618 INT _getSel(TCtrl& tCtrl)
619 {
620 return tCtrl.GetCurSel();
621 }
622
623 template <class TCtrl>
624 void _setSel(TCtrl& tCtrl, INT iSel)
625 {
626 if(iSel < 0)
627 tCtrl.SetCurSel(-1);
628 else
629 tCtrl.SetCurSel(iSel);
630 }
631
632 #ifdef __ATLCTRLS_H__
633 // ListViewCtrl specialization
634 template <>
635 INT _getSel(WTL::CListViewCtrl& tCtrl)
636 {
637 return tCtrl.GetSelectedIndex();
638 }
639
640 template <>
641 void _setSel(WTL::CListViewCtrl& tCtrl, INT iSel)
642 {
643 if(iSel < 0)
644 tCtrl.SelectItem(-1);
645 else
646 tCtrl.SelectItem(iSel);
647 }
648 #endif // __ATLCTRLS_H__
649
650 template <class TCtrl>
651 void DDX_Index(UINT nID, INT& nVal, BOOL bSave)
652 {
653 T* pT = static_cast<T*>(this);
654 TCtrl ctrl(pT->GetDlgItem(nID));
655
656 if(bSave)
657 nVal = _getSel(ctrl);
658 else
659 _setSel(ctrl, nVal);
660 }
661 #endif // (_MSC_VER >= 1300)
662
663 // Overrideables
664 void OnDataExchangeError(UINT nCtrlID, BOOL /*bSave*/)
665 {
666 // Override to display an error message
667 ::MessageBeep((UINT)-1);
668 T* pT = static_cast<T*>(this);
669 ::SetFocus(pT->GetDlgItem(nCtrlID));
670 }
671
672 void OnDataValidateError(UINT nCtrlID, BOOL /*bSave*/, _XData& /*data*/)
673 {
674 // Override to display an error message
675 ::MessageBeep((UINT)-1);
676 T* pT = static_cast<T*>(this);
677 ::SetFocus(pT->GetDlgItem(nCtrlID));
678 }
679 };
680
681 }; // namespace WTL
682
683 #endif // __ATLDDX_H__
+0
-6507
src/third_party/wtl/Include/atldlgs.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLDLGS_H__
9 #define __ATLDLGS_H__
10
11 #pragma once
12
13 #ifndef __ATLAPP_H__
14 #error atldlgs.h requires atlapp.h to be included first
15 #endif
16
17 #ifndef __ATLWIN_H__
18 #error atldlgs.h requires atlwin.h to be included first
19 #endif
20
21 #include <commdlg.h>
22 #include <shlobj.h>
23
24 #if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
25 #include <shobjidl.h>
26 #endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
27
28
29 ///////////////////////////////////////////////////////////////////////////////
30 // Classes in this file:
31 //
32 // CFileDialogImpl<T>
33 // CFileDialog
34 // CFileDialogEx
35 // CMultiFileDialogImpl<T>
36 // CMultiFileDialog
37 // CShellFileDialogImpl<T>
38 // CShellFileOpenDialogImpl<T>
39 // CShellFileOpenDialog
40 // CShellFileSaveDialogImpl<T>
41 // CShellFileSaveDialog
42 // CFolderDialogImpl<T>
43 // CFolderDialog
44 // CFontDialogImpl<T>
45 // CFontDialog
46 // CRichEditFontDialogImpl<T>
47 // CRichEditFontDialog
48 // CColorDialogImpl<T>
49 // CColorDialog
50 // CPrintDialogImpl<T>
51 // CPrintDialog
52 // CPrintDialogExImpl<T>
53 // CPrintDialogEx
54 // CPageSetupDialogImpl<T>
55 // CPageSetupDialog
56 // CFindReplaceDialogImpl<T>
57 // CFindReplaceDialog
58 //
59 // CDialogBaseUnits
60 // CMemDlgTemplate
61 // CIndirectDialogImpl<T, TDlgTemplate, TBase>
62 //
63 // CPropertySheetWindow
64 // CPropertySheetImpl<T, TBase>
65 // CPropertySheet
66 // CPropertyPageWindow
67 // CPropertyPageImpl<T, TBase>
68 // CPropertyPage<t_wDlgTemplateID>
69 // CAxPropertyPageImpl<T, TBase>
70 // CAxPropertyPage<t_wDlgTemplateID>
71 //
72 // CWizard97SheetWindow
73 // CWizard97SheetImpl<T, TBase>
74 // CWizard97Sheet
75 // CWizard97PageWindow
76 // CWizard97PageImpl<T, TBase>
77 // CWizard97ExteriorPageImpl<T, TBase>
78 // CWizard97InteriorPageImpl<T, TBase>
79 //
80 // CAeroWizardFrameWindow
81 // CAeroWizardFrameImpl<T, TBase>
82 // CAeroWizardFrame
83 // CAeroWizardPageWindow
84 // CAeroWizardPageImpl<T, TBase>
85 // CAeroWizardPage<t_wDlgTemplateID>
86 // CAeroWizardAxPageImpl<T, TBase>
87 // CAeroWizardAxPage<t_wDlgTemplateID>
88 //
89 // CTaskDialogConfig
90 // CTaskDialogImpl<T>
91 // CTaskDialog
92 //
93 // Global functions:
94 // AtlTaskDialog()
95
96
97 namespace WTL
98 {
99
100 ///////////////////////////////////////////////////////////////////////////////
101 // CFileDialogImpl - used for File Open or File Save As
102
103 // compatibility with the old (vc6.0) headers
104 #if (_WIN32_WINNT >= 0x0500) && !defined(OPENFILENAME_SIZE_VERSION_400)
105 #ifndef CDSIZEOF_STRUCT
106 #define CDSIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member))
107 #endif
108 #define OPENFILENAME_SIZE_VERSION_400A CDSIZEOF_STRUCT(OPENFILENAMEA,lpTemplateName)
109 #define OPENFILENAME_SIZE_VERSION_400W CDSIZEOF_STRUCT(OPENFILENAMEW,lpTemplateName)
110 #ifdef UNICODE
111 #define OPENFILENAME_SIZE_VERSION_400 OPENFILENAME_SIZE_VERSION_400W
112 #else
113 #define OPENFILENAME_SIZE_VERSION_400 OPENFILENAME_SIZE_VERSION_400A
114 #endif // !UNICODE
115 #endif // (_WIN32_WINNT >= 0x0500) && !defined(OPENFILENAME_SIZE_VERSION_400)
116
117 #if !defined(_WIN32_WCE) && !defined(CDN_INCLUDEITEM)
118 #define CDN_INCLUDEITEM (CDN_FIRST - 0x0007)
119 #endif
120
121 template <class T>
122 class ATL_NO_VTABLE CFileDialogImpl : public ATL::CDialogImplBase
123 {
124 public:
125 #if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501)
126 OPENFILENAMEEX m_ofn;
127 #else
128 OPENFILENAME m_ofn;
129 #endif
130 BOOL m_bOpenFileDialog; // TRUE for file open, FALSE for file save
131 TCHAR m_szFileTitle[_MAX_FNAME]; // contains file title after return
132 TCHAR m_szFileName[_MAX_PATH]; // contains full path name after return
133
134 CFileDialogImpl(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
135 LPCTSTR lpszDefExt = NULL,
136 LPCTSTR lpszFileName = NULL,
137 DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
138 LPCTSTR lpszFilter = NULL,
139 HWND hWndParent = NULL)
140 {
141 memset(&m_ofn, 0, sizeof(m_ofn)); // initialize structure to 0/NULL
142 m_szFileName[0] = _T('\0');
143 m_szFileTitle[0] = _T('\0');
144
145 m_bOpenFileDialog = bOpenFileDialog;
146
147 #if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501)
148 m_ofn.lStructSize = bOpenFileDialog ? sizeof(m_ofn) : sizeof(OPENFILENAME);
149 #else
150 m_ofn.lStructSize = sizeof(m_ofn);
151 #endif
152
153 #if (_WIN32_WINNT >= 0x0500)
154 // adjust struct size if running on older version of Windows
155 if(AtlIsOldWindows())
156 {
157 ATLASSERT(sizeof(m_ofn) > OPENFILENAME_SIZE_VERSION_400); // must be
158 m_ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
159 }
160 #endif // (_WIN32_WINNT >= 0x0500)
161 m_ofn.lpstrFile = m_szFileName;
162 m_ofn.nMaxFile = _MAX_PATH;
163 m_ofn.lpstrDefExt = lpszDefExt;
164 m_ofn.lpstrFileTitle = (LPTSTR)m_szFileTitle;
165 m_ofn.nMaxFileTitle = _MAX_FNAME;
166 #ifndef _WIN32_WCE
167 m_ofn.Flags = dwFlags | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLESIZING;
168 #else // CE specific
169 m_ofn.Flags = dwFlags | OFN_EXPLORER | OFN_ENABLEHOOK;
170 #endif // !_WIN32_WCE
171 m_ofn.lpstrFilter = lpszFilter;
172 m_ofn.hInstance = ModuleHelper::GetResourceInstance();
173 m_ofn.lpfnHook = (LPOFNHOOKPROC)T::StartDialogProc;
174 m_ofn.hwndOwner = hWndParent;
175
176 // setup initial file name
177 if(lpszFileName != NULL)
178 SecureHelper::strncpy_x(m_szFileName, _countof(m_szFileName), lpszFileName, _TRUNCATE);
179 }
180
181 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
182 {
183 ATLASSERT((m_ofn.Flags & OFN_ENABLEHOOK) != 0);
184 ATLASSERT(m_ofn.lpfnHook != NULL); // can still be a user hook
185
186 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);
187
188 if(m_ofn.hwndOwner == NULL) // set only if not specified before
189 m_ofn.hwndOwner = hWndParent;
190
191 ATLASSERT(m_hWnd == NULL);
192
193 #if (_ATL_VER >= 0x0800)
194 // Allocate the thunk structure here, where we can fail gracefully.
195 BOOL bRetTh = m_thunk.Init(NULL, NULL);
196 if(bRetTh == FALSE)
197 {
198 ::SetLastError(ERROR_OUTOFMEMORY);
199 return -1;
200 }
201 #endif // (_ATL_VER >= 0x0800)
202
203 ModuleHelper::AddCreateWndData(&m_thunk.cd, (ATL::CDialogImplBase*)this);
204
205 BOOL bRet;
206 if(m_bOpenFileDialog)
207 #if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501)
208 bRet = ::GetOpenFileNameEx(&m_ofn);
209 else
210 bRet = ::GetSaveFileName((LPOPENFILENAME)&m_ofn);
211 #else
212 bRet = ::GetOpenFileName(&m_ofn);
213 else
214 bRet = ::GetSaveFileName(&m_ofn);
215 #endif
216
217 m_hWnd = NULL;
218
219 return bRet ? IDOK : IDCANCEL;
220 }
221
222 // Attributes
223 ATL::CWindow GetFileDialogWindow() const
224 {
225 ATLASSERT(::IsWindow(m_hWnd));
226 return ATL::CWindow(GetParent());
227 }
228
229 int GetFilePath(LPTSTR lpstrFilePath, int nLength) const
230 {
231 ATLASSERT(::IsWindow(m_hWnd));
232 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);
233
234 return (int)GetFileDialogWindow().SendMessage(CDM_GETFILEPATH, nLength, (LPARAM)lpstrFilePath);
235 }
236
237 int GetFolderIDList(LPVOID lpBuff, int nLength) const
238 {
239 ATLASSERT(::IsWindow(m_hWnd));
240 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);
241
242 return (int)GetFileDialogWindow().SendMessage(CDM_GETFOLDERIDLIST, nLength, (LPARAM)lpBuff);
243 }
244
245 int GetFolderPath(LPTSTR lpstrFolderPath, int nLength) const
246 {
247 ATLASSERT(::IsWindow(m_hWnd));
248 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);
249
250 return (int)GetFileDialogWindow().SendMessage(CDM_GETFOLDERPATH, nLength, (LPARAM)lpstrFolderPath);
251 }
252
253 int GetSpec(LPTSTR lpstrSpec, int nLength) const
254 {
255 ATLASSERT(::IsWindow(m_hWnd));
256 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);
257
258 return (int)GetFileDialogWindow().SendMessage(CDM_GETSPEC, nLength, (LPARAM)lpstrSpec);
259 }
260
261 void SetControlText(int nCtrlID, LPCTSTR lpstrText)
262 {
263 ATLASSERT(::IsWindow(m_hWnd));
264 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);
265
266 GetFileDialogWindow().SendMessage(CDM_SETCONTROLTEXT, nCtrlID, (LPARAM)lpstrText);
267 }
268
269 void SetDefExt(LPCTSTR lpstrExt)
270 {
271 ATLASSERT(::IsWindow(m_hWnd));
272 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);
273
274 GetFileDialogWindow().SendMessage(CDM_SETDEFEXT, 0, (LPARAM)lpstrExt);
275 }
276
277 BOOL GetReadOnlyPref() const // return TRUE if readonly checked
278 {
279 return ((m_ofn.Flags & OFN_READONLY) != 0) ? TRUE : FALSE;
280 }
281
282 // Operations
283 void HideControl(int nCtrlID)
284 {
285 ATLASSERT(::IsWindow(m_hWnd));
286 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);
287
288 GetFileDialogWindow().SendMessage(CDM_HIDECONTROL, nCtrlID);
289 }
290
291 // Special override for common dialogs
292 BOOL EndDialog(INT_PTR /*nRetCode*/ = 0)
293 {
294 ATLASSERT(::IsWindow(m_hWnd));
295 GetFileDialogWindow().SendMessage(WM_COMMAND, MAKEWPARAM(IDCANCEL, 0));
296 return TRUE;
297 }
298
299 // Message map and handlers
300 BEGIN_MSG_MAP(CFileDialogImpl)
301 NOTIFY_CODE_HANDLER(CDN_FILEOK, _OnFileOK)
302 NOTIFY_CODE_HANDLER(CDN_FOLDERCHANGE, _OnFolderChange)
303 NOTIFY_CODE_HANDLER(CDN_HELP, _OnHelp)
304 NOTIFY_CODE_HANDLER(CDN_INITDONE, _OnInitDone)
305 NOTIFY_CODE_HANDLER(CDN_SELCHANGE, _OnSelChange)
306 NOTIFY_CODE_HANDLER(CDN_SHAREVIOLATION, _OnShareViolation)
307 NOTIFY_CODE_HANDLER(CDN_TYPECHANGE, _OnTypeChange)
308 #ifndef _WIN32_WCE
309 NOTIFY_CODE_HANDLER(CDN_INCLUDEITEM, _OnIncludeItem)
310 #endif // !_WIN32_WCE
311 END_MSG_MAP()
312
313 LRESULT _OnFileOK(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
314 {
315 ATLASSERT(::IsWindow(m_hWnd));
316 T* pT = static_cast<T*>(this);
317 return !pT->OnFileOK((LPOFNOTIFY)pnmh);
318 }
319
320 LRESULT _OnFolderChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
321 {
322 ATLASSERT(::IsWindow(m_hWnd));
323 T* pT = static_cast<T*>(this);
324 pT->OnFolderChange((LPOFNOTIFY)pnmh);
325 return 0;
326 }
327
328 LRESULT _OnHelp(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
329 {
330 ATLASSERT(::IsWindow(m_hWnd));
331 T* pT = static_cast<T*>(this);
332 pT->OnHelp((LPOFNOTIFY)pnmh);
333 return 0;
334 }
335
336 LRESULT _OnInitDone(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
337 {
338 ATLASSERT(::IsWindow(m_hWnd));
339 T* pT = static_cast<T*>(this);
340 pT->OnInitDone((LPOFNOTIFY)pnmh);
341 return 0;
342 }
343
344 LRESULT _OnSelChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
345 {
346 ATLASSERT(::IsWindow(m_hWnd));
347 T* pT = static_cast<T*>(this);
348 pT->OnSelChange((LPOFNOTIFY)pnmh);
349 return 0;
350 }
351
352 LRESULT _OnShareViolation(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
353 {
354 ATLASSERT(::IsWindow(m_hWnd));
355 T* pT = static_cast<T*>(this);
356 return pT->OnShareViolation((LPOFNOTIFY)pnmh);
357 }
358
359 LRESULT _OnTypeChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
360 {
361 ATLASSERT(::IsWindow(m_hWnd));
362 T* pT = static_cast<T*>(this);
363 pT->OnTypeChange((LPOFNOTIFY)pnmh);
364 return 0;
365 }
366
367 #ifndef _WIN32_WCE
368 LRESULT _OnIncludeItem(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
369 {
370 ATLASSERT(::IsWindow(m_hWnd));
371 T* pT = static_cast<T*>(this);
372 return pT->OnIncludeItem((LPOFNOTIFYEX)pnmh);
373 }
374 #endif // !_WIN32_WCE
375
376 // Overrideables
377 BOOL OnFileOK(LPOFNOTIFY /*lpon*/)
378 {
379 return TRUE;
380 }
381
382 void OnFolderChange(LPOFNOTIFY /*lpon*/)
383 {
384 }
385
386 void OnHelp(LPOFNOTIFY /*lpon*/)
387 {
388 }
389
390 void OnInitDone(LPOFNOTIFY /*lpon*/)
391 {
392 }
393
394 void OnSelChange(LPOFNOTIFY /*lpon*/)
395 {
396 }
397
398 int OnShareViolation(LPOFNOTIFY /*lpon*/)
399 {
400 return 0;
401 }
402
403 void OnTypeChange(LPOFNOTIFY /*lpon*/)
404 {
405 }
406
407 #ifndef _WIN32_WCE
408 BOOL OnIncludeItem(LPOFNOTIFYEX /*lponex*/)
409 {
410 return TRUE; // include item
411 }
412 #endif // !_WIN32_WCE
413 };
414
415 class CFileDialog : public CFileDialogImpl<CFileDialog>
416 {
417 public:
418 CFileDialog(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
419 LPCTSTR lpszDefExt = NULL,
420 LPCTSTR lpszFileName = NULL,
421 DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
422 LPCTSTR lpszFilter = NULL,
423 HWND hWndParent = NULL)
424 : CFileDialogImpl<CFileDialog>(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, hWndParent)
425 { }
426
427 // override base class map and references to handlers
428 DECLARE_EMPTY_MSG_MAP()
429 };
430
431 #if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501)
432 class CFileDialogEx : public CFileDialogImpl<CFileDialogEx>
433 {
434 public:
435 CFileDialogEx( // Supports only FileOpen
436 LPCTSTR lpszDefExt = NULL,
437 LPCTSTR lpszFileName = NULL,
438 DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
439 OFN_EXFLAG ExFlags = OFN_EXFLAG_THUMBNAILVIEW,
440 OFN_SORTORDER dwSortOrder = OFN_SORTORDER_AUTO,
441 LPCTSTR lpszFilter = NULL,
442 HWND hWndParent = NULL)
443 : CFileDialogImpl<CFileDialogEx>(TRUE, lpszDefExt, lpszFileName, dwFlags, lpszFilter, hWndParent)
444 {
445 m_ofn.ExFlags = ExFlags;
446 m_ofn.dwSortOrder = dwSortOrder;
447 }
448
449 // override base class map and references to handlers
450 DECLARE_EMPTY_MSG_MAP()
451 };
452 #endif // defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501)
453
454
455 ///////////////////////////////////////////////////////////////////////////////
456 // Multi File Dialog - Multi-select File Open dialog
457
458 #ifndef _WIN32_WCE
459
460 // The class dynamically resizes the buffer as the file selection changes
461 // (as described in Knowledge Base article 131462). It also expands selected
462 // shortcut files to take into account the full path of the target file.
463 // Note that this doesn't work on Win9x for the old style dialogs, as well as
464 // on NT for non-Unicode builds.
465
466 #ifndef _WTL_FIXED_OFN_BUFFER_LENGTH
467 #define _WTL_FIXED_OFN_BUFFER_LENGTH 0x10000
468 #endif
469
470 template <class T>
471 class ATL_NO_VTABLE CMultiFileDialogImpl : public CFileDialogImpl< T >
472 {
473 public:
474 mutable LPCTSTR m_pNextFile;
475 #ifndef _UNICODE
476 bool m_bIsNT;
477 #endif
478
479 CMultiFileDialogImpl(
480 LPCTSTR lpszDefExt = NULL,
481 LPCTSTR lpszFileName = NULL,
482 DWORD dwFlags = OFN_HIDEREADONLY,
483 LPCTSTR lpszFilter = NULL,
484 HWND hWndParent = NULL)
485 : CFileDialogImpl<T>(TRUE, lpszDefExt, lpszFileName, dwFlags, lpszFilter, hWndParent),
486 m_pNextFile(NULL)
487 {
488 m_ofn.Flags |= OFN_ALLOWMULTISELECT; // Force multiple selection mode
489
490 #ifndef _UNICODE
491 #ifdef _versionhelpers_H_INCLUDED_
492 OSVERSIONINFOEX ovi = { sizeof(OSVERSIONINFOEX) };
493 ovi.dwPlatformId = VER_PLATFORM_WIN32_NT;
494 DWORDLONG const dwlConditionMask = ::VerSetConditionMask(0, VER_PLATFORMID, VER_EQUAL);
495 m_bIsNT = (::VerifyVersionInfo(&ovi, VER_PLATFORMID, dwlConditionMask) != FALSE);
496 #else // !_versionhelpers_H_INCLUDED_
497 OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) };
498 ::GetVersionEx(&ovi);
499 m_bIsNT = (ovi.dwPlatformId == VER_PLATFORM_WIN32_NT);
500 #endif // _versionhelpers_H_INCLUDED_
501 if (m_bIsNT)
502 {
503 // On NT platforms, GetOpenFileNameA thunks to GetOpenFileNameW and there
504 // is absolutely nothing we can do except to start off with a large buffer.
505 ATLVERIFY(ResizeFilenameBuffer(_WTL_FIXED_OFN_BUFFER_LENGTH));
506 }
507 #endif
508 }
509
510 ~CMultiFileDialogImpl()
511 {
512 if (m_ofn.lpstrFile != m_szFileName) // Free the buffer if we allocated it
513 delete[] m_ofn.lpstrFile;
514 }
515
516 // Operations
517 // Get the directory that the files were chosen from.
518 // The function returns the number of characters copied, not including the terminating zero.
519 // If the buffer is NULL, the function returns the required size, in characters, including the terminating zero.
520 // If the function fails, the return value is zero.
521 int GetDirectory(LPTSTR pBuffer, int nBufLen) const
522 {
523 if (m_ofn.lpstrFile == NULL)
524 return 0;
525
526 LPCTSTR pStr = m_ofn.lpstrFile;
527 int nLength = lstrlen(pStr);
528 if (pStr[nLength + 1] == 0)
529 {
530 // The OFN buffer contains a single item so extract its path.
531 LPCTSTR pSep = MinCrtHelper::_strrchr(pStr, _T('\\'));
532 if (pSep != NULL)
533 nLength = (int)(DWORD_PTR)(pSep - pStr);
534 }
535
536 int nRet = 0;
537 if (pBuffer == NULL) // If the buffer is NULL, return the required length
538 {
539 nRet = nLength + 1;
540 }
541 else if (nBufLen > nLength)
542 {
543 SecureHelper::strncpy_x(pBuffer, nBufLen, pStr, nLength);
544 nRet = nLength;
545 }
546
547 return nRet;
548 }
549
550 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
551 bool GetDirectory(_CSTRING_NS::CString& strDir) const
552 {
553 bool bRet = false;
554
555 int nLength = GetDirectory(NULL, 0);
556 if (nLength > 0)
557 {
558 bRet = (GetDirectory(strDir.GetBuffer(nLength), nLength) > 0);
559 strDir.ReleaseBuffer(nLength - 1);
560 }
561
562 return bRet;
563 }
564 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
565
566 // Get the first filename as a pointer into the buffer.
567 LPCTSTR GetFirstFileName() const
568 {
569 if (m_ofn.lpstrFile == NULL)
570 return NULL;
571
572 m_pNextFile = NULL; // Reset internal buffer pointer
573
574 LPCTSTR pStr = m_ofn.lpstrFile;
575 int nLength = lstrlen(pStr);
576 if (pStr[nLength + 1] != 0)
577 {
578 // Multiple items were selected. The first string is the directory,
579 // so skip forwards to the second string.
580 pStr += nLength + 1;
581
582 // Set up m_pNext so it points to the second item (or null).
583 m_pNextFile = pStr;
584 GetNextFileName();
585 }
586 else
587 {
588 // A single item was selected. Skip forward past the path.
589 LPCTSTR pSep = MinCrtHelper::_strrchr(pStr, _T('\\'));
590 if (pSep != NULL)
591 pStr = pSep + 1;
592 }
593
594 return pStr;
595 }
596
597 // Get the next filename as a pointer into the buffer.
598 LPCTSTR GetNextFileName() const
599 {
600 if (m_pNextFile == NULL)
601 return NULL;
602
603 LPCTSTR pStr = m_pNextFile;
604 // Set "m_pNextFile" to point to the next file name, or null if we
605 // have reached the last file in the list.
606 int nLength = lstrlen(pStr);
607 m_pNextFile = (pStr[nLength + 1] != 0) ? &pStr[nLength + 1] : NULL;
608
609 return pStr;
610 }
611
612 // Get the first filename as a full path.
613 // The function returns the number of characters copied, not including the terminating zero.
614 // If the buffer is NULL, the function returns the required size, in characters, including the terminating zero.
615 // If the function fails, the return value is zero.
616 int GetFirstPathName(LPTSTR pBuffer, int nBufLen) const
617 {
618 LPCTSTR pStr = GetFirstFileName();
619 int nLengthDir = GetDirectory(NULL, 0);
620 if((pStr == NULL) || (nLengthDir == 0))
621 return 0;
622
623 // Figure out the required length.
624 int nLengthTotal = nLengthDir + lstrlen(pStr);
625
626 int nRet = 0;
627 if(pBuffer == NULL) // If the buffer is NULL, return the required length
628 {
629 nRet = nLengthTotal + 1;
630 }
631 else if (nBufLen > nLengthTotal) // If the buffer is big enough, go ahead and construct the path
632 {
633 GetDirectory(pBuffer, nBufLen);
634 SecureHelper::strcat_x(pBuffer, nBufLen, _T("\\"));
635 SecureHelper::strcat_x(pBuffer, nBufLen, pStr);
636 nRet = nLengthTotal;
637 }
638
639 return nRet;
640 }
641
642 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
643 bool GetFirstPathName(_CSTRING_NS::CString& strPath) const
644 {
645 bool bRet = false;
646
647 int nLength = GetFirstPathName(NULL, 0);
648 if (nLength > 0)
649 {
650 bRet = (GetFirstPathName(strPath.GetBuffer(nLength), nLength) > 0);
651 strPath.ReleaseBuffer(nLength - 1);
652 }
653
654 return bRet;
655 }
656 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
657
658 // Get the next filename as a full path.
659 // The function returns the number of characters copied, not including the terminating zero.
660 // If the buffer is NULL, the function returns the required size, in characters, including the terminating zero.
661 // If the function fails, the return value is zero.
662 // The internal position marker is moved forward only if the function succeeds and the buffer was large enough.
663 int GetNextPathName(LPTSTR pBuffer, int nBufLen) const
664 {
665 if (m_pNextFile == NULL)
666 return 0;
667
668 int nRet = 0;
669 LPCTSTR pStr = m_pNextFile;
670 // Does the filename contain a backslash?
671 if (MinCrtHelper::_strrchr(pStr, _T('\\')) != NULL)
672 {
673 // Yes, so we'll assume it's a full path.
674 int nLength = lstrlen(pStr);
675
676 if (pBuffer == NULL) // If the buffer is NULL, return the required length
677 {
678 nRet = nLength + 1;
679 }
680 else if (nBufLen > nLength) // The buffer is big enough, so go ahead and copy the filename
681 {
682 SecureHelper::strcpy_x(pBuffer, nBufLen, GetNextFileName());
683 nRet = nBufLen;
684 }
685 }
686 else
687 {
688 // The filename is relative, so construct the full path.
689 int nLengthDir = GetDirectory(NULL, 0);
690 if (nLengthDir > 0)
691 {
692 // Calculate the required space.
693 int nLengthTotal = nLengthDir + lstrlen(pStr);
694
695 if(pBuffer == NULL) // If the buffer is NULL, return the required length
696 {
697 nRet = nLengthTotal + 1;
698 }
699 else if (nBufLen > nLengthTotal) // If the buffer is big enough, go ahead and construct the path
700 {
701 GetDirectory(pBuffer, nBufLen);
702 SecureHelper::strcat_x(pBuffer, nBufLen, _T("\\"));
703 SecureHelper::strcat_x(pBuffer, nBufLen, GetNextFileName());
704 nRet = nLengthTotal;
705 }
706 }
707 }
708
709 return nRet;
710 }
711
712 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
713 bool GetNextPathName(_CSTRING_NS::CString& strPath) const
714 {
715 bool bRet = false;
716
717 int nLength = GetNextPathName(NULL, 0);
718 if (nLength > 0)
719 {
720 bRet = (GetNextPathName(strPath.GetBuffer(nLength), nLength) > 0);
721 strPath.ReleaseBuffer(nLength - 1);
722 }
723
724 return bRet;
725 }
726 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
727
728 // Implementation
729 bool ResizeFilenameBuffer(DWORD dwLength)
730 {
731 if (dwLength > m_ofn.nMaxFile)
732 {
733 // Free the old buffer.
734 if (m_ofn.lpstrFile != m_szFileName)
735 {
736 delete[] m_ofn.lpstrFile;
737 m_ofn.lpstrFile = NULL;
738 m_ofn.nMaxFile = 0;
739 }
740
741 // Allocate the new buffer.
742 LPTSTR lpstrBuff = NULL;
743 ATLTRY(lpstrBuff = new TCHAR[dwLength]);
744 if (lpstrBuff != NULL)
745 {
746 m_ofn.lpstrFile = lpstrBuff;
747 m_ofn.lpstrFile[0] = 0;
748 m_ofn.nMaxFile = dwLength;
749 }
750 }
751
752 return (m_ofn.lpstrFile != NULL);
753 }
754
755 void OnSelChange(LPOFNOTIFY /*lpon*/)
756 {
757 #ifndef _UNICODE
758 // There is no point resizing the buffer in ANSI builds running on NT.
759 if (m_bIsNT)
760 return;
761 #endif
762
763 // Get the buffer length required to hold the spec.
764 int nLength = GetSpec(NULL, 0);
765 if (nLength <= 1)
766 return; // no files are selected, presumably
767
768 // Add room for the directory, and an extra terminating zero.
769 nLength += GetFolderPath(NULL, 0) + 1;
770
771 if (!ResizeFilenameBuffer(nLength))
772 {
773 ATLASSERT(FALSE);
774 return;
775 }
776
777 // If we are not following links then our work is done.
778 if ((m_ofn.Flags & OFN_NODEREFERENCELINKS) != 0)
779 return;
780
781 // Get the file spec, which is the text in the edit control.
782 if (GetSpec(m_ofn.lpstrFile, m_ofn.nMaxFile) <= 0)
783 return;
784
785 // Get the ID-list of the current folder.
786 int nBytes = GetFolderIDList(NULL, 0);
787 #ifdef STRICT_TYPED_ITEMIDS
788 CTempBuffer<ITEMIDLIST_RELATIVE> idlist;
789 #else
790 CTempBuffer<ITEMIDLIST> idlist;
791 #endif
792 idlist.AllocateBytes(nBytes);
793 if ((nBytes <= 0) || (GetFolderIDList(idlist, nBytes) <= 0))
794 return;
795
796 // First bind to the desktop folder, then to the current folder.
797 ATL::CComPtr<IShellFolder> pDesktop, pFolder;
798 if (FAILED(::SHGetDesktopFolder(&pDesktop)))
799 return;
800 if (FAILED(pDesktop->BindToObject(idlist, NULL, IID_IShellFolder, (void**)&pFolder)))
801 return;
802
803 // Work through the file spec, looking for quoted filenames. If we find a shortcut file, then
804 // we need to add enough extra buffer space to hold its target path.
805 DWORD nExtraChars = 0;
806 bool bInsideQuotes = false;
807 LPCTSTR pAnchor = m_ofn.lpstrFile;
808 LPCTSTR pChar = m_ofn.lpstrFile;
809 for ( ; *pChar; ++pChar)
810 {
811 // Look for quotation marks.
812 if (*pChar == _T('\"'))
813 {
814 // We are either entering or leaving a passage of quoted text.
815 bInsideQuotes = !bInsideQuotes;
816
817 // Is it an opening or closing quote?
818 if (bInsideQuotes)
819 {
820 // We found an opening quote, so set "pAnchor" to the following character.
821 pAnchor = pChar + 1;
822 }
823 else // closing quote
824 {
825 // Each quoted entity should be shorter than MAX_PATH.
826 if (pChar - pAnchor >= MAX_PATH)
827 return;
828
829 // Get the ID-list and attributes of the file.
830 USES_CONVERSION;
831 int nFileNameLength = (int)(DWORD_PTR)(pChar - pAnchor);
832 TCHAR szFileName[MAX_PATH] = { 0 };
833 SecureHelper::strncpy_x(szFileName, MAX_PATH, pAnchor, nFileNameLength);
834 #ifdef STRICT_TYPED_ITEMIDS
835 PIDLIST_RELATIVE pidl = NULL;
836 #else
837 LPITEMIDLIST pidl = NULL;
838 #endif
839 DWORD dwAttrib = SFGAO_LINK;
840 if (SUCCEEDED(pFolder->ParseDisplayName(NULL, NULL, T2W(szFileName), NULL, &pidl, &dwAttrib)))
841 {
842 // Is it a shortcut file?
843 if (dwAttrib & SFGAO_LINK)
844 {
845 // Bind to its IShellLink interface.
846 ATL::CComPtr<IShellLink> pLink;
847 if (SUCCEEDED(pFolder->BindToObject(pidl, NULL, IID_IShellLink, (void**)&pLink)))
848 {
849 // Get the shortcut's target path.
850 TCHAR szPath[MAX_PATH] = { 0 };
851 if (SUCCEEDED(pLink->GetPath(szPath, MAX_PATH, NULL, 0)))
852 {
853 // If the target path is longer than the shortcut name, then add on the number
854 // of extra characters that are required.
855 int nNewLength = lstrlen(szPath);
856 if (nNewLength > nFileNameLength)
857 nExtraChars += nNewLength - nFileNameLength;
858 }
859 }
860 }
861
862 // Free the ID-list returned by ParseDisplayName.
863 ::CoTaskMemFree(pidl);
864 }
865 }
866 }
867 }
868
869 // If we need more space for shortcut targets, then reallocate.
870 if (nExtraChars > 0)
871 ATLVERIFY(ResizeFilenameBuffer(m_ofn.nMaxFile + nExtraChars));
872 }
873 };
874
875 class CMultiFileDialog : public CMultiFileDialogImpl<CMultiFileDialog>
876 {
877 public:
878 CMultiFileDialog(
879 LPCTSTR lpszDefExt = NULL,
880 LPCTSTR lpszFileName = NULL,
881 DWORD dwFlags = OFN_HIDEREADONLY,
882 LPCTSTR lpszFilter = NULL,
883 HWND hWndParent = NULL)
884 : CMultiFileDialogImpl<CMultiFileDialog>(lpszDefExt, lpszFileName, dwFlags, lpszFilter, hWndParent)
885 { }
886
887 BEGIN_MSG_MAP(CMultiFileDialog)
888 CHAIN_MSG_MAP(CMultiFileDialogImpl<CMultiFileDialog>)
889 END_MSG_MAP()
890 };
891
892 #endif // !_WIN32_WCE
893
894
895 ///////////////////////////////////////////////////////////////////////////////
896 // Shell File Dialog - new Shell File Open and Save dialogs in Vista
897
898 // Note: Use GetPtr() to access dialog interface methods.
899 // Example:
900 // CShellFileOpenDialog dlg;
901 // dlg.GetPtr()->SetTitle(L"MyFileOpenDialog");
902
903 #if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
904
905 ///////////////////////////////////////////////////////////////////////////////
906 // CShellFileDialogImpl - base class for CShellFileOpenDialogImpl and CShellFileSaveDialogImpl
907
908 template <class T>
909 class ATL_NO_VTABLE CShellFileDialogImpl : public IFileDialogEvents
910 {
911 public:
912 // Operations
913 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
914 {
915 INT_PTR nRet = -1;
916
917 T* pT = static_cast<T*>(this);
918 if(pT->m_spFileDlg == NULL)
919 {
920 ATLASSERT(FALSE);
921 return nRet;
922 }
923
924 DWORD dwCookie = 0;
925 pT->_Advise(dwCookie);
926
927 HRESULT hRet = pT->m_spFileDlg->Show(hWndParent);
928 if(SUCCEEDED(hRet))
929 nRet = IDOK;
930 else if(hRet == HRESULT_FROM_WIN32(ERROR_CANCELLED))
931 nRet = IDCANCEL;
932 else
933 ATLASSERT(FALSE); // error
934
935 pT->_Unadvise(dwCookie);
936
937 return nRet;
938 }
939
940 bool IsNull() const
941 {
942 const T* pT = static_cast<const T*>(this);
943 return (pT->m_spFileDlg == NULL);
944 }
945
946 // Operations - get file path after dialog returns
947 HRESULT GetFilePath(LPWSTR lpstrFilePath, int cchLength)
948 {
949 T* pT = static_cast<T*>(this);
950 ATLASSERT(pT->m_spFileDlg != NULL);
951
952 ATL::CComPtr<IShellItem> spItem;
953 HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem);
954
955 if(SUCCEEDED(hRet))
956 hRet = GetFileNameFromShellItem(spItem, SIGDN_FILESYSPATH, lpstrFilePath, cchLength);
957
958 return hRet;
959 }
960
961 HRESULT GetFileTitle(LPWSTR lpstrFileTitle, int cchLength)
962 {
963 T* pT = static_cast<T*>(this);
964 ATLASSERT(pT->m_spFileDlg != NULL);
965
966 ATL::CComPtr<IShellItem> spItem;
967 HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem);
968
969 if(SUCCEEDED(hRet))
970 hRet = GetFileNameFromShellItem(spItem, SIGDN_NORMALDISPLAY, lpstrFileTitle, cchLength);
971
972 return hRet;
973 }
974
975 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
976 HRESULT GetFilePath(_CSTRING_NS::CString& strFilePath)
977 {
978 T* pT = static_cast<T*>(this);
979 ATLASSERT(pT->m_spFileDlg != NULL);
980
981 ATL::CComPtr<IShellItem> spItem;
982 HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem);
983
984 if(SUCCEEDED(hRet))
985 hRet = GetFileNameFromShellItem(spItem, SIGDN_FILESYSPATH, strFilePath);
986
987 return hRet;
988 }
989
990 HRESULT GetFileTitle(_CSTRING_NS::CString& strFileTitle)
991 {
992 T* pT = static_cast<T*>(this);
993 ATLASSERT(pT->m_spFileDlg != NULL);
994
995 ATL::CComPtr<IShellItem> spItem;
996 HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem);
997
998 if(SUCCEEDED(hRet))
999 hRet = GetFileNameFromShellItem(spItem, SIGDN_NORMALDISPLAY, strFileTitle);
1000
1001 return hRet;
1002 }
1003 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
1004
1005 // Helpers for IShellItem
1006 static HRESULT GetFileNameFromShellItem(IShellItem* pShellItem, SIGDN type, LPWSTR lpstr, int cchLength)
1007 {
1008 ATLASSERT(pShellItem != NULL);
1009
1010 LPWSTR lpstrName = NULL;
1011 HRESULT hRet = pShellItem->GetDisplayName(type, &lpstrName);
1012
1013 if(SUCCEEDED(hRet))
1014 {
1015 if(lstrlenW(lpstrName) < cchLength)
1016 {
1017 SecureHelper::strcpyW_x(lpstr, cchLength, lpstrName);
1018 }
1019 else
1020 {
1021 ATLASSERT(FALSE);
1022 hRet = DISP_E_BUFFERTOOSMALL;
1023 }
1024
1025 ::CoTaskMemFree(lpstrName);
1026 }
1027
1028 return hRet;
1029 }
1030
1031 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
1032 static HRESULT GetFileNameFromShellItem(IShellItem* pShellItem, SIGDN type, _CSTRING_NS::CString& str)
1033 {
1034 ATLASSERT(pShellItem != NULL);
1035
1036 LPWSTR lpstrName = NULL;
1037 HRESULT hRet = pShellItem->GetDisplayName(type, &lpstrName);
1038
1039 if(SUCCEEDED(hRet))
1040 {
1041 str = lpstrName;
1042 ::CoTaskMemFree(lpstrName);
1043 }
1044
1045 return hRet;
1046 }
1047 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
1048
1049 // Implementation
1050 void _Advise(DWORD& dwCookie)
1051 {
1052 T* pT = static_cast<T*>(this);
1053 ATLASSERT(pT->m_spFileDlg != NULL);
1054 HRESULT hRet = pT->m_spFileDlg->Advise((IFileDialogEvents*)this, &dwCookie);
1055 ATLVERIFY(SUCCEEDED(hRet));
1056 }
1057
1058 void _Unadvise(DWORD dwCookie)
1059 {
1060 T* pT = static_cast<T*>(this);
1061 ATLASSERT(pT->m_spFileDlg != NULL);
1062 HRESULT hRet = pT->m_spFileDlg->Unadvise(dwCookie);
1063 ATLVERIFY(SUCCEEDED(hRet));
1064 }
1065
1066 void _Init(LPCWSTR lpszFileName, DWORD dwOptions, LPCWSTR lpszDefExt, const COMDLG_FILTERSPEC* arrFilterSpec, UINT uFilterSpecCount)
1067 {
1068 T* pT = static_cast<T*>(this);
1069 ATLASSERT(pT->m_spFileDlg != NULL);
1070
1071 HRESULT hRet = E_FAIL;
1072
1073 if(lpszFileName != NULL)
1074 {
1075 hRet = pT->m_spFileDlg->SetFileName(lpszFileName);
1076 ATLASSERT(SUCCEEDED(hRet));
1077 }
1078
1079 hRet = pT->m_spFileDlg->SetOptions(dwOptions);
1080 ATLASSERT(SUCCEEDED(hRet));
1081
1082 if(lpszDefExt != NULL)
1083 {
1084 hRet = pT->m_spFileDlg->SetDefaultExtension(lpszDefExt);
1085 ATLASSERT(SUCCEEDED(hRet));
1086 }
1087
1088 if(arrFilterSpec != NULL && uFilterSpecCount != 0U)
1089 {
1090 hRet = pT->m_spFileDlg->SetFileTypes(uFilterSpecCount, arrFilterSpec);
1091 ATLASSERT(SUCCEEDED(hRet));
1092 }
1093 }
1094
1095 // Implementation - IUnknown interface
1096 STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject)
1097 {
1098 if(ppvObject == NULL)
1099 return E_POINTER;
1100
1101 T* pT = static_cast<T*>(this);
1102 if(IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IFileDialogEvents))
1103 {
1104 *ppvObject = (IFileDialogEvents*)pT;
1105 // AddRef() not needed
1106 return S_OK;
1107 }
1108
1109 return E_NOINTERFACE;
1110 }
1111
1112 virtual ULONG STDMETHODCALLTYPE AddRef()
1113 {
1114 return 1;
1115 }
1116
1117 virtual ULONG STDMETHODCALLTYPE Release()
1118 {
1119 return 1;
1120 }
1121
1122 // Implementation - IFileDialogEvents interface
1123 virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFileOk(IFileDialog* pfd)
1124 {
1125 T* pT = static_cast<T*>(this);
1126 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
1127 pfd; // avoid level 4 warning
1128 return pT->OnFileOk();
1129 }
1130
1131 virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFolderChanging(IFileDialog* pfd, IShellItem* psiFolder)
1132 {
1133 T* pT = static_cast<T*>(this);
1134 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
1135 pfd; // avoid level 4 warning
1136 return pT->OnFolderChanging(psiFolder);
1137 }
1138
1139 virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFolderChange(IFileDialog* pfd)
1140 {
1141 T* pT = static_cast<T*>(this);
1142 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
1143 pfd; // avoid level 4 warning
1144 return pT->OnFolderChange();
1145 }
1146
1147 virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnSelectionChange(IFileDialog* pfd)
1148 {
1149 T* pT = static_cast<T*>(this);
1150 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
1151 pfd; // avoid level 4 warning
1152 return pT->OnSelectionChange();
1153 }
1154
1155 virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnShareViolation(IFileDialog* pfd, IShellItem* psi, FDE_SHAREVIOLATION_RESPONSE* pResponse)
1156 {
1157 T* pT = static_cast<T*>(this);
1158 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
1159 pfd; // avoid level 4 warning
1160 return pT->OnShareViolation(psi, pResponse);
1161 }
1162
1163 virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnTypeChange(IFileDialog* pfd)
1164 {
1165 T* pT = static_cast<T*>(this);
1166 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
1167 pfd; // avoid level 4 warning
1168 return pT->OnTypeChange();
1169 }
1170
1171 virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnOverwrite(IFileDialog* pfd, IShellItem* psi, FDE_OVERWRITE_RESPONSE* pResponse)
1172 {
1173 T* pT = static_cast<T*>(this);
1174 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
1175 pfd; // avoid level 4 warning
1176 return pT->OnOverwrite(psi, pResponse);
1177 }
1178
1179 // Overrideables - Event handlers
1180 HRESULT OnFileOk()
1181 {
1182 return E_NOTIMPL;
1183 }
1184
1185 HRESULT OnFolderChanging(IShellItem* /*psiFolder*/)
1186 {
1187 return E_NOTIMPL;
1188 }
1189
1190 HRESULT OnFolderChange()
1191 {
1192 return E_NOTIMPL;
1193 }
1194
1195 HRESULT OnSelectionChange()
1196 {
1197 return E_NOTIMPL;
1198 }
1199
1200 HRESULT OnShareViolation(IShellItem* /*psi*/, FDE_SHAREVIOLATION_RESPONSE* /*pResponse*/)
1201 {
1202 return E_NOTIMPL;
1203 }
1204
1205 HRESULT OnTypeChange()
1206 {
1207 return E_NOTIMPL;
1208 }
1209
1210 HRESULT OnOverwrite(IShellItem* /*psi*/, FDE_OVERWRITE_RESPONSE* /*pResponse*/)
1211 {
1212 return E_NOTIMPL;
1213 }
1214 };
1215
1216
1217 ///////////////////////////////////////////////////////////////////////////////
1218 // CShellFileOpenDialogImpl - implements new Shell File Open dialog
1219
1220 template <class T>
1221 class ATL_NO_VTABLE CShellFileOpenDialogImpl : public CShellFileDialogImpl< T >
1222 {
1223 public:
1224 ATL::CComPtr<IFileOpenDialog> m_spFileDlg;
1225
1226 CShellFileOpenDialogImpl(LPCWSTR lpszFileName = NULL,
1227 DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST,
1228 LPCWSTR lpszDefExt = NULL,
1229 const COMDLG_FILTERSPEC* arrFilterSpec = NULL,
1230 UINT uFilterSpecCount = 0U)
1231 {
1232 HRESULT hRet = m_spFileDlg.CoCreateInstance(CLSID_FileOpenDialog);
1233
1234 if(SUCCEEDED(hRet))
1235 _Init(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount);
1236 }
1237
1238 IFileOpenDialog* GetPtr()
1239 {
1240 return m_spFileDlg;
1241 }
1242 };
1243
1244
1245 ///////////////////////////////////////////////////////////////////////////////
1246 // CShellFileOpenDialog - new Shell File Open dialog without events
1247
1248 class CShellFileOpenDialog : public CShellFileOpenDialogImpl<CShellFileOpenDialog>
1249 {
1250 public:
1251 CShellFileOpenDialog(LPCWSTR lpszFileName = NULL,
1252 DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST,
1253 LPCWSTR lpszDefExt = NULL,
1254 const COMDLG_FILTERSPEC* arrFilterSpec = NULL,
1255 UINT uFilterSpecCount = 0U) : CShellFileOpenDialogImpl<CShellFileOpenDialog>(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount)
1256 { }
1257
1258 // Implementation (remove _Advise/_Unadvise code using template magic)
1259 void _Advise(DWORD& /*dwCookie*/)
1260 { }
1261
1262 void _Unadvise(DWORD /*dwCookie*/)
1263 { }
1264 };
1265
1266
1267 ///////////////////////////////////////////////////////////////////////////////
1268 // CShellFileSaveDialogImpl - implements new Shell File Save dialog
1269
1270 template <class T>
1271 class ATL_NO_VTABLE CShellFileSaveDialogImpl : public CShellFileDialogImpl< T >
1272 {
1273 public:
1274 ATL::CComPtr<IFileSaveDialog> m_spFileDlg;
1275
1276 CShellFileSaveDialogImpl(LPCWSTR lpszFileName = NULL,
1277 DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT,
1278 LPCWSTR lpszDefExt = NULL,
1279 const COMDLG_FILTERSPEC* arrFilterSpec = NULL,
1280 UINT uFilterSpecCount = 0U)
1281 {
1282 HRESULT hRet = m_spFileDlg.CoCreateInstance(CLSID_FileSaveDialog);
1283
1284 if(SUCCEEDED(hRet))
1285 _Init(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount);
1286 }
1287
1288 IFileSaveDialog* GetPtr()
1289 {
1290 return m_spFileDlg;
1291 }
1292 };
1293
1294
1295 ///////////////////////////////////////////////////////////////////////////////
1296 // CShellFileSaveDialog - new Shell File Save dialog without events
1297
1298 class CShellFileSaveDialog : public CShellFileSaveDialogImpl<CShellFileSaveDialog>
1299 {
1300 public:
1301 CShellFileSaveDialog(LPCWSTR lpszFileName = NULL,
1302 DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT,
1303 LPCWSTR lpszDefExt = NULL,
1304 const COMDLG_FILTERSPEC* arrFilterSpec = NULL,
1305 UINT uFilterSpecCount = 0U) : CShellFileSaveDialogImpl<CShellFileSaveDialog>(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount)
1306 { }
1307
1308 // Implementation (remove _Advise/_Unadvise code using template magic)
1309 void _Advise(DWORD& /*dwCookie*/)
1310 { }
1311
1312 void _Unadvise(DWORD /*dwCookie*/)
1313 { }
1314 };
1315
1316 #endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
1317
1318
1319 ///////////////////////////////////////////////////////////////////////////////
1320 // CFolderDialogImpl - used for browsing for a folder
1321
1322 #ifndef _WIN32_WCE
1323
1324 template <class T>
1325 class ATL_NO_VTABLE CFolderDialogImpl
1326 {
1327 public:
1328 BROWSEINFO m_bi;
1329 LPCTSTR m_lpstrInitialFolder;
1330 LPCITEMIDLIST m_pidlInitialSelection;
1331 bool m_bExpandInitialSelection;
1332 TCHAR m_szFolderDisplayName[MAX_PATH];
1333 TCHAR m_szFolderPath[MAX_PATH];
1334 #ifdef STRICT_TYPED_ITEMIDS
1335 PIDLIST_ABSOLUTE m_pidlSelected;
1336 #else
1337 LPITEMIDLIST m_pidlSelected;
1338 #endif
1339 HWND m_hWnd; // used only in the callback function
1340
1341 // Constructor
1342 CFolderDialogImpl(HWND hWndParent = NULL, LPCTSTR lpstrTitle = NULL, UINT uFlags = BIF_RETURNONLYFSDIRS) :
1343 m_lpstrInitialFolder(NULL), m_pidlInitialSelection(NULL), m_bExpandInitialSelection(false), m_pidlSelected(NULL), m_hWnd(NULL)
1344 {
1345 memset(&m_bi, 0, sizeof(m_bi)); // initialize structure to 0/NULL
1346
1347 m_bi.hwndOwner = hWndParent;
1348 m_bi.pidlRoot = NULL;
1349 m_bi.pszDisplayName = m_szFolderDisplayName;
1350 m_bi.lpszTitle = lpstrTitle;
1351 m_bi.ulFlags = uFlags;
1352 m_bi.lpfn = BrowseCallbackProc;
1353 m_bi.lParam = (LPARAM)static_cast<T*>(this);
1354
1355 m_szFolderPath[0] = 0;
1356 m_szFolderDisplayName[0] = 0;
1357 }
1358
1359 ~CFolderDialogImpl()
1360 {
1361 ::CoTaskMemFree(m_pidlSelected);
1362 }
1363
1364 // Operations
1365 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
1366 {
1367 if(m_bi.hwndOwner == NULL) // set only if not specified before
1368 m_bi.hwndOwner = hWndParent;
1369
1370 // Clear out any previous results
1371 m_szFolderPath[0] = 0;
1372 m_szFolderDisplayName[0] = 0;
1373 ::CoTaskMemFree(m_pidlSelected);
1374
1375 INT_PTR nRet = IDCANCEL;
1376 m_pidlSelected = ::SHBrowseForFolder(&m_bi);
1377
1378 if(m_pidlSelected != NULL)
1379 {
1380 nRet = IDOK;
1381
1382 // If BIF_RETURNONLYFSDIRS is set, we try to get the filesystem path.
1383 // Otherwise, the caller must handle the ID-list directly.
1384 if((m_bi.ulFlags & BIF_RETURNONLYFSDIRS) != 0)
1385 {
1386 if(::SHGetPathFromIDList(m_pidlSelected, m_szFolderPath) == FALSE)
1387 nRet = IDCANCEL;
1388 }
1389 }
1390
1391 return nRet;
1392 }
1393
1394 // Methods to call before DoModal
1395 void SetInitialFolder(LPCTSTR lpstrInitialFolder, bool bExpand = true)
1396 {
1397 // lpstrInitialFolder may be a file if BIF_BROWSEINCLUDEFILES is specified
1398 m_lpstrInitialFolder = lpstrInitialFolder;
1399 m_bExpandInitialSelection = bExpand;
1400 }
1401
1402 void SetInitialSelection(LPCITEMIDLIST pidl, bool bExpand = true)
1403 {
1404 m_pidlInitialSelection = pidl;
1405 m_bExpandInitialSelection = bExpand;
1406 }
1407
1408 #ifdef STRICT_TYPED_ITEMIDS
1409 void SetRootFolder(PCIDLIST_ABSOLUTE pidl)
1410 #else
1411 void SetRootFolder(LPCITEMIDLIST pidl)
1412 #endif
1413 {
1414 m_bi.pidlRoot = pidl;
1415 }
1416
1417 // Methods to call after DoModal
1418 LPITEMIDLIST GetSelectedItem(bool bDetach = false)
1419 {
1420 LPITEMIDLIST pidl = m_pidlSelected;
1421 if(bDetach)
1422 m_pidlSelected = NULL;
1423
1424 return pidl;
1425 }
1426
1427 LPCTSTR GetFolderPath() const
1428 {
1429 return m_szFolderPath;
1430 }
1431
1432 LPCTSTR GetFolderDisplayName() const
1433 {
1434 return m_szFolderDisplayName;
1435 }
1436
1437 int GetFolderImageIndex() const
1438 {
1439 return m_bi.iImage;
1440 }
1441
1442 // Callback function and overrideables
1443 static int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
1444 {
1445 #ifndef BFFM_VALIDATEFAILED
1446 #ifdef UNICODE
1447 const int BFFM_VALIDATEFAILED = 4;
1448 #else
1449 const int BFFM_VALIDATEFAILED = 3;
1450 #endif
1451 #endif // !BFFM_VALIDATEFAILED
1452 #ifndef BFFM_IUNKNOWN
1453 const int BFFM_IUNKNOWN = 5;
1454 #endif // !BFFM_IUNKNOWN
1455 #ifndef BIF_NEWDIALOGSTYLE
1456 const UINT BIF_NEWDIALOGSTYLE = 0x0040;
1457 #endif // !BIF_NEWDIALOGSTYLE
1458
1459 int nRet = 0;
1460 T* pT = (T*)lpData;
1461 bool bClear = false;
1462 if(pT->m_hWnd == NULL)
1463 {
1464 pT->m_hWnd = hWnd;
1465 bClear = true;
1466 }
1467 else
1468 {
1469 ATLASSERT(pT->m_hWnd == hWnd);
1470 }
1471
1472 switch(uMsg)
1473 {
1474 case BFFM_INITIALIZED:
1475 // Set initial selection
1476 // Note that m_pidlInitialSelection, if set, takes precedence over m_lpstrInitialFolder
1477 if(pT->m_pidlInitialSelection != NULL)
1478 pT->SetSelection(pT->m_pidlInitialSelection);
1479 else if(pT->m_lpstrInitialFolder != NULL)
1480 pT->SetSelection(pT->m_lpstrInitialFolder);
1481
1482 // Expand initial selection if appropriate
1483 if(pT->m_bExpandInitialSelection && ((pT->m_bi.ulFlags & BIF_NEWDIALOGSTYLE) != 0))
1484 {
1485 if(pT->m_pidlInitialSelection != NULL)
1486 pT->SetExpanded(pT->m_pidlInitialSelection);
1487 else if(pT->m_lpstrInitialFolder != NULL)
1488 pT->SetExpanded(pT->m_lpstrInitialFolder);
1489 }
1490 pT->OnInitialized();
1491 break;
1492 case BFFM_SELCHANGED:
1493 pT->OnSelChanged((LPITEMIDLIST)lParam);
1494 break;
1495 case BFFM_VALIDATEFAILED:
1496 nRet = pT->OnValidateFailed((LPCTSTR)lParam);
1497 break;
1498 case BFFM_IUNKNOWN:
1499 pT->OnIUnknown((IUnknown*)lParam);
1500 break;
1501 default:
1502 ATLTRACE2(atlTraceUI, 0, _T("Unknown message received in CFolderDialogImpl::BrowseCallbackProc\n"));
1503 break;
1504 }
1505
1506 if(bClear)
1507 pT->m_hWnd = NULL;
1508 return nRet;
1509 }
1510
1511 void OnInitialized()
1512 {
1513 }
1514
1515 void OnSelChanged(LPITEMIDLIST /*pItemIDList*/)
1516 {
1517 }
1518
1519 int OnValidateFailed(LPCTSTR /*lpstrFolderPath*/)
1520 {
1521 return 1; // 1=continue, 0=EndDialog
1522 }
1523
1524 void OnIUnknown(IUnknown* /*pUnknown*/)
1525 {
1526 }
1527
1528 // Commands - valid to call only from handlers
1529 void EnableOK(BOOL bEnable)
1530 {
1531 ATLASSERT(m_hWnd != NULL);
1532 ::SendMessage(m_hWnd, BFFM_ENABLEOK, 0, bEnable);
1533 }
1534
1535 void SetSelection(LPCITEMIDLIST pItemIDList)
1536 {
1537 ATLASSERT(m_hWnd != NULL);
1538 ::SendMessage(m_hWnd, BFFM_SETSELECTION, FALSE, (LPARAM)pItemIDList);
1539 }
1540
1541 void SetSelection(LPCTSTR lpstrFolderPath)
1542 {
1543 ATLASSERT(m_hWnd != NULL);
1544 ::SendMessage(m_hWnd, BFFM_SETSELECTION, TRUE, (LPARAM)lpstrFolderPath);
1545 }
1546
1547 void SetStatusText(LPCTSTR lpstrText)
1548 {
1549 ATLASSERT(m_hWnd != NULL);
1550 ::SendMessage(m_hWnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)lpstrText);
1551 }
1552
1553 void SetOKText(LPCTSTR lpstrOKText)
1554 {
1555 #ifndef BFFM_SETOKTEXT
1556 const UINT BFFM_SETOKTEXT = WM_USER + 105;
1557 #endif
1558 ATLASSERT(m_hWnd != NULL);
1559 USES_CONVERSION;
1560 LPCWSTR lpstr = T2CW(lpstrOKText);
1561 ::SendMessage(m_hWnd, BFFM_SETOKTEXT, 0, (LPARAM)lpstr);
1562 }
1563
1564 void SetExpanded(LPCITEMIDLIST pItemIDList)
1565 {
1566 #ifndef BFFM_SETEXPANDED
1567 const UINT BFFM_SETEXPANDED = WM_USER + 106;
1568 #endif
1569 ATLASSERT(m_hWnd != NULL);
1570 ::SendMessage(m_hWnd, BFFM_SETEXPANDED, FALSE, (LPARAM)pItemIDList);
1571 }
1572
1573 void SetExpanded(LPCTSTR lpstrFolderPath)
1574 {
1575 #ifndef BFFM_SETEXPANDED
1576 const UINT BFFM_SETEXPANDED = WM_USER + 106;
1577 #endif
1578 ATLASSERT(m_hWnd != NULL);
1579 USES_CONVERSION;
1580 LPCWSTR lpstr = T2CW(lpstrFolderPath);
1581 ::SendMessage(m_hWnd, BFFM_SETEXPANDED, TRUE, (LPARAM)lpstr);
1582 }
1583 };
1584
1585 class CFolderDialog : public CFolderDialogImpl<CFolderDialog>
1586 {
1587 public:
1588 CFolderDialog(HWND hWndParent = NULL, LPCTSTR lpstrTitle = NULL, UINT uFlags = BIF_RETURNONLYFSDIRS)
1589 : CFolderDialogImpl<CFolderDialog>(hWndParent, lpstrTitle, uFlags)
1590 { }
1591 };
1592
1593 #endif // !_WIN32_WCE
1594
1595
1596 ///////////////////////////////////////////////////////////////////////////////
1597 // CCommonDialogImplBase - base class for common dialog classes
1598
1599 class ATL_NO_VTABLE CCommonDialogImplBase : public ATL::CWindowImplBase
1600 {
1601 public:
1602 static UINT_PTR APIENTRY HookProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1603 {
1604 if(uMsg != WM_INITDIALOG)
1605 return 0;
1606 CCommonDialogImplBase* pT = (CCommonDialogImplBase*)ModuleHelper::ExtractCreateWndData();
1607 ATLASSERT(pT != NULL);
1608 ATLASSERT(pT->m_hWnd == NULL);
1609 ATLASSERT(::IsWindow(hWnd));
1610 // subclass dialog's window
1611 if(!pT->SubclassWindow(hWnd))
1612 {
1613 ATLTRACE2(atlTraceUI, 0, _T("Subclassing a common dialog failed\n"));
1614 return 0;
1615 }
1616 // check message map for WM_INITDIALOG handler
1617 LRESULT lRes = 0;
1618 if(pT->ProcessWindowMessage(pT->m_hWnd, uMsg, wParam, lParam, lRes, 0) == FALSE)
1619 return 0;
1620 return lRes;
1621 }
1622
1623 // Special override for common dialogs
1624 BOOL EndDialog(INT_PTR /*nRetCode*/ = 0)
1625 {
1626 ATLASSERT(::IsWindow(m_hWnd));
1627 SendMessage(WM_COMMAND, MAKEWPARAM(IDABORT, 0));
1628 return TRUE;
1629 }
1630
1631 // Implementation - try to override these, to prevent errors
1632 HWND Create(HWND, ATL::_U_RECT, LPCTSTR, DWORD, DWORD, ATL::_U_MENUorID, ATOM, LPVOID)
1633 {
1634 ATLASSERT(FALSE); // should not be called
1635 return NULL;
1636 }
1637
1638 static LRESULT CALLBACK StartWindowProc(HWND /*hWnd*/, UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/)
1639 {
1640 ATLASSERT(FALSE); // should not be called
1641 return 0;
1642 }
1643 };
1644
1645
1646 ///////////////////////////////////////////////////////////////////////////////
1647 // CFontDialogImpl - font selection dialog
1648
1649 #ifndef _WIN32_WCE
1650
1651 template <class T>
1652 class ATL_NO_VTABLE CFontDialogImpl : public CCommonDialogImplBase
1653 {
1654 public:
1655 enum { _cchStyleName = 64 };
1656
1657 CHOOSEFONT m_cf;
1658 TCHAR m_szStyleName[_cchStyleName]; // contains style name after return
1659 LOGFONT m_lf; // default LOGFONT to store the info
1660
1661 // Constructors
1662 CFontDialogImpl(LPLOGFONT lplfInitial = NULL,
1663 DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS,
1664 HDC hDCPrinter = NULL,
1665 HWND hWndParent = NULL)
1666 {
1667 memset(&m_cf, 0, sizeof(m_cf));
1668 memset(&m_lf, 0, sizeof(m_lf));
1669 memset(&m_szStyleName, 0, sizeof(m_szStyleName));
1670
1671 m_cf.lStructSize = sizeof(m_cf);
1672 m_cf.hwndOwner = hWndParent;
1673 m_cf.rgbColors = RGB(0, 0, 0);
1674 m_cf.lpszStyle = (LPTSTR)&m_szStyleName;
1675 m_cf.Flags = dwFlags | CF_ENABLEHOOK;
1676 m_cf.lpfnHook = (LPCFHOOKPROC)T::HookProc;
1677
1678 if(lplfInitial != NULL)
1679 {
1680 m_cf.lpLogFont = lplfInitial;
1681 m_cf.Flags |= CF_INITTOLOGFONTSTRUCT;
1682 m_lf = *lplfInitial;
1683 }
1684 else
1685 {
1686 m_cf.lpLogFont = &m_lf;
1687 }
1688
1689 if(hDCPrinter != NULL)
1690 {
1691 m_cf.hDC = hDCPrinter;
1692 m_cf.Flags |= CF_PRINTERFONTS;
1693 }
1694 }
1695
1696 // Operations
1697 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
1698 {
1699 ATLASSERT((m_cf.Flags & CF_ENABLEHOOK) != 0);
1700 ATLASSERT(m_cf.lpfnHook != NULL); // can still be a user hook
1701
1702 if(m_cf.hwndOwner == NULL) // set only if not specified before
1703 m_cf.hwndOwner = hWndParent;
1704
1705 ATLASSERT(m_hWnd == NULL);
1706
1707 #if (_ATL_VER >= 0x0800)
1708 // Allocate the thunk structure here, where we can fail gracefully.
1709 BOOL bRetTh = m_thunk.Init(NULL, NULL);
1710 if(bRetTh == FALSE)
1711 {
1712 ::SetLastError(ERROR_OUTOFMEMORY);
1713 return -1;
1714 }
1715 #endif // (_ATL_VER >= 0x0800)
1716
1717 ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this);
1718
1719 BOOL bRet = ::ChooseFont(&m_cf);
1720
1721 m_hWnd = NULL;
1722
1723 if(bRet) // copy logical font from user's initialization buffer (if needed)
1724 SecureHelper::memcpy_x(&m_lf, sizeof(m_lf), m_cf.lpLogFont, sizeof(m_lf));
1725
1726 return bRet ? IDOK : IDCANCEL;
1727 }
1728
1729 // works only when the dialog is dislayed or after
1730 void GetCurrentFont(LPLOGFONT lplf) const
1731 {
1732 ATLASSERT(lplf != NULL);
1733
1734 if(m_hWnd != NULL)
1735 ::SendMessage(m_hWnd, WM_CHOOSEFONT_GETLOGFONT, 0, (LPARAM)lplf);
1736 else
1737 *lplf = m_lf;
1738 }
1739
1740 // works only when the dialog is dislayed or before
1741 #ifndef _WIN32_WCE
1742 void SetLogFont(LPLOGFONT lplf)
1743 {
1744 ATLASSERT(lplf != NULL);
1745 #ifndef WM_CHOOSEFONT_SETLOGFONT
1746 const UINT WM_CHOOSEFONT_SETLOGFONT = (WM_USER + 101);
1747 #endif
1748 if(m_hWnd != NULL)
1749 {
1750 ::SendMessage(m_hWnd, WM_CHOOSEFONT_SETLOGFONT, 0, (LPARAM)lplf);
1751 }
1752 else
1753 {
1754 m_lf = *lplf;
1755 m_cf.Flags |= CF_INITTOLOGFONTSTRUCT;
1756 }
1757 }
1758
1759 void SetFlags(DWORD dwFlags)
1760 {
1761 #ifndef WM_CHOOSEFONT_SETFLAGS
1762 const UINT WM_CHOOSEFONT_SETFLAGS = (WM_USER + 102);
1763 #endif
1764 if(m_hWnd != NULL)
1765 {
1766 CHOOSEFONT cf = { sizeof(CHOOSEFONT) };
1767 cf.Flags = dwFlags;
1768 ::SendMessage(m_hWnd, WM_CHOOSEFONT_SETFLAGS, 0, (LPARAM)&cf);
1769 }
1770 else
1771 {
1772 m_cf.Flags = dwFlags;
1773 }
1774 }
1775 #endif // !_WIN32_WCE
1776
1777 // Helpers for parsing information after successful return
1778 LPCTSTR GetFaceName() const // return the face name of the font
1779 {
1780 return (LPCTSTR)m_cf.lpLogFont->lfFaceName;
1781 }
1782
1783 LPCTSTR GetStyleName() const // return the style name of the font
1784 {
1785 return m_cf.lpszStyle;
1786 }
1787
1788 int GetSize() const // return the pt size of the font
1789 {
1790 return m_cf.iPointSize;
1791 }
1792
1793 COLORREF GetColor() const // return the color of the font
1794 {
1795 return m_cf.rgbColors;
1796 }
1797
1798 int GetWeight() const // return the chosen font weight
1799 {
1800 return (int)m_cf.lpLogFont->lfWeight;
1801 }
1802
1803 BOOL IsStrikeOut() const // return TRUE if strikeout
1804 {
1805 return (m_cf.lpLogFont->lfStrikeOut) ? TRUE : FALSE;
1806 }
1807
1808 BOOL IsUnderline() const // return TRUE if underline
1809 {
1810 return (m_cf.lpLogFont->lfUnderline) ? TRUE : FALSE;
1811 }
1812
1813 BOOL IsBold() const // return TRUE if bold font
1814 {
1815 return (m_cf.lpLogFont->lfWeight == FW_BOLD) ? TRUE : FALSE;
1816 }
1817
1818 BOOL IsItalic() const // return TRUE if italic font
1819 {
1820 return m_cf.lpLogFont->lfItalic ? TRUE : FALSE;
1821 }
1822 };
1823
1824 class CFontDialog : public CFontDialogImpl<CFontDialog>
1825 {
1826 public:
1827 CFontDialog(LPLOGFONT lplfInitial = NULL,
1828 DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS,
1829 HDC hDCPrinter = NULL,
1830 HWND hWndParent = NULL)
1831 : CFontDialogImpl<CFontDialog>(lplfInitial, dwFlags, hDCPrinter, hWndParent)
1832 { }
1833
1834 DECLARE_EMPTY_MSG_MAP()
1835 };
1836
1837 #endif // _WIN32_WCE
1838
1839
1840 ///////////////////////////////////////////////////////////////////////////////
1841 // CRichEditFontDialogImpl - font selection for the Rich Edit ctrl
1842
1843 #if defined(_RICHEDIT_) && !defined(_WIN32_WCE)
1844
1845 template <class T>
1846 class ATL_NO_VTABLE CRichEditFontDialogImpl : public CFontDialogImpl< T >
1847 {
1848 public:
1849 CRichEditFontDialogImpl(const CHARFORMAT& charformat,
1850 DWORD dwFlags = CF_SCREENFONTS,
1851 HDC hDCPrinter = NULL,
1852 HWND hWndParent = NULL)
1853 : CFontDialogImpl< T >(NULL, dwFlags, hDCPrinter, hWndParent)
1854 {
1855 m_cf.Flags |= CF_INITTOLOGFONTSTRUCT;
1856 m_cf.Flags |= FillInLogFont(charformat);
1857 m_cf.lpLogFont = &m_lf;
1858
1859 if((charformat.dwMask & CFM_COLOR) != 0)
1860 m_cf.rgbColors = charformat.crTextColor;
1861 }
1862
1863 void GetCharFormat(CHARFORMAT& cf) const
1864 {
1865 USES_CONVERSION;
1866 cf.dwEffects = 0;
1867 cf.dwMask = 0;
1868 if((m_cf.Flags & CF_NOSTYLESEL) == 0)
1869 {
1870 cf.dwMask |= CFM_BOLD | CFM_ITALIC;
1871 cf.dwEffects |= IsBold() ? CFE_BOLD : 0;
1872 cf.dwEffects |= IsItalic() ? CFE_ITALIC : 0;
1873 }
1874 if((m_cf.Flags & CF_NOSIZESEL) == 0)
1875 {
1876 cf.dwMask |= CFM_SIZE;
1877 // GetSize() returns in tenths of points so mulitply by 2 to get twips
1878 cf.yHeight = GetSize() * 2;
1879 }
1880
1881 if((m_cf.Flags & CF_NOFACESEL) == 0)
1882 {
1883 cf.dwMask |= CFM_FACE;
1884 cf.bPitchAndFamily = m_cf.lpLogFont->lfPitchAndFamily;
1885 #if (_RICHEDIT_VER >= 0x0200)
1886 SecureHelper::strcpy_x(cf.szFaceName, _countof(cf.szFaceName), GetFaceName());
1887 #else // !(_RICHEDIT_VER >= 0x0200)
1888 SecureHelper::strcpyA_x(cf.szFaceName, _countof(cf.szFaceName), T2A((LPTSTR)(LPCTSTR)GetFaceName()));
1889 #endif // !(_RICHEDIT_VER >= 0x0200)
1890 }
1891
1892 if((m_cf.Flags & CF_EFFECTS) != 0)
1893 {
1894 cf.dwMask |= CFM_UNDERLINE | CFM_STRIKEOUT | CFM_COLOR;
1895 cf.dwEffects |= IsUnderline() ? CFE_UNDERLINE : 0;
1896 cf.dwEffects |= IsStrikeOut() ? CFE_STRIKEOUT : 0;
1897 cf.crTextColor = GetColor();
1898 }
1899 if((m_cf.Flags & CF_NOSCRIPTSEL) == 0)
1900 {
1901 cf.bCharSet = m_cf.lpLogFont->lfCharSet;
1902 cf.dwMask |= CFM_CHARSET;
1903 }
1904 cf.yOffset = 0;
1905 }
1906
1907 DWORD FillInLogFont(const CHARFORMAT& cf)
1908 {
1909 USES_CONVERSION;
1910 DWORD dwFlags = 0;
1911 if((cf.dwMask & CFM_SIZE) != 0)
1912 {
1913 HDC hDC = ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
1914 LONG yPerInch = ::GetDeviceCaps(hDC, LOGPIXELSY);
1915 m_lf.lfHeight = -(int)((cf.yHeight * yPerInch) / 1440);
1916 }
1917 else
1918 m_lf.lfHeight = 0;
1919
1920 m_lf.lfWidth = 0;
1921 m_lf.lfEscapement = 0;
1922 m_lf.lfOrientation = 0;
1923
1924 if((cf.dwMask & (CFM_ITALIC | CFM_BOLD)) == (CFM_ITALIC | CFM_BOLD))
1925 {
1926 m_lf.lfWeight = ((cf.dwEffects & CFE_BOLD) != 0) ? FW_BOLD : FW_NORMAL;
1927 m_lf.lfItalic = (BYTE)(((cf.dwEffects & CFE_ITALIC) != 0) ? TRUE : FALSE);
1928 }
1929 else
1930 {
1931 dwFlags |= CF_NOSTYLESEL;
1932 m_lf.lfWeight = FW_DONTCARE;
1933 m_lf.lfItalic = FALSE;
1934 }
1935
1936 if((cf.dwMask & (CFM_UNDERLINE | CFM_STRIKEOUT | CFM_COLOR)) == (CFM_UNDERLINE|CFM_STRIKEOUT|CFM_COLOR))
1937 {
1938 dwFlags |= CF_EFFECTS;
1939 m_lf.lfUnderline = (BYTE)(((cf.dwEffects & CFE_UNDERLINE) != 0) ? TRUE : FALSE);
1940 m_lf.lfStrikeOut = (BYTE)(((cf.dwEffects & CFE_STRIKEOUT) != 0) ? TRUE : FALSE);
1941 }
1942 else
1943 {
1944 m_lf.lfUnderline = (BYTE)FALSE;
1945 m_lf.lfStrikeOut = (BYTE)FALSE;
1946 }
1947
1948 if((cf.dwMask & CFM_CHARSET) != 0)
1949 m_lf.lfCharSet = cf.bCharSet;
1950 else
1951 dwFlags |= CF_NOSCRIPTSEL;
1952 m_lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1953 m_lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1954 m_lf.lfQuality = DEFAULT_QUALITY;
1955 if((cf.dwMask & CFM_FACE) != 0)
1956 {
1957 m_lf.lfPitchAndFamily = cf.bPitchAndFamily;
1958 #if (_RICHEDIT_VER >= 0x0200)
1959 SecureHelper::strcpy_x(m_lf.lfFaceName, _countof(m_lf.lfFaceName), cf.szFaceName);
1960 #else // !(_RICHEDIT_VER >= 0x0200)
1961 SecureHelper::strcpy_x(m_lf.lfFaceName, _countof(m_lf.lfFaceName), A2T((LPSTR)cf.szFaceName));
1962 #endif // !(_RICHEDIT_VER >= 0x0200)
1963 }
1964 else
1965 {
1966 m_lf.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
1967 m_lf.lfFaceName[0] = (TCHAR)0;
1968 }
1969 return dwFlags;
1970 }
1971 };
1972
1973 class CRichEditFontDialog : public CRichEditFontDialogImpl<CRichEditFontDialog>
1974 {
1975 public:
1976 CRichEditFontDialog(const CHARFORMAT& charformat,
1977 DWORD dwFlags = CF_SCREENFONTS,
1978 HDC hDCPrinter = NULL,
1979 HWND hWndParent = NULL)
1980 : CRichEditFontDialogImpl<CRichEditFontDialog>(charformat, dwFlags, hDCPrinter, hWndParent)
1981 { }
1982
1983 DECLARE_EMPTY_MSG_MAP()
1984 };
1985
1986 #endif // defined(_RICHEDIT_) && !defined(_WIN32_WCE)
1987
1988
1989 ///////////////////////////////////////////////////////////////////////////////
1990 // CColorDialogImpl - color selection
1991
1992 #if !defined(_WIN32_WCE) || ((_WIN32_WCE > 420) && !(defined(WIN32_PLATFORM_WFSP) && (_WIN32_WCE > 0x0500)))
1993
1994 #ifdef _WIN32_WCE
1995 #pragma comment(lib, "commdlg.lib")
1996
1997 #ifndef SETRGBSTRING
1998 #define SETRGBSTRING _T("commdlg_SetRGBColor")
1999 #endif
2000
2001 #ifndef COLOROKSTRING
2002 #define COLOROKSTRING _T("commdlg_ColorOK")
2003 #endif
2004 #endif
2005
2006 template <class T>
2007 class ATL_NO_VTABLE CColorDialogImpl : public CCommonDialogImplBase
2008 {
2009 public:
2010 CHOOSECOLOR m_cc;
2011
2012 // Constructor
2013 CColorDialogImpl(COLORREF clrInit = 0, DWORD dwFlags = 0, HWND hWndParent = NULL)
2014 {
2015 memset(&m_cc, 0, sizeof(m_cc));
2016
2017 m_cc.lStructSize = sizeof(m_cc);
2018 m_cc.lpCustColors = GetCustomColors();
2019 m_cc.hwndOwner = hWndParent;
2020 m_cc.Flags = dwFlags | CC_ENABLEHOOK;
2021 m_cc.lpfnHook = (LPCCHOOKPROC)T::HookProc;
2022
2023 if(clrInit != 0)
2024 {
2025 m_cc.rgbResult = clrInit;
2026 m_cc.Flags |= CC_RGBINIT;
2027 }
2028 }
2029
2030 // Operations
2031 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
2032 {
2033 ATLASSERT((m_cc.Flags & CC_ENABLEHOOK) != 0);
2034 ATLASSERT(m_cc.lpfnHook != NULL); // can still be a user hook
2035
2036 if(m_cc.hwndOwner == NULL) // set only if not specified before
2037 m_cc.hwndOwner = hWndParent;
2038
2039 ATLASSERT(m_hWnd == NULL);
2040
2041 #if (_ATL_VER >= 0x0800)
2042 // Allocate the thunk structure here, where we can fail gracefully.
2043 BOOL bRetTh = m_thunk.Init(NULL, NULL);
2044 if(bRetTh == FALSE)
2045 {
2046 ::SetLastError(ERROR_OUTOFMEMORY);
2047 return -1;
2048 }
2049 #endif // (_ATL_VER >= 0x0800)
2050
2051 ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this);
2052
2053 BOOL bRet = ::ChooseColor(&m_cc);
2054
2055 m_hWnd = NULL;
2056
2057 return bRet ? IDOK : IDCANCEL;
2058 }
2059
2060 // Set the current color while dialog is displayed
2061 void SetCurrentColor(COLORREF clr)
2062 {
2063 ATLASSERT(::IsWindow(m_hWnd));
2064 SendMessage(_GetSetRGBMessage(), 0, (LPARAM)clr);
2065 }
2066
2067 // Get the selected color after DoModal returns, or in OnColorOK
2068 COLORREF GetColor() const
2069 {
2070 return m_cc.rgbResult;
2071 }
2072
2073 // Special override for the color dialog
2074 static UINT_PTR APIENTRY HookProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2075 {
2076 if(uMsg != WM_INITDIALOG && uMsg != _GetColorOKMessage())
2077 return 0;
2078
2079 LPCHOOSECOLOR lpCC = (LPCHOOSECOLOR)lParam;
2080 CCommonDialogImplBase* pT = NULL;
2081
2082 if(uMsg == WM_INITDIALOG)
2083 {
2084 pT = (CCommonDialogImplBase*)ModuleHelper::ExtractCreateWndData();
2085 lpCC->lCustData = (LPARAM)pT;
2086 ATLASSERT(pT != NULL);
2087 ATLASSERT(pT->m_hWnd == NULL);
2088 ATLASSERT(::IsWindow(hWnd));
2089 // subclass dialog's window
2090 if(!pT->SubclassWindow(hWnd))
2091 {
2092 ATLTRACE2(atlTraceUI, 0, _T("Subclassing a Color common dialog failed\n"));
2093 return 0;
2094 }
2095 }
2096 else if(uMsg == _GetColorOKMessage())
2097 {
2098 pT = (CCommonDialogImplBase*)lpCC->lCustData;
2099 ATLASSERT(pT != NULL);
2100 ATLASSERT(::IsWindow(pT->m_hWnd));
2101 }
2102 else
2103 {
2104 ATLASSERT(FALSE);
2105 return 0;
2106 }
2107
2108 // pass to the message map
2109 LRESULT lRes = 0;
2110 if(pT->ProcessWindowMessage(pT->m_hWnd, uMsg, wParam, lParam, lRes, 0) == FALSE)
2111 return 0;
2112
2113 return lRes;
2114 }
2115
2116 // Helpers
2117 static COLORREF* GetCustomColors()
2118 {
2119 static COLORREF rgbCustomColors[16] =
2120 {
2121 RGB(255, 255, 255), RGB(255, 255, 255),
2122 RGB(255, 255, 255), RGB(255, 255, 255),
2123 RGB(255, 255, 255), RGB(255, 255, 255),
2124 RGB(255, 255, 255), RGB(255, 255, 255),
2125 RGB(255, 255, 255), RGB(255, 255, 255),
2126 RGB(255, 255, 255), RGB(255, 255, 255),
2127 RGB(255, 255, 255), RGB(255, 255, 255),
2128 RGB(255, 255, 255), RGB(255, 255, 255),
2129 };
2130
2131 return rgbCustomColors;
2132 }
2133
2134 static UINT _GetSetRGBMessage()
2135 {
2136 static UINT uSetRGBMessage = 0;
2137 if(uSetRGBMessage == 0)
2138 {
2139 CStaticDataInitCriticalSectionLock lock;
2140 if(FAILED(lock.Lock()))
2141 {
2142 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CColorDialogImpl::_GetSetRGBMessage.\n"));
2143 ATLASSERT(FALSE);
2144 return 0;
2145 }
2146
2147 if(uSetRGBMessage == 0)
2148 uSetRGBMessage = ::RegisterWindowMessage(SETRGBSTRING);
2149
2150 lock.Unlock();
2151 }
2152 ATLASSERT(uSetRGBMessage != 0);
2153 return uSetRGBMessage;
2154 }
2155
2156 static UINT _GetColorOKMessage()
2157 {
2158 static UINT uColorOKMessage = 0;
2159 if(uColorOKMessage == 0)
2160 {
2161 CStaticDataInitCriticalSectionLock lock;
2162 if(FAILED(lock.Lock()))
2163 {
2164 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CColorDialogImpl::_GetColorOKMessage.\n"));
2165 ATLASSERT(FALSE);
2166 return 0;
2167 }
2168
2169 if(uColorOKMessage == 0)
2170 uColorOKMessage = ::RegisterWindowMessage(COLOROKSTRING);
2171
2172 lock.Unlock();
2173 }
2174 ATLASSERT(uColorOKMessage != 0);
2175 return uColorOKMessage;
2176 }
2177
2178 // Message map and handlers
2179 BEGIN_MSG_MAP(CColorDialogImpl)
2180 MESSAGE_HANDLER(_GetColorOKMessage(), _OnColorOK)
2181 END_MSG_MAP()
2182
2183 LRESULT _OnColorOK(UINT, WPARAM, LPARAM, BOOL&)
2184 {
2185 T* pT = static_cast<T*>(this);
2186 return pT->OnColorOK();
2187 }
2188
2189 // Overrideable
2190 BOOL OnColorOK() // validate color
2191 {
2192 return FALSE;
2193 }
2194 };
2195
2196 class CColorDialog : public CColorDialogImpl<CColorDialog>
2197 {
2198 public:
2199 CColorDialog(COLORREF clrInit = 0, DWORD dwFlags = 0, HWND hWndParent = NULL)
2200 : CColorDialogImpl<CColorDialog>(clrInit, dwFlags, hWndParent)
2201 { }
2202
2203 // override base class map and references to handlers
2204 DECLARE_EMPTY_MSG_MAP()
2205 };
2206
2207 #endif // !defined(_WIN32_WCE) || ((_WIN32_WCE > 420) && !(defined(WIN32_PLATFORM_WFSP) && (_WIN32_WCE > 0x0500)))
2208
2209
2210 ///////////////////////////////////////////////////////////////////////////////
2211 // CPrintDialogImpl - used for Print... and PrintSetup...
2212
2213 #ifndef _WIN32_WCE
2214
2215 // global helper
2216 static inline HDC _AtlCreateDC(HGLOBAL hDevNames, HGLOBAL hDevMode)
2217 {
2218 if(hDevNames == NULL)
2219 return NULL;
2220
2221 LPDEVNAMES lpDevNames = (LPDEVNAMES)::GlobalLock(hDevNames);
2222 LPDEVMODE lpDevMode = (hDevMode != NULL) ? (LPDEVMODE)::GlobalLock(hDevMode) : NULL;
2223
2224 if(lpDevNames == NULL)
2225 return NULL;
2226
2227 HDC hDC = ::CreateDC((LPCTSTR)lpDevNames + lpDevNames->wDriverOffset,
2228 (LPCTSTR)lpDevNames + lpDevNames->wDeviceOffset,
2229 (LPCTSTR)lpDevNames + lpDevNames->wOutputOffset,
2230 lpDevMode);
2231
2232 ::GlobalUnlock(hDevNames);
2233 if(hDevMode != NULL)
2234 ::GlobalUnlock(hDevMode);
2235 return hDC;
2236 }
2237
2238 #pragma warning(push)
2239 #pragma warning(disable: 4512) // assignment operator could not be generated
2240
2241 template <class T>
2242 class ATL_NO_VTABLE CPrintDialogImpl : public CCommonDialogImplBase
2243 {
2244 public:
2245 // print dialog parameter block (note this is a reference)
2246 PRINTDLG& m_pd;
2247
2248 // Constructors
2249 CPrintDialogImpl(BOOL bPrintSetupOnly = FALSE, // TRUE for Print Setup, FALSE for Print Dialog
2250 DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_NOSELECTION,
2251 HWND hWndParent = NULL)
2252 : m_pd(m_pdActual)
2253 {
2254 memset(&m_pdActual, 0, sizeof(m_pdActual));
2255
2256 m_pd.lStructSize = sizeof(m_pdActual);
2257 m_pd.hwndOwner = hWndParent;
2258 m_pd.Flags = (dwFlags | PD_ENABLEPRINTHOOK | PD_ENABLESETUPHOOK);
2259 m_pd.lpfnPrintHook = (LPPRINTHOOKPROC)T::HookProc;
2260 m_pd.lpfnSetupHook = (LPSETUPHOOKPROC)T::HookProc;
2261
2262 if(bPrintSetupOnly)
2263 m_pd.Flags |= PD_PRINTSETUP;
2264 else
2265 m_pd.Flags |= PD_RETURNDC;
2266
2267 m_pd.Flags &= ~PD_RETURNIC; // do not support information context
2268 }
2269
2270 // Operations
2271 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
2272 {
2273 ATLASSERT((m_pd.Flags & PD_ENABLEPRINTHOOK) != 0);
2274 ATLASSERT((m_pd.Flags & PD_ENABLESETUPHOOK) != 0);
2275 ATLASSERT(m_pd.lpfnPrintHook != NULL); // can still be a user hook
2276 ATLASSERT(m_pd.lpfnSetupHook != NULL); // can still be a user hook
2277 ATLASSERT((m_pd.Flags & PD_RETURNDEFAULT) == 0); // use GetDefaults for this
2278
2279 if(m_pd.hwndOwner == NULL) // set only if not specified before
2280 m_pd.hwndOwner = hWndParent;
2281
2282 ATLASSERT(m_hWnd == NULL);
2283
2284 #if (_ATL_VER >= 0x0800)
2285 // Allocate the thunk structure here, where we can fail gracefully.
2286 BOOL bRetTh = m_thunk.Init(NULL, NULL);
2287 if(bRetTh == FALSE)
2288 {
2289 ::SetLastError(ERROR_OUTOFMEMORY);
2290 return -1;
2291 }
2292 #endif // (_ATL_VER >= 0x0800)
2293
2294 ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this);
2295
2296 BOOL bRet = ::PrintDlg(&m_pd);
2297
2298 m_hWnd = NULL;
2299
2300 return bRet ? IDOK : IDCANCEL;
2301 }
2302
2303 // GetDefaults will not display a dialog but will get device defaults
2304 BOOL GetDefaults()
2305 {
2306 m_pd.Flags |= PD_RETURNDEFAULT;
2307 ATLASSERT(m_pd.hDevMode == NULL); // must be NULL
2308 ATLASSERT(m_pd.hDevNames == NULL); // must be NULL
2309
2310 return ::PrintDlg(&m_pd);
2311 }
2312
2313 // Helpers for parsing information after successful return num. copies requested
2314 int GetCopies() const
2315 {
2316 if((m_pd.Flags & PD_USEDEVMODECOPIES) != 0)
2317 {
2318 LPDEVMODE lpDevMode = GetDevMode();
2319 return (lpDevMode != NULL) ? lpDevMode->dmCopies : -1;
2320 }
2321
2322 return m_pd.nCopies;
2323 }
2324
2325 BOOL PrintCollate() const // TRUE if collate checked
2326 {
2327 return ((m_pd.Flags & PD_COLLATE) != 0) ? TRUE : FALSE;
2328 }
2329
2330 BOOL PrintSelection() const // TRUE if printing selection
2331 {
2332 return ((m_pd.Flags & PD_SELECTION) != 0) ? TRUE : FALSE;
2333 }
2334
2335 BOOL PrintAll() const // TRUE if printing all pages
2336 {
2337 return (!PrintRange() && !PrintSelection()) ? TRUE : FALSE;
2338 }
2339
2340 BOOL PrintRange() const // TRUE if printing page range
2341 {
2342 return ((m_pd.Flags & PD_PAGENUMS) != 0) ? TRUE : FALSE;
2343 }
2344
2345 BOOL PrintToFile() const // TRUE if printing to a file
2346 {
2347 return ((m_pd.Flags & PD_PRINTTOFILE) != 0) ? TRUE : FALSE;
2348 }
2349
2350 int GetFromPage() const // starting page if valid
2351 {
2352 return PrintRange() ? m_pd.nFromPage : -1;
2353 }
2354
2355 int GetToPage() const // ending page if valid
2356 {
2357 return PrintRange() ? m_pd.nToPage : -1;
2358 }
2359
2360 LPDEVMODE GetDevMode() const // return DEVMODE
2361 {
2362 if(m_pd.hDevMode == NULL)
2363 return NULL;
2364
2365 return (LPDEVMODE)::GlobalLock(m_pd.hDevMode);
2366 }
2367
2368 LPCTSTR GetDriverName() const // return driver name
2369 {
2370 if(m_pd.hDevNames == NULL)
2371 return NULL;
2372
2373 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pd.hDevNames);
2374 if(lpDev == NULL)
2375 return NULL;
2376
2377 return (LPCTSTR)lpDev + lpDev->wDriverOffset;
2378 }
2379
2380 LPCTSTR GetDeviceName() const // return device name
2381 {
2382 if(m_pd.hDevNames == NULL)
2383 return NULL;
2384
2385 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pd.hDevNames);
2386 if(lpDev == NULL)
2387 return NULL;
2388
2389 return (LPCTSTR)lpDev + lpDev->wDeviceOffset;
2390 }
2391
2392 LPCTSTR GetPortName() const // return output port name
2393 {
2394 if(m_pd.hDevNames == NULL)
2395 return NULL;
2396
2397 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pd.hDevNames);
2398 if(lpDev == NULL)
2399 return NULL;
2400
2401 return (LPCTSTR)lpDev + lpDev->wOutputOffset;
2402 }
2403
2404 HDC GetPrinterDC() const // return HDC (caller must delete)
2405 {
2406 ATLASSERT((m_pd.Flags & PD_RETURNDC) != 0);
2407 return m_pd.hDC;
2408 }
2409
2410 // This helper creates a DC based on the DEVNAMES and DEVMODE structures.
2411 // This DC is returned, but also stored in m_pd.hDC as though it had been
2412 // returned by CommDlg. It is assumed that any previously obtained DC
2413 // has been/will be deleted by the user. This may be
2414 // used without ever invoking the print/print setup dialogs.
2415 HDC CreatePrinterDC()
2416 {
2417 m_pd.hDC = _AtlCreateDC(m_pd.hDevNames, m_pd.hDevMode);
2418 return m_pd.hDC;
2419 }
2420
2421 // Implementation
2422 PRINTDLG m_pdActual; // the Print/Print Setup need to share this
2423
2424 // The following handle the case of print setup... from the print dialog
2425 CPrintDialogImpl(PRINTDLG& pdInit) : m_pd(pdInit)
2426 { }
2427
2428 BEGIN_MSG_MAP(CPrintDialogImpl)
2429 #ifdef psh1
2430 COMMAND_ID_HANDLER(psh1, OnPrintSetup) // print setup button when print is displayed
2431 #else // !psh1
2432 COMMAND_ID_HANDLER(0x0400, OnPrintSetup) // value from dlgs.h
2433 #endif // !psh1
2434 END_MSG_MAP()
2435
2436 LRESULT OnPrintSetup(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& /*bHandled*/)
2437 {
2438 T dlgSetup(m_pd);
2439 ModuleHelper::AddCreateWndData(&dlgSetup.m_thunk.cd, (CCommonDialogImplBase*)&dlgSetup);
2440 return DefWindowProc(WM_COMMAND, MAKEWPARAM(wID, wNotifyCode), (LPARAM)hWndCtl);
2441 }
2442 };
2443
2444 class CPrintDialog : public CPrintDialogImpl<CPrintDialog>
2445 {
2446 public:
2447 CPrintDialog(BOOL bPrintSetupOnly = FALSE,
2448 DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_NOSELECTION,
2449 HWND hWndParent = NULL)
2450 : CPrintDialogImpl<CPrintDialog>(bPrintSetupOnly, dwFlags, hWndParent)
2451 { }
2452
2453 CPrintDialog(PRINTDLG& pdInit) : CPrintDialogImpl<CPrintDialog>(pdInit)
2454 { }
2455 };
2456
2457 #pragma warning(pop)
2458
2459 #endif // _WIN32_WCE
2460
2461
2462 ///////////////////////////////////////////////////////////////////////////////
2463 // CPrintDialogExImpl - new print dialog for Windows 2000
2464
2465 #if (WINVER >= 0x0500) && !defined(_WIN32_WCE)
2466
2467 }; // namespace WTL
2468
2469 #include <atlcom.h>
2470
2471 extern "C" const __declspec(selectany) IID IID_IPrintDialogCallback = {0x5852a2c3, 0x6530, 0x11d1, {0xb6, 0xa3, 0x0, 0x0, 0xf8, 0x75, 0x7b, 0xf9}};
2472 extern "C" const __declspec(selectany) IID IID_IPrintDialogServices = {0x509aaeda, 0x5639, 0x11d1, {0xb6, 0xa1, 0x0, 0x0, 0xf8, 0x75, 0x7b, 0xf9}};
2473
2474 namespace WTL
2475 {
2476
2477 template <class T>
2478 class ATL_NO_VTABLE CPrintDialogExImpl :
2479 public ATL::CWindow,
2480 public ATL::CMessageMap,
2481 public IPrintDialogCallback,
2482 public ATL::IObjectWithSiteImpl< T >
2483 {
2484 public:
2485 PRINTDLGEX m_pdex;
2486
2487 // Constructor
2488 CPrintDialogExImpl(DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_NOSELECTION | PD_NOCURRENTPAGE,
2489 HWND hWndParent = NULL)
2490 {
2491 memset(&m_pdex, 0, sizeof(m_pdex));
2492
2493 m_pdex.lStructSize = sizeof(PRINTDLGEX);
2494 m_pdex.hwndOwner = hWndParent;
2495 m_pdex.Flags = dwFlags;
2496 m_pdex.nStartPage = START_PAGE_GENERAL;
2497 // callback object will be set in DoModal
2498
2499 m_pdex.Flags &= ~PD_RETURNIC; // do not support information context
2500 }
2501
2502 // Operations
2503 HRESULT DoModal(HWND hWndParent = ::GetActiveWindow())
2504 {
2505 ATLASSERT(m_hWnd == NULL);
2506 ATLASSERT((m_pdex.Flags & PD_RETURNDEFAULT) == 0); // use GetDefaults for this
2507
2508 if(m_pdex.hwndOwner == NULL) // set only if not specified before
2509 m_pdex.hwndOwner = hWndParent;
2510
2511 T* pT = static_cast<T*>(this);
2512 m_pdex.lpCallback = (IUnknown*)(IPrintDialogCallback*)pT;
2513
2514 HRESULT hResult = ::PrintDlgEx(&m_pdex);
2515
2516 m_hWnd = NULL;
2517
2518 return hResult;
2519 }
2520
2521 BOOL EndDialog(INT_PTR /*nRetCode*/ = 0)
2522 {
2523 ATLASSERT(::IsWindow(m_hWnd));
2524 SendMessage(WM_COMMAND, MAKEWPARAM(IDABORT, 0));
2525 return TRUE;
2526 }
2527
2528 // GetDefaults will not display a dialog but will get device defaults
2529 HRESULT GetDefaults()
2530 {
2531 ATLASSERT(m_pdex.hDevMode == NULL); // must be NULL
2532 ATLASSERT(m_pdex.hDevNames == NULL); // must be NULL
2533
2534 if(m_pdex.hwndOwner == NULL) // set only if not specified before
2535 m_pdex.hwndOwner = ::GetActiveWindow();
2536
2537 m_pdex.Flags |= PD_RETURNDEFAULT;
2538 HRESULT hRet = ::PrintDlgEx(&m_pdex);
2539 m_pdex.Flags &= ~PD_RETURNDEFAULT;
2540
2541 return hRet;
2542 }
2543
2544 // Helpers for parsing information after successful return num. copies requested
2545 int GetCopies() const
2546 {
2547 if((m_pdex.Flags & PD_USEDEVMODECOPIES) != 0)
2548 {
2549 LPDEVMODE lpDevMode = GetDevMode();
2550 return (lpDevMode != NULL) ? lpDevMode->dmCopies : -1;
2551 }
2552
2553 return m_pdex.nCopies;
2554 }
2555
2556 BOOL PrintCollate() const // TRUE if collate checked
2557 {
2558 return ((m_pdex.Flags & PD_COLLATE) != 0) ? TRUE : FALSE;
2559 }
2560
2561 BOOL PrintSelection() const // TRUE if printing selection
2562 {
2563 return ((m_pdex.Flags & PD_SELECTION) != 0) ? TRUE : FALSE;
2564 }
2565
2566 BOOL PrintAll() const // TRUE if printing all pages
2567 {
2568 return (!PrintRange() && !PrintSelection()) ? TRUE : FALSE;
2569 }
2570
2571 BOOL PrintRange() const // TRUE if printing page range
2572 {
2573 return ((m_pdex.Flags & PD_PAGENUMS) != 0) ? TRUE : FALSE;
2574 }
2575
2576 BOOL PrintToFile() const // TRUE if printing to a file
2577 {
2578 return ((m_pdex.Flags & PD_PRINTTOFILE) != 0) ? TRUE : FALSE;
2579 }
2580
2581 LPDEVMODE GetDevMode() const // return DEVMODE
2582 {
2583 if(m_pdex.hDevMode == NULL)
2584 return NULL;
2585
2586 return (LPDEVMODE)::GlobalLock(m_pdex.hDevMode);
2587 }
2588
2589 LPCTSTR GetDriverName() const // return driver name
2590 {
2591 if(m_pdex.hDevNames == NULL)
2592 return NULL;
2593
2594 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pdex.hDevNames);
2595 if(lpDev == NULL)
2596 return NULL;
2597
2598 return (LPCTSTR)lpDev + lpDev->wDriverOffset;
2599 }
2600
2601 LPCTSTR GetDeviceName() const // return device name
2602 {
2603 if(m_pdex.hDevNames == NULL)
2604 return NULL;
2605
2606 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pdex.hDevNames);
2607 if(lpDev == NULL)
2608 return NULL;
2609
2610 return (LPCTSTR)lpDev + lpDev->wDeviceOffset;
2611 }
2612
2613 LPCTSTR GetPortName() const // return output port name
2614 {
2615 if(m_pdex.hDevNames == NULL)
2616 return NULL;
2617
2618 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pdex.hDevNames);
2619 if(lpDev == NULL)
2620 return NULL;
2621
2622 return (LPCTSTR)lpDev + lpDev->wOutputOffset;
2623 }
2624
2625 HDC GetPrinterDC() const // return HDC (caller must delete)
2626 {
2627 ATLASSERT((m_pdex.Flags & PD_RETURNDC) != 0);
2628 return m_pdex.hDC;
2629 }
2630
2631 // This helper creates a DC based on the DEVNAMES and DEVMODE structures.
2632 // This DC is returned, but also stored in m_pdex.hDC as though it had been
2633 // returned by CommDlg. It is assumed that any previously obtained DC
2634 // has been/will be deleted by the user. This may be
2635 // used without ever invoking the print/print setup dialogs.
2636 HDC CreatePrinterDC()
2637 {
2638 m_pdex.hDC = _AtlCreateDC(m_pdex.hDevNames, m_pdex.hDevMode);
2639 return m_pdex.hDC;
2640 }
2641
2642 // Implementation - interfaces
2643
2644 // IUnknown
2645 STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject)
2646 {
2647 if(ppvObject == NULL)
2648 return E_POINTER;
2649
2650 T* pT = static_cast<T*>(this);
2651 if(IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IPrintDialogCallback))
2652 {
2653 *ppvObject = (IPrintDialogCallback*)pT;
2654 // AddRef() not needed
2655 return S_OK;
2656 }
2657 else if(IsEqualGUID(riid, IID_IObjectWithSite))
2658 {
2659 *ppvObject = (IObjectWithSite*)pT;
2660 // AddRef() not needed
2661 return S_OK;
2662 }
2663
2664 return E_NOINTERFACE;
2665 }
2666
2667 virtual ULONG STDMETHODCALLTYPE AddRef()
2668 {
2669 return 1;
2670 }
2671
2672 virtual ULONG STDMETHODCALLTYPE Release()
2673 {
2674 return 1;
2675 }
2676
2677 // IPrintDialogCallback
2678 STDMETHOD(InitDone)()
2679 {
2680 return S_FALSE;
2681 }
2682
2683 STDMETHOD(SelectionChange)()
2684 {
2685 return S_FALSE;
2686 }
2687
2688 STDMETHOD(HandleMessage)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* plResult)
2689 {
2690 // set up m_hWnd the first time
2691 if(m_hWnd == NULL)
2692 Attach(hWnd);
2693
2694 // call message map
2695 HRESULT hRet = ProcessWindowMessage(hWnd, uMsg, wParam, lParam, *plResult, 0) ? S_OK : S_FALSE;
2696 if(hRet == S_OK && uMsg == WM_NOTIFY) // return in DWLP_MSGRESULT
2697 ::SetWindowLongPtr(GetParent(), DWLP_MSGRESULT, (LONG_PTR)*plResult);
2698
2699 if(uMsg == WM_INITDIALOG && hRet == S_OK && (BOOL)*plResult != FALSE)
2700 hRet = S_FALSE;
2701
2702 return hRet;
2703 }
2704 };
2705
2706 class CPrintDialogEx : public CPrintDialogExImpl<CPrintDialogEx>
2707 {
2708 public:
2709 CPrintDialogEx(
2710 DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_NOSELECTION | PD_NOCURRENTPAGE,
2711 HWND hWndParent = NULL)
2712 : CPrintDialogExImpl<CPrintDialogEx>(dwFlags, hWndParent)
2713 { }
2714
2715 DECLARE_EMPTY_MSG_MAP()
2716 };
2717
2718 #endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE)
2719
2720
2721 ///////////////////////////////////////////////////////////////////////////////
2722 // CPageSetupDialogImpl - Page Setup dialog
2723
2724 #ifndef _WIN32_WCE
2725
2726 template <class T>
2727 class ATL_NO_VTABLE CPageSetupDialogImpl : public CCommonDialogImplBase
2728 {
2729 public:
2730 PAGESETUPDLG m_psd;
2731 ATL::CWndProcThunk m_thunkPaint;
2732
2733 // Constructors
2734 CPageSetupDialogImpl(DWORD dwFlags = PSD_MARGINS | PSD_INWININIINTLMEASURE, HWND hWndParent = NULL)
2735 {
2736 memset(&m_psd, 0, sizeof(m_psd));
2737
2738 m_psd.lStructSize = sizeof(m_psd);
2739 m_psd.hwndOwner = hWndParent;
2740 m_psd.Flags = (dwFlags | PSD_ENABLEPAGESETUPHOOK | PSD_ENABLEPAGEPAINTHOOK);
2741 m_psd.lpfnPageSetupHook = (LPPAGESETUPHOOK)T::HookProc;
2742 m_thunkPaint.Init((WNDPROC)T::PaintHookProc, this);
2743 #if (_ATL_VER >= 0x0700)
2744 m_psd.lpfnPagePaintHook = (LPPAGEPAINTHOOK)m_thunkPaint.GetWNDPROC();
2745 #else
2746 m_psd.lpfnPagePaintHook = (LPPAGEPAINTHOOK)&(m_thunkPaint.thunk);
2747 #endif
2748 }
2749
2750 DECLARE_EMPTY_MSG_MAP()
2751
2752 // Attributes
2753 LPDEVMODE GetDevMode() const // return DEVMODE
2754 {
2755 if(m_psd.hDevMode == NULL)
2756 return NULL;
2757
2758 return (LPDEVMODE)::GlobalLock(m_psd.hDevMode);
2759 }
2760
2761 LPCTSTR GetDriverName() const // return driver name
2762 {
2763 if(m_psd.hDevNames == NULL)
2764 return NULL;
2765
2766 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_psd.hDevNames);
2767 return (LPCTSTR)lpDev + lpDev->wDriverOffset;
2768 }
2769
2770 LPCTSTR GetDeviceName() const // return device name
2771 {
2772 if(m_psd.hDevNames == NULL)
2773 return NULL;
2774
2775 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_psd.hDevNames);
2776 return (LPCTSTR)lpDev + lpDev->wDeviceOffset;
2777 }
2778
2779 LPCTSTR GetPortName() const // return output port name
2780 {
2781 if(m_psd.hDevNames == NULL)
2782 return NULL;
2783
2784 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_psd.hDevNames);
2785 return (LPCTSTR)lpDev + lpDev->wOutputOffset;
2786 }
2787
2788 HDC CreatePrinterDC()
2789 {
2790 return _AtlCreateDC(m_psd.hDevNames, m_psd.hDevMode);
2791 }
2792
2793 SIZE GetPaperSize() const
2794 {
2795 SIZE size = { m_psd.ptPaperSize.x, m_psd.ptPaperSize.y };
2796 return size;
2797 }
2798
2799 void GetMargins(LPRECT lpRectMargins, LPRECT lpRectMinMargins) const
2800 {
2801 if(lpRectMargins != NULL)
2802 *lpRectMargins = m_psd.rtMargin;
2803 if(lpRectMinMargins != NULL)
2804 *lpRectMinMargins = m_psd.rtMinMargin;
2805 }
2806
2807 // Operations
2808 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
2809 {
2810 ATLASSERT((m_psd.Flags & PSD_ENABLEPAGESETUPHOOK) != 0);
2811 ATLASSERT((m_psd.Flags & PSD_ENABLEPAGEPAINTHOOK) != 0);
2812 ATLASSERT(m_psd.lpfnPageSetupHook != NULL); // can still be a user hook
2813 ATLASSERT(m_psd.lpfnPagePaintHook != NULL); // can still be a user hook
2814
2815 if(m_psd.hwndOwner == NULL) // set only if not specified before
2816 m_psd.hwndOwner = hWndParent;
2817
2818 ATLASSERT(m_hWnd == NULL);
2819
2820 #if (_ATL_VER >= 0x0800)
2821 // Allocate the thunk structure here, where we can fail gracefully.
2822 BOOL bRetTh = m_thunk.Init(NULL, NULL);
2823 if(bRetTh == FALSE)
2824 {
2825 ::SetLastError(ERROR_OUTOFMEMORY);
2826 return -1;
2827 }
2828 #endif // (_ATL_VER >= 0x0800)
2829
2830 ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this);
2831
2832 BOOL bRet = ::PageSetupDlg(&m_psd);
2833
2834 m_hWnd = NULL;
2835
2836 return bRet ? IDOK : IDCANCEL;
2837 }
2838
2839 // Implementation
2840 static UINT_PTR CALLBACK PaintHookProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2841 {
2842 T* pT = (T*)hWnd;
2843 UINT_PTR uRet = 0;
2844 switch(uMsg)
2845 {
2846 case WM_PSD_PAGESETUPDLG:
2847 uRet = pT->PreDrawPage(LOWORD(wParam), HIWORD(wParam), (LPPAGESETUPDLG)lParam);
2848 break;
2849 case WM_PSD_FULLPAGERECT:
2850 case WM_PSD_MINMARGINRECT:
2851 case WM_PSD_MARGINRECT:
2852 case WM_PSD_GREEKTEXTRECT:
2853 case WM_PSD_ENVSTAMPRECT:
2854 case WM_PSD_YAFULLPAGERECT:
2855 uRet = pT->OnDrawPage(uMsg, (HDC)wParam, (LPRECT)lParam);
2856 break;
2857 default:
2858 ATLTRACE2(atlTraceUI, 0, _T("CPageSetupDialogImpl::PaintHookProc - unknown message received\n"));
2859 break;
2860 }
2861 return uRet;
2862 }
2863
2864 // Overridables
2865 UINT_PTR PreDrawPage(WORD /*wPaper*/, WORD /*wFlags*/, LPPAGESETUPDLG /*pPSD*/)
2866 {
2867 // return 1 to prevent any more drawing
2868 return 0;
2869 }
2870
2871 UINT_PTR OnDrawPage(UINT /*uMsg*/, HDC /*hDC*/, LPRECT /*lpRect*/)
2872 {
2873 return 0; // do the default
2874 }
2875 };
2876
2877 class CPageSetupDialog : public CPageSetupDialogImpl<CPageSetupDialog>
2878 {
2879 public:
2880 CPageSetupDialog(DWORD dwFlags = PSD_MARGINS | PSD_INWININIINTLMEASURE, HWND hWndParent = NULL)
2881 : CPageSetupDialogImpl<CPageSetupDialog>(dwFlags, hWndParent)
2882 { }
2883
2884 // override PaintHookProc and references to handlers
2885 static UINT_PTR CALLBACK PaintHookProc(HWND, UINT, WPARAM, LPARAM)
2886 {
2887 return 0;
2888 }
2889 };
2890
2891 #endif // _WIN32_WCE
2892
2893
2894 ///////////////////////////////////////////////////////////////////////////////
2895 // CFindReplaceDialogImpl - Find/FindReplace modeless dialogs
2896
2897 #ifndef _WIN32_WCE
2898
2899 template <class T>
2900 class ATL_NO_VTABLE CFindReplaceDialogImpl : public CCommonDialogImplBase
2901 {
2902 public:
2903 enum { _cchFindReplaceBuffer = 128 };
2904
2905 FINDREPLACE m_fr;
2906 TCHAR m_szFindWhat[_cchFindReplaceBuffer];
2907 TCHAR m_szReplaceWith[_cchFindReplaceBuffer];
2908
2909 // Constructors
2910 CFindReplaceDialogImpl()
2911 {
2912 memset(&m_fr, 0, sizeof(m_fr));
2913 m_szFindWhat[0] = _T('\0');
2914 m_szReplaceWith[0] = _T('\0');
2915
2916 m_fr.lStructSize = sizeof(m_fr);
2917 m_fr.Flags = FR_ENABLEHOOK;
2918 m_fr.lpfnHook = (LPFRHOOKPROC)T::HookProc;
2919 m_fr.lpstrFindWhat = (LPTSTR)m_szFindWhat;
2920 m_fr.wFindWhatLen = _cchFindReplaceBuffer;
2921 m_fr.lpstrReplaceWith = (LPTSTR)m_szReplaceWith;
2922 m_fr.wReplaceWithLen = _cchFindReplaceBuffer;
2923 }
2924
2925 // Note: You must allocate the object on the heap.
2926 // If you do not, you must override OnFinalMessage()
2927 virtual void OnFinalMessage(HWND /*hWnd*/)
2928 {
2929 delete this;
2930 }
2931
2932 HWND Create(BOOL bFindDialogOnly, // TRUE for Find, FALSE for FindReplace
2933 LPCTSTR lpszFindWhat,
2934 LPCTSTR lpszReplaceWith = NULL,
2935 DWORD dwFlags = FR_DOWN,
2936 HWND hWndParent = NULL)
2937 {
2938 ATLASSERT((m_fr.Flags & FR_ENABLEHOOK) != 0);
2939 ATLASSERT(m_fr.lpfnHook != NULL);
2940
2941 m_fr.Flags |= dwFlags;
2942
2943 if(hWndParent == NULL)
2944 m_fr.hwndOwner = ::GetActiveWindow();
2945 else
2946 m_fr.hwndOwner = hWndParent;
2947 ATLASSERT(m_fr.hwndOwner != NULL); // must have an owner for modeless dialog
2948
2949 if(lpszFindWhat != NULL)
2950 SecureHelper::strncpy_x(m_szFindWhat, _countof(m_szFindWhat), lpszFindWhat, _TRUNCATE);
2951
2952 if(lpszReplaceWith != NULL)
2953 SecureHelper::strncpy_x(m_szReplaceWith, _countof(m_szReplaceWith), lpszReplaceWith, _TRUNCATE);
2954
2955 ATLASSERT(m_hWnd == NULL);
2956
2957 #if (_ATL_VER >= 0x0800)
2958 // Allocate the thunk structure here, where we can fail gracefully.
2959 BOOL bRet = m_thunk.Init(NULL, NULL);
2960 if(bRet == FALSE)
2961 {
2962 ::SetLastError(ERROR_OUTOFMEMORY);
2963 return NULL;
2964 }
2965 #endif // (_ATL_VER >= 0x0800)
2966
2967 ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this);
2968
2969 HWND hWnd = NULL;
2970 if(bFindDialogOnly)
2971 hWnd = ::FindText(&m_fr);
2972 else
2973 hWnd = ::ReplaceText(&m_fr);
2974
2975 ATLASSERT(m_hWnd == hWnd);
2976 return hWnd;
2977 }
2978
2979 static const UINT GetFindReplaceMsg()
2980 {
2981 static const UINT nMsgFindReplace = ::RegisterWindowMessage(FINDMSGSTRING);
2982 return nMsgFindReplace;
2983 }
2984 // call while handling FINDMSGSTRING registered message
2985 // to retreive the object
2986 static T* PASCAL GetNotifier(LPARAM lParam)
2987 {
2988 ATLASSERT(lParam != NULL);
2989 T* pDlg = (T*)(lParam - offsetof(T, m_fr));
2990 return pDlg;
2991 }
2992
2993 // Operations
2994 // Helpers for parsing information after successful return
2995 LPCTSTR GetFindString() const // get find string
2996 {
2997 return (LPCTSTR)m_fr.lpstrFindWhat;
2998 }
2999
3000 LPCTSTR GetReplaceString() const // get replacement string
3001 {
3002 return (LPCTSTR)m_fr.lpstrReplaceWith;
3003 }
3004
3005 BOOL SearchDown() const // TRUE if search down, FALSE is up
3006 {
3007 return ((m_fr.Flags & FR_DOWN) != 0) ? TRUE : FALSE;
3008 }
3009
3010 BOOL FindNext() const // TRUE if command is find next
3011 {
3012 return ((m_fr.Flags & FR_FINDNEXT) != 0) ? TRUE : FALSE;
3013 }
3014
3015 BOOL MatchCase() const // TRUE if matching case
3016 {
3017 return ((m_fr.Flags & FR_MATCHCASE) != 0) ? TRUE : FALSE;
3018 }
3019
3020 BOOL MatchWholeWord() const // TRUE if matching whole words only
3021 {
3022 return ((m_fr.Flags & FR_WHOLEWORD) != 0) ? TRUE : FALSE;
3023 }
3024
3025 BOOL ReplaceCurrent() const // TRUE if replacing current string
3026 {
3027 return ((m_fr. Flags & FR_REPLACE) != 0) ? TRUE : FALSE;
3028 }
3029
3030 BOOL ReplaceAll() const // TRUE if replacing all occurrences
3031 {
3032 return ((m_fr.Flags & FR_REPLACEALL) != 0) ? TRUE : FALSE;
3033 }
3034
3035 BOOL IsTerminating() const // TRUE if terminating dialog
3036 {
3037 return ((m_fr.Flags & FR_DIALOGTERM) != 0) ? TRUE : FALSE ;
3038 }
3039 };
3040
3041 class CFindReplaceDialog : public CFindReplaceDialogImpl<CFindReplaceDialog>
3042 {
3043 public:
3044 DECLARE_EMPTY_MSG_MAP()
3045 };
3046
3047 #endif // !_WIN32_WCE
3048
3049
3050 /////////////////////////////////////////////////////////////////////////
3051 // CDialogBaseUnits - Dialog Units helper
3052 //
3053
3054 class CDialogBaseUnits
3055 {
3056 public:
3057 SIZE m_sizeUnits;
3058
3059 // Constructors
3060 CDialogBaseUnits()
3061 {
3062 // The base units of the out-dated System Font
3063 LONG nDlgBaseUnits = ::GetDialogBaseUnits();
3064 m_sizeUnits.cx = LOWORD(nDlgBaseUnits);
3065 m_sizeUnits.cy = HIWORD(nDlgBaseUnits);
3066 }
3067
3068 CDialogBaseUnits(HWND hWnd)
3069 {
3070 if(!InitDialogBaseUnits(hWnd)) {
3071 LONG nDlgBaseUnits = ::GetDialogBaseUnits();
3072 m_sizeUnits.cx = LOWORD(nDlgBaseUnits);
3073 m_sizeUnits.cy = HIWORD(nDlgBaseUnits);
3074 }
3075 }
3076
3077 CDialogBaseUnits(HFONT hFont, HWND hWnd = NULL)
3078 {
3079 if(!InitDialogBaseUnits(hFont, hWnd)) {
3080 LONG nDlgBaseUnits = ::GetDialogBaseUnits();
3081 m_sizeUnits.cx = LOWORD(nDlgBaseUnits);
3082 m_sizeUnits.cy = HIWORD(nDlgBaseUnits);
3083 }
3084 }
3085
3086 CDialogBaseUnits(LOGFONT lf, HWND hWnd = NULL)
3087 {
3088 if(!InitDialogBaseUnits(lf, hWnd)) {
3089 LONG nDlgBaseUnits = ::GetDialogBaseUnits();
3090 m_sizeUnits.cx = LOWORD(nDlgBaseUnits);
3091 m_sizeUnits.cy = HIWORD(nDlgBaseUnits);
3092 }
3093 }
3094
3095 // Operations
3096 BOOL InitDialogBaseUnits(HWND hWnd)
3097 {
3098 ATLASSERT(::IsWindow(hWnd));
3099 RECT rc = { 0, 0, 4, 8 };
3100 if(!::MapDialogRect(hWnd, &rc)) return FALSE;
3101 m_sizeUnits.cx = rc.right;
3102 m_sizeUnits.cy = rc.bottom;
3103 return TRUE;
3104 }
3105
3106 BOOL InitDialogBaseUnits(LOGFONT lf, HWND hWnd = NULL)
3107 {
3108 CFont font;
3109 font.CreateFontIndirect(&lf);
3110 if(font.IsNull()) return FALSE;
3111 return InitDialogBaseUnits(font, hWnd);
3112 }
3113
3114 BOOL InitDialogBaseUnits(HFONT hFont, HWND hWnd = NULL)
3115 {
3116 ATLASSERT(hFont != NULL);
3117 CWindowDC dc = hWnd;
3118 TEXTMETRIC tmText = { 0 };
3119 SIZE sizeText = { 0 };
3120 HFONT hFontOld = dc.SelectFont(hFont);
3121 dc.GetTextMetrics(&tmText);
3122 m_sizeUnits.cy = tmText.tmHeight + tmText.tmExternalLeading;
3123 dc.GetTextExtent(_T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), 52, &sizeText);
3124 m_sizeUnits.cx = (sizeText.cx + 26) / 52;
3125 dc.SelectFont(hFontOld);
3126 return TRUE;
3127 }
3128
3129 SIZE GetDialogBaseUnits() const
3130 {
3131 return m_sizeUnits;
3132 }
3133
3134 INT MapDialogPixelsX(INT x) const
3135 {
3136 return ::MulDiv(x, 4, m_sizeUnits.cx); // Pixels X to DLU
3137 }
3138
3139 INT MapDialogPixelsY(INT y) const
3140 {
3141 return ::MulDiv(y, 8, m_sizeUnits.cy); // Pixels Y to DLU
3142 }
3143
3144 POINT MapDialogPixels(POINT pt) const
3145 {
3146 POINT out = { MapDialogPixelsX(pt.x), MapDialogPixelsY(pt.y) };
3147 return out;
3148 }
3149
3150 SIZE MapDialogPixels(SIZE input) const
3151 {
3152 SIZE out = { MapDialogPixelsX(input.cx), MapDialogPixelsY(input.cy) };
3153 return out;
3154 }
3155
3156 RECT MapDialogPixels(const RECT& input) const
3157 {
3158 RECT out = { MapDialogPixelsX(input.left), MapDialogPixelsY(input.top), MapDialogPixelsX(input.right), MapDialogPixelsY(input.bottom) };
3159 return out;
3160 }
3161
3162 INT MapDialogUnitsX(INT x) const
3163 {
3164 return ::MulDiv(x, m_sizeUnits.cx, 4); // DLU to Pixels X
3165 }
3166
3167 INT MapDialogUnitsY(INT y) const
3168 {
3169 return ::MulDiv(y, m_sizeUnits.cy, 8); // DLU to Pixels Y
3170 }
3171
3172 POINT MapDialogUnits(POINT pt) const
3173 {
3174 POINT out = { MapDialogUnitsX(pt.x), MapDialogUnitsY(pt.y) };
3175 return out;
3176 }
3177
3178 SIZE MapDialogUnits(SIZE input) const
3179 {
3180 SIZE out = { MapDialogUnitsX(input.cx), MapDialogUnitsY(input.cy) };
3181 return out;
3182 }
3183
3184 RECT MapDialogUnits(const RECT& input) const
3185 {
3186 RECT out = { MapDialogUnitsX(input.left), MapDialogUnitsY(input.top), MapDialogUnitsX(input.right), MapDialogUnitsY(input.bottom) };
3187 return out;
3188 }
3189 };
3190
3191
3192 ///////////////////////////////////////////////////////////////////////////////
3193 // CMemDlgTemplate - in-memory dialog template - DLGTEMPLATE or DLGTEMPLATEEX
3194
3195 #if (_ATL_VER >= 0x800)
3196 typedef ATL::_DialogSplitHelper::DLGTEMPLATEEX DLGTEMPLATEEX;
3197 typedef ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX DLGITEMTEMPLATEEX;
3198 #else // (_ATL_VER >= 0x800)
3199 typedef ATL::_DialogSizeHelper::_ATL_DLGTEMPLATEEX DLGTEMPLATEEX;
3200 #pragma pack(push, 4)
3201 struct DLGITEMTEMPLATEEX
3202 {
3203 DWORD helpID;
3204 DWORD exStyle;
3205 DWORD style;
3206 short x;
3207 short y;
3208 short cx;
3209 short cy;
3210 DWORD id;
3211 };
3212 #pragma pack(pop)
3213 #endif // (_ATL_VER >= 0x800)
3214
3215
3216 template <class TWinTraits>
3217 class CMemDlgTemplateT
3218 {
3219 public:
3220 enum StdCtrlType
3221 {
3222 CTRL_BUTTON = 0x0080,
3223 CTRL_EDIT = 0x0081,
3224 CTRL_STATIC = 0x0082,
3225 CTRL_LISTBOX = 0x0083,
3226 CTRL_SCROLLBAR = 0x0084,
3227 CTRL_COMBOBOX = 0x0085
3228 };
3229
3230 HANDLE m_hData;
3231 LPBYTE m_pData;
3232 LPBYTE m_pPtr;
3233 SIZE_T m_cAllocated;
3234
3235 CMemDlgTemplateT() : m_hData(NULL), m_pData(NULL), m_pPtr(NULL), m_cAllocated(0)
3236 { }
3237
3238 ~CMemDlgTemplateT()
3239 {
3240 Reset();
3241 }
3242
3243 bool IsValid() const
3244 {
3245 return (m_pData != NULL);
3246 }
3247
3248 bool IsTemplateEx() const
3249 {
3250 return (IsValid() && ((DLGTEMPLATEEX*)m_pData)->signature == 0xFFFF);
3251 }
3252
3253 LPDLGTEMPLATE GetTemplatePtr()
3254 {
3255 return reinterpret_cast<LPDLGTEMPLATE>(m_pData);
3256 }
3257
3258 DLGTEMPLATEEX* GetTemplateExPtr()
3259 {
3260 return reinterpret_cast<DLGTEMPLATEEX*>(m_pData);
3261 }
3262
3263 void Reset()
3264 {
3265 if (IsValid()) {
3266 #ifndef UNDER_CE
3267 ::GlobalUnlock(m_pData);
3268 #endif
3269 ATLVERIFY(::GlobalFree(m_hData) == NULL);
3270 }
3271
3272 m_hData = NULL;
3273 m_pData = NULL;
3274 m_pPtr = NULL;
3275 m_cAllocated = 0;
3276 }
3277
3278 void Create(bool bDlgEx, LPCTSTR lpszCaption, const RECT& rc, DWORD dwStyle = 0, DWORD dwExStyle = 0,
3279 LPCTSTR lpstrFontName = NULL, WORD wFontSize = 0, WORD wWeight = 0, BYTE bItalic = 0, BYTE bCharset = 0, DWORD dwHelpID = 0,
3280 ATL::_U_STRINGorID ClassName = 0U, ATL::_U_STRINGorID Menu = 0U)
3281 {
3282 Create(bDlgEx, lpszCaption, (short) rc.left, (short) rc.top, (short) (rc.right - rc.left), (short) (rc.bottom - rc.top), dwStyle, dwExStyle,
3283 lpstrFontName, wFontSize, wWeight, bItalic, bCharset, dwHelpID, ClassName.m_lpstr, Menu.m_lpstr);
3284 }
3285
3286 void Create(bool bDlgEx, LPCTSTR lpszCaption, short nX, short nY, short nWidth, short nHeight, DWORD dwStyle = 0, DWORD dwExStyle = 0,
3287 LPCTSTR lpstrFontName = NULL, WORD wFontSize = 0, WORD wWeight = 0, BYTE bItalic = 0, BYTE bCharset = 0, DWORD dwHelpID = 0,
3288 ATL::_U_STRINGorID ClassName = 0U, ATL::_U_STRINGorID Menu = 0U)
3289 {
3290 // Should have DS_SETFONT style to set the dialog font name and size
3291 if (lpstrFontName != NULL)
3292 {
3293 dwStyle |= DS_SETFONT;
3294 }
3295 else
3296 {
3297 dwStyle &= ~DS_SETFONT;
3298 }
3299
3300 if (bDlgEx)
3301 {
3302 DLGTEMPLATEEX dlg = {1, 0xFFFF, dwHelpID, dwExStyle, dwStyle, 0, nX, nY, nWidth, nHeight};
3303 AddData(&dlg, sizeof(dlg));
3304 }
3305 else
3306 {
3307 DLGTEMPLATE dlg = {dwStyle, dwExStyle, 0, nX, nY, nWidth, nHeight};
3308 AddData(&dlg, sizeof(dlg));
3309 }
3310
3311 #ifndef _WIN32_WCE
3312 if (Menu.m_lpstr == NULL)
3313 {
3314 WORD menuData = 0;
3315 AddData(&menuData, sizeof(WORD));
3316 }
3317 else if (IS_INTRESOURCE(Menu.m_lpstr))
3318 {
3319 WORD menuData[] = { 0xFFFF, LOWORD(Menu.m_lpstr) };
3320 AddData(menuData, sizeof(menuData));
3321 }
3322 else
3323 {
3324 AddString(Menu.m_lpstr);
3325 }
3326 #else // _WIN32_WCE
3327 // Windows CE doesn't support the addition of menus to a dialog box
3328 ATLASSERT(Menu.m_lpstr == NULL);
3329 Menu.m_lpstr; // avoid level 4 warning
3330 WORD menuData = 0;
3331 AddData(&menuData, sizeof(WORD));
3332 #endif // _WIN32_WCE
3333
3334 if (ClassName.m_lpstr == NULL)
3335 {
3336 WORD classData = 0;
3337 AddData(&classData, sizeof(WORD));
3338 }
3339 else if (IS_INTRESOURCE(ClassName.m_lpstr))
3340 {
3341 WORD classData[] = { 0xFFFF, LOWORD(ClassName.m_lpstr) };
3342 AddData(classData, sizeof(classData));
3343 }
3344 else
3345 {
3346 AddString(ClassName.m_lpstr);
3347 }
3348
3349 // Set dialog caption
3350 AddString(lpszCaption);
3351
3352 if (lpstrFontName != NULL)
3353 {
3354 AddData(&wFontSize, sizeof(wFontSize));
3355
3356 if (bDlgEx)
3357 {
3358 AddData(&wWeight, sizeof(wWeight));
3359 AddData(&bItalic, sizeof(bItalic));
3360 AddData(&bCharset, sizeof(bCharset));
3361 }
3362
3363 AddString(lpstrFontName);
3364 }
3365 }
3366
3367 void AddControl(ATL::_U_STRINGorID ClassName, WORD wId, const RECT& rc, DWORD dwStyle, DWORD dwExStyle,
3368 ATL::_U_STRINGorID Text, const WORD* pCreationData = NULL, WORD nCreationData = 0, DWORD dwHelpID = 0)
3369 {
3370 AddControl(ClassName.m_lpstr, wId, (short) rc.left, (short) rc.top, (short) (rc.right - rc.left), (short) (rc.bottom - rc.top), dwStyle, dwExStyle,
3371 Text.m_lpstr, pCreationData, nCreationData, dwHelpID);
3372 }
3373
3374 void AddControl(ATL::_U_STRINGorID ClassName, WORD wId, short nX, short nY, short nWidth, short nHeight, DWORD dwStyle, DWORD dwExStyle,
3375 ATL::_U_STRINGorID Text, const WORD* pCreationData = NULL, WORD nCreationData = 0, DWORD dwHelpID = 0)
3376 {
3377 ATLASSERT(IsValid());
3378
3379 // DWORD align data
3380 const DWORD_PTR dwDwordAlignBits = sizeof(DWORD) - 1;
3381 m_pPtr = (LPBYTE)(((DWORD_PTR)m_pPtr + dwDwordAlignBits) & (~dwDwordAlignBits));
3382
3383 if (IsTemplateEx())
3384 {
3385 DLGTEMPLATEEX* dlg = (DLGTEMPLATEEX*)m_pData;
3386 dlg->cDlgItems++;
3387
3388 DLGITEMTEMPLATEEX item = {dwHelpID, TWinTraits::GetWndExStyle(0) | dwExStyle, TWinTraits::GetWndStyle(0) | dwStyle, nX, nY, nWidth, nHeight, wId};
3389 AddData(&item, sizeof(item));
3390 }
3391 else
3392 {
3393 LPDLGTEMPLATE dlg = (LPDLGTEMPLATE)m_pData;
3394 dlg->cdit++;
3395
3396 DLGITEMTEMPLATE item = {TWinTraits::GetWndStyle(0) | dwStyle, TWinTraits::GetWndExStyle(0) | dwExStyle, nX, nY, nWidth, nHeight, wId};
3397 AddData(&item, sizeof(item));
3398 }
3399
3400 ATLASSERT(ClassName.m_lpstr != NULL);
3401 if (IS_INTRESOURCE(ClassName.m_lpstr))
3402 {
3403 WORD wData[] = { 0xFFFF, LOWORD(ClassName.m_lpstr) };
3404 AddData(wData, sizeof(wData));
3405 }
3406 else
3407 {
3408 AddString(ClassName.m_lpstr);
3409 }
3410
3411 if (Text.m_lpstr == NULL)
3412 {
3413 WORD classData = 0;
3414 AddData(&classData, sizeof(WORD));
3415 }
3416 else if (IS_INTRESOURCE(Text.m_lpstr))
3417 {
3418 WORD wData[] = { 0xFFFF, LOWORD(Text.m_lpstr) };
3419 AddData(wData, sizeof(wData));
3420 }
3421 else
3422 {
3423 AddString(Text.m_lpstr);
3424 }
3425
3426 AddData(&nCreationData, sizeof(nCreationData));
3427
3428 if ((nCreationData != 0))
3429 {
3430 ATLASSERT(pCreationData != NULL);
3431 AddData(pCreationData, nCreationData * sizeof(WORD));
3432 }
3433 }
3434
3435 void AddStdControl(StdCtrlType CtrlType, WORD wId, short nX, short nY, short nWidth, short nHeight,
3436 DWORD dwStyle, DWORD dwExStyle, ATL::_U_STRINGorID Text, const WORD* pCreationData = NULL, WORD nCreationData = 0, DWORD dwHelpID = 0)
3437 {
3438 AddControl(CtrlType, wId, nX, nY, nWidth, nHeight, dwStyle, dwExStyle, Text, pCreationData, nCreationData, dwHelpID);
3439 }
3440
3441 void AddData(LPCVOID pData, size_t nData)
3442 {
3443 ATLASSERT(pData != NULL);
3444
3445 const SIZE_T ALLOCATION_INCREMENT = 1024;
3446
3447 if (m_pData == NULL)
3448 {
3449 m_cAllocated = ((nData / ALLOCATION_INCREMENT) + 1) * ALLOCATION_INCREMENT;
3450 m_hData = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, m_cAllocated);
3451 ATLASSERT(m_hData != NULL);
3452 #ifndef UNDER_CE
3453 m_pPtr = m_pData = static_cast<LPBYTE>(::GlobalLock(m_hData));
3454 #else
3455 m_pPtr = m_pData = static_cast<LPBYTE>(m_hData);
3456 #endif
3457 ATLASSERT(m_pData != NULL);
3458 }
3459 else if (((m_pPtr - m_pData) + nData) > m_cAllocated)
3460 {
3461 SIZE_T ptrPos = (m_pPtr - m_pData);
3462 m_cAllocated += ((nData / ALLOCATION_INCREMENT) + 1) * ALLOCATION_INCREMENT;
3463 #ifndef UNDER_CE
3464 ::GlobalUnlock(m_pData);
3465 #endif
3466 m_hData = ::GlobalReAlloc(m_hData, m_cAllocated, GMEM_MOVEABLE | GMEM_ZEROINIT);
3467 ATLASSERT(m_hData != NULL);
3468 #ifndef UNDER_CE
3469 m_pData = static_cast<LPBYTE>(::GlobalLock(m_hData));
3470 #else
3471 m_pData = static_cast<LPBYTE>(m_hData);
3472 #endif
3473 ATLASSERT(m_pData != NULL);
3474 m_pPtr = m_pData + ptrPos;
3475 }
3476
3477 SecureHelper::memcpy_x(m_pPtr, m_cAllocated - (m_pPtr - m_pData), pData, nData);
3478
3479 m_pPtr += nData;
3480 }
3481
3482 void AddString(LPCTSTR lpszStr)
3483 {
3484 if (lpszStr == NULL)
3485 {
3486 WCHAR szEmpty = 0;
3487 AddData(&szEmpty, sizeof(szEmpty));
3488 }
3489 else
3490 {
3491 USES_CONVERSION;
3492 LPCWSTR lpstr = T2CW(lpszStr);
3493 int nSize = lstrlenW(lpstr) + 1;
3494 AddData(lpstr, nSize * sizeof(WCHAR));
3495 }
3496 }
3497 };
3498
3499 typedef CMemDlgTemplateT<ATL::CControlWinTraits> CMemDlgTemplate;
3500
3501
3502 ///////////////////////////////////////////////////////////////////////////////
3503 // Dialog and control macros for indirect dialogs
3504
3505 // for DLGTEMPLATE
3506 #define BEGIN_DIALOG(x, y, width, height) \
3507 void DoInitTemplate() \
3508 { \
3509 bool bExTemplate = false; \
3510 short nX = x, nY = y, nWidth = width, nHeight = height; \
3511 LPCTSTR szCaption = NULL; \
3512 DWORD dwStyle = WS_POPUP | WS_BORDER | WS_SYSMENU; \
3513 DWORD dwExStyle = 0; \
3514 LPCTSTR szFontName = NULL; \
3515 WORD wFontSize = 0; \
3516 WORD wWeight = 0; \
3517 BYTE bItalic = 0; \
3518 BYTE bCharset = 0; \
3519 DWORD dwHelpID = 0; \
3520 ATL::_U_STRINGorID Menu = 0U; \
3521 ATL::_U_STRINGorID ClassName = 0U;
3522
3523 // for DLGTEMPLATEEX
3524 #define BEGIN_DIALOG_EX(x, y, width, height, helpID) \
3525 void DoInitTemplate() \
3526 { \
3527 bool bExTemplate = true; \
3528 short nX = x, nY = y, nWidth = width, nHeight = height; \
3529 LPCTSTR szCaption = NULL; \
3530 DWORD dwStyle = WS_POPUP | WS_BORDER | WS_SYSMENU; \
3531 DWORD dwExStyle = 0; \
3532 LPCTSTR szFontName = NULL; \
3533 WORD wFontSize = 0; \
3534 WORD wWeight = 0; \
3535 BYTE bItalic = 0; \
3536 BYTE bCharset = 0; \
3537 DWORD dwHelpID = helpID; \
3538 ATL::_U_STRINGorID Menu = 0U; \
3539 ATL::_U_STRINGorID ClassName = 0U;
3540
3541 #define END_DIALOG() \
3542 m_Template.Create(bExTemplate, szCaption, nX, nY, nWidth, nHeight, dwStyle, dwExStyle, szFontName, wFontSize, wWeight, bItalic, bCharset, dwHelpID, ClassName, Menu); \
3543 };
3544
3545 #define DIALOG_CAPTION(caption) \
3546 szCaption = caption;
3547 #define DIALOG_STYLE(style) \
3548 dwStyle = style;
3549 #define DIALOG_EXSTYLE(exStyle) \
3550 dwExStyle = exStyle;
3551 #define DIALOG_FONT(pointSize, typeFace) \
3552 wFontSize = pointSize; \
3553 szFontName = typeFace;
3554 #define DIALOG_FONT_EX(pointsize, typeface, weight, italic, charset) \
3555 ATLASSERT(bExTemplate); \
3556 wFontSize = pointsize; \
3557 szFontName = typeface; \
3558 wWeight = weight; \
3559 bItalic = italic; \
3560 bCharset = charset;
3561 #define DIALOG_MENU(menuName) \
3562 Menu = menuName;
3563 #define DIALOG_CLASS(className) \
3564 ClassName = className;
3565
3566 #define BEGIN_CONTROLS_MAP() \
3567 void DoInitControls() \
3568 {
3569
3570 #define END_CONTROLS_MAP() \
3571 };
3572
3573
3574 #define CONTROL_LTEXT(text, id, x, y, width, height, style, exStyle) \
3575 m_Template.AddStdControl(m_Template.CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_LEFT | WS_GROUP, exStyle, text, NULL, 0);
3576 #define CONTROL_CTEXT(text, id, x, y, width, height, style, exStyle) \
3577 m_Template.AddStdControl(m_Template.CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_CENTER | WS_GROUP, exStyle, text, NULL, 0);
3578 #define CONTROL_RTEXT(text, id, x, y, width, height, style, exStyle) \
3579 m_Template.AddStdControl(m_Template.CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_RIGHT | WS_GROUP, exStyle, text, NULL, 0);
3580 #define CONTROL_PUSHBUTTON(text, id, x, y, width, height, style, exStyle) \
3581 m_Template.AddStdControl(m_Template.CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_PUSHBUTTON | WS_TABSTOP, exStyle, text, NULL, 0);
3582 #define CONTROL_DEFPUSHBUTTON(text, id, x, y, width, height, style, exStyle) \
3583 m_Template.AddStdControl(m_Template.CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_DEFPUSHBUTTON | WS_TABSTOP, exStyle, text, NULL, 0);
3584 #ifndef _WIN32_WCE
3585 #define CONTROL_PUSHBOX(text, id, x, y, width, height, style, exStyle) \
3586 m_Template.AddStdControl(m_Template.CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_PUSHBOX | WS_TABSTOP, exStyle, text, NULL, 0);
3587 #endif // !_WIN32_WCE
3588 #define CONTROL_STATE3(text, id, x, y, width, height, style, exStyle) \
3589 m_Template.AddStdControl(m_Template.CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_3STATE | WS_TABSTOP, exStyle, text, NULL, 0);
3590 #define CONTROL_AUTO3STATE(text, id, x, y, width, height, style, exStyle) \
3591 m_Template.AddStdControl(m_Template.CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_AUTO3STATE | WS_TABSTOP, exStyle, text, NULL, 0);
3592 #define CONTROL_CHECKBOX(text, id, x, y, width, height, style, exStyle) \
3593 m_Template.AddStdControl(m_Template.CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_CHECKBOX | WS_TABSTOP, exStyle, text, NULL, 0);
3594 #define CONTROL_AUTOCHECKBOX(text, id, x, y, width, height, style, exStyle) \
3595 m_Template.AddStdControl(m_Template.CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_AUTOCHECKBOX | WS_TABSTOP, exStyle, text, NULL, 0);
3596 #define CONTROL_RADIOBUTTON(text, id, x, y, width, height, style, exStyle) \
3597 m_Template.AddStdControl(m_Template.CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_RADIOBUTTON | WS_TABSTOP, exStyle, text, NULL, 0);
3598 #define CONTROL_AUTORADIOBUTTON(text, id, x, y, width, height, style, exStyle) \
3599 m_Template.AddStdControl(m_Template.CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_AUTORADIOBUTTON | WS_TABSTOP, exStyle, text, NULL, 0);
3600 #define CONTROL_COMBOBOX(id, x, y, width, height, style, exStyle) \
3601 m_Template.AddStdControl(m_Template.CTRL_COMBOBOX, (WORD)id, x, y, width, height, style | CBS_DROPDOWN | WS_TABSTOP, exStyle, (LPCTSTR)NULL, NULL, 0);
3602 #define CONTROL_EDITTEXT(id, x, y, width, height, style, exStyle) \
3603 m_Template.AddStdControl(m_Template.CTRL_EDIT, (WORD)id, x, y, width, height, style | ES_LEFT | WS_BORDER | WS_TABSTOP, exStyle, (LPCTSTR)NULL, NULL, 0);
3604 #define CONTROL_GROUPBOX(text, id, x, y, width, height, style, exStyle) \
3605 m_Template.AddStdControl(m_Template.CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_GROUPBOX, exStyle, text, NULL, 0);
3606 #define CONTROL_LISTBOX(id, x, y, width, height, style, exStyle) \
3607 m_Template.AddStdControl(m_Template.CTRL_LISTBOX, (WORD)id, x, y, width, height, style | LBS_NOTIFY | WS_BORDER, exStyle, (LPCTSTR)NULL, NULL, 0);
3608 #define CONTROL_SCROLLBAR(id, x, y, width, height, style, exStyle) \
3609 m_Template.AddStdControl(m_Template.CTRL_SCROLLBAR, (WORD)id, x, y, width, height, style | SBS_HORZ, exStyle, (LPCTSTR)NULL, NULL, 0);
3610 #define CONTROL_ICON(text, id, x, y, width, height, style, exStyle) \
3611 m_Template.AddStdControl(m_Template.CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_ICON, exStyle, text, NULL, 0);
3612 #define CONTROL_CONTROL(text, id, className, style, x, y, width, height, exStyle) \
3613 m_Template.AddControl(className, (WORD)id, x, y, width, height, style, exStyle, text, NULL, 0);
3614
3615
3616 ///////////////////////////////////////////////////////////////////////////////
3617 // CIndirectDialogImpl - dialogs with template in memory
3618
3619 template <class T, class TDlgTemplate = CMemDlgTemplate, class TBase = ATL::CWindow>
3620 class ATL_NO_VTABLE CIndirectDialogImpl : public ATL::CDialogImpl< T, TBase >
3621 {
3622 public:
3623 enum { IDD = 0 }; // no dialog template resource
3624
3625 TDlgTemplate m_Template;
3626
3627 void CreateTemplate()
3628 {
3629 T* pT = static_cast<T*>(this);
3630 pT->DoInitTemplate();
3631 pT->DoInitControls();
3632 }
3633
3634 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow(), LPARAM dwInitParam = NULL)
3635 {
3636 T* pT = static_cast<T*>(this);
3637 ATLASSERT(pT->m_hWnd == NULL);
3638
3639 if(!m_Template.IsValid())
3640 CreateTemplate();
3641
3642 #if (_ATL_VER >= 0x0800)
3643 // Allocate the thunk structure here, where we can fail gracefully.
3644 BOOL bRet = m_thunk.Init(NULL, NULL);
3645 if(bRet == FALSE)
3646 {
3647 ::SetLastError(ERROR_OUTOFMEMORY);
3648 return -1;
3649 }
3650 #endif // (_ATL_VER >= 0x0800)
3651
3652 ModuleHelper::AddCreateWndData(&m_thunk.cd, (ATL::CDialogImplBaseT< TBase >*)pT);
3653
3654 #ifdef _DEBUG
3655 m_bModal = true;
3656 #endif // _DEBUG
3657
3658 return ::DialogBoxIndirectParam(ModuleHelper::GetResourceInstance(), m_Template.GetTemplatePtr(), hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam);
3659 }
3660
3661 HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL)
3662 {
3663 T* pT = static_cast<T*>(this);
3664 ATLASSERT(pT->m_hWnd == NULL);
3665
3666 if(!m_Template.IsValid())
3667 CreateTemplate();
3668
3669 #if (_ATL_VER >= 0x0800)
3670 // Allocate the thunk structure here, where we can fail gracefully.
3671 BOOL bRet = m_thunk.Init(NULL, NULL);
3672 if(bRet == FALSE)
3673 {
3674 ::SetLastError(ERROR_OUTOFMEMORY);
3675 return NULL;
3676 }
3677 #endif // (_ATL_VER >= 0x0800)
3678
3679 ModuleHelper::AddCreateWndData(&m_thunk.cd, (ATL::CDialogImplBaseT< TBase >*)pT);
3680
3681 #ifdef _DEBUG
3682 m_bModal = false;
3683 #endif // _DEBUG
3684
3685 HWND hWnd = ::CreateDialogIndirectParam(ModuleHelper::GetResourceInstance(), (LPCDLGTEMPLATE)m_Template.GetTemplatePtr(), hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam);
3686 ATLASSERT(m_hWnd == hWnd);
3687
3688 return hWnd;
3689 }
3690
3691 // for CComControl
3692 HWND Create(HWND hWndParent, RECT&, LPARAM dwInitParam = NULL)
3693 {
3694 return Create(hWndParent, dwInitParam);
3695 }
3696
3697 void DoInitTemplate()
3698 {
3699 ATLASSERT(FALSE); // MUST be defined in derived class
3700 }
3701
3702 void DoInitControls()
3703 {
3704 ATLASSERT(FALSE); // MUST be defined in derived class
3705 }
3706 };
3707
3708
3709 ///////////////////////////////////////////////////////////////////////////////
3710 // CPropertySheetWindow - client side for a property sheet
3711
3712 class CPropertySheetWindow : public ATL::CWindow
3713 {
3714 public:
3715 // Constructors
3716 CPropertySheetWindow(HWND hWnd = NULL) : ATL::CWindow(hWnd)
3717 { }
3718
3719 CPropertySheetWindow& operator =(HWND hWnd)
3720 {
3721 m_hWnd = hWnd;
3722 return *this;
3723 }
3724
3725 // Attributes
3726 int GetPageCount() const
3727 {
3728 ATLASSERT(::IsWindow(m_hWnd));
3729 HWND hWndTabCtrl = GetTabControl();
3730 ATLASSERT(hWndTabCtrl != NULL);
3731 return (int)::SendMessage(hWndTabCtrl, TCM_GETITEMCOUNT, 0, 0L);
3732 }
3733
3734 HWND GetActivePage() const
3735 {
3736 ATLASSERT(::IsWindow(m_hWnd));
3737 return (HWND)::SendMessage(m_hWnd, PSM_GETCURRENTPAGEHWND, 0, 0L);
3738 }
3739
3740 int GetActiveIndex() const
3741 {
3742 ATLASSERT(::IsWindow(m_hWnd));
3743 HWND hWndTabCtrl = GetTabControl();
3744 ATLASSERT(hWndTabCtrl != NULL);
3745 return (int)::SendMessage(hWndTabCtrl, TCM_GETCURSEL, 0, 0L);
3746 }
3747
3748 BOOL SetActivePage(int nPageIndex)
3749 {
3750 ATLASSERT(::IsWindow(m_hWnd));
3751 return (BOOL)::SendMessage(m_hWnd, PSM_SETCURSEL, nPageIndex, 0L);
3752 }
3753
3754 BOOL SetActivePage(HPROPSHEETPAGE hPage)
3755 {
3756 ATLASSERT(::IsWindow(m_hWnd));
3757 ATLASSERT(hPage != NULL);
3758 return (BOOL)::SendMessage(m_hWnd, PSM_SETCURSEL, 0, (LPARAM)hPage);
3759 }
3760
3761 BOOL SetActivePageByID(int nPageID)
3762 {
3763 ATLASSERT(::IsWindow(m_hWnd));
3764 return (BOOL)::SendMessage(m_hWnd, PSM_SETCURSELID, 0, nPageID);
3765 }
3766
3767 void SetTitle(LPCTSTR lpszText, UINT nStyle = 0)
3768 {
3769 ATLASSERT(::IsWindow(m_hWnd));
3770 ATLASSERT((nStyle & ~PSH_PROPTITLE) == 0); // only PSH_PROPTITLE is valid
3771 ATLASSERT(lpszText != NULL);
3772 ::SendMessage(m_hWnd, PSM_SETTITLE, nStyle, (LPARAM)lpszText);
3773 }
3774
3775 HWND GetTabControl() const
3776 {
3777 ATLASSERT(::IsWindow(m_hWnd));
3778 return (HWND)::SendMessage(m_hWnd, PSM_GETTABCONTROL, 0, 0L);
3779 }
3780
3781 void SetFinishText(LPCTSTR lpszText)
3782 {
3783 ATLASSERT(::IsWindow(m_hWnd));
3784 ::SendMessage(m_hWnd, PSM_SETFINISHTEXT, 0, (LPARAM)lpszText);
3785 }
3786
3787 void SetWizardButtons(DWORD dwFlags)
3788 {
3789 ATLASSERT(::IsWindow(m_hWnd));
3790 ::PostMessage(m_hWnd, PSM_SETWIZBUTTONS, 0, dwFlags);
3791 }
3792
3793 // Operations
3794 BOOL AddPage(HPROPSHEETPAGE hPage)
3795 {
3796 ATLASSERT(::IsWindow(m_hWnd));
3797 ATLASSERT(hPage != NULL);
3798 return (BOOL)::SendMessage(m_hWnd, PSM_ADDPAGE, 0, (LPARAM)hPage);
3799 }
3800
3801 BOOL AddPage(LPCPROPSHEETPAGE pPage)
3802 {
3803 ATLASSERT(::IsWindow(m_hWnd));
3804 ATLASSERT(pPage != NULL);
3805 HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage);
3806 if(hPage == NULL)
3807 return FALSE;
3808 return (BOOL)::SendMessage(m_hWnd, PSM_ADDPAGE, 0, (LPARAM)hPage);
3809 }
3810
3811 #ifndef _WIN32_WCE
3812 BOOL InsertPage(int nNewPageIndex, HPROPSHEETPAGE hPage)
3813 {
3814 ATLASSERT(::IsWindow(m_hWnd));
3815 ATLASSERT(hPage != NULL);
3816 return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, nNewPageIndex, (LPARAM)hPage);
3817 }
3818
3819 BOOL InsertPage(int nNewPageIndex, LPCPROPSHEETPAGE pPage)
3820 {
3821 ATLASSERT(::IsWindow(m_hWnd));
3822 ATLASSERT(pPage != NULL);
3823 HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage);
3824 if(hPage == NULL)
3825 return FALSE;
3826 return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, nNewPageIndex, (LPARAM)hPage);
3827 }
3828
3829 BOOL InsertPage(HPROPSHEETPAGE hPageInsertAfter, HPROPSHEETPAGE hPage)
3830 {
3831 ATLASSERT(::IsWindow(m_hWnd));
3832 ATLASSERT(hPage != NULL);
3833 return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, (WPARAM)hPageInsertAfter, (LPARAM)hPage);
3834 }
3835
3836 BOOL InsertPage(HPROPSHEETPAGE hPageInsertAfter, LPCPROPSHEETPAGE pPage)
3837 {
3838 ATLASSERT(::IsWindow(m_hWnd));
3839 ATLASSERT(pPage != NULL);
3840 HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage);
3841 if(hPage == NULL)
3842 return FALSE;
3843 return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, (WPARAM)hPageInsertAfter, (LPARAM)hPage);
3844 }
3845 #endif // !_WIN32_WCE
3846
3847 void RemovePage(int nPageIndex)
3848 {
3849 ATLASSERT(::IsWindow(m_hWnd));
3850 ::SendMessage(m_hWnd, PSM_REMOVEPAGE, nPageIndex, 0L);
3851 }
3852
3853 void RemovePage(HPROPSHEETPAGE hPage)
3854 {
3855 ATLASSERT(::IsWindow(m_hWnd));
3856 ATLASSERT(hPage != NULL);
3857 ::SendMessage(m_hWnd, PSM_REMOVEPAGE, 0, (LPARAM)hPage);
3858 }
3859
3860 BOOL PressButton(int nButton)
3861 {
3862 ATLASSERT(::IsWindow(m_hWnd));
3863 return (BOOL)::SendMessage(m_hWnd, PSM_PRESSBUTTON, nButton, 0L);
3864 }
3865
3866 BOOL Apply()
3867 {
3868 ATLASSERT(::IsWindow(m_hWnd));
3869 return (BOOL)::SendMessage(m_hWnd, PSM_APPLY, 0, 0L);
3870 }
3871
3872 void CancelToClose()
3873 {
3874 ATLASSERT(::IsWindow(m_hWnd));
3875 ::SendMessage(m_hWnd, PSM_CANCELTOCLOSE, 0, 0L);
3876 }
3877
3878 void SetModified(HWND hWndPage, BOOL bChanged = TRUE)
3879 {
3880 ATLASSERT(::IsWindow(m_hWnd));
3881 ATLASSERT(::IsWindow(hWndPage));
3882 UINT uMsg = bChanged ? PSM_CHANGED : PSM_UNCHANGED;
3883 ::SendMessage(m_hWnd, uMsg, (WPARAM)hWndPage, 0L);
3884 }
3885
3886 LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam)
3887 {
3888 ATLASSERT(::IsWindow(m_hWnd));
3889 return ::SendMessage(m_hWnd, PSM_QUERYSIBLINGS, wParam, lParam);
3890 }
3891
3892 void RebootSystem()
3893 {
3894 ATLASSERT(::IsWindow(m_hWnd));
3895 ::SendMessage(m_hWnd, PSM_REBOOTSYSTEM, 0, 0L);
3896 }
3897
3898 void RestartWindows()
3899 {
3900 ATLASSERT(::IsWindow(m_hWnd));
3901 ::SendMessage(m_hWnd, PSM_RESTARTWINDOWS, 0, 0L);
3902 }
3903
3904 BOOL IsDialogMessage(LPMSG lpMsg)
3905 {
3906 ATLASSERT(::IsWindow(m_hWnd));
3907 return (BOOL)::SendMessage(m_hWnd, PSM_ISDIALOGMESSAGE, 0, (LPARAM)lpMsg);
3908 }
3909
3910 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
3911 int HwndToIndex(HWND hWnd) const
3912 {
3913 ATLASSERT(::IsWindow(m_hWnd));
3914 return (int)::SendMessage(m_hWnd, PSM_HWNDTOINDEX, (WPARAM)hWnd, 0L);
3915 }
3916
3917 HWND IndexToHwnd(int nIndex) const
3918 {
3919 ATLASSERT(::IsWindow(m_hWnd));
3920 return (HWND)::SendMessage(m_hWnd, PSM_INDEXTOHWND, nIndex, 0L);
3921 }
3922
3923 int PageToIndex(HPROPSHEETPAGE hPage) const
3924 {
3925 ATLASSERT(::IsWindow(m_hWnd));
3926 return (int)::SendMessage(m_hWnd, PSM_PAGETOINDEX, 0, (LPARAM)hPage);
3927 }
3928
3929 HPROPSHEETPAGE IndexToPage(int nIndex) const
3930 {
3931 ATLASSERT(::IsWindow(m_hWnd));
3932 return (HPROPSHEETPAGE)::SendMessage(m_hWnd, PSM_INDEXTOPAGE, nIndex, 0L);
3933 }
3934
3935 int IdToIndex(int nID) const
3936 {
3937 ATLASSERT(::IsWindow(m_hWnd));
3938 return (int)::SendMessage(m_hWnd, PSM_IDTOINDEX, 0, nID);
3939 }
3940
3941 int IndexToId(int nIndex) const
3942 {
3943 ATLASSERT(::IsWindow(m_hWnd));
3944 return (int)::SendMessage(m_hWnd, PSM_INDEXTOID, nIndex, 0L);
3945 }
3946
3947 int GetResult() const
3948 {
3949 ATLASSERT(::IsWindow(m_hWnd));
3950 return (int)::SendMessage(m_hWnd, PSM_GETRESULT, 0, 0L);
3951 }
3952
3953 BOOL RecalcPageSizes()
3954 {
3955 ATLASSERT(::IsWindow(m_hWnd));
3956 return (BOOL)::SendMessage(m_hWnd, PSM_RECALCPAGESIZES, 0, 0L);
3957 }
3958
3959 void SetHeaderTitle(int nIndex, LPCTSTR lpstrHeaderTitle)
3960 {
3961 ATLASSERT(::IsWindow(m_hWnd));
3962 ::SendMessage(m_hWnd, PSM_SETHEADERTITLE, nIndex, (LPARAM)lpstrHeaderTitle);
3963 }
3964
3965 void SetHeaderSubTitle(int nIndex, LPCTSTR lpstrHeaderSubTitle)
3966 {
3967 ATLASSERT(::IsWindow(m_hWnd));
3968 ::SendMessage(m_hWnd, PSM_SETHEADERSUBTITLE, nIndex, (LPARAM)lpstrHeaderSubTitle);
3969 }
3970 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
3971
3972 // Implementation - override to prevent usage
3973 HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL)
3974 {
3975 ATLASSERT(FALSE);
3976 return NULL;
3977 }
3978 };
3979
3980 ///////////////////////////////////////////////////////////////////////////////
3981 // CPropertySheetImpl - implements a property sheet
3982
3983 template <class T, class TBase = CPropertySheetWindow>
3984 class ATL_NO_VTABLE CPropertySheetImpl : public ATL::CWindowImplBaseT< TBase >
3985 {
3986 public:
3987 PROPSHEETHEADER m_psh;
3988 ATL::CSimpleArray<HPROPSHEETPAGE> m_arrPages;
3989
3990 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific
3991 #ifndef PROPSHEET_LINK_SIZE
3992 #define PROPSHEET_LINK_SIZE 128
3993 #endif // PROPSHEET_LINK_SIZE
3994 TCHAR m_szLink[PROPSHEET_LINK_SIZE];
3995 static LPCTSTR m_pszTitle;
3996 static LPCTSTR m_pszLink;
3997 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
3998
3999 // Construction/Destruction
4000 CPropertySheetImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL)
4001 {
4002 memset(&m_psh, 0, sizeof(PROPSHEETHEADER));
4003 m_psh.dwSize = sizeof(PROPSHEETHEADER);
4004 m_psh.dwFlags = PSH_USECALLBACK;
4005 m_psh.hInstance = ModuleHelper::GetResourceInstance();
4006 m_psh.phpage = NULL; // will be set later
4007 m_psh.nPages = 0; // will be set later
4008 m_psh.pszCaption = title.m_lpstr;
4009 m_psh.nStartPage = uStartPage;
4010 m_psh.hwndParent = hWndParent; // if NULL, will be set in DoModal/Create
4011 m_psh.pfnCallback = T::PropSheetCallback;
4012
4013 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific
4014 m_psh.dwFlags |= PSH_MAXIMIZE;
4015 m_szLink[0] = 0;
4016 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
4017 }
4018
4019 ~CPropertySheetImpl()
4020 {
4021 if(m_arrPages.GetSize() > 0) // sheet never created, destroy all pages
4022 {
4023 for(int i = 0; i < m_arrPages.GetSize(); i++)
4024 ::DestroyPropertySheetPage((HPROPSHEETPAGE)m_arrPages[i]);
4025 }
4026 }
4027
4028 // Callback function and overrideables
4029 static int CALLBACK PropSheetCallback(HWND hWnd, UINT uMsg, LPARAM lParam)
4030 {
4031 lParam; // avoid level 4 warning
4032 int nRet = 0;
4033
4034 if(uMsg == PSCB_INITIALIZED)
4035 {
4036 ATLASSERT(hWnd != NULL);
4037 T* pT = (T*)ModuleHelper::ExtractCreateWndData();
4038 // subclass the sheet window
4039 pT->SubclassWindow(hWnd);
4040 // remove page handles array
4041 pT->_CleanUpPages();
4042
4043 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific
4044 m_pszTitle = pT->m_psh.pszCaption;
4045 if(*pT->m_szLink != 0)
4046 m_pszLink = pT->m_szLink;
4047 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific
4048
4049 pT->OnSheetInitialized();
4050 }
4051 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific uMsg
4052 else
4053 {
4054 switch(uMsg)
4055 {
4056 case PSCB_GETVERSION :
4057 nRet = COMCTL32_VERSION;
4058 break;
4059 case PSCB_GETTITLE :
4060 if(m_pszTitle != NULL)
4061 {
4062 lstrcpy((LPTSTR)lParam, m_pszTitle);
4063 m_pszTitle = NULL;
4064 }
4065 break;
4066 case PSCB_GETLINKTEXT:
4067 if(m_pszLink != NULL)
4068 {
4069 lstrcpy((LPTSTR)lParam, m_pszLink);
4070 m_pszLink = NULL;
4071 }
4072 break;
4073 default:
4074 break;
4075 }
4076 }
4077 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
4078
4079 return nRet;
4080 }
4081
4082 void OnSheetInitialized()
4083 {
4084 }
4085
4086 // Create method
4087 HWND Create(HWND hWndParent = NULL)
4088 {
4089 ATLASSERT(m_hWnd == NULL);
4090
4091 m_psh.dwFlags |= PSH_MODELESS;
4092 if(m_psh.hwndParent == NULL)
4093 m_psh.hwndParent = hWndParent;
4094 m_psh.phpage = (HPROPSHEETPAGE*)m_arrPages.GetData();
4095 m_psh.nPages = m_arrPages.GetSize();
4096
4097 T* pT = static_cast<T*>(this);
4098
4099 #if (_ATL_VER >= 0x0800)
4100 // Allocate the thunk structure here, where we can fail gracefully.
4101 BOOL bRet = pT->m_thunk.Init(NULL, NULL);
4102 if(bRet == FALSE)
4103 {
4104 ::SetLastError(ERROR_OUTOFMEMORY);
4105 return NULL;
4106 }
4107 #endif // (_ATL_VER >= 0x0800)
4108
4109 ModuleHelper::AddCreateWndData(&pT->m_thunk.cd, pT);
4110
4111 HWND hWnd = (HWND)::PropertySheet(&m_psh);
4112 _CleanUpPages(); // ensure clean-up, required if call failed
4113
4114 ATLASSERT(m_hWnd == hWnd);
4115
4116 return hWnd;
4117 }
4118
4119 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
4120 {
4121 ATLASSERT(m_hWnd == NULL);
4122
4123 m_psh.dwFlags &= ~PSH_MODELESS;
4124 if(m_psh.hwndParent == NULL)
4125 m_psh.hwndParent = hWndParent;
4126 m_psh.phpage = (HPROPSHEETPAGE*)m_arrPages.GetData();
4127 m_psh.nPages = m_arrPages.GetSize();
4128
4129 T* pT = static_cast<T*>(this);
4130
4131 #if (_ATL_VER >= 0x0800)
4132 // Allocate the thunk structure here, where we can fail gracefully.
4133 BOOL bRet = pT->m_thunk.Init(NULL, NULL);
4134 if(bRet == FALSE)
4135 {
4136 ::SetLastError(ERROR_OUTOFMEMORY);
4137 return -1;
4138 }
4139 #endif // (_ATL_VER >= 0x0800)
4140
4141 ModuleHelper::AddCreateWndData(&pT->m_thunk.cd, pT);
4142
4143 INT_PTR nRet = ::PropertySheet(&m_psh);
4144 _CleanUpPages(); // ensure clean-up, required if call failed
4145
4146 return nRet;
4147 }
4148
4149 // implementation helper - clean up pages array
4150 void _CleanUpPages()
4151 {
4152 m_psh.nPages = 0;
4153 m_psh.phpage = NULL;
4154 m_arrPages.RemoveAll();
4155 }
4156
4157 // Attributes (extended overrides of client class methods)
4158 // These now can be called before the sheet is created
4159 // Note: Calling these after the sheet is created gives unpredictable results
4160 int GetPageCount() const
4161 {
4162 if(m_hWnd == NULL) // not created yet
4163 return m_arrPages.GetSize();
4164 return TBase::GetPageCount();
4165 }
4166
4167 int GetActiveIndex() const
4168 {
4169 if(m_hWnd == NULL) // not created yet
4170 return m_psh.nStartPage;
4171 return TBase::GetActiveIndex();
4172 }
4173
4174 HPROPSHEETPAGE GetPage(int nPageIndex) const
4175 {
4176 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
4177 return (HPROPSHEETPAGE)m_arrPages[nPageIndex];
4178 }
4179
4180 int GetPageIndex(HPROPSHEETPAGE hPage) const
4181 {
4182 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
4183 return m_arrPages.Find((HPROPSHEETPAGE&)hPage);
4184 }
4185
4186 BOOL SetActivePage(int nPageIndex)
4187 {
4188 if(m_hWnd == NULL) // not created yet
4189 {
4190 ATLASSERT(nPageIndex >= 0 && nPageIndex < m_arrPages.GetSize());
4191 m_psh.nStartPage = nPageIndex;
4192 return TRUE;
4193 }
4194 return TBase::SetActivePage(nPageIndex);
4195 }
4196
4197 BOOL SetActivePage(HPROPSHEETPAGE hPage)
4198 {
4199 ATLASSERT(hPage != NULL);
4200 if (m_hWnd == NULL) // not created yet
4201 {
4202 int nPageIndex = GetPageIndex(hPage);
4203 if(nPageIndex == -1)
4204 return FALSE;
4205
4206 return SetActivePage(nPageIndex);
4207 }
4208 return TBase::SetActivePage(hPage);
4209
4210 }
4211
4212 void SetTitle(LPCTSTR lpszText, UINT nStyle = 0)
4213 {
4214 ATLASSERT((nStyle & ~PSH_PROPTITLE) == 0); // only PSH_PROPTITLE is valid
4215 ATLASSERT(lpszText != NULL);
4216
4217 if(m_hWnd == NULL)
4218 {
4219 // set internal state
4220 m_psh.pszCaption = lpszText; // must exist until sheet is created
4221 m_psh.dwFlags &= ~PSH_PROPTITLE;
4222 m_psh.dwFlags |= nStyle;
4223 }
4224 else
4225 {
4226 // set external state
4227 TBase::SetTitle(lpszText, nStyle);
4228 }
4229 }
4230
4231 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific Link field
4232 void SetLinkText(LPCTSTR lpszText)
4233 {
4234 ATLASSERT(lpszText != NULL);
4235 ATLASSERT(lstrlen(lpszText) < PROPSHEET_LINK_SIZE);
4236 lstrcpy(m_szLink, lpszText);
4237 }
4238 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
4239
4240 void SetWizardMode()
4241 {
4242 m_psh.dwFlags |= PSH_WIZARD;
4243 }
4244
4245 void EnableHelp()
4246 {
4247 m_psh.dwFlags |= PSH_HASHELP;
4248 }
4249
4250 // Operations
4251 BOOL AddPage(HPROPSHEETPAGE hPage)
4252 {
4253 ATLASSERT(hPage != NULL);
4254 BOOL bRet = FALSE;
4255 if(m_hWnd != NULL)
4256 bRet = TBase::AddPage(hPage);
4257 else // sheet not created yet, use internal data
4258 bRet = m_arrPages.Add((HPROPSHEETPAGE&)hPage);
4259 return bRet;
4260 }
4261
4262 BOOL AddPage(LPCPROPSHEETPAGE pPage)
4263 {
4264 ATLASSERT(pPage != NULL);
4265 HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage);
4266 if(hPage == NULL)
4267 return FALSE;
4268 BOOL bRet = AddPage(hPage);
4269 if(!bRet)
4270 ::DestroyPropertySheetPage(hPage);
4271 return bRet;
4272 }
4273
4274 BOOL RemovePage(HPROPSHEETPAGE hPage)
4275 {
4276 ATLASSERT(hPage != NULL);
4277 if (m_hWnd == NULL) // not created yet
4278 {
4279 int nPage = GetPageIndex(hPage);
4280 if(nPage == -1)
4281 return FALSE;
4282 return RemovePage(nPage);
4283 }
4284 TBase::RemovePage(hPage);
4285 return TRUE;
4286
4287 }
4288
4289 BOOL RemovePage(int nPageIndex)
4290 {
4291 BOOL bRet = TRUE;
4292 if(m_hWnd != NULL)
4293 TBase::RemovePage(nPageIndex);
4294 else // sheet not created yet, use internal data
4295 bRet = m_arrPages.RemoveAt(nPageIndex);
4296 return bRet;
4297 }
4298
4299 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
4300 void SetHeader(LPCTSTR szbmHeader)
4301 {
4302 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
4303
4304 m_psh.dwFlags &= ~PSH_WIZARD;
4305 m_psh.dwFlags |= (PSH_HEADER | PSH_WIZARD97);
4306 m_psh.pszbmHeader = szbmHeader;
4307 }
4308
4309 void SetHeader(HBITMAP hbmHeader)
4310 {
4311 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
4312
4313 m_psh.dwFlags &= ~PSH_WIZARD;
4314 m_psh.dwFlags |= (PSH_HEADER | PSH_USEHBMHEADER | PSH_WIZARD97);
4315 m_psh.hbmHeader = hbmHeader;
4316 }
4317
4318 void SetWatermark(LPCTSTR szbmWatermark, HPALETTE hplWatermark = NULL)
4319 {
4320 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
4321
4322 m_psh.dwFlags &= ~PSH_WIZARD;
4323 m_psh.dwFlags |= PSH_WATERMARK | PSH_WIZARD97;
4324 m_psh.pszbmWatermark = szbmWatermark;
4325
4326 if (hplWatermark != NULL)
4327 {
4328 m_psh.dwFlags |= PSH_USEHPLWATERMARK;
4329 m_psh.hplWatermark = hplWatermark;
4330 }
4331 }
4332
4333 void SetWatermark(HBITMAP hbmWatermark, HPALETTE hplWatermark = NULL)
4334 {
4335 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
4336
4337 m_psh.dwFlags &= ~PSH_WIZARD;
4338 m_psh.dwFlags |= (PSH_WATERMARK | PSH_USEHBMWATERMARK | PSH_WIZARD97);
4339 m_psh.hbmWatermark = hbmWatermark;
4340
4341 if (hplWatermark != NULL)
4342 {
4343 m_psh.dwFlags |= PSH_USEHPLWATERMARK;
4344 m_psh.hplWatermark = hplWatermark;
4345 }
4346 }
4347
4348 void StretchWatermark(bool bStretchWatermark)
4349 {
4350 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
4351 if (bStretchWatermark)
4352 m_psh.dwFlags |= PSH_STRETCHWATERMARK;
4353 else
4354 m_psh.dwFlags &= ~PSH_STRETCHWATERMARK;
4355 }
4356 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
4357
4358 // Message map and handlers
4359 BEGIN_MSG_MAP(CPropertySheetImpl)
4360 MESSAGE_HANDLER(WM_COMMAND, OnCommand)
4361 MESSAGE_HANDLER(WM_SYSCOMMAND, OnSysCommand)
4362 END_MSG_MAP()
4363
4364 LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
4365 {
4366 LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
4367 if(HIWORD(wParam) == BN_CLICKED && (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) &&
4368 ((m_psh.dwFlags & PSH_MODELESS) != 0) && (GetActivePage() == NULL))
4369 DestroyWindow();
4370 return lRet;
4371 }
4372
4373 LRESULT OnSysCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
4374 {
4375 if(((m_psh.dwFlags & PSH_MODELESS) == PSH_MODELESS) && ((wParam & 0xFFF0) == SC_CLOSE))
4376 SendMessage(WM_CLOSE);
4377 else
4378 bHandled = FALSE;
4379 return 0;
4380 }
4381 };
4382
4383 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC static pointers
4384 template < class T, class TBase >
4385 LPCWSTR CPropertySheetImpl<T,TBase>::m_pszTitle = NULL;
4386 template < class T, class TBase>
4387 LPCWSTR CPropertySheetImpl<T,TBase>::m_pszLink = NULL;
4388 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
4389
4390 // for non-customized sheets
4391 class CPropertySheet : public CPropertySheetImpl<CPropertySheet>
4392 {
4393 public:
4394 CPropertySheet(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL)
4395 : CPropertySheetImpl<CPropertySheet>(title, uStartPage, hWndParent)
4396 { }
4397 };
4398
4399
4400 ///////////////////////////////////////////////////////////////////////////////
4401 // CPropertyPageWindow - client side for a property page
4402
4403 class CPropertyPageWindow : public ATL::CWindow
4404 {
4405 public:
4406 // Constructors
4407 CPropertyPageWindow(HWND hWnd = NULL) : ATL::CWindow(hWnd)
4408 { }
4409
4410 CPropertyPageWindow& operator =(HWND hWnd)
4411 {
4412 m_hWnd = hWnd;
4413 return *this;
4414 }
4415
4416 // Attributes
4417 CPropertySheetWindow GetPropertySheet() const
4418 {
4419 ATLASSERT(::IsWindow(m_hWnd));
4420 return CPropertySheetWindow(GetParent());
4421 }
4422
4423 // Operations
4424 BOOL Apply()
4425 {
4426 ATLASSERT(::IsWindow(m_hWnd));
4427 ATLASSERT(GetParent() != NULL);
4428 return GetPropertySheet().Apply();
4429 }
4430
4431 void CancelToClose()
4432 {
4433 ATLASSERT(::IsWindow(m_hWnd));
4434 ATLASSERT(GetParent() != NULL);
4435 GetPropertySheet().CancelToClose();
4436 }
4437
4438 void SetModified(BOOL bChanged = TRUE)
4439 {
4440 ATLASSERT(::IsWindow(m_hWnd));
4441 ATLASSERT(GetParent() != NULL);
4442 GetPropertySheet().SetModified(m_hWnd, bChanged);
4443 }
4444
4445 LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam)
4446 {
4447 ATLASSERT(::IsWindow(m_hWnd));
4448 ATLASSERT(GetParent() != NULL);
4449 return GetPropertySheet().QuerySiblings(wParam, lParam);
4450 }
4451
4452 void RebootSystem()
4453 {
4454 ATLASSERT(::IsWindow(m_hWnd));
4455 ATLASSERT(GetParent() != NULL);
4456 GetPropertySheet().RebootSystem();
4457 }
4458
4459 void RestartWindows()
4460 {
4461 ATLASSERT(::IsWindow(m_hWnd));
4462 ATLASSERT(GetParent() != NULL);
4463 GetPropertySheet().RestartWindows();
4464 }
4465
4466 void SetWizardButtons(DWORD dwFlags)
4467 {
4468 ATLASSERT(::IsWindow(m_hWnd));
4469 ATLASSERT(GetParent() != NULL);
4470 GetPropertySheet().SetWizardButtons(dwFlags);
4471 }
4472
4473 // Implementation - overrides to prevent usage
4474 HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL)
4475 {
4476 ATLASSERT(FALSE);
4477 return NULL;
4478 }
4479 };
4480
4481 ///////////////////////////////////////////////////////////////////////////////
4482 // CPropertyPageImpl - implements a property page
4483
4484 template <class T, class TBase = CPropertyPageWindow>
4485 class ATL_NO_VTABLE CPropertyPageImpl : public ATL::CDialogImplBaseT< TBase >
4486 {
4487 public:
4488 PROPSHEETPAGE m_psp;
4489
4490 operator PROPSHEETPAGE*() { return &m_psp; }
4491
4492 // Construction
4493 CPropertyPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL)
4494 {
4495 // initialize PROPSHEETPAGE struct
4496 memset(&m_psp, 0, sizeof(PROPSHEETPAGE));
4497 m_psp.dwSize = sizeof(PROPSHEETPAGE);
4498 m_psp.dwFlags = PSP_USECALLBACK;
4499 m_psp.hInstance = ModuleHelper::GetResourceInstance();
4500 T* pT = static_cast<T*>(this);
4501 m_psp.pszTemplate = MAKEINTRESOURCE(pT->IDD);
4502 m_psp.pfnDlgProc = (DLGPROC)T::StartDialogProc;
4503 m_psp.pfnCallback = T::PropPageCallback;
4504 m_psp.lParam = (LPARAM)pT;
4505
4506 if(title.m_lpstr != NULL)
4507 SetTitle(title);
4508 }
4509
4510 // Callback function and overrideables
4511 static UINT CALLBACK PropPageCallback(HWND hWnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
4512 {
4513 hWnd; // avoid level 4 warning
4514 ATLASSERT(hWnd == NULL);
4515 T* pT = (T*)ppsp->lParam;
4516 UINT uRet = 0;
4517
4518 switch(uMsg)
4519 {
4520 case PSPCB_CREATE:
4521 {
4522 ATL::CDialogImplBaseT< TBase >* pPage = (ATL::CDialogImplBaseT< TBase >*)pT;
4523 ModuleHelper::AddCreateWndData(&pPage->m_thunk.cd, pPage);
4524 uRet = pT->OnPageCreate() ? 1 : 0;
4525 }
4526 break;
4527 #if (_WIN32_IE >= 0x0500)
4528 case PSPCB_ADDREF:
4529 pT->OnPageAddRef();
4530 break;
4531 #endif // (_WIN32_IE >= 0x0500)
4532 case PSPCB_RELEASE:
4533 pT->OnPageRelease();
4534 break;
4535 default:
4536 break;
4537 }
4538
4539 return uRet;
4540 }
4541
4542 bool OnPageCreate()
4543 {
4544 return true; // true - allow page to be created, false - prevent creation
4545 }
4546
4547 #if (_WIN32_IE >= 0x0500)
4548 void OnPageAddRef()
4549 {
4550 }
4551 #endif // (_WIN32_IE >= 0x0500)
4552
4553 void OnPageRelease()
4554 {
4555 }
4556
4557 // Create method
4558 HPROPSHEETPAGE Create()
4559 {
4560 return ::CreatePropertySheetPage(&m_psp);
4561 }
4562
4563 // Attributes
4564 void SetTitle(ATL::_U_STRINGorID title)
4565 {
4566 m_psp.pszTitle = title.m_lpstr;
4567 m_psp.dwFlags |= PSP_USETITLE;
4568 }
4569
4570 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
4571 void SetHeaderTitle(LPCTSTR lpstrHeaderTitle)
4572 {
4573 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
4574 m_psp.dwFlags |= PSP_USEHEADERTITLE;
4575 m_psp.pszHeaderTitle = lpstrHeaderTitle;
4576 }
4577
4578 void SetHeaderSubTitle(LPCTSTR lpstrHeaderSubTitle)
4579 {
4580 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
4581 m_psp.dwFlags |= PSP_USEHEADERSUBTITLE;
4582 m_psp.pszHeaderSubTitle = lpstrHeaderSubTitle;
4583 }
4584 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
4585
4586 // Operations
4587 void EnableHelp()
4588 {
4589 m_psp.dwFlags |= PSP_HASHELP;
4590 }
4591
4592 // Message map and handlers
4593 BEGIN_MSG_MAP(CPropertyPageImpl)
4594 MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
4595 END_MSG_MAP()
4596
4597 // NOTE: Define _WTL_NEW_PAGE_NOTIFY_HANDLERS to use new notification
4598 // handlers that return direct values without any restrictions
4599 LRESULT OnNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
4600 {
4601 #ifndef _WIN32_WCE
4602 // This notification is sometimes received on Windows CE after the window is already destroyed
4603 ATLASSERT(::IsWindow(m_hWnd));
4604 #endif
4605 NMHDR* pNMHDR = (NMHDR*)lParam;
4606
4607 // don't handle messages not from the page/sheet itself
4608 if(pNMHDR->hwndFrom != m_hWnd && pNMHDR->hwndFrom != ::GetParent(m_hWnd))
4609 {
4610 bHandled = FALSE;
4611 return 1;
4612 }
4613 #ifdef _WIN32_WCE
4614 ATLASSERT(::IsWindow(m_hWnd));
4615 #endif
4616
4617 T* pT = static_cast<T*>(this);
4618 LRESULT lResult = 0;
4619 switch(pNMHDR->code)
4620 {
4621 #ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS
4622 case PSN_SETACTIVE:
4623 lResult = pT->OnSetActive();
4624 break;
4625 case PSN_KILLACTIVE:
4626 lResult = pT->OnKillActive();
4627 break;
4628 case PSN_APPLY:
4629 lResult = pT->OnApply();
4630 break;
4631 case PSN_RESET:
4632 pT->OnReset();
4633 break;
4634 case PSN_QUERYCANCEL:
4635 lResult = pT->OnQueryCancel();
4636 break;
4637 case PSN_WIZNEXT:
4638 lResult = pT->OnWizardNext();
4639 break;
4640 case PSN_WIZBACK:
4641 lResult = pT->OnWizardBack();
4642 break;
4643 case PSN_WIZFINISH:
4644 lResult = pT->OnWizardFinish();
4645 break;
4646 case PSN_HELP:
4647 pT->OnHelp();
4648 break;
4649 #ifndef _WIN32_WCE
4650 #if (_WIN32_IE >= 0x0400)
4651 case PSN_GETOBJECT:
4652 if(!pT->OnGetObject((LPNMOBJECTNOTIFY)lParam))
4653 bHandled = FALSE;
4654 break;
4655 #endif // (_WIN32_IE >= 0x0400)
4656 #if (_WIN32_IE >= 0x0500)
4657 case PSN_TRANSLATEACCELERATOR:
4658 {
4659 LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam;
4660 lResult = pT->OnTranslateAccelerator((LPMSG)lpPSHNotify->lParam);
4661 }
4662 break;
4663 case PSN_QUERYINITIALFOCUS:
4664 {
4665 LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam;
4666 lResult = (LRESULT)pT->OnQueryInitialFocus((HWND)lpPSHNotify->lParam);
4667 }
4668 break;
4669 #endif // (_WIN32_IE >= 0x0500)
4670 #endif // !_WIN32_WCE
4671
4672 #else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
4673 case PSN_SETACTIVE:
4674 lResult = pT->OnSetActive() ? 0 : -1;
4675 break;
4676 case PSN_KILLACTIVE:
4677 lResult = !pT->OnKillActive();
4678 break;
4679 case PSN_APPLY:
4680 lResult = pT->OnApply() ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE;
4681 break;
4682 case PSN_RESET:
4683 pT->OnReset();
4684 break;
4685 case PSN_QUERYCANCEL:
4686 lResult = !pT->OnQueryCancel();
4687 break;
4688 case PSN_WIZNEXT:
4689 lResult = pT->OnWizardNext();
4690 break;
4691 case PSN_WIZBACK:
4692 lResult = pT->OnWizardBack();
4693 break;
4694 case PSN_WIZFINISH:
4695 lResult = !pT->OnWizardFinish();
4696 break;
4697 case PSN_HELP:
4698 pT->OnHelp();
4699 break;
4700 #ifndef _WIN32_WCE
4701 #if (_WIN32_IE >= 0x0400)
4702 case PSN_GETOBJECT:
4703 if(!pT->OnGetObject((LPNMOBJECTNOTIFY)lParam))
4704 bHandled = FALSE;
4705 break;
4706 #endif // (_WIN32_IE >= 0x0400)
4707 #if (_WIN32_IE >= 0x0500)
4708 case PSN_TRANSLATEACCELERATOR:
4709 {
4710 LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam;
4711 lResult = pT->OnTranslateAccelerator((LPMSG)lpPSHNotify->lParam) ? PSNRET_MESSAGEHANDLED : PSNRET_NOERROR;
4712 }
4713 break;
4714 case PSN_QUERYINITIALFOCUS:
4715 {
4716 LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam;
4717 lResult = (LRESULT)pT->OnQueryInitialFocus((HWND)lpPSHNotify->lParam);
4718 }
4719 break;
4720 #endif // (_WIN32_IE >= 0x0500)
4721 #endif // !_WIN32_WCE
4722
4723 #endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
4724 default:
4725 bHandled = FALSE; // not handled
4726 }
4727
4728 return lResult;
4729 }
4730
4731 // Overridables
4732 // NOTE: Define _WTL_NEW_PAGE_NOTIFY_HANDLERS to use new notification
4733 // handlers that return direct values without any restrictions
4734 #ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS
4735 int OnSetActive()
4736 {
4737 // 0 = allow activate
4738 // -1 = go back that was active
4739 // page ID = jump to page
4740 return 0;
4741 }
4742
4743 BOOL OnKillActive()
4744 {
4745 // FALSE = allow deactivate
4746 // TRUE = prevent deactivation
4747 return FALSE;
4748 }
4749
4750 int OnApply()
4751 {
4752 // PSNRET_NOERROR = apply OK
4753 // PSNRET_INVALID = apply not OK, return to this page
4754 // PSNRET_INVALID_NOCHANGEPAGE = apply not OK, don't change focus
4755 return PSNRET_NOERROR;
4756 }
4757
4758 void OnReset()
4759 {
4760 }
4761
4762 BOOL OnQueryCancel()
4763 {
4764 // FALSE = allow cancel
4765 // TRUE = prevent cancel
4766 return FALSE;
4767 }
4768
4769 int OnWizardBack()
4770 {
4771 // 0 = goto previous page
4772 // -1 = prevent page change
4773 // >0 = jump to page by dlg ID
4774 return 0;
4775 }
4776
4777 int OnWizardNext()
4778 {
4779 // 0 = goto next page
4780 // -1 = prevent page change
4781 // >0 = jump to page by dlg ID
4782 return 0;
4783 }
4784
4785 INT_PTR OnWizardFinish()
4786 {
4787 // FALSE = allow finish
4788 // TRUE = prevent finish
4789 // HWND = prevent finish and set focus to HWND (CommCtrl 5.80 only)
4790 return FALSE;
4791 }
4792
4793 void OnHelp()
4794 {
4795 }
4796
4797 #ifndef _WIN32_WCE
4798 #if (_WIN32_IE >= 0x0400)
4799 BOOL OnGetObject(LPNMOBJECTNOTIFY /*lpObjectNotify*/)
4800 {
4801 return FALSE; // not processed
4802 }
4803 #endif // (_WIN32_IE >= 0x0400)
4804
4805 #if (_WIN32_IE >= 0x0500)
4806 int OnTranslateAccelerator(LPMSG /*lpMsg*/)
4807 {
4808 // PSNRET_NOERROR - message not handled
4809 // PSNRET_MESSAGEHANDLED - message handled
4810 return PSNRET_NOERROR;
4811 }
4812
4813 HWND OnQueryInitialFocus(HWND /*hWndFocus*/)
4814 {
4815 // NULL = set focus to default control
4816 // HWND = set focus to HWND
4817 return NULL;
4818 }
4819 #endif // (_WIN32_IE >= 0x0500)
4820 #endif // !_WIN32_WCE
4821
4822 #else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
4823 BOOL OnSetActive()
4824 {
4825 return TRUE;
4826 }
4827
4828 BOOL OnKillActive()
4829 {
4830 return TRUE;
4831 }
4832
4833 BOOL OnApply()
4834 {
4835 return TRUE;
4836 }
4837
4838 void OnReset()
4839 {
4840 }
4841
4842 BOOL OnQueryCancel()
4843 {
4844 return TRUE; // ok to cancel
4845 }
4846
4847 int OnWizardBack()
4848 {
4849 // 0 = goto previous page
4850 // -1 = prevent page change
4851 // >0 = jump to page by dlg ID
4852 return 0;
4853 }
4854
4855 int OnWizardNext()
4856 {
4857 // 0 = goto next page
4858 // -1 = prevent page change
4859 // >0 = jump to page by dlg ID
4860 return 0;
4861 }
4862
4863 BOOL OnWizardFinish()
4864 {
4865 return TRUE;
4866 }
4867
4868 void OnHelp()
4869 {
4870 }
4871
4872 #ifndef _WIN32_WCE
4873 #if (_WIN32_IE >= 0x0400)
4874 BOOL OnGetObject(LPNMOBJECTNOTIFY /*lpObjectNotify*/)
4875 {
4876 return FALSE; // not processed
4877 }
4878 #endif // (_WIN32_IE >= 0x0400)
4879
4880 #if (_WIN32_IE >= 0x0500)
4881 BOOL OnTranslateAccelerator(LPMSG /*lpMsg*/)
4882 {
4883 return FALSE; // not translated
4884 }
4885
4886 HWND OnQueryInitialFocus(HWND /*hWndFocus*/)
4887 {
4888 return NULL; // default
4889 }
4890 #endif // (_WIN32_IE >= 0x0500)
4891 #endif // !_WIN32_WCE
4892
4893 #endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
4894 };
4895
4896 // for non-customized pages
4897 template <WORD t_wDlgTemplateID>
4898 class CPropertyPage : public CPropertyPageImpl<CPropertyPage<t_wDlgTemplateID> >
4899 {
4900 public:
4901 enum { IDD = t_wDlgTemplateID };
4902
4903 CPropertyPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CPropertyPageImpl<CPropertyPage>(title)
4904 { }
4905
4906 DECLARE_EMPTY_MSG_MAP()
4907 };
4908
4909 ///////////////////////////////////////////////////////////////////////////////
4910 // CAxPropertyPageImpl - property page that hosts ActiveX controls
4911
4912 #ifndef _ATL_NO_HOSTING
4913
4914 // Note: You must #include <atlhost.h> to use these classes
4915
4916 template <class T, class TBase = CPropertyPageWindow>
4917 class ATL_NO_VTABLE CAxPropertyPageImpl : public CPropertyPageImpl< T, TBase >
4918 {
4919 public:
4920 // Data members
4921 HGLOBAL m_hInitData;
4922 HGLOBAL m_hDlgRes;
4923 HGLOBAL m_hDlgResSplit;
4924
4925 // Constructor/destructor
4926 CAxPropertyPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) :
4927 CPropertyPageImpl< T, TBase >(title),
4928 m_hInitData(NULL), m_hDlgRes(NULL), m_hDlgResSplit(NULL)
4929 {
4930 T* pT = static_cast<T*>(this);
4931 pT; // avoid level 4 warning
4932
4933 // initialize ActiveX hosting and modify dialog template
4934 ATL::AtlAxWinInit();
4935
4936 HINSTANCE hInstance = ModuleHelper::GetResourceInstance();
4937 LPCTSTR lpTemplateName = MAKEINTRESOURCE(pT->IDD);
4938 HRSRC hDlg = ::FindResource(hInstance, lpTemplateName, (LPTSTR)RT_DIALOG);
4939 if(hDlg != NULL)
4940 {
4941 HRSRC hDlgInit = ::FindResource(hInstance, lpTemplateName, (LPTSTR)_ATL_RT_DLGINIT);
4942
4943 BYTE* pInitData = NULL;
4944 if(hDlgInit != NULL)
4945 {
4946 m_hInitData = ::LoadResource(hInstance, hDlgInit);
4947 pInitData = (BYTE*)::LockResource(m_hInitData);
4948 }
4949
4950 m_hDlgRes = ::LoadResource(hInstance, hDlg);
4951 DLGTEMPLATE* pDlg = (DLGTEMPLATE*)::LockResource(m_hDlgRes);
4952 LPCDLGTEMPLATE lpDialogTemplate = ATL::_DialogSplitHelper::SplitDialogTemplate(pDlg, pInitData);
4953 if(lpDialogTemplate != pDlg)
4954 m_hDlgResSplit = GlobalHandle(lpDialogTemplate);
4955
4956 // set up property page to use in-memory dialog template
4957 if(lpDialogTemplate != NULL)
4958 {
4959 m_psp.dwFlags |= PSP_DLGINDIRECT;
4960 m_psp.pResource = lpDialogTemplate;
4961 }
4962 else
4963 {
4964 ATLASSERT(FALSE && _T("CAxPropertyPageImpl - ActiveX initializtion failed!"));
4965 }
4966 }
4967 else
4968 {
4969 ATLASSERT(FALSE && _T("CAxPropertyPageImpl - Cannot find dialog template!"));
4970 }
4971 }
4972
4973 ~CAxPropertyPageImpl()
4974 {
4975 if(m_hInitData != NULL)
4976 {
4977 UnlockResource(m_hInitData);
4978 FreeResource(m_hInitData);
4979 }
4980 if(m_hDlgRes != NULL)
4981 {
4982 UnlockResource(m_hDlgRes);
4983 FreeResource(m_hDlgRes);
4984 }
4985 if(m_hDlgResSplit != NULL)
4986 {
4987 ::GlobalFree(m_hDlgResSplit);
4988 }
4989 }
4990
4991 // Methods
4992 // call this one to handle keyboard message for ActiveX controls
4993 BOOL PreTranslateMessage(LPMSG pMsg)
4994 {
4995 if ((pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST) &&
4996 (pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAST))
4997 return FALSE;
4998 // find a direct child of the dialog from the window that has focus
4999 HWND hWndCtl = ::GetFocus();
5000 if (IsChild(hWndCtl) && ::GetParent(hWndCtl) != m_hWnd)
5001 {
5002 do
5003 {
5004 hWndCtl = ::GetParent(hWndCtl);
5005 }
5006 while (::GetParent(hWndCtl) != m_hWnd);
5007 }
5008 // give controls a chance to translate this message
5009 return (BOOL)::SendMessage(hWndCtl, WM_FORWARDMSG, 0, (LPARAM)pMsg);
5010 }
5011
5012 // Overridables
5013 #if (_WIN32_IE >= 0x0500)
5014 // new default implementation for ActiveX hosting pages
5015 #ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS
5016 int OnTranslateAccelerator(LPMSG lpMsg)
5017 {
5018 T* pT = static_cast<T*>(this);
5019 return (pT->PreTranslateMessage(lpMsg) != FALSE) ? PSNRET_MESSAGEHANDLED : PSNRET_NOERROR;
5020 }
5021 #else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
5022 BOOL OnTranslateAccelerator(LPMSG lpMsg)
5023 {
5024 T* pT = static_cast<T*>(this);
5025 return pT->PreTranslateMessage(lpMsg);
5026 }
5027 #endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
5028 #endif // (_WIN32_IE >= 0x0500)
5029
5030 // Support for new stuff in ATL7
5031 #if (_ATL_VER >= 0x0700)
5032 int GetIDD()
5033 {
5034 return( static_cast<T*>(this)->IDD );
5035 }
5036
5037 virtual DLGPROC GetDialogProc()
5038 {
5039 return DialogProc;
5040 }
5041
5042 static INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
5043 {
5044 CAxPropertyPageImpl< T, TBase >* pThis = (CAxPropertyPageImpl< T, TBase >*)hWnd;
5045 if (uMsg == WM_INITDIALOG)
5046 {
5047 HRESULT hr;
5048 if (FAILED(hr = pThis->CreateActiveXControls(pThis->GetIDD())))
5049 {
5050 ATLASSERT(FALSE);
5051 return FALSE;
5052 }
5053 }
5054 return CPropertyPageImpl< T, TBase >::DialogProc(hWnd, uMsg, wParam, lParam);
5055 }
5056
5057 // ActiveX controls creation
5058 virtual HRESULT CreateActiveXControls(UINT nID)
5059 {
5060 // Load dialog template and InitData
5061 HRSRC hDlgInit = ::FindResource(ATL::_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(nID), (LPTSTR)_ATL_RT_DLGINIT);
5062 BYTE* pInitData = NULL;
5063 HGLOBAL hData = NULL;
5064 HRESULT hr = S_OK;
5065 if (hDlgInit != NULL)
5066 {
5067 hData = ::LoadResource(ATL::_AtlBaseModule.GetResourceInstance(), hDlgInit);
5068 if (hData != NULL)
5069 pInitData = (BYTE*) ::LockResource(hData);
5070 }
5071
5072 HRSRC hDlg = ::FindResource(ATL::_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(nID), (LPTSTR)RT_DIALOG);
5073 if (hDlg != NULL)
5074 {
5075 HGLOBAL hResource = ::LoadResource(ATL::_AtlBaseModule.GetResourceInstance(), hDlg);
5076 DLGTEMPLATE* pDlg = NULL;
5077 if (hResource != NULL)
5078 {
5079 pDlg = (DLGTEMPLATE*) ::LockResource(hResource);
5080 if (pDlg != NULL)
5081 {
5082 // Get first control on the template
5083 BOOL bDialogEx = ATL::_DialogSplitHelper::IsDialogEx(pDlg);
5084 WORD nItems = ATL::_DialogSplitHelper::DlgTemplateItemCount(pDlg);
5085
5086 // Get first control on the dialog
5087 DLGITEMTEMPLATE* pItem = ATL::_DialogSplitHelper::FindFirstDlgItem(pDlg);
5088 HWND hWndPrev = GetWindow(GW_CHILD);
5089
5090 // Create all ActiveX cotnrols in the dialog template and place them in the correct tab order (z-order)
5091 for (WORD nItem = 0; nItem < nItems; nItem++)
5092 {
5093 DWORD wID = bDialogEx ? ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->id : pItem->id;
5094 if (ATL::_DialogSplitHelper::IsActiveXControl(pItem, bDialogEx))
5095 {
5096 BYTE* pData = NULL;
5097 DWORD dwLen = ATL::_DialogSplitHelper::FindCreateData(wID, pInitData, &pData);
5098 ATL::CComPtr<IStream> spStream;
5099 if (dwLen != 0)
5100 {
5101 HGLOBAL h = GlobalAlloc(GHND, dwLen);
5102 if (h != NULL)
5103 {
5104 BYTE* pBytes = (BYTE*) GlobalLock(h);
5105 BYTE* pSource = pData;
5106 SecureHelper::memcpy_x(pBytes, dwLen, pSource, dwLen);
5107 GlobalUnlock(h);
5108 CreateStreamOnHGlobal(h, TRUE, &spStream);
5109 }
5110 else
5111 {
5112 hr = E_OUTOFMEMORY;
5113 break;
5114 }
5115 }
5116
5117 ATL::CComBSTR bstrLicKey;
5118 hr = ATL::_DialogSplitHelper::ParseInitData(spStream, &bstrLicKey.m_str);
5119 if (SUCCEEDED(hr))
5120 {
5121 ATL::CAxWindow2 wnd;
5122 // Get control caption.
5123 LPWSTR pszClassName =
5124 bDialogEx ?
5125 (LPWSTR)(((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem) + 1) :
5126 (LPWSTR)(pItem + 1);
5127 // Get control rect.
5128 RECT rect = { 0 };
5129 rect.left = bDialogEx ? ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->x : pItem->x;
5130 rect.top = bDialogEx ? ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->y : pItem->y;
5131 rect.right = rect.left + (bDialogEx ? ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->cx : pItem->cx);
5132 rect.bottom = rect.top + (bDialogEx ? ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->cy : pItem->cy);
5133
5134 // Convert from dialog units to screen units
5135 MapDialogRect(&rect);
5136
5137 // Create AxWindow with a NULL caption.
5138 wnd.Create(m_hWnd,
5139 &rect,
5140 NULL,
5141 (bDialogEx ?
5142 ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->style :
5143 pItem->style) | WS_TABSTOP,
5144 bDialogEx ?
5145 ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->exStyle :
5146 0,
5147 bDialogEx ?
5148 ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->id :
5149 pItem->id,
5150 NULL);
5151
5152 if (wnd != NULL)
5153 {
5154 #ifndef _WIN32_WCE
5155 // Set the Help ID
5156 if (bDialogEx && ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->helpID != 0)
5157 wnd.SetWindowContextHelpId(((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->helpID);
5158 #endif // !_WIN32_WCE
5159 // Try to create the ActiveX control.
5160 hr = wnd.CreateControlLic(pszClassName, spStream, NULL, bstrLicKey);
5161 if (FAILED(hr))
5162 break;
5163 // Set the correct tab position.
5164 if (nItem == 0)
5165 hWndPrev = HWND_TOP;
5166 wnd.SetWindowPos(hWndPrev, 0,0,0,0,SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
5167 hWndPrev = wnd;
5168 }
5169 else
5170 {
5171 hr = ATL::AtlHresultFromLastError();
5172 }
5173 }
5174 }
5175 else
5176 {
5177 if (nItem != 0)
5178 hWndPrev = ::GetWindow(hWndPrev, GW_HWNDNEXT);
5179 }
5180 pItem = ATL::_DialogSplitHelper::FindNextDlgItem(pItem, bDialogEx);
5181 }
5182 }
5183 else
5184 hr = ATL::AtlHresultFromLastError();
5185 }
5186 else
5187 hr = ATL::AtlHresultFromLastError();
5188 }
5189 return hr;
5190 }
5191
5192 // Event handling support
5193 HRESULT AdviseSinkMap(bool bAdvise)
5194 {
5195 if(!bAdvise && m_hWnd == NULL)
5196 {
5197 // window is gone, controls are already unadvised
5198 ATLTRACE2(atlTraceUI, 0, _T("CAxPropertyPageImpl::AdviseSinkMap called after the window was destroyed\n"));
5199 return S_OK;
5200 }
5201 HRESULT hRet = E_NOTIMPL;
5202 __if_exists(T::_GetSinkMapFinder)
5203 {
5204 T* pT = static_cast<T*>(this);
5205 hRet = AtlAdviseSinkMap(pT, bAdvise);
5206 }
5207 return hRet;
5208 }
5209
5210 // Message map and handlers
5211 typedef CPropertyPageImpl< T, TBase> _baseClass;
5212 BEGIN_MSG_MAP(CAxPropertyPageImpl)
5213 MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
5214 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
5215 CHAIN_MSG_MAP(_baseClass)
5216 END_MSG_MAP()
5217
5218 LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
5219 {
5220 // initialize controls in dialog with DLGINIT resource section
5221 ExecuteDlgInit(static_cast<T*>(this)->IDD);
5222 AdviseSinkMap(true);
5223 bHandled = FALSE;
5224 return 1;
5225 }
5226
5227 LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
5228 {
5229 AdviseSinkMap(false);
5230 bHandled = FALSE;
5231 return 1;
5232 }
5233 #endif // (_ATL_VER >= 0x0700)
5234 };
5235
5236 // for non-customized pages
5237 template <WORD t_wDlgTemplateID>
5238 class CAxPropertyPage : public CAxPropertyPageImpl<CAxPropertyPage<t_wDlgTemplateID> >
5239 {
5240 public:
5241 enum { IDD = t_wDlgTemplateID };
5242
5243 CAxPropertyPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAxPropertyPageImpl<CAxPropertyPage>(title)
5244 { }
5245
5246 #if (_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)
5247 // not empty so we handle accelerators/create controls
5248 BEGIN_MSG_MAP(CAxPropertyPage)
5249 CHAIN_MSG_MAP(CAxPropertyPageImpl<CAxPropertyPage<t_wDlgTemplateID> >)
5250 END_MSG_MAP()
5251 #else // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700))
5252 DECLARE_EMPTY_MSG_MAP()
5253 #endif // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700))
5254 };
5255
5256 #endif // _ATL_NO_HOSTING
5257
5258
5259 ///////////////////////////////////////////////////////////////////////////////
5260 // Wizard97 Support
5261
5262 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
5263
5264 // Sample wizard dialog resources:
5265 //
5266 // IDD_WIZ97_INTERIOR_BLANK DIALOG 0, 0, 317, 143
5267 // STYLE DS_SETFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
5268 // CAPTION "Wizard97 Property Page - Interior"
5269 // FONT 8, "MS Shell Dlg"
5270 // BEGIN
5271 // END
5272 //
5273 // IDD_WIZ97_EXTERIOR_BLANK DIALOGEX 0, 0, 317, 193
5274 // STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
5275 // CAPTION "Wizard97 Property Page - Welcome/Complete"
5276 // FONT 8, "MS Shell Dlg", 0, 0, 0x0
5277 // BEGIN
5278 // LTEXT "Welcome to the X Wizard",IDC_WIZ97_EXTERIOR_TITLE,115,8,
5279 // 195,24
5280 // LTEXT "Wizard Explanation\r\n(The height of the static text should be in multiples of 8 dlus)",
5281 // IDC_STATIC,115,40,195,16
5282 // LTEXT "h",IDC_WIZ97_BULLET1,118,64,8,8
5283 // LTEXT "List Item 1 (the h is turned into a bullet)",IDC_STATIC,
5284 // 127,63,122,8
5285 // LTEXT "h",IDC_WIZ97_BULLET2,118,79,8,8
5286 // LTEXT "List Item 2. Keep 7 dlus between paragraphs",IDC_STATIC,
5287 // 127,78,33,8
5288 // CONTROL "&Do not show this Welcome page again",
5289 // IDC_WIZ97_WELCOME_NOTAGAIN,"Button",BS_AUTOCHECKBOX |
5290 // WS_TABSTOP,115,169,138,10
5291 // END
5292 //
5293 // GUIDELINES DESIGNINFO
5294 // BEGIN
5295 // IDD_WIZ97_INTERIOR_BLANK, DIALOG
5296 // BEGIN
5297 // LEFTMARGIN, 7
5298 // RIGHTMARGIN, 310
5299 // VERTGUIDE, 21
5300 // VERTGUIDE, 31
5301 // VERTGUIDE, 286
5302 // VERTGUIDE, 296
5303 // TOPMARGIN, 7
5304 // BOTTOMMARGIN, 136
5305 // HORZGUIDE, 8
5306 // END
5307 //
5308 // IDD_WIZ97_EXTERIOR_BLANK, DIALOG
5309 // BEGIN
5310 // RIGHTMARGIN, 310
5311 // VERTGUIDE, 115
5312 // VERTGUIDE, 118
5313 // VERTGUIDE, 127
5314 // TOPMARGIN, 7
5315 // BOTTOMMARGIN, 186
5316 // HORZGUIDE, 8
5317 // HORZGUIDE, 32
5318 // HORZGUIDE, 40
5319 // HORZGUIDE, 169
5320 // END
5321 // END
5322
5323 ///////////////////////////////////////////////////////////////////////////////
5324 // CWizard97SheetWindow - client side for a Wizard 97 style wizard sheet
5325
5326 class CWizard97SheetWindow : public CPropertySheetWindow
5327 {
5328 public:
5329 // Constructors
5330 CWizard97SheetWindow(HWND hWnd = NULL) : CPropertySheetWindow(hWnd)
5331 { }
5332
5333 CWizard97SheetWindow& operator =(HWND hWnd)
5334 {
5335 m_hWnd = hWnd;
5336 return *this;
5337 }
5338
5339 // Operations
5340 HFONT GetExteriorPageTitleFont(void)
5341 {
5342 ATLASSERT(::IsWindow(m_hWnd));
5343 return (HFONT)::SendMessage(m_hWnd, GetMessage_GetExteriorPageTitleFont(), 0, 0L);
5344 }
5345
5346 HFONT GetBulletFont(void)
5347 {
5348 ATLASSERT(::IsWindow(m_hWnd));
5349 return (HFONT)::SendMessage(m_hWnd, GetMessage_GetBulletFont(), 0, 0L);
5350 }
5351
5352 // Helpers
5353 static UINT GetMessage_GetExteriorPageTitleFont()
5354 {
5355 static UINT uGetExteriorPageTitleFont = 0;
5356 if(uGetExteriorPageTitleFont == 0)
5357 {
5358 CStaticDataInitCriticalSectionLock lock;
5359 if(FAILED(lock.Lock()))
5360 {
5361 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CWizard97SheetWindow::GetMessage_GetExteriorPageTitleFont().\n"));
5362 ATLASSERT(FALSE);
5363 return 0;
5364 }
5365
5366 if(uGetExteriorPageTitleFont == 0)
5367 uGetExteriorPageTitleFont = ::RegisterWindowMessage(_T("GetExteriorPageTitleFont_531AF056-B8BE-4c4c-B786-AC608DF0DF12"));
5368
5369 lock.Unlock();
5370 }
5371 ATLASSERT(uGetExteriorPageTitleFont != 0);
5372 return uGetExteriorPageTitleFont;
5373 }
5374
5375 static UINT GetMessage_GetBulletFont()
5376 {
5377 static UINT uGetBulletFont = 0;
5378 if(uGetBulletFont == 0)
5379 {
5380 CStaticDataInitCriticalSectionLock lock;
5381 if(FAILED(lock.Lock()))
5382 {
5383 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CWizard97SheetWindow::GetMessage_GetBulletFont().\n"));
5384 ATLASSERT(FALSE);
5385 return 0;
5386 }
5387
5388 if(uGetBulletFont == 0)
5389 uGetBulletFont = ::RegisterWindowMessage(_T("GetBulletFont_AD347D08-8F65-45ef-982E-6352E8218AD5"));
5390
5391 lock.Unlock();
5392 }
5393 ATLASSERT(uGetBulletFont != 0);
5394 return uGetBulletFont;
5395 }
5396
5397 // Implementation - override to prevent usage
5398 HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL)
5399 {
5400 ATLASSERT(FALSE);
5401 return NULL;
5402 }
5403 };
5404
5405
5406 ///////////////////////////////////////////////////////////////////////////////
5407 // CWizard97SheetImpl - implements a Wizard 97 style wizard sheet
5408
5409 template <class T, class TBase = CWizard97SheetWindow>
5410 class ATL_NO_VTABLE CWizard97SheetImpl : public CPropertySheetImpl< T, TBase >
5411 {
5412 protected:
5413 // Typedefs
5414 typedef CWizard97SheetImpl< T, TBase > thisClass;
5415 typedef CPropertySheetImpl< T, TBase > baseClass;
5416
5417 // Member variables
5418 CFont m_fontExteriorPageTitle; // Welcome and Completion page title font
5419 CFont m_fontBullet; // Bullet font (used on static text 'h' to produce a small bullet)
5420 bool m_bReceivedFirstSizeMessage;
5421
5422 public:
5423 CWizard97SheetImpl(ATL::_U_STRINGorID title, ATL::_U_STRINGorID headerBitmap, ATL::_U_STRINGorID watermarkBitmap, UINT uStartPage = 0, HWND hWndParent = NULL) :
5424 baseClass(title, uStartPage, hWndParent),
5425 m_bReceivedFirstSizeMessage(false)
5426 {
5427 m_psh.dwFlags &= ~(PSH_NOCONTEXTHELP);
5428 m_psh.dwFlags &= ~(PSH_WIZARD | PSH_WIZARD_LITE);
5429
5430 m_psh.dwFlags |= (PSH_HASHELP | PSH_WIZARDCONTEXTHELP);
5431 m_psh.dwFlags |= PSH_WIZARD97;
5432
5433 baseClass::SetHeader(headerBitmap.m_lpstr);
5434 baseClass::SetWatermark(watermarkBitmap.m_lpstr);
5435 }
5436
5437 // Overrides from base class
5438 void OnSheetInitialized()
5439 {
5440 T* pT = static_cast<T*>(this);
5441 pT->_InitializeFonts();
5442
5443 // We'd like to center the wizard here, but its too early.
5444 // Instead, we'll do CenterWindow upon our first WM_SIZE message
5445 }
5446
5447 // Initialization
5448 void _InitializeFonts()
5449 {
5450 // Setup the Title and Bullet Font
5451 // (Property pages can send the "get external page title font" and "get bullet font" messages)
5452 // The derived class needs to do the actual SetFont for the dialog items)
5453
5454 CFontHandle fontThisDialog = this->GetFont();
5455 CClientDC dcScreen(NULL);
5456
5457 LOGFONT titleLogFont = {0};
5458 LOGFONT bulletLogFont = {0};
5459 fontThisDialog.GetLogFont(&titleLogFont);
5460 fontThisDialog.GetLogFont(&bulletLogFont);
5461
5462 // The Wizard 97 Spec recommends to do the Title Font
5463 // as Verdana Bold, 12pt.
5464 titleLogFont.lfCharSet = DEFAULT_CHARSET;
5465 titleLogFont.lfWeight = FW_BOLD;
5466 SecureHelper::strcpy_x(titleLogFont.lfFaceName, _countof(titleLogFont.lfFaceName), _T("Verdana Bold"));
5467 INT titleFontPointSize = 12;
5468 titleLogFont.lfHeight = -::MulDiv(titleFontPointSize, dcScreen.GetDeviceCaps(LOGPIXELSY), 72);
5469 m_fontExteriorPageTitle.CreateFontIndirect(&titleLogFont);
5470
5471 // The Wizard 97 Spec recommends to do Bullets by having
5472 // static text of "h" in the Marlett font.
5473 bulletLogFont.lfCharSet = DEFAULT_CHARSET;
5474 bulletLogFont.lfWeight = FW_NORMAL;
5475 SecureHelper::strcpy_x(bulletLogFont.lfFaceName, _countof(bulletLogFont.lfFaceName), _T("Marlett"));
5476 INT bulletFontSize = 8;
5477 bulletLogFont.lfHeight = -::MulDiv(bulletFontSize, dcScreen.GetDeviceCaps(LOGPIXELSY), 72);
5478 m_fontBullet.CreateFontIndirect(&bulletLogFont);
5479 }
5480
5481 // Message Handling
5482 BEGIN_MSG_MAP(thisClass)
5483 MESSAGE_HANDLER(CWizard97SheetWindow::GetMessage_GetExteriorPageTitleFont(), OnGetExteriorPageTitleFont)
5484 MESSAGE_HANDLER(CWizard97SheetWindow::GetMessage_GetBulletFont(), OnGetBulletFont)
5485 MESSAGE_HANDLER(WM_SIZE, OnSize)
5486 CHAIN_MSG_MAP(baseClass)
5487 END_MSG_MAP()
5488
5489 LRESULT OnGetExteriorPageTitleFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
5490 {
5491 return (LRESULT)(HFONT)m_fontExteriorPageTitle;
5492 }
5493
5494 LRESULT OnGetBulletFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
5495 {
5496 return (LRESULT)(HFONT)m_fontBullet;
5497 }
5498
5499 LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
5500 {
5501 if(!m_bReceivedFirstSizeMessage)
5502 {
5503 m_bReceivedFirstSizeMessage = true;
5504 this->CenterWindow();
5505 }
5506
5507 bHandled = FALSE;
5508 return 0;
5509 }
5510 };
5511
5512 // for non-customized sheets
5513 class CWizard97Sheet : public CWizard97SheetImpl<CWizard97Sheet>
5514 {
5515 protected:
5516 // Typedefs
5517 typedef CWizard97Sheet thisClass;
5518 typedef CWizard97SheetImpl<CWizard97Sheet> baseClass;
5519
5520 public:
5521 CWizard97Sheet(ATL::_U_STRINGorID title, ATL::_U_STRINGorID headerBitmap, ATL::_U_STRINGorID watermarkBitmap, UINT uStartPage = 0, HWND hWndParent = NULL) :
5522 baseClass(title, headerBitmap, watermarkBitmap, uStartPage, hWndParent)
5523 { }
5524
5525 BEGIN_MSG_MAP(thisClass)
5526 CHAIN_MSG_MAP(baseClass)
5527 END_MSG_MAP()
5528 };
5529
5530
5531 ///////////////////////////////////////////////////////////////////////////////
5532 // CWizard97PageWindow - client side for a Wizard 97 style wizard page
5533
5534 #define WIZARD97_EXTERIOR_CXDLG 317
5535 #define WIZARD97_EXTERIOR_CYDLG 193
5536
5537 #define WIZARD97_INTERIOR_CXDLG 317
5538 #define WIZARD97_INTERIOR_CYDLG 143
5539
5540 class CWizard97PageWindow : public CPropertyPageWindow
5541 {
5542 public:
5543 // Constructors
5544 CWizard97PageWindow(HWND hWnd = NULL) : CPropertyPageWindow(hWnd)
5545 { }
5546
5547 CWizard97PageWindow& operator =(HWND hWnd)
5548 {
5549 m_hWnd = hWnd;
5550 return *this;
5551 }
5552
5553 // Attributes
5554 CWizard97SheetWindow GetPropertySheet() const
5555 {
5556 ATLASSERT(::IsWindow(m_hWnd));
5557 return CWizard97SheetWindow(GetParent());
5558 }
5559
5560 // Operations
5561 HFONT GetExteriorPageTitleFont(void)
5562 {
5563 ATLASSERT(::IsWindow(m_hWnd));
5564 return GetPropertySheet().GetExteriorPageTitleFont();
5565 }
5566
5567 HFONT GetBulletFont(void)
5568 {
5569 ATLASSERT(::IsWindow(m_hWnd));
5570 return GetPropertySheet().GetBulletFont();
5571 }
5572
5573 // Implementation - overrides to prevent usage
5574 HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL)
5575 {
5576 ATLASSERT(FALSE);
5577 return NULL;
5578 }
5579
5580 };
5581
5582
5583 ///////////////////////////////////////////////////////////////////////////////
5584 // CWizard97PageImpl - implements a Wizard 97 style wizard page
5585
5586 template <class T, class TBase = CWizard97PageWindow>
5587 class ATL_NO_VTABLE CWizard97PageImpl : public CPropertyPageImpl< T, TBase >
5588 {
5589 protected:
5590 // Typedefs
5591 typedef CWizard97PageImpl< T, TBase > thisClass;
5592 typedef CPropertyPageImpl< T, TBase > baseClass;
5593
5594 public:
5595 CWizard97PageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : baseClass(title)
5596 { }
5597
5598 // Message Handling
5599 BEGIN_MSG_MAP(thisClass)
5600 CHAIN_MSG_MAP(baseClass)
5601 END_MSG_MAP()
5602 };
5603
5604
5605 ///////////////////////////////////////////////////////////////////////////////
5606 // CWizard97ExteriorPageImpl - implements a Wizard 97 style exterior wizard page
5607
5608 template <class T, class TBase = CWizard97PageWindow>
5609 class ATL_NO_VTABLE CWizard97ExteriorPageImpl : public CPropertyPageImpl< T, TBase >
5610 {
5611 protected:
5612 // Typedefs
5613 typedef CWizard97ExteriorPageImpl< T, TBase > thisClass;
5614 typedef CPropertyPageImpl< T, TBase > baseClass;
5615
5616 public:
5617 // Constructors
5618 CWizard97ExteriorPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : baseClass(title)
5619 {
5620 m_psp.dwFlags |= PSP_HASHELP;
5621 m_psp.dwFlags |= PSP_HIDEHEADER;
5622 }
5623
5624 // Message Handling
5625 BEGIN_MSG_MAP(thisClass)
5626 CHAIN_MSG_MAP(baseClass)
5627 END_MSG_MAP()
5628 };
5629
5630
5631 ///////////////////////////////////////////////////////////////////////////////
5632 // CWizard97InteriorPageImpl - implements a Wizard 97 style interior wizard page
5633
5634 template <class T, class TBase = CWizard97PageWindow>
5635 class ATL_NO_VTABLE CWizard97InteriorPageImpl : public CPropertyPageImpl< T, TBase >
5636 {
5637 protected:
5638 // Typedefs
5639 typedef CWizard97InteriorPageImpl< T, TBase > thisClass;
5640 typedef CPropertyPageImpl< T, TBase > baseClass;
5641
5642 public:
5643 // Constructors
5644 CWizard97InteriorPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : baseClass(title)
5645 {
5646 m_psp.dwFlags |= PSP_HASHELP;
5647 m_psp.dwFlags &= ~PSP_HIDEHEADER;
5648 m_psp.dwFlags |= PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
5649
5650 // Be sure to have the derived class define this in the constructor.
5651 // We'll default it to something obvious in case its forgotten.
5652 baseClass::SetHeaderTitle(_T("Call SetHeaderTitle in Derived Class"));
5653 baseClass::SetHeaderSubTitle(_T("Call SetHeaderSubTitle in the constructor of the Derived Class."));
5654 }
5655
5656 // Message Handling
5657 BEGIN_MSG_MAP(thisClass)
5658 CHAIN_MSG_MAP(baseClass)
5659 END_MSG_MAP()
5660 };
5661
5662 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
5663
5664
5665 ///////////////////////////////////////////////////////////////////////////////
5666 // Aero Wizard support
5667
5668 #if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
5669
5670 ///////////////////////////////////////////////////////////////////////////////
5671 // CAeroWizardFrameWindow - client side for an Aero Wizard frame window
5672
5673 class CAeroWizardFrameWindow : public CPropertySheetWindow
5674 {
5675 public:
5676 // Constructors
5677 CAeroWizardFrameWindow(HWND hWnd = NULL) : CPropertySheetWindow(hWnd)
5678 { }
5679
5680 CAeroWizardFrameWindow& operator =(HWND hWnd)
5681 {
5682 m_hWnd = hWnd;
5683 return *this;
5684 }
5685
5686 // Operations - new, Aero Wizard only
5687 void SetNextText(LPCWSTR lpszText)
5688 {
5689 ATLASSERT(::IsWindow(m_hWnd));
5690 ::SendMessage(m_hWnd, PSM_SETNEXTTEXT, 0, (LPARAM)lpszText);
5691 }
5692
5693 void ShowWizardButtons(DWORD dwButtons, DWORD dwStates)
5694 {
5695 ATLASSERT(::IsWindow(m_hWnd));
5696 ::PostMessage(m_hWnd, PSM_SHOWWIZBUTTONS, (WPARAM)dwStates, (LPARAM)dwButtons);
5697 }
5698
5699 void EnableWizardButtons(DWORD dwButtons, DWORD dwStates)
5700 {
5701 ATLASSERT(::IsWindow(m_hWnd));
5702 ::PostMessage(m_hWnd, PSM_ENABLEWIZBUTTONS, (WPARAM)dwStates, (LPARAM)dwButtons);
5703 }
5704
5705 void SetButtonText(DWORD dwButton, LPCWSTR lpszText)
5706 {
5707 ATLASSERT(::IsWindow(m_hWnd));
5708 ::SendMessage(m_hWnd, PSM_SETBUTTONTEXT, (WPARAM)dwButton, (LPARAM)lpszText);
5709 }
5710 };
5711
5712
5713 ///////////////////////////////////////////////////////////////////////////////
5714 // CAeroWizardFrameImpl - implements an Aero Wizard frame
5715
5716 template <class T, class TBase = CAeroWizardFrameWindow>
5717 class ATL_NO_VTABLE CAeroWizardFrameImpl : public CPropertySheetImpl<T, TBase >
5718 {
5719 public:
5720 // Constructor
5721 CAeroWizardFrameImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL) :
5722 CPropertySheetImpl<T, TBase >(title, uStartPage, hWndParent)
5723 {
5724 m_psh.dwFlags |= PSH_WIZARD | PSH_AEROWIZARD;
5725 }
5726
5727 // Operations
5728 void EnableResizing()
5729 {
5730 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
5731 m_psh.dwFlags |= PSH_RESIZABLE;
5732 }
5733
5734 void UseHeaderBitmap()
5735 {
5736 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
5737 m_psh.dwFlags |= PSH_HEADERBITMAP;
5738 }
5739
5740 void SetNoMargin()
5741 {
5742 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
5743 m_psh.dwFlags |= PSH_NOMARGIN;
5744 }
5745
5746 // Override to prevent use
5747 HWND Create(HWND /*hWndParent*/ = NULL)
5748 {
5749 ATLASSERT(FALSE); // not supported for Aero Wizard
5750 return NULL;
5751 }
5752 };
5753
5754
5755 ///////////////////////////////////////////////////////////////////////////////
5756 // CAeroWizardFrame - for non-customized frames
5757
5758 class CAeroWizardFrame : public CAeroWizardFrameImpl<CAeroWizardFrame>
5759 {
5760 public:
5761 CAeroWizardFrame(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL)
5762 : CAeroWizardFrameImpl<CAeroWizardFrame>(title, uStartPage, hWndParent)
5763 { }
5764
5765 BEGIN_MSG_MAP(CAeroWizardFrame)
5766 MESSAGE_HANDLER(WM_COMMAND, CAeroWizardFrameImpl<CAeroWizardFrame>::OnCommand)
5767 END_MSG_MAP()
5768 };
5769
5770
5771 ///////////////////////////////////////////////////////////////////////////////
5772 // CAeroWizardPageWindow - client side for an Aero Wizard page
5773
5774 class CAeroWizardPageWindow : public CPropertyPageWindow
5775 {
5776 public:
5777 // Constructors
5778 CAeroWizardPageWindow(HWND hWnd = NULL) : CPropertyPageWindow(hWnd)
5779 { }
5780
5781 CAeroWizardPageWindow& operator =(HWND hWnd)
5782 {
5783 m_hWnd = hWnd;
5784 return *this;
5785 }
5786
5787 // Attributes
5788 CAeroWizardFrameWindow GetAeroWizardFrame() const
5789 {
5790 ATLASSERT(::IsWindow(m_hWnd));
5791 // This is not really top-level frame window, but it processes all frame messages
5792 return CAeroWizardFrameWindow(GetParent());
5793 }
5794
5795 // Operations - new, Aero Wizard only
5796 void SetNextText(LPCWSTR lpszText)
5797 {
5798 ATLASSERT(::IsWindow(m_hWnd));
5799 ATLASSERT(GetParent() != NULL);
5800 GetAeroWizardFrame().SetNextText(lpszText);
5801 }
5802
5803 void ShowWizardButtons(DWORD dwButtons, DWORD dwStates)
5804 {
5805 ATLASSERT(::IsWindow(m_hWnd));
5806 ATLASSERT(GetParent() != NULL);
5807 GetAeroWizardFrame().ShowWizardButtons(dwButtons, dwStates);
5808 }
5809
5810 void EnableWizardButtons(DWORD dwButtons, DWORD dwStates)
5811 {
5812 ATLASSERT(::IsWindow(m_hWnd));
5813 ATLASSERT(GetParent() != NULL);
5814 GetAeroWizardFrame().EnableWizardButtons(dwButtons, dwStates);
5815 }
5816
5817 void SetButtonText(DWORD dwButton, LPCWSTR lpszText)
5818 {
5819 ATLASSERT(::IsWindow(m_hWnd));
5820 ATLASSERT(GetParent() != NULL);
5821 GetAeroWizardFrame().SetButtonText(dwButton, lpszText);
5822 }
5823 };
5824
5825
5826 ///////////////////////////////////////////////////////////////////////////////
5827 // CAeroWizardPageImpl - implements an Aero Wizard page
5828
5829 template <class T, class TBase = CAeroWizardPageWindow>
5830 class ATL_NO_VTABLE CAeroWizardPageImpl : public CPropertyPageImpl<T, TBase >
5831 {
5832 public:
5833 CAeroWizardPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CPropertyPageImpl<T, TBase >(title)
5834 { }
5835 };
5836
5837
5838 ///////////////////////////////////////////////////////////////////////////////
5839 // CAeroWizardPage - for non-customized pages
5840
5841 template <WORD t_wDlgTemplateID>
5842 class CAeroWizardPage : public CAeroWizardPageImpl<CAeroWizardPage<t_wDlgTemplateID> >
5843 {
5844 public:
5845 enum { IDD = t_wDlgTemplateID };
5846
5847 CAeroWizardPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAeroWizardPageImpl<CAeroWizardPage>(title)
5848 { }
5849
5850 DECLARE_EMPTY_MSG_MAP()
5851 };
5852
5853
5854 #ifndef _ATL_NO_HOSTING
5855
5856 // Note: You must #include <atlhost.h> to use these classes
5857
5858 ///////////////////////////////////////////////////////////////////////////////
5859 // CAeroWizardAxPageImpl - Aero Wizard page that hosts ActiveX controls
5860
5861 template <class T, class TBase = CAeroWizardPageWindow>
5862 class ATL_NO_VTABLE CAeroWizardAxPageImpl : public CAxPropertyPageImpl< T, TBase >
5863 {
5864 public:
5865 CAeroWizardAxPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAxPropertyPageImpl< T, TBase >(title)
5866 { }
5867 };
5868
5869
5870 ///////////////////////////////////////////////////////////////////////////////
5871 // CAeroWizardAxPage - for non-customized pages
5872
5873 template <WORD t_wDlgTemplateID>
5874 class CAeroWizardAxPage : public CAeroWizardAxPageImpl<CAeroWizardAxPage<t_wDlgTemplateID> >
5875 {
5876 public:
5877 enum { IDD = t_wDlgTemplateID };
5878
5879 CAeroWizardAxPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAeroWizardAxPageImpl<CAeroWizardAxPage>(title)
5880 { }
5881
5882 #if (_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)
5883 // not empty so we handle accelerators/create controls
5884 BEGIN_MSG_MAP(CAeroWizardAxPage)
5885 CHAIN_MSG_MAP(CAeroWizardAxPageImpl<CAeroWizardAxPage<t_wDlgTemplateID> >)
5886 END_MSG_MAP()
5887 #else // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700))
5888 DECLARE_EMPTY_MSG_MAP()
5889 #endif // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700))
5890 };
5891
5892 #endif // _ATL_NO_HOSTING
5893
5894 #endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
5895
5896
5897 ///////////////////////////////////////////////////////////////////////////////
5898 // TaskDialog support
5899
5900 #if ((_WIN32_WINNT >= 0x0600) || defined(_WTL_TASKDIALOG)) && !defined(_WIN32_WCE)
5901
5902 ///////////////////////////////////////////////////////////////////////////////
5903 // AtlTaskDialog - support for TaskDialog() function
5904
5905 inline int AtlTaskDialog(HWND hWndParent,
5906 ATL::_U_STRINGorID WindowTitle, ATL::_U_STRINGorID MainInstructionText, ATL::_U_STRINGorID ContentText,
5907 TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons = 0U, ATL::_U_STRINGorID Icon = (LPCTSTR)NULL)
5908 {
5909 int nRet = -1;
5910
5911 #ifdef _WTL_TASKDIALOG_DIRECT
5912 USES_CONVERSION;
5913 HRESULT hRet = ::TaskDialog(hWndParent, ModuleHelper::GetResourceInstance(),
5914 IS_INTRESOURCE(WindowTitle.m_lpstr) ? (LPCWSTR) WindowTitle.m_lpstr : T2CW(WindowTitle.m_lpstr),
5915 IS_INTRESOURCE(MainInstructionText.m_lpstr) ? (LPCWSTR) MainInstructionText.m_lpstr : T2CW(MainInstructionText.m_lpstr),
5916 IS_INTRESOURCE(ContentText.m_lpstr) ? (LPCWSTR) ContentText.m_lpstr : T2CW(ContentText.m_lpstr),
5917 dwCommonButtons,
5918 IS_INTRESOURCE(Icon.m_lpstr) ? (LPCWSTR) Icon.m_lpstr : T2CW(Icon.m_lpstr),
5919 &nRet);
5920 ATLVERIFY(SUCCEEDED(hRet));
5921 #else
5922 // This allows apps to run on older versions of Windows
5923 typedef HRESULT (STDAPICALLTYPE *PFN_TaskDialog)(HWND hwndParent, HINSTANCE hInstance, PCWSTR pszWindowTitle, PCWSTR pszMainInstruction, PCWSTR pszContent, TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons, PCWSTR pszIcon, int* pnButton);
5924
5925 HMODULE m_hCommCtrlDLL = ::LoadLibrary(_T("comctl32.dll"));
5926 if(m_hCommCtrlDLL != NULL)
5927 {
5928 PFN_TaskDialog pfnTaskDialog = (PFN_TaskDialog)::GetProcAddress(m_hCommCtrlDLL, "TaskDialog");
5929 if(pfnTaskDialog != NULL)
5930 {
5931 USES_CONVERSION;
5932 HRESULT hRet = pfnTaskDialog(hWndParent, ModuleHelper::GetResourceInstance(),
5933 IS_INTRESOURCE(WindowTitle.m_lpstr) ? (LPCWSTR) WindowTitle.m_lpstr : T2CW(WindowTitle.m_lpstr),
5934 IS_INTRESOURCE(MainInstructionText.m_lpstr) ? (LPCWSTR) MainInstructionText.m_lpstr : T2CW(MainInstructionText.m_lpstr),
5935 IS_INTRESOURCE(ContentText.m_lpstr) ? (LPCWSTR) ContentText.m_lpstr : T2CW(ContentText.m_lpstr),
5936 dwCommonButtons,
5937 IS_INTRESOURCE(Icon.m_lpstr) ? (LPCWSTR) Icon.m_lpstr : T2CW(Icon.m_lpstr),
5938 &nRet);
5939 ATLVERIFY(SUCCEEDED(hRet));
5940 }
5941
5942 ::FreeLibrary(m_hCommCtrlDLL);
5943 }
5944 #endif
5945
5946 return nRet;
5947 }
5948
5949
5950 ///////////////////////////////////////////////////////////////////////////////
5951 // CTaskDialogConfig - TASKDIALOGCONFIG wrapper
5952
5953 class CTaskDialogConfig : public TASKDIALOGCONFIG
5954 {
5955 public:
5956 // Constructor
5957 CTaskDialogConfig()
5958 {
5959 Init();
5960 }
5961
5962 void Init()
5963 {
5964 memset(this, 0, sizeof(TASKDIALOGCONFIG)); // initialize structure to 0/NULL
5965 this->cbSize = sizeof(TASKDIALOGCONFIG);
5966 this->hInstance = ModuleHelper::GetResourceInstance();
5967 }
5968
5969 // Operations - setting values
5970 // common buttons
5971 void SetCommonButtons(TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtonsArg)
5972 {
5973 this->dwCommonButtons = dwCommonButtonsArg;
5974 }
5975
5976 // window title text
5977 void SetWindowTitle(UINT nID)
5978 {
5979 this->pszWindowTitle = MAKEINTRESOURCEW(nID);
5980 }
5981
5982 void SetWindowTitle(LPCWSTR lpstrWindowTitle)
5983 {
5984 this->pszWindowTitle = lpstrWindowTitle;
5985 }
5986
5987 // main icon
5988 void SetMainIcon(HICON hIcon)
5989 {
5990 this->dwFlags |= TDF_USE_HICON_MAIN;
5991 this->hMainIcon = hIcon;
5992 }
5993
5994 void SetMainIcon(UINT nID)
5995 {
5996 this->dwFlags &= ~TDF_USE_HICON_MAIN;
5997 this->pszMainIcon = MAKEINTRESOURCEW(nID);
5998 }
5999
6000 void SetMainIcon(LPCWSTR lpstrMainIcon)
6001 {
6002 this->dwFlags &= ~TDF_USE_HICON_MAIN;
6003 this->pszMainIcon = lpstrMainIcon;
6004 }
6005
6006 // main instruction text
6007 void SetMainInstructionText(UINT nID)
6008 {
6009 this->pszMainInstruction = MAKEINTRESOURCEW(nID);
6010 }
6011
6012 void SetMainInstructionText(LPCWSTR lpstrMainInstruction)
6013 {
6014 this->pszMainInstruction = lpstrMainInstruction;
6015 }
6016
6017 // content text
6018 void SetContentText(UINT nID)
6019 {
6020 this->pszContent = MAKEINTRESOURCEW(nID);
6021 }
6022
6023 void SetContentText(LPCWSTR lpstrContent)
6024 {
6025 this->pszContent = lpstrContent;
6026 }
6027
6028 // buttons
6029 void SetButtons(const TASKDIALOG_BUTTON* pButtonsArg, UINT cButtonsArg, int nDefaultButtonArg = 0)
6030 {
6031 this->pButtons = pButtonsArg;
6032 this->cButtons = cButtonsArg;
6033 if(nDefaultButtonArg != 0)
6034 this->nDefaultButton = nDefaultButtonArg;
6035 }
6036
6037 void SetDefaultButton(int nDefaultButtonArg)
6038 {
6039 this->nDefaultButton = nDefaultButtonArg;
6040 }
6041
6042 // radio buttons
6043 void SetRadioButtons(const TASKDIALOG_BUTTON* pRadioButtonsArg, UINT cRadioButtonsArg, int nDefaultRadioButtonArg = 0)
6044 {
6045 this->pRadioButtons = pRadioButtonsArg;
6046 this->cRadioButtons = cRadioButtonsArg;
6047 if(nDefaultRadioButtonArg != 0)
6048 this->nDefaultRadioButton = nDefaultRadioButtonArg;
6049 }
6050
6051 void SetDefaultRadioButton(int nDefaultRadioButtonArg)
6052 {
6053 this->nDefaultRadioButton = nDefaultRadioButtonArg;
6054 }
6055
6056 // verification text
6057 void SetVerificationText(UINT nID)
6058 {
6059 this->pszVerificationText = MAKEINTRESOURCEW(nID);
6060 }
6061
6062 void SetVerificationText(LPCWSTR lpstrVerificationText)
6063 {
6064 this->pszVerificationText = lpstrVerificationText;
6065 }
6066
6067 // expanded information text
6068 void SetExpandedInformationText(UINT nID)
6069 {
6070 this->pszExpandedInformation = MAKEINTRESOURCEW(nID);
6071 }
6072
6073 void SetExpandedInformationText(LPCWSTR lpstrExpandedInformation)
6074 {
6075 this->pszExpandedInformation = lpstrExpandedInformation;
6076 }
6077
6078 // expanded control text
6079 void SetExpandedControlText(UINT nID)
6080 {
6081 this->pszExpandedControlText = MAKEINTRESOURCEW(nID);
6082 }
6083
6084 void SetExpandedControlText(LPCWSTR lpstrExpandedControlText)
6085 {
6086 this->pszExpandedControlText = lpstrExpandedControlText;
6087 }
6088
6089 // collapsed control text
6090 void SetCollapsedControlText(UINT nID)
6091 {
6092 this->pszCollapsedControlText = MAKEINTRESOURCEW(nID);
6093 }
6094
6095 void SetCollapsedControlText(LPCWSTR lpstrCollapsedControlText)
6096 {
6097 this->pszCollapsedControlText = lpstrCollapsedControlText;
6098 }
6099
6100 // footer icon
6101 void SetFooterIcon(HICON hIcon)
6102 {
6103 this->dwFlags |= TDF_USE_HICON_FOOTER;
6104 this->hFooterIcon = hIcon;
6105 }
6106
6107 void SetFooterIcon(UINT nID)
6108 {
6109 this->dwFlags &= ~TDF_USE_HICON_FOOTER;
6110 this->pszFooterIcon = MAKEINTRESOURCEW(nID);
6111 }
6112
6113 void SetFooterIcon(LPCWSTR lpstrFooterIcon)
6114 {
6115 this->dwFlags &= ~TDF_USE_HICON_FOOTER;
6116 this->pszFooterIcon = lpstrFooterIcon;
6117 }
6118
6119 // footer text
6120 void SetFooterText(UINT nID)
6121 {
6122 this->pszFooter = MAKEINTRESOURCEW(nID);
6123 }
6124
6125 void SetFooterText(LPCWSTR lpstrFooterText)
6126 {
6127 this->pszFooter = lpstrFooterText;
6128 }
6129
6130 // width (in DLUs)
6131 void SetWidth(UINT cxWidthArg)
6132 {
6133 this->cxWidth = cxWidthArg;
6134 }
6135
6136 // modify flags
6137 void ModifyFlags(DWORD dwRemove, DWORD dwAdd)
6138 {
6139 this->dwFlags = (this->dwFlags & ~dwRemove) | dwAdd;
6140 }
6141 };
6142
6143
6144 ///////////////////////////////////////////////////////////////////////////////
6145 // CTaskDialogImpl - implements a Task Dialog
6146
6147 template <class T>
6148 class ATL_NO_VTABLE CTaskDialogImpl
6149 {
6150 public:
6151 CTaskDialogConfig m_tdc;
6152 HWND m_hWnd; // used only in callback functions
6153
6154 // Constructor
6155 CTaskDialogImpl(HWND hWndParent = NULL) : m_hWnd(NULL)
6156 {
6157 m_tdc.hwndParent = hWndParent;
6158 m_tdc.pfCallback = T::TaskDialogCallback;
6159 m_tdc.lpCallbackData = (LONG_PTR)static_cast<T*>(this);
6160 }
6161
6162 // Operations
6163 HRESULT DoModal(HWND hWndParent = ::GetActiveWindow(), int* pnButton = NULL, int* pnRadioButton = NULL, BOOL* pfVerificationFlagChecked = NULL)
6164 {
6165 if(m_tdc.hwndParent == NULL)
6166 m_tdc.hwndParent = hWndParent;
6167
6168 #ifdef _WTL_TASKDIALOG_DIRECT
6169 return ::TaskDialogIndirect(&m_tdc, pnButton, pnRadioButton, pfVerificationFlagChecked);
6170 #else
6171
6172 // This allows apps to run on older versions of Windows
6173 typedef HRESULT (STDAPICALLTYPE *PFN_TaskDialogIndirect)(const TASKDIALOGCONFIG* pTaskConfig, int* pnButton, int* pnRadioButton, BOOL* pfVerificationFlagChecked);
6174
6175 HRESULT hRet = E_UNEXPECTED;
6176 HMODULE m_hCommCtrlDLL = ::LoadLibrary(_T("comctl32.dll"));
6177 if(m_hCommCtrlDLL != NULL)
6178 {
6179 PFN_TaskDialogIndirect pfnTaskDialogIndirect = (PFN_TaskDialogIndirect)::GetProcAddress(m_hCommCtrlDLL, "TaskDialogIndirect");
6180 if(pfnTaskDialogIndirect != NULL)
6181 hRet = pfnTaskDialogIndirect(&m_tdc, pnButton, pnRadioButton, pfVerificationFlagChecked);
6182
6183 ::FreeLibrary(m_hCommCtrlDLL);
6184 }
6185
6186 return hRet;
6187 #endif
6188 }
6189
6190 // Operations - setting values of TASKDIALOGCONFIG
6191 // common buttons
6192 void SetCommonButtons(TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons)
6193 { m_tdc.SetCommonButtons(dwCommonButtons); }
6194 // window title text
6195 void SetWindowTitle(UINT nID)
6196 { m_tdc.SetWindowTitle(nID); }
6197 void SetWindowTitle(LPCWSTR lpstrWindowTitle)
6198 { m_tdc.SetWindowTitle(lpstrWindowTitle); }
6199 // main icon
6200 void SetMainIcon(HICON hIcon)
6201 { m_tdc.SetMainIcon(hIcon); }
6202 void SetMainIcon(UINT nID)
6203 { m_tdc.SetMainIcon(nID); }
6204 void SetMainIcon(LPCWSTR lpstrMainIcon)
6205 { m_tdc.SetMainIcon(lpstrMainIcon); }
6206 // main instruction text
6207 void SetMainInstructionText(UINT nID)
6208 { m_tdc.SetMainInstructionText(nID); }
6209 void SetMainInstructionText(LPCWSTR lpstrMainInstruction)
6210 { m_tdc.SetMainInstructionText(lpstrMainInstruction); }
6211 // content text
6212 void SetContentText(UINT nID)
6213 { m_tdc.SetContentText(nID); }
6214 void SetContentText(LPCWSTR lpstrContent)
6215 { m_tdc.SetContentText(lpstrContent); }
6216 // buttons
6217 void SetButtons(const TASKDIALOG_BUTTON* pButtons, UINT cButtons, int nDefaultButton = 0)
6218 { m_tdc.SetButtons(pButtons, cButtons, nDefaultButton); }
6219 void SetDefaultButton(int nDefaultButton)
6220 { m_tdc.SetDefaultButton(nDefaultButton); }
6221 // radio buttons
6222 void SetRadioButtons(const TASKDIALOG_BUTTON* pRadioButtons, UINT cRadioButtons, int nDefaultRadioButton = 0)
6223 { m_tdc.SetRadioButtons(pRadioButtons, cRadioButtons, nDefaultRadioButton); }
6224 void SetDefaultRadioButton(int nDefaultRadioButton)
6225 { m_tdc.SetDefaultRadioButton(nDefaultRadioButton); }
6226 // verification text
6227 void SetVerificationText(UINT nID)
6228 { m_tdc.SetVerificationText(nID); }
6229 void SetVerificationText(LPCWSTR lpstrVerificationText)
6230 { m_tdc.SetVerificationText(lpstrVerificationText); }
6231 // expanded information text
6232 void SetExpandedInformationText(UINT nID)
6233 { m_tdc.SetExpandedInformationText(nID); }
6234 void SetExpandedInformationText(LPCWSTR lpstrExpandedInformation)
6235 { m_tdc.SetExpandedInformationText(lpstrExpandedInformation); }
6236 // expanded control text
6237 void SetExpandedControlText(UINT nID)
6238 { m_tdc.SetExpandedControlText(nID); }
6239 void SetExpandedControlText(LPCWSTR lpstrExpandedControlText)
6240 { m_tdc.SetExpandedControlText(lpstrExpandedControlText); }
6241 // collapsed control text
6242 void SetCollapsedControlText(UINT nID)
6243 { m_tdc.SetCollapsedControlText(nID); }
6244 void SetCollapsedControlText(LPCWSTR lpstrCollapsedControlText)
6245 { m_tdc.SetCollapsedControlText(lpstrCollapsedControlText); }
6246 // footer icon
6247 void SetFooterIcon(HICON hIcon)
6248 { m_tdc.SetFooterIcon(hIcon); }
6249 void SetFooterIcon(UINT nID)
6250 { m_tdc.SetFooterIcon(nID); }
6251 void SetFooterIcon(LPCWSTR lpstrFooterIcon)
6252 { m_tdc.SetFooterIcon(lpstrFooterIcon); }
6253 // footer text
6254 void SetFooterText(UINT nID)
6255 { m_tdc.SetFooterText(nID); }
6256 void SetFooterText(LPCWSTR lpstrFooterText)
6257 { m_tdc.SetFooterText(lpstrFooterText); }
6258 // width (in DLUs)
6259 void SetWidth(UINT cxWidth)
6260 { m_tdc.SetWidth(cxWidth); }
6261 // modify flags
6262 void ModifyFlags(DWORD dwRemove, DWORD dwAdd)
6263 { m_tdc.ModifyFlags(dwRemove, dwAdd); }
6264
6265 // Implementation
6266 static HRESULT CALLBACK TaskDialogCallback(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData)
6267 {
6268 T* pT = (T*)lpRefData;
6269 ATLASSERT(pT->m_hWnd == NULL || pT->m_hWnd == hWnd);
6270
6271 BOOL bRet = FALSE;
6272 switch(uMsg)
6273 {
6274 case TDN_DIALOG_CONSTRUCTED:
6275 pT->m_hWnd = hWnd;
6276 pT->OnDialogConstructed();
6277 break;
6278 case TDN_CREATED:
6279 pT->OnCreated();
6280 break;
6281 case TDN_BUTTON_CLICKED:
6282 bRet = pT->OnButtonClicked((int)wParam);
6283 break;
6284 case TDN_RADIO_BUTTON_CLICKED:
6285 pT->OnRadioButtonClicked((int)wParam);
6286 break;
6287 case TDN_HYPERLINK_CLICKED:
6288 pT->OnHyperlinkClicked((LPCWSTR)lParam);
6289 break;
6290 case TDN_EXPANDO_BUTTON_CLICKED:
6291 pT->OnExpandoButtonClicked((wParam != 0));
6292 break;
6293 case TDN_VERIFICATION_CLICKED:
6294 pT->OnVerificationClicked((wParam != 0));
6295 break;
6296 case TDN_HELP:
6297 pT->OnHelp();
6298 break;
6299 case TDN_TIMER:
6300 bRet = pT->OnTimer((DWORD)wParam);
6301 break;
6302 case TDN_NAVIGATED:
6303 pT->OnNavigated();
6304 break;
6305 case TDN_DESTROYED:
6306 pT->OnDestroyed();
6307 pT->m_hWnd = NULL;
6308 break;
6309 default:
6310 ATLTRACE2(atlTraceUI, 0, _T("Unknown notification received in CTaskDialogImpl::TaskDialogCallback\n"));
6311 break;
6312 }
6313
6314 return (bRet != FALSE) ? S_OK : S_FALSE;
6315 }
6316
6317 // Overrideables - notification handlers
6318 void OnDialogConstructed()
6319 {
6320 }
6321
6322 void OnCreated()
6323 {
6324 }
6325
6326 BOOL OnButtonClicked(int /*nButton*/)
6327 {
6328 return FALSE; // don't prevent dialog to close
6329 }
6330
6331 void OnRadioButtonClicked(int /*nRadioButton*/)
6332 {
6333 }
6334
6335 void OnHyperlinkClicked(LPCWSTR /*pszHREF*/)
6336 {
6337 }
6338
6339 void OnExpandoButtonClicked(bool /*bExpanded*/)
6340 {
6341 }
6342
6343 void OnVerificationClicked(bool /*bChecked*/)
6344 {
6345 }
6346
6347 void OnHelp()
6348 {
6349 }
6350
6351 BOOL OnTimer(DWORD /*dwTickCount*/)
6352 {
6353 return FALSE; // don't reset counter
6354 }
6355
6356 void OnNavigated()
6357 {
6358 }
6359
6360 void OnDestroyed()
6361 {
6362 }
6363
6364 // Commands - valid to call only from handlers
6365 void NavigatePage(TASKDIALOGCONFIG& tdc)
6366 {
6367 ATLASSERT(m_hWnd != NULL);
6368
6369 tdc.cbSize = sizeof(TASKDIALOGCONFIG);
6370 if(tdc.hwndParent == NULL)
6371 tdc.hwndParent = m_tdc.hwndParent;
6372 tdc.pfCallback = m_tdc.pfCallback;
6373 tdc.lpCallbackData = m_tdc.lpCallbackData;
6374 (TASKDIALOGCONFIG)m_tdc = tdc;
6375
6376 ::SendMessage(m_hWnd, TDM_NAVIGATE_PAGE, 0, (LPARAM)&tdc);
6377 }
6378
6379 // modify TASKDIALOGCONFIG values, then call this to update task dialog
6380 void NavigatePage()
6381 {
6382 ATLASSERT(m_hWnd != NULL);
6383 ::SendMessage(m_hWnd, TDM_NAVIGATE_PAGE, 0, (LPARAM)&m_tdc);
6384 }
6385
6386 void ClickButton(int nButton)
6387 {
6388 ATLASSERT(m_hWnd != NULL);
6389 ::SendMessage(m_hWnd, TDM_CLICK_BUTTON, nButton, 0L);
6390 }
6391
6392 void SetMarqueeProgressBar(BOOL bMarquee)
6393 {
6394 ATLASSERT(m_hWnd != NULL);
6395 ::SendMessage(m_hWnd, TDM_SET_MARQUEE_PROGRESS_BAR, bMarquee, 0L);
6396 }
6397
6398 BOOL SetProgressBarState(int nNewState)
6399 {
6400 ATLASSERT(m_hWnd != NULL);
6401 return (BOOL)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_STATE, nNewState, 0L);
6402 }
6403
6404 DWORD SetProgressBarRange(int nMinRange, int nMaxRange)
6405 {
6406 ATLASSERT(m_hWnd != NULL);
6407 return (DWORD)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_RANGE, 0, MAKELPARAM(nMinRange, nMaxRange));
6408 }
6409
6410 int SetProgressBarPos(int nNewPos)
6411 {
6412 ATLASSERT(m_hWnd != NULL);
6413 return (int)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_POS, nNewPos, 0L);
6414 }
6415
6416 BOOL SetProgressBarMarquee(BOOL bMarquee, UINT uSpeed)
6417 {
6418 ATLASSERT(m_hWnd != NULL);
6419 return (BOOL)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_MARQUEE, bMarquee, uSpeed);
6420 }
6421
6422 void SetElementText(TASKDIALOG_ELEMENTS element, LPCWSTR lpstrText)
6423 {
6424 ATLASSERT(m_hWnd != NULL);
6425 ::SendMessage(m_hWnd, TDM_SET_ELEMENT_TEXT, element, (LPARAM)lpstrText);
6426 }
6427
6428 void ClickRadioButton(int nRadioButton)
6429 {
6430 ATLASSERT(m_hWnd != NULL);
6431 ::SendMessage(m_hWnd, TDM_CLICK_RADIO_BUTTON, nRadioButton, 0L);
6432 }
6433
6434 void EnableButton(int nButton, BOOL bEnable)
6435 {
6436 ATLASSERT(m_hWnd != NULL);
6437 ::SendMessage(m_hWnd, TDM_ENABLE_BUTTON, nButton, bEnable);
6438 }
6439
6440 void EnableRadioButton(int nButton, BOOL bEnable)
6441 {
6442 ATLASSERT(m_hWnd != NULL);
6443 ::SendMessage(m_hWnd, TDM_ENABLE_RADIO_BUTTON, nButton, bEnable);
6444 }
6445
6446 void ClickVerification(BOOL bCheck, BOOL bFocus)
6447 {
6448 ATLASSERT(m_hWnd != NULL);
6449 ::SendMessage(m_hWnd, TDM_CLICK_VERIFICATION, bCheck, bFocus);
6450 }
6451
6452 void UpdateElementText(TASKDIALOG_ELEMENTS element, LPCWSTR lpstrText)
6453 {
6454 ATLASSERT(m_hWnd != NULL);
6455 ::SendMessage(m_hWnd, TDM_UPDATE_ELEMENT_TEXT, element, (LPARAM)lpstrText);
6456 }
6457
6458 void SetButtonElevationRequiredState(int nButton, BOOL bElevation)
6459 {
6460 ATLASSERT(m_hWnd != NULL);
6461 ::SendMessage(m_hWnd, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, nButton, bElevation);
6462 }
6463
6464 void UpdateIcon(TASKDIALOG_ICON_ELEMENTS element, HICON hIcon)
6465 {
6466 ATLASSERT(m_hWnd != NULL);
6467 #ifdef _DEBUG
6468 if(element == TDIE_ICON_MAIN)
6469 ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_MAIN) != 0);
6470 else if(element == TDIE_ICON_FOOTER)
6471 ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_FOOTER) != 0);
6472 #endif // _DEBUG
6473 ::SendMessage(m_hWnd, TDM_UPDATE_ICON, element, (LPARAM)hIcon);
6474 }
6475
6476 void UpdateIcon(TASKDIALOG_ICON_ELEMENTS element, LPCWSTR lpstrIcon)
6477 {
6478 ATLASSERT(m_hWnd != NULL);
6479 #ifdef _DEBUG
6480 if(element == TDIE_ICON_MAIN)
6481 ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_MAIN) == 0);
6482 else if(element == TDIE_ICON_FOOTER)
6483 ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_FOOTER) == 0);
6484 #endif // _DEBUG
6485 ::SendMessage(m_hWnd, TDM_UPDATE_ICON, element, (LPARAM)lpstrIcon);
6486 }
6487 };
6488
6489
6490 ///////////////////////////////////////////////////////////////////////////////
6491 // CTaskDialog - for non-customized task dialogs
6492
6493 class CTaskDialog : public CTaskDialogImpl<CTaskDialog>
6494 {
6495 public:
6496 CTaskDialog(HWND hWndParent = NULL) : CTaskDialogImpl<CTaskDialog>(hWndParent)
6497 {
6498 m_tdc.pfCallback = NULL;
6499 }
6500 };
6501
6502 #endif // ((_WIN32_WINNT >= 0x0600) || defined(_WTL_TASKDIALOG)) && !defined(_WIN32_WCE)
6503
6504 }; // namespace WTL
6505
6506 #endif // __ATLDLGS_H__
+0
-505
src/third_party/wtl/Include/atldwm.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLDWM_H__
9 #define __ATLDWM_H__
10
11 #pragma once
12
13 #ifdef _WIN32_WCE
14 #error atldwm.h is not supported on Windows CE
15 #endif
16
17 #ifndef __ATLAPP_H__
18 #error atldwm.h requires atlapp.h to be included first
19 #endif
20
21 #ifndef __ATLWIN_H__
22 #error atldwm.h requires atlwin.h to be included first
23 #endif
24
25 #if (_WIN32_WINNT < 0x0600)
26 #error atldwm.h requires _WIN32_WINNT >= 0x0600
27 #endif
28
29 #ifndef _DWMAPI_H_
30 #include <dwmapi.h>
31 #endif
32 #pragma comment(lib, "dwmapi.lib")
33
34 // Note: To create an application that also runs on older versions of Windows,
35 // use delay load of dwmapi.dll and ensure that no calls to the DWM API are
36 // Delay load is NOT AUTOMATIC for VC++ 7, you have to link to delayimp.lib,
37 // and add dwmapi.dll in the Linker.Input.Delay Loaded DLLs section of the
38 // project properties.
39 #if (_MSC_VER < 1300) && !defined(_WTL_NO_DWMAPI_DELAYLOAD)
40 #pragma comment(lib, "delayimp.lib")
41 #pragma comment(linker, "/delayload:dwmapi.dll")
42 #endif // (_MSC_VER < 1300) && !defined(_WTL_NO_DWMAPI_DELAYLOAD)
43
44 ///////////////////////////////////////////////////////////////////////////////
45 // Classes in this file:
46 //
47 // CDwm
48 // CDwmImpl<T, TBase>
49 // CDwmWindowT<TBase> - CDwmWindow
50 // CDwmThumbnailT<t_bManaged, TBase>
51 // CDwmThumbnail
52 // CDwmThumbnailHandle
53 // CAeroControlImpl
54
55
56 namespace WTL
57 {
58
59 ///////////////////////////////////////////////////////////////////////////////
60 // CDwm - wrapper for DWM handle
61
62 class CDwm
63 {
64 public:
65 // Data members
66 static int m_nIsDwmSupported;
67
68 // Constructor
69 CDwm()
70 {
71 IsDwmSupported();
72 }
73
74 // Dwm support helper
75 static bool IsDwmSupported()
76 {
77 if(m_nIsDwmSupported == -1)
78 {
79 CStaticDataInitCriticalSectionLock lock;
80 if(FAILED(lock.Lock()))
81 {
82 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CDwm::IsDwmSupported.\n"));
83 ATLASSERT(FALSE);
84 return false;
85 }
86
87 if(m_nIsDwmSupported == -1)
88 {
89 HMODULE hDwmDLL = ::LoadLibrary(_T("dwmapi.dll"));
90 m_nIsDwmSupported = (hDwmDLL != NULL) ? 1 : 0;
91 if(hDwmDLL != NULL)
92 ::FreeLibrary(hDwmDLL);
93 }
94
95 lock.Unlock();
96 }
97
98 ATLASSERT(m_nIsDwmSupported != -1);
99 return (m_nIsDwmSupported == 1);
100 }
101
102 // Operations
103 BOOL DwmIsCompositionEnabled() const
104 {
105 if(!IsDwmSupported())
106 return FALSE;
107
108 BOOL bRes = FALSE;
109 return (SUCCEEDED(::DwmIsCompositionEnabled(&bRes)) && bRes) ? TRUE : FALSE;
110 }
111
112 BOOL DwmEnableComposition(UINT fEnable)
113 {
114 if(!IsDwmSupported())
115 return FALSE;
116
117 return SUCCEEDED(::DwmEnableComposition(fEnable)) ? TRUE : FALSE;
118 }
119
120 BOOL DwmEnableMMCSS(BOOL fEnableMMCSS)
121 {
122 if(!IsDwmSupported())
123 return FALSE;
124
125 return SUCCEEDED(::DwmEnableMMCSS(fEnableMMCSS)) ? TRUE : FALSE;
126 }
127
128 HRESULT DwmGetColorizationColor(DWORD* pcrColorization, BOOL* pfOpaqueBlend)
129 {
130 if(!IsDwmSupported())
131 return E_NOTIMPL;
132
133 return ::DwmGetColorizationColor(pcrColorization, pfOpaqueBlend);
134 }
135
136 HRESULT DwmFlush()
137 {
138 if(!IsDwmSupported())
139 return E_NOTIMPL;
140
141 return ::DwmFlush();
142 }
143 };
144
145 __declspec(selectany) int CDwm::m_nIsDwmSupported = -1;
146
147
148 ///////////////////////////////////////////////////////////////////////////////
149 // CDwmImpl - DWM window support
150
151 template <class T, class TBase = CDwm>
152 class CDwmImpl : public TBase
153 {
154 public:
155 HRESULT DwmEnableBlurBehindWindow(const DWM_BLURBEHIND* pBB)
156 {
157 if(!IsDwmSupported())
158 return E_NOTIMPL;
159
160 T* pT = static_cast<T*>(this);
161 ATLASSERT(::IsWindow(pT->m_hWnd));
162 return ::DwmEnableBlurBehindWindow(pT->m_hWnd, pBB);
163 }
164
165 HRESULT DwmExtendFrameIntoClientArea(const MARGINS* pMargins)
166 {
167 if(!IsDwmSupported())
168 return E_NOTIMPL;
169
170 T* pT = static_cast<T*>(this);
171 ATLASSERT(::IsWindow(pT->m_hWnd));
172 return ::DwmExtendFrameIntoClientArea(pT->m_hWnd, pMargins);
173 }
174
175 HRESULT DwmExtendFrameIntoEntireClientArea()
176 {
177 MARGINS margins = { -1 };
178 return DwmExtendFrameIntoClientArea(&margins);
179 }
180
181 HRESULT DwmGetCompositionTimingInfo(DWM_TIMING_INFO* pTimingInfo)
182 {
183 if(!IsDwmSupported())
184 return E_NOTIMPL;
185
186 T* pT = static_cast<T*>(this);
187 ATLASSERT(::IsWindow(pT->m_hWnd));
188 return ::DwmGetCompositionTimingInfo(pT->m_hWnd, pTimingInfo);
189 }
190
191 HRESULT DwmGetWindowAttribute(DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute)
192 {
193 if(!IsDwmSupported())
194 return E_NOTIMPL;
195
196 T* pT = static_cast<T*>(this);
197 ATLASSERT(::IsWindow(pT->m_hWnd));
198 return ::DwmGetWindowAttribute(pT->m_hWnd, dwAttribute, pvAttribute, cbAttribute);
199 }
200
201 HRESULT DwmModifyPreviousDxFrameDuration(INT cRefreshes, BOOL fRelative)
202 {
203 if(!IsDwmSupported())
204 return E_NOTIMPL;
205
206 T* pT = static_cast<T*>(this);
207 ATLASSERT(::IsWindow(pT->m_hWnd));
208 return ::DwmModifyPreviousDxFrameDuration(pT->m_hWnd, cRefreshes, fRelative);
209 }
210
211 HRESULT DwmSetDxFrameDuration(INT cRefreshes)
212 {
213 if(!IsDwmSupported())
214 return E_NOTIMPL;
215
216 T* pT = static_cast<T*>(this);
217 ATLASSERT(::IsWindow(pT->m_hWnd));
218 return ::DwmSetDxFrameDuration(pT->m_hWnd, cRefreshes);
219 }
220
221 HRESULT DwmSetPresentParameters(DWM_PRESENT_PARAMETERS* pPresentParams)
222 {
223 if(!IsDwmSupported())
224 return E_NOTIMPL;
225
226 T* pT = static_cast<T*>(this);
227 ATLASSERT(::IsWindow(pT->m_hWnd));
228 return ::DwmSetPresentParameters(pT->m_hWnd, pPresentParams);
229 }
230
231 HRESULT DwmSetWindowAttribute(DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute)
232 {
233 if(!IsDwmSupported())
234 return E_NOTIMPL;
235
236 T* pT = static_cast<T*>(this);
237 ATLASSERT(::IsWindow(pT->m_hWnd));
238 return ::DwmSetWindowAttribute(pT->m_hWnd, dwAttribute, pvAttribute, cbAttribute);
239 }
240
241 HRESULT DwmAttachMilContent()
242 {
243 if(!IsDwmSupported())
244 return E_NOTIMPL;
245
246 T* pT = static_cast<T*>(this);
247 ATLASSERT(::IsWindow(pT->m_hWnd));
248 return ::DwmAttachMilContent(pT->m_hWnd);
249 }
250
251 HRESULT DwmDetachMilContent()
252 {
253 if(!IsDwmSupported())
254 return E_NOTIMPL;
255
256 T* pT = static_cast<T*>(this);
257 ATLASSERT(::IsWindow(pT->m_hWnd));
258 return ::DwmDetachMilContent(pT->m_hWnd);
259 }
260 };
261
262 template <class TBase>
263 class CDwmWindowT : public TBase, public CDwmImpl<CDwmWindowT< TBase > >
264 {
265 public:
266 CDwmWindowT(HWND hWnd = NULL) : TBase(hWnd)
267 { }
268
269 CDwmWindowT< TBase >& operator =(HWND hWnd)
270 {
271 m_hWnd = hWnd;
272 return *this;
273 }
274 };
275
276 typedef CDwmWindowT<ATL::CWindow> CDwmWindow;
277
278
279 ///////////////////////////////////////////////////////////////////////////////
280 // CDwmThumbnail - provides DWM thumbnail support
281
282 template <bool t_bManaged, class TBase = CDwm>
283 class CDwmThumbnailT : public TBase
284 {
285 public:
286 // Data members
287 HTHUMBNAIL m_hThumbnail;
288
289 // Constructor
290 CDwmThumbnailT(HTHUMBNAIL hThumbnail = NULL) : m_hThumbnail(hThumbnail)
291 { }
292
293 ~CDwmThumbnailT()
294 {
295 if(t_bManaged && (m_hThumbnail != NULL))
296 Unregister();
297 }
298
299 // Operations
300 CDwmThumbnailT<t_bManaged, TBase>& operator =(HTHUMBNAIL hThumbnail)
301 {
302 Attach(hThumbnail);
303 return *this;
304 }
305
306 void Attach(HTHUMBNAIL hThumbnailNew)
307 {
308 if(t_bManaged && m_hThumbnail != NULL && m_hThumbnail != hThumbnailNew)
309 Unregister();
310 m_hThumbnail = hThumbnailNew;
311 }
312
313 HTHUMBNAIL Detach()
314 {
315 HTHUMBNAIL hThumbnail = m_hThumbnail;
316 m_hThumbnail = NULL;
317 return hThumbnail;
318 }
319
320 HRESULT Register(HWND hwndDestination, HWND hwndSource)
321 {
322 ATLASSERT(::IsWindow(hwndDestination));
323 ATLASSERT(::IsWindow(hwndSource));
324 ATLASSERT(m_hThumbnail==NULL);
325
326 if(!IsDwmSupported())
327 return E_NOTIMPL;
328
329 return ::DwmRegisterThumbnail(hwndDestination, hwndSource, &m_hThumbnail);
330 }
331
332 HRESULT Unregister()
333 {
334 if(!IsDwmSupported())
335 return E_NOTIMPL;
336 if(m_hThumbnail == NULL)
337 return S_FALSE;
338
339 HRESULT Hr = ::DwmUnregisterThumbnail(m_hThumbnail);
340 if(SUCCEEDED(Hr))
341 m_hThumbnail = NULL;
342
343 return Hr;
344 }
345
346 operator HTHUMBNAIL() const { return m_hThumbnail; }
347
348 bool IsNull() const { return (m_hThumbnail == NULL); }
349
350 HRESULT UpdateProperties(const DWM_THUMBNAIL_PROPERTIES* ptnProperties)
351 {
352 if(!IsDwmSupported())
353 return E_NOTIMPL;
354
355 ATLASSERT(m_hThumbnail != NULL);
356 return ::DwmUpdateThumbnailProperties(m_hThumbnail, ptnProperties);
357 }
358
359 // Attributes
360 HRESULT QuerySourceSize(PSIZE pSize)
361 {
362 if(!IsDwmSupported())
363 return E_NOTIMPL;
364
365 ATLASSERT(m_hThumbnail != NULL);
366 return ::DwmQueryThumbnailSourceSize(m_hThumbnail, pSize);
367 }
368 };
369
370 typedef CDwmThumbnailT<true, CDwm> CDwmThumbnail;
371 typedef CDwmThumbnailT<false, CDwm> CDwmThumbnailHandle;
372
373
374 #ifdef __ATLTHEME_H__
375
376 ///////////////////////////////////////////////////////////////////////////////
377 // CAeroControlImpl - Base class for controls on Glass
378
379 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
380 class CAeroControlImpl : public CThemeImpl<T>,
381 public CBufferedPaintImpl<T>,
382 public ATL::CWindowImpl<T, TBase, TWinTraits>
383 {
384 public:
385 typedef CThemeImpl<T> _themeClass;
386 typedef CBufferedPaintImpl<T> _baseClass;
387 typedef ATL::CWindowImpl<T, TBase, TWinTraits> _windowClass;
388
389 CAeroControlImpl()
390 {
391 m_PaintParams.dwFlags = BPPF_ERASE;
392 }
393
394 static LPCWSTR GetThemeName()
395 {
396 #ifdef _UNICODE
397 return TBase::GetWndClassName();
398 #else
399 ATLASSERT(!_T("Return UNICODE string of window classname / theme class"));
400 return NULL;
401 #endif // _UNICODE
402 }
403
404 // Message map and handlers
405 BEGIN_MSG_MAP(CAeroControlImpl)
406 MESSAGE_HANDLER(WM_CREATE, OnCreate)
407 MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
408 CHAIN_MSG_MAP(_themeClass)
409 CHAIN_MSG_MAP(_baseClass)
410 END_MSG_MAP()
411
412 LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
413 {
414 T* pT = static_cast<T*>(this);
415 pT->Init();
416
417 bHandled = FALSE;
418 return 0;
419 }
420
421 LRESULT OnActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
422 {
423 if(IsThemingSupported())
424 Invalidate(FALSE);
425
426 bHandled = FALSE;
427 return 0;
428 }
429
430 // Operations
431 BOOL SubclassWindow(HWND hWnd)
432 {
433 ATLASSERT(m_hWnd == NULL);
434 ATLASSERT(::IsWindow(hWnd));
435 BOOL bRet = _windowClass::SubclassWindow(hWnd);
436 if(bRet)
437 {
438 T* pT = static_cast<T*>(this);
439 pT->Init();
440 }
441
442 return bRet;
443 }
444
445 // Implementation
446 LRESULT DefWindowProc()
447 {
448 const ATL::_ATL_MSG* pMsg = m_pCurrentMsg;
449 LRESULT lRes = 0;
450 if(pMsg != NULL)
451 lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg->lParam);
452
453 return lRes;
454 }
455
456 LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
457 {
458 T* pT = static_cast<T*>(this);
459 LRESULT lRes = 0;
460 if(::DwmDefWindowProc(pT->m_hWnd, uMsg, wParam, lParam, &lRes) != FALSE)
461 return lRes;
462
463 return _windowClass::DefWindowProc(uMsg, wParam, lParam);
464 }
465
466 void DoBufferedPaint(HDC hDC, RECT& rcPaint)
467 {
468 T* pT = static_cast<T*>(this);
469 HDC hDCPaint = NULL;
470 RECT rcClient = { 0 };
471 GetClientRect(&rcClient);
472 m_BufferedPaint.Begin(hDC, &rcClient, m_dwFormat, &m_PaintParams, &hDCPaint);
473 ATLASSERT(hDCPaint != NULL);
474 pT->DoAeroPaint(hDCPaint, rcClient, rcPaint);
475 m_BufferedPaint.End();
476 }
477
478 void DoPaint(HDC /*hdc*/, RECT& /*rcClient*/)
479 {
480 DefWindowProc();
481 }
482
483 // Overridables
484 void Init()
485 {
486 T* pT = static_cast<T*>(this);
487 pT; // avoid level 4 warning
488 SetThemeClassList(pT->GetThemeName());
489 if(m_lpstrThemeClassList != NULL)
490 OpenThemeData();
491 }
492
493 void DoAeroPaint(HDC hDC, RECT& /*rcClient*/, RECT& rcPaint)
494 {
495 DefWindowProc(WM_PAINT, (WPARAM) hDC, 0L);
496 m_BufferedPaint.MakeOpaque(&rcPaint);
497 }
498 };
499
500 #endif // __ATLTHEME_H__
501
502 }; // namespace WTL
503
504 #endif // __ATLDWM_H__
+0
-1012
src/third_party/wtl/Include/atlfind.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLFIND_H__
9 #define __ATLFIND_H__
10
11 #pragma once
12
13 #ifdef _WIN32_WCE
14 #error atlfind.h is not supported on Windows CE
15 #endif
16
17 #ifndef __ATLCTRLS_H__
18 #error atlfind.h requires atlctrls.h to be included first
19 #endif
20
21 #ifndef __ATLDLGS_H__
22 #error atlfind.h requires atldlgs.h to be included first
23 #endif
24
25 #if !((defined(__ATLMISC_H__) && defined(_WTL_USE_CSTRING)) || defined(__ATLSTR_H__))
26 #error atlfind.h requires CString (either from ATL's atlstr.h or WTL's atlmisc.h with _WTL_USE_CSTRING)
27 #endif
28
29
30 ///////////////////////////////////////////////////////////////////////////////
31 // Classes in this file:
32 //
33 // CEditFindReplaceImplBase<T, TFindReplaceDialog>
34 // CEditFindReplaceImpl<T, TFindReplaceDialog>
35 // CRichEditFindReplaceImpl<T, TFindReplaceDialog>
36
37
38 namespace WTL
39 {
40
41 ///////////////////////////////////////////////////////////////////////////////
42 // CEditFindReplaceImplBase - Base class for mixin classes that
43 // help implement Find/Replace for CEdit or CRichEditCtrl based window classes.
44
45 template <class T, class TFindReplaceDialog = CFindReplaceDialog>
46 class CEditFindReplaceImplBase
47 {
48 protected:
49 // Typedefs
50 typedef CEditFindReplaceImplBase<T, TFindReplaceDialog> thisClass;
51
52 // Data members
53 TFindReplaceDialog* m_pFindReplaceDialog;
54 _CSTRING_NS::CString m_sFindNext, m_sReplaceWith;
55 BOOL m_bFindOnly, m_bFirstSearch, m_bMatchCase, m_bWholeWord, m_bFindDown;
56 LONG m_nInitialSearchPos;
57 HCURSOR m_hOldCursor;
58
59 // Enumerations
60 enum TranslationTextItem
61 {
62 eText_OnReplaceAllMessage = 0,
63 eText_OnReplaceAllTitle = 1,
64 eText_OnTextNotFoundMessage = 2,
65 eText_OnTextNotFoundTitle = 3
66 };
67
68 public:
69 // Constructors
70 CEditFindReplaceImplBase() :
71 m_pFindReplaceDialog(NULL),
72 m_bFindOnly(TRUE),
73 m_bFirstSearch(TRUE),
74 m_bMatchCase(FALSE),
75 m_bWholeWord(FALSE),
76 m_bFindDown(TRUE),
77 m_nInitialSearchPos(0),
78 m_hOldCursor(NULL)
79 {
80 }
81
82 // Message Handlers
83 BEGIN_MSG_MAP(thisClass)
84 ALT_MSG_MAP(1)
85 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
86 MESSAGE_HANDLER(TFindReplaceDialog::GetFindReplaceMsg(), OnFindReplaceCmd)
87 COMMAND_ID_HANDLER(ID_EDIT_FIND, OnEditFind)
88 COMMAND_ID_HANDLER(ID_EDIT_REPEAT, OnEditRepeat)
89 COMMAND_ID_HANDLER(ID_EDIT_REPLACE, OnEditReplace)
90 END_MSG_MAP()
91
92 LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
93 {
94 if(m_pFindReplaceDialog != NULL)
95 {
96 m_pFindReplaceDialog->SendMessage(WM_CLOSE);
97 ATLASSERT(m_pFindReplaceDialog == NULL);
98 }
99
100 bHandled = FALSE;
101 return 0;
102 }
103
104 LRESULT OnFindReplaceCmd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
105 {
106 T* pT = static_cast<T*>(this);
107
108 TFindReplaceDialog* pDialog = TFindReplaceDialog::GetNotifier(lParam);
109 if(pDialog == NULL)
110 {
111 ATLASSERT(FALSE);
112 ::MessageBeep(MB_ICONERROR);
113 return 1;
114 }
115 ATLASSERT(pDialog == m_pFindReplaceDialog);
116
117 LPFINDREPLACE findReplace = (LPFINDREPLACE)lParam;
118 if((m_pFindReplaceDialog != NULL) && (findReplace != NULL))
119 {
120 if(pDialog->FindNext())
121 {
122 pT->OnFindNext(pDialog->GetFindString(), pDialog->SearchDown(),
123 pDialog->MatchCase(), pDialog->MatchWholeWord());
124 }
125 else if(pDialog->ReplaceCurrent())
126 {
127 pT->OnReplaceSel(pDialog->GetFindString(),
128 pDialog->SearchDown(), pDialog->MatchCase(), pDialog->MatchWholeWord(),
129 pDialog->GetReplaceString());
130 }
131 else if(pDialog->ReplaceAll())
132 {
133 pT->OnReplaceAll(pDialog->GetFindString(), pDialog->GetReplaceString(),
134 pDialog->MatchCase(), pDialog->MatchWholeWord());
135 }
136 else if(pDialog->IsTerminating())
137 {
138 // Dialog is going away (but hasn't gone away yet)
139 // OnFinalMessage will "delete this"
140 pT->OnTerminatingFindReplaceDialog(m_pFindReplaceDialog);
141 m_pFindReplaceDialog = NULL;
142 }
143 }
144
145 return 0;
146 }
147
148 LRESULT OnEditFind(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
149 {
150 T* pT = static_cast<T*>(this);
151 pT->FindReplace(TRUE);
152
153 return 0;
154 }
155
156 LRESULT OnEditRepeat(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
157 {
158 T* pT = static_cast<T*>(this);
159
160 // If the user is holding down SHIFT when hitting F3, we'll
161 // search in reverse. Otherwise, we'll search forward.
162 // (be sure to have an accelerator mapped to ID_EDIT_REPEAT
163 // for both F3 and Shift+F3)
164 m_bFindDown = !((::GetKeyState(VK_SHIFT) & 0x8000) == 0x8000);
165
166 if(m_sFindNext.IsEmpty())
167 {
168 pT->FindReplace(TRUE);
169 }
170 else
171 {
172 if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown))
173 pT->TextNotFound(m_sFindNext);
174 }
175
176 return 0;
177 }
178
179 LRESULT OnEditReplace(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& bHandled)
180 {
181 T* pT = static_cast<T*>(this);
182
183 DWORD style = pT->GetStyle();
184 if((style & ES_READONLY) != ES_READONLY)
185 {
186 pT->FindReplace(FALSE);
187 }
188 else
189 {
190 // Don't allow replace when the edit control is read only
191 bHandled = FALSE;
192 }
193
194 return 0;
195 }
196
197 // Operations (overrideable)
198 TFindReplaceDialog* CreateFindReplaceDialog(BOOL bFindOnly, // TRUE for Find, FALSE for FindReplace
199 LPCTSTR lpszFindWhat,
200 LPCTSTR lpszReplaceWith = NULL,
201 DWORD dwFlags = FR_DOWN,
202 HWND hWndParent = NULL)
203 {
204 // You can override all of this in a derived class
205
206 TFindReplaceDialog* findReplaceDialog = new TFindReplaceDialog();
207 if(findReplaceDialog == NULL)
208 {
209 ::MessageBeep(MB_ICONHAND);
210 }
211 else
212 {
213 HWND hWndFindReplace = findReplaceDialog->Create(bFindOnly,
214 lpszFindWhat, lpszReplaceWith, dwFlags, hWndParent);
215 if(hWndFindReplace == NULL)
216 {
217 delete findReplaceDialog;
218 findReplaceDialog = NULL;
219 }
220 else
221 {
222 findReplaceDialog->SetActiveWindow();
223 findReplaceDialog->ShowWindow(SW_SHOW);
224 }
225 }
226
227 return findReplaceDialog;
228 }
229
230 void AdjustDialogPosition(HWND hWndDialog)
231 {
232 ATLASSERT((hWndDialog != NULL) && ::IsWindow(hWndDialog));
233
234 T* pT = static_cast<T*>(this);
235 LONG nStartChar = 0, nEndChar = 0;
236 // Send EM_GETSEL so we can use both Edit and RichEdit
237 // (CEdit::GetSel uses int&, and CRichEditCtrlT::GetSel uses LONG&)
238 ::SendMessage(pT->m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar);
239 POINT point = pT->PosFromChar(nStartChar);
240 ::ClientToScreen(pT->GetParent(), &point);
241 CRect rect;
242 ::GetWindowRect(hWndDialog, &rect);
243 if(rect.PtInRect(point))
244 {
245 if(point.y > rect.Height())
246 {
247 rect.OffsetRect(0, point.y - rect.bottom - 20);
248 }
249 else
250 {
251 int nVertExt = GetSystemMetrics(SM_CYSCREEN);
252 if(point.y + rect.Height() < nVertExt)
253 rect.OffsetRect(0, 40 + point.y - rect.top);
254 }
255
256 ::MoveWindow(hWndDialog, rect.left, rect.top, rect.Width(), rect.Height(), TRUE);
257 }
258 }
259
260 DWORD GetFindReplaceDialogFlags(void) const
261 {
262 DWORD dwFlags = 0;
263 if(m_bFindDown)
264 dwFlags |= FR_DOWN;
265 if(m_bMatchCase)
266 dwFlags |= FR_MATCHCASE;
267 if(m_bWholeWord)
268 dwFlags |= FR_WHOLEWORD;
269
270 return dwFlags;
271 }
272
273 void FindReplace(BOOL bFindOnly)
274 {
275 T* pT = static_cast<T*>(this);
276 m_bFirstSearch = TRUE;
277 if(m_pFindReplaceDialog != NULL)
278 {
279 if(m_bFindOnly == bFindOnly)
280 {
281 m_pFindReplaceDialog->SetActiveWindow();
282 m_pFindReplaceDialog->ShowWindow(SW_SHOW);
283 return;
284 }
285 else
286 {
287 m_pFindReplaceDialog->SendMessage(WM_CLOSE);
288 ATLASSERT(m_pFindReplaceDialog == NULL);
289 }
290 }
291
292 ATLASSERT(m_pFindReplaceDialog == NULL);
293
294 _CSTRING_NS::CString findNext;
295 pT->GetSelText(findNext);
296 // if selection is empty or spans multiple lines use old find text
297 if(findNext.IsEmpty() || (findNext.FindOneOf(_T("\n\r")) != -1))
298 findNext = m_sFindNext;
299 _CSTRING_NS::CString replaceWith = m_sReplaceWith;
300 DWORD dwFlags = pT->GetFindReplaceDialogFlags();
301
302 m_pFindReplaceDialog = pT->CreateFindReplaceDialog(bFindOnly,
303 findNext, replaceWith, dwFlags, pT->operator HWND());
304 ATLASSERT(m_pFindReplaceDialog != NULL);
305 if(m_pFindReplaceDialog != NULL)
306 m_bFindOnly = bFindOnly;
307 }
308
309 BOOL SameAsSelected(LPCTSTR lpszCompare, BOOL bMatchCase, BOOL /*bWholeWord*/)
310 {
311 T* pT = static_cast<T*>(this);
312
313 // check length first
314 size_t nLen = lstrlen(lpszCompare);
315 LONG nStartChar = 0, nEndChar = 0;
316 // Send EM_GETSEL so we can use both Edit and RichEdit
317 // (CEdit::GetSel uses int&, and CRichEditCtrlT::GetSel uses LONG&)
318 ::SendMessage(pT->m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar);
319 if(nLen != (size_t)(nEndChar - nStartChar))
320 return FALSE;
321
322 // length is the same, check contents
323 _CSTRING_NS::CString selectedText;
324 pT->GetSelText(selectedText);
325
326 return (bMatchCase && selectedText.Compare(lpszCompare) == 0) ||
327 (!bMatchCase && selectedText.CompareNoCase(lpszCompare) == 0);
328 }
329
330 void TextNotFound(LPCTSTR lpszFind)
331 {
332 T* pT = static_cast<T*>(this);
333 m_bFirstSearch = TRUE;
334 pT->OnTextNotFound(lpszFind);
335 }
336
337 _CSTRING_NS::CString GetTranslationText(enum TranslationTextItem eItem) const
338 {
339 _CSTRING_NS::CString text;
340 switch(eItem)
341 {
342 case eText_OnReplaceAllMessage:
343 text = _T("Replaced %d occurances of \"%s\" with \"%s\"");
344 break;
345 case eText_OnReplaceAllTitle:
346 text = _T("Replace All");
347 break;
348 case eText_OnTextNotFoundMessage:
349 text = _T("Unable to find the text \"%s\"");
350 break;
351 case eText_OnTextNotFoundTitle:
352 text = _T("Text not found");
353 break;
354 }
355
356 return text;
357 }
358
359 // Overrideable Handlers
360 void OnFindNext(LPCTSTR lpszFind, BOOL bFindDown, BOOL bMatchCase, BOOL bWholeWord)
361 {
362 T* pT = static_cast<T*>(this);
363
364 m_sFindNext = lpszFind;
365 m_bMatchCase = bMatchCase;
366 m_bWholeWord = bWholeWord;
367 m_bFindDown = bFindDown;
368
369 if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown))
370 pT->TextNotFound(m_sFindNext);
371 else
372 pT->AdjustDialogPosition(m_pFindReplaceDialog->operator HWND());
373 }
374
375 void OnReplaceSel(LPCTSTR lpszFind, BOOL bFindDown, BOOL bMatchCase, BOOL bWholeWord, LPCTSTR lpszReplace)
376 {
377 T* pT = static_cast<T*>(this);
378
379 m_sFindNext = lpszFind;
380 m_sReplaceWith = lpszReplace;
381 m_bMatchCase = bMatchCase;
382 m_bWholeWord = bWholeWord;
383 m_bFindDown = bFindDown;
384
385 if(pT->SameAsSelected(m_sFindNext, m_bMatchCase, m_bWholeWord))
386 pT->ReplaceSel(m_sReplaceWith);
387
388 if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown))
389 pT->TextNotFound(m_sFindNext);
390 else
391 pT->AdjustDialogPosition(m_pFindReplaceDialog->operator HWND());
392 }
393
394 void OnReplaceAll(LPCTSTR lpszFind, LPCTSTR lpszReplace, BOOL bMatchCase, BOOL bWholeWord)
395 {
396 T* pT = static_cast<T*>(this);
397
398 m_sFindNext = lpszFind;
399 m_sReplaceWith = lpszReplace;
400 m_bMatchCase = bMatchCase;
401 m_bWholeWord = bWholeWord;
402 m_bFindDown = TRUE;
403
404 // no selection or different than what looking for
405 if(!pT->SameAsSelected(m_sFindNext, m_bMatchCase, m_bWholeWord))
406 {
407 if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown))
408 {
409 pT->TextNotFound(m_sFindNext);
410 return;
411 }
412 }
413
414 pT->OnReplaceAllCoreBegin();
415
416 int replaceCount=0;
417 do
418 {
419 ++replaceCount;
420 pT->ReplaceSel(m_sReplaceWith);
421 } while(pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown));
422
423 pT->OnReplaceAllCoreEnd(replaceCount);
424 }
425
426 void OnReplaceAllCoreBegin()
427 {
428 T* pT = static_cast<T*>(this);
429
430 m_hOldCursor = ::SetCursor(::LoadCursor(NULL, IDC_WAIT));
431
432 pT->HideSelection(TRUE, FALSE);
433
434 }
435
436 void OnReplaceAllCoreEnd(int replaceCount)
437 {
438 T* pT = static_cast<T*>(this);
439 pT->HideSelection(FALSE, FALSE);
440
441 ::SetCursor(m_hOldCursor);
442
443 _CSTRING_NS::CString message = pT->GetTranslationText(eText_OnReplaceAllMessage);
444 if(message.GetLength() > 0)
445 {
446 _CSTRING_NS::CString formattedMessage;
447 formattedMessage.Format(message, replaceCount, m_sFindNext, m_sReplaceWith);
448 if(m_pFindReplaceDialog != NULL)
449 {
450 m_pFindReplaceDialog->MessageBox(formattedMessage,
451 pT->GetTranslationText(eText_OnReplaceAllTitle),
452 MB_OK | MB_ICONINFORMATION | MB_APPLMODAL);
453 }
454 else
455 {
456 pT->MessageBox(formattedMessage,
457 pT->GetTranslationText(eText_OnReplaceAllTitle),
458 MB_OK | MB_ICONINFORMATION | MB_APPLMODAL);
459 }
460 }
461 }
462
463 void OnTextNotFound(LPCTSTR lpszFind)
464 {
465 T* pT = static_cast<T*>(this);
466 _CSTRING_NS::CString message = pT->GetTranslationText(eText_OnTextNotFoundMessage);
467 if(message.GetLength() > 0)
468 {
469 _CSTRING_NS::CString formattedMessage;
470 formattedMessage.Format(message, lpszFind);
471 if(m_pFindReplaceDialog != NULL)
472 {
473 m_pFindReplaceDialog->MessageBox(formattedMessage,
474 pT->GetTranslationText(eText_OnTextNotFoundTitle),
475 MB_OK | MB_ICONINFORMATION | MB_APPLMODAL);
476 }
477 else
478 {
479 pT->MessageBox(formattedMessage,
480 pT->GetTranslationText(eText_OnTextNotFoundTitle),
481 MB_OK | MB_ICONINFORMATION | MB_APPLMODAL);
482 }
483 }
484 else
485 {
486 ::MessageBeep(MB_ICONHAND);
487 }
488 }
489
490 void OnTerminatingFindReplaceDialog(TFindReplaceDialog*& /*findReplaceDialog*/)
491 {
492 }
493 };
494
495
496 ///////////////////////////////////////////////////////////////////////////////
497 // CEditFindReplaceImpl - Mixin class for implementing Find/Replace for CEdit
498 // based window classes.
499
500 // Chain to CEditFindReplaceImpl message map. Your class must also derive from CEdit.
501 // Example:
502 // class CMyEdit : public CWindowImpl<CMyEdit, CEdit>,
503 // public CEditFindReplaceImpl<CMyEdit>
504 // {
505 // public:
506 // BEGIN_MSG_MAP(CMyEdit)
507 // // your handlers...
508 // CHAIN_MSG_MAP_ALT(CEditFindReplaceImpl<CMyEdit>, 1)
509 // END_MSG_MAP()
510 // // other stuff...
511 // };
512
513 template <class T, class TFindReplaceDialog = CFindReplaceDialog>
514 class CEditFindReplaceImpl : public CEditFindReplaceImplBase<T, TFindReplaceDialog>
515 {
516 protected:
517 typedef CEditFindReplaceImpl<T, TFindReplaceDialog> thisClass;
518 typedef CEditFindReplaceImplBase<T, TFindReplaceDialog> baseClass;
519
520 // Data members
521 LPTSTR m_pShadowBuffer; // Special shadow buffer only used in some cases.
522 UINT m_nShadowSize;
523 int m_bShadowBufferNeeded; // TRUE, FALSE, < 0 => Need to check
524
525 public:
526 // Constructors
527 CEditFindReplaceImpl() :
528 m_pShadowBuffer(NULL),
529 m_nShadowSize(0),
530 m_bShadowBufferNeeded(-1)
531 {
532 }
533
534 virtual ~CEditFindReplaceImpl()
535 {
536 if(m_pShadowBuffer != NULL)
537 {
538 delete [] m_pShadowBuffer;
539 m_pShadowBuffer = NULL;
540 }
541 }
542
543 // Message Handlers
544 BEGIN_MSG_MAP(thisClass)
545 ALT_MSG_MAP(1)
546 CHAIN_MSG_MAP_ALT(baseClass, 1)
547 END_MSG_MAP()
548
549 // Operations
550 // Supported only for RichEdit, so this does nothing for Edit
551 void HideSelection(BOOL /*bHide*/ = TRUE, BOOL /*bChangeStyle*/ = FALSE)
552 {
553 }
554
555 // Operations (overrideable)
556 BOOL FindTextSimple(LPCTSTR lpszFind, BOOL bMatchCase, BOOL bWholeWord, BOOL bFindDown = TRUE)
557 {
558 T* pT = static_cast<T*>(this);
559
560 ATLASSERT(lpszFind != NULL);
561 ATLASSERT(*lpszFind != _T('\0'));
562
563 UINT nLen = pT->GetBufferLength();
564 int nStartChar = 0, nEndChar = 0;
565 pT->GetSel(nStartChar, nEndChar);
566 UINT nStart = nStartChar;
567 int iDir = bFindDown ? +1 : -1;
568
569 // can't find a match before the first character
570 if((nStart == 0) && (iDir < 0))
571 return FALSE;
572
573 LPCTSTR lpszText = pT->LockBuffer();
574
575 bool isDBCS = false;
576 #ifdef _MBCS
577 CPINFO info = { 0 };
578 ::GetCPInfo(::GetOEMCP(), &info);
579 isDBCS = (info.MaxCharSize > 1);
580 #endif
581
582 if(iDir < 0)
583 {
584 // always go back one for search backwards
585 nStart -= int((lpszText + nStart) - ::CharPrev(lpszText, lpszText + nStart));
586 }
587 else if((nStartChar != nEndChar) && (pT->SameAsSelected(lpszFind, bMatchCase, bWholeWord)))
588 {
589 // easy to go backward/forward with SBCS
590 #ifndef _UNICODE
591 if(::IsDBCSLeadByte(lpszText[nStart]))
592 nStart++;
593 #endif
594 nStart += iDir;
595 }
596
597 // handle search with nStart past end of buffer
598 UINT nLenFind = ::lstrlen(lpszFind);
599 if((nStart + nLenFind - 1) >= nLen)
600 {
601 if((iDir < 0) && (nLen >= nLenFind))
602 {
603 if(isDBCS)
604 {
605 // walk back to previous character n times
606 nStart = nLen;
607 int n = nLenFind;
608 while(n--)
609 {
610 nStart -= int((lpszText + nStart) - ::CharPrev(lpszText, lpszText + nStart));
611 }
612 }
613 else
614 {
615 // single-byte character set is easy and fast
616 nStart = nLen - nLenFind;
617 }
618 ATLASSERT((nStart + nLenFind - 1) <= nLen);
619 }
620 else
621 {
622 pT->UnlockBuffer();
623 return FALSE;
624 }
625 }
626
627 // start the search at nStart
628 LPCTSTR lpsz = lpszText + nStart;
629 typedef int (WINAPI* CompareProc)(LPCTSTR str1, LPCTSTR str2);
630 CompareProc pfnCompare = bMatchCase ? lstrcmp : lstrcmpi;
631
632 if(isDBCS)
633 {
634 // double-byte string search
635 LPCTSTR lpszStop = NULL;
636 if(iDir > 0)
637 {
638 // start at current and find _first_ occurrance
639 lpszStop = lpszText + nLen - nLenFind + 1;
640 }
641 else
642 {
643 // start at top and find _last_ occurrance
644 lpszStop = lpsz;
645 lpsz = lpszText;
646 }
647
648 LPCTSTR lpszFound = NULL;
649 while(lpsz <= lpszStop)
650 {
651 #ifndef _UNICODE
652 if(!bMatchCase || (*lpsz == *lpszFind && (!::IsDBCSLeadByte(*lpsz) || lpsz[1] == lpszFind[1])))
653 #else
654 if(!bMatchCase || (*lpsz == *lpszFind && lpsz[1] == lpszFind[1]))
655 #endif
656 {
657 LPTSTR lpch = (LPTSTR)(lpsz + nLenFind);
658 TCHAR chSave = *lpch;
659 *lpch = _T('\0');
660 int nResult = (*pfnCompare)(lpsz, lpszFind);
661 *lpch = chSave;
662 if(nResult == 0)
663 {
664 lpszFound = lpsz;
665 if(iDir > 0)
666 break;
667 }
668 }
669 lpsz = ::CharNext(lpsz);
670 }
671 pT->UnlockBuffer();
672
673 if(lpszFound != NULL)
674 {
675 int n = (int)(lpszFound - lpszText);
676 pT->SetSel(n, n + nLenFind);
677 return TRUE;
678 }
679 }
680 else
681 {
682 // single-byte string search
683 UINT nCompare = 0;
684 if(iDir < 0)
685 nCompare = (UINT)(lpsz - lpszText) + 1;
686 else
687 nCompare = nLen - (UINT)(lpsz - lpszText) - nLenFind + 1;
688
689 while(nCompare > 0)
690 {
691 ATLASSERT(lpsz >= lpszText);
692 ATLASSERT((lpsz + nLenFind - 1) <= (lpszText + nLen - 1));
693
694 LPSTR lpch = (LPSTR)(lpsz + nLenFind);
695 char chSave = *lpch;
696 *lpch = '\0';
697 int nResult = (*pfnCompare)(lpsz, lpszFind);
698 *lpch = chSave;
699 if(nResult == 0)
700 {
701 pT->UnlockBuffer();
702 int n = (int)(lpsz - lpszText);
703 pT->SetSel(n, n + nLenFind);
704 return TRUE;
705 }
706
707 // restore character at end of search
708 *lpch = chSave;
709
710 // move on to next substring
711 nCompare--;
712 lpsz += iDir;
713 }
714 pT->UnlockBuffer();
715 }
716
717 return FALSE;
718 }
719
720 LPCTSTR LockBuffer() const
721 {
722 const T* pT = static_cast<const T*>(this);
723 ATLASSERT(pT->m_hWnd != NULL);
724
725 BOOL useShadowBuffer = pT->UseShadowBuffer();
726 if(useShadowBuffer)
727 {
728 if((m_pShadowBuffer == NULL) || pT->GetModify())
729 {
730 ATLASSERT((m_pShadowBuffer != NULL) || (m_nShadowSize == 0));
731 UINT nSize = pT->GetWindowTextLength() + 1;
732 if(nSize > m_nShadowSize)
733 {
734 // need more room for shadow buffer
735 T* pThisNoConst = const_cast<T*>(pT);
736 delete[] m_pShadowBuffer;
737 pThisNoConst->m_pShadowBuffer = NULL;
738 pThisNoConst->m_nShadowSize = 0;
739 pThisNoConst->m_pShadowBuffer = new TCHAR[nSize];
740 pThisNoConst->m_nShadowSize = nSize;
741 }
742
743 // update the shadow buffer with GetWindowText
744 ATLASSERT(m_nShadowSize >= nSize);
745 ATLASSERT(m_pShadowBuffer != NULL);
746 pT->GetWindowText(m_pShadowBuffer, nSize);
747 }
748
749 return m_pShadowBuffer;
750 }
751
752 HLOCAL hLocal = pT->GetHandle();
753 ATLASSERT(hLocal != NULL);
754 LPCTSTR lpszText = (LPCTSTR)::LocalLock(hLocal);
755 ATLASSERT(lpszText != NULL);
756
757 return lpszText;
758 }
759
760 void UnlockBuffer() const
761 {
762 const T* pT = static_cast<const T*>(this);
763 ATLASSERT(pT->m_hWnd != NULL);
764
765 BOOL useShadowBuffer = pT->UseShadowBuffer();
766 if(!useShadowBuffer)
767 {
768 HLOCAL hLocal = pT->GetHandle();
769 ATLASSERT(hLocal != NULL);
770 ::LocalUnlock(hLocal);
771 }
772 }
773
774 UINT GetBufferLength() const
775 {
776 const T* pT = static_cast<const T*>(this);
777 ATLASSERT(pT->m_hWnd != NULL);
778
779 UINT nLen = 0;
780 LPCTSTR lpszText = pT->LockBuffer();
781 if(lpszText != NULL)
782 nLen = ::lstrlen(lpszText);
783 pT->UnlockBuffer();
784
785 return nLen;
786 }
787
788 LONG EndOfLine(LPCTSTR lpszText, UINT nLen, UINT nIndex) const
789 {
790 LPCTSTR lpsz = lpszText + nIndex;
791 LPCTSTR lpszStop = lpszText + nLen;
792 while(lpsz < lpszStop && *lpsz != _T('\r'))
793 ++lpsz;
794 return LONG(lpsz - lpszText);
795 }
796
797 LONG GetSelText(_CSTRING_NS::CString& strText) const
798 {
799 const T* pT = static_cast<const T*>(this);
800
801 int nStartChar = 0, nEndChar = 0;
802 pT->GetSel(nStartChar, nEndChar);
803 ATLASSERT((UINT)nEndChar <= pT->GetBufferLength());
804 LPCTSTR lpszText = pT->LockBuffer();
805 LONG nLen = pT->EndOfLine(lpszText, nEndChar, nStartChar) - nStartChar;
806 SecureHelper::memcpy_x(strText.GetBuffer(nLen), nLen * sizeof(TCHAR), lpszText + nStartChar, nLen * sizeof(TCHAR));
807 strText.ReleaseBuffer(nLen);
808 pT->UnlockBuffer();
809
810 return nLen;
811 }
812
813 BOOL UseShadowBuffer(void) const
814 {
815 const T* pT = static_cast<const T*>(this);
816
817 if(pT->m_bShadowBufferNeeded < 0)
818 {
819 T* pThisNoConst = const_cast<T*>(pT);
820
821 #ifdef _versionhelpers_H_INCLUDED_
822 OSVERSIONINFOEX ovi = { sizeof(OSVERSIONINFOEX) };
823 ovi.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;
824 DWORDLONG const dwlConditionMask = ::VerSetConditionMask(0, VER_PLATFORMID, VER_EQUAL);
825 bool bWin9x = (::VerifyVersionInfo(&ovi, VER_PLATFORMID, dwlConditionMask) != FALSE);
826 #else // !_versionhelpers_H_INCLUDED_
827 OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) };
828 ::GetVersionEx(&ovi);
829
830 bool bWin9x = (ovi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
831 #endif // _versionhelpers_H_INCLUDED_
832 if(bWin9x)
833 {
834 // Windows 95, 98, ME
835 // Under Win9x, it is necessary to maintain a shadow buffer.
836 // It is only updated when the control contents have been changed.
837 pThisNoConst->m_bShadowBufferNeeded = TRUE;
838 }
839 else
840 {
841 // Windows NT, 2000, XP, etc.
842 pThisNoConst->m_bShadowBufferNeeded = FALSE;
843
844 #ifndef _UNICODE
845 // On Windows XP (or later), if common controls version 6 is in use
846 // (such as via theming), then EM_GETHANDLE will always return a UNICODE string.
847 // If theming is enabled and Common Controls version 6 is in use,
848 // you're really not suppose to superclass or subclass common controls
849 // with an ANSI windows procedure (so its best to only theme if you use UNICODE).
850 // Using a shadow buffer uses GetWindowText instead, so it solves
851 // this problem for us (although it makes it a little less efficient).
852
853 #ifdef _versionhelpers_H_INCLUDED_
854 if(::IsWindowsXPOrGreater())
855 #else // !_versionhelpers_H_INCLUDED_
856 if ((ovi.dwMajorVersion == 5 && ovi.dwMinorVersion >= 1) || (ovi.dwMajorVersion > 5))
857 #endif // _versionhelpers_H_INCLUDED_
858 {
859 DWORD dwMajor = 0, dwMinor = 0;
860 HRESULT hRet = ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor);
861 if(SUCCEEDED(hRet))
862 {
863 if(dwMajor >= 6)
864 {
865 pThisNoConst->m_bShadowBufferNeeded = TRUE;
866
867 ATLTRACE2(atlTraceUI, 0, _T("Warning: You have compiled for MBCS/ANSI but are using common controls version 6 or later (likely through a manifest file).\r\n"));
868 ATLTRACE2(atlTraceUI, 0, _T("If you use common controls version 6 or later, you should only do so for UNICODE builds.\r\n"));
869 }
870 }
871 }
872 #endif // !_UNICODE
873 }
874 }
875
876 return (pT->m_bShadowBufferNeeded != FALSE);
877 }
878 };
879
880
881 ///////////////////////////////////////////////////////////////////////////////
882 // CRichEditFindReplaceImpl - Mixin class for implementing Find/Replace for CRichEditCtrl
883 // based window classes.
884
885 // Chain to CRichEditFindReplaceImpl message map. Your class must also derive from CRichEditCtrl.
886 // Example:
887 // class CMyRichEdit : public CWindowImpl<CMyRichEdit, CRichEditCtrl>,
888 // public CRichEditFindReplaceImpl<CMyRichEdit>
889 // {
890 // public:
891 // BEGIN_MSG_MAP(CMyRichEdit)
892 // // your handlers...
893 // CHAIN_MSG_MAP_ALT(CRichEditFindReplaceImpl<CMyRichEdit>, 1)
894 // END_MSG_MAP()
895 // // other stuff...
896 // };
897
898 template <class T, class TFindReplaceDialog = CFindReplaceDialog>
899 class CRichEditFindReplaceImpl : public CEditFindReplaceImplBase<T, TFindReplaceDialog>
900 {
901 protected:
902 typedef CRichEditFindReplaceImpl<T, TFindReplaceDialog> thisClass;
903 typedef CEditFindReplaceImplBase<T, TFindReplaceDialog> baseClass;
904
905 public:
906 BEGIN_MSG_MAP(thisClass)
907 ALT_MSG_MAP(1)
908 CHAIN_MSG_MAP_ALT(baseClass, 1)
909 END_MSG_MAP()
910
911 // Operations (overrideable)
912 BOOL FindTextSimple(LPCTSTR lpszFind, BOOL bMatchCase, BOOL bWholeWord, BOOL bFindDown = TRUE)
913 {
914 T* pT = static_cast<T*>(this);
915
916 ATLASSERT(lpszFind != NULL);
917 FINDTEXTEX ft = { 0 };
918
919 pT->GetSel(ft.chrg);
920 if(m_bFirstSearch)
921 {
922 if(bFindDown)
923 m_nInitialSearchPos = ft.chrg.cpMin;
924 else
925 m_nInitialSearchPos = ft.chrg.cpMax;
926 m_bFirstSearch = FALSE;
927 }
928
929 #if (_RICHEDIT_VER >= 0x0200)
930 ft.lpstrText = (LPTSTR)lpszFind;
931 #else // !(_RICHEDIT_VER >= 0x0200)
932 USES_CONVERSION;
933 ft.lpstrText = T2A((LPTSTR)lpszFind);
934 #endif // !(_RICHEDIT_VER >= 0x0200)
935
936 if(ft.chrg.cpMin != ft.chrg.cpMax) // i.e. there is a selection
937 {
938 if(bFindDown)
939 {
940 ft.chrg.cpMin++;
941 }
942 else
943 {
944 // won't wraparound backwards
945 ft.chrg.cpMin = __max(ft.chrg.cpMin, 0);
946 }
947 }
948
949 DWORD dwFlags = bMatchCase ? FR_MATCHCASE : 0;
950 dwFlags |= bWholeWord ? FR_WHOLEWORD : 0;
951
952 ft.chrg.cpMax = pT->GetTextLength() + m_nInitialSearchPos;
953
954 if(bFindDown)
955 {
956 if(m_nInitialSearchPos >= 0)
957 ft.chrg.cpMax = pT->GetTextLength();
958
959 dwFlags |= FR_DOWN;
960 ATLASSERT(ft.chrg.cpMax >= ft.chrg.cpMin);
961 }
962 else
963 {
964 if(m_nInitialSearchPos >= 0)
965 ft.chrg.cpMax = 0;
966
967 dwFlags &= ~FR_DOWN;
968 ATLASSERT(ft.chrg.cpMax <= ft.chrg.cpMin);
969 }
970
971 BOOL bRet = FALSE;
972 if(pT->FindAndSelect(dwFlags, ft) != -1)
973 {
974 bRet = TRUE; // we found the text
975 }
976 else if(m_nInitialSearchPos > 0)
977 {
978 // if the original starting point was not the beginning
979 // of the buffer and we haven't already been here
980 if(bFindDown)
981 {
982 ft.chrg.cpMin = 0;
983 ft.chrg.cpMax = m_nInitialSearchPos;
984 }
985 else
986 {
987 ft.chrg.cpMin = pT->GetTextLength();
988 ft.chrg.cpMax = m_nInitialSearchPos;
989 }
990 m_nInitialSearchPos = m_nInitialSearchPos - pT->GetTextLength();
991
992 bRet = (pT->FindAndSelect(dwFlags, ft) != -1) ? TRUE : FALSE;
993 }
994
995 return bRet;
996 }
997
998 long FindAndSelect(DWORD dwFlags, FINDTEXTEX& ft)
999 {
1000 T* pT = static_cast<T*>(this);
1001 LONG index = pT->FindText(dwFlags, ft);
1002 if(index != -1) // i.e. we found something
1003 pT->SetSel(ft.chrgText);
1004
1005 return index;
1006 }
1007 };
1008
1009 }; // namespace WTL
1010
1011 #endif // __ATLFIND_H__
+0
-3696
src/third_party/wtl/Include/atlframe.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLFRAME_H__
9 #define __ATLFRAME_H__
10
11 #pragma once
12
13 #ifndef __ATLAPP_H__
14 #error atlframe.h requires atlapp.h to be included first
15 #endif
16
17 #ifndef __ATLWIN_H__
18 #error atlframe.h requires atlwin.h to be included first
19 #endif
20
21
22 ///////////////////////////////////////////////////////////////////////////////
23 // Classes in this file:
24 //
25 // CFrameWindowImpl<T, TBase, TWinTraits>
26 // CMDIWindow
27 // CMDIFrameWindowImpl<T, TBase, TWinTraits>
28 // CMDIChildWindowImpl<T, TBase, TWinTraits>
29 // COwnerDraw<T>
30 // CUpdateUIBase
31 // CUpdateUI<T>
32 // CDynamicUpdateUI<T>
33 // CAutoUpdateUI<T>
34 // CDialogResize<T>
35 // CDoubleBufferImpl<T>
36 // CDoubleBufferWindowImpl<T, TBase, TWinTraits>
37 //
38 // Global functions:
39 // AtlCreateSimpleToolBar()
40
41
42 namespace WTL
43 {
44
45 ///////////////////////////////////////////////////////////////////////////////
46 // CFrameWndClassInfo - Manages frame window Windows class information
47
48 class CFrameWndClassInfo
49 {
50 public:
51 #ifndef _WIN32_WCE
52 enum { cchAutoName = 5 + sizeof(void*) * 2 }; // sizeof(void*) * 2 is the number of digits %p outputs
53 WNDCLASSEX m_wc;
54 #else // CE specific
55 enum { cchAutoName = MAX_PATH }; // MAX_PATH because this can be set in the wizard generated CMainFrame::ActivatePreviousInstance to a user defined string.
56 WNDCLASS m_wc;
57 #endif // !_WIN32_WCE
58 LPCTSTR m_lpszOrigName;
59 WNDPROC pWndProc;
60 LPCTSTR m_lpszCursorID;
61 BOOL m_bSystemCursor;
62 ATOM m_atom;
63 TCHAR m_szAutoName[cchAutoName];
64 UINT m_uCommonResourceID;
65
66 #ifndef _WIN32_WCE
67 ATOM Register(WNDPROC* pProc)
68 {
69 if (m_atom == 0)
70 {
71 CWindowCreateCriticalSectionLock lock;
72 if(FAILED(lock.Lock()))
73 {
74 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CFrameWndClassInfo::Register.\n"));
75 ATLASSERT(FALSE);
76 return 0;
77 }
78
79 if(m_atom == 0)
80 {
81 HINSTANCE hInst = ModuleHelper::GetModuleInstance();
82
83 if (m_lpszOrigName != NULL)
84 {
85 ATLASSERT(pProc != NULL);
86 LPCTSTR lpsz = m_wc.lpszClassName;
87 WNDPROC proc = m_wc.lpfnWndProc;
88
89 WNDCLASSEX wc = { sizeof(WNDCLASSEX) };
90 // try process local class first
91 if(!::GetClassInfoEx(ModuleHelper::GetModuleInstance(), m_lpszOrigName, &wc))
92 {
93 // try global class
94 if(!::GetClassInfoEx(NULL, m_lpszOrigName, &wc))
95 {
96 lock.Unlock();
97 return 0;
98 }
99 }
100 m_wc = wc;
101 pWndProc = m_wc.lpfnWndProc;
102 m_wc.lpszClassName = lpsz;
103 m_wc.lpfnWndProc = proc;
104 }
105 else
106 {
107 m_wc.hCursor = ::LoadCursor(m_bSystemCursor ? NULL : hInst, m_lpszCursorID);
108 }
109
110 m_wc.hInstance = hInst;
111 m_wc.style &= ~CS_GLOBALCLASS; // we don't register global classes
112 if (m_wc.lpszClassName == NULL)
113 {
114 #if (_WIN32_WINNT >= 0x0500) || defined(_WIN64)
115 SecureHelper::wsprintf_x(m_szAutoName, cchAutoName, _T("ATL:%p"), &m_wc);
116 #else // !((_WIN32_WINNT >= 0x0500) || defined(_WIN64))
117 SecureHelper::wsprintf_x(m_szAutoName, cchAutoName, _T("ATL:%8.8X"), (DWORD_PTR)&m_wc);
118 #endif // !((_WIN32_WINNT >= 0x0500) || defined(_WIN64))
119 m_wc.lpszClassName = m_szAutoName;
120 }
121
122 WNDCLASSEX wcTemp = m_wc;
123 m_atom = (ATOM)::GetClassInfoEx(m_wc.hInstance, m_wc.lpszClassName, &wcTemp);
124 if (m_atom == 0)
125 {
126 if(m_uCommonResourceID != 0) // use it if not zero
127 {
128 m_wc.hIcon = (HICON)::LoadImage(ModuleHelper::GetResourceInstance(),
129 MAKEINTRESOURCE(m_uCommonResourceID), IMAGE_ICON,
130 ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);
131 m_wc.hIconSm = (HICON)::LoadImage(ModuleHelper::GetResourceInstance(),
132 MAKEINTRESOURCE(m_uCommonResourceID), IMAGE_ICON,
133 ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
134 }
135 m_atom = ::RegisterClassEx(&m_wc);
136 }
137 }
138
139 lock.Unlock();
140 }
141
142 if (m_lpszOrigName != NULL)
143 {
144 ATLASSERT(pProc != NULL);
145 ATLASSERT(pWndProc != NULL);
146 *pProc = pWndProc;
147 }
148
149 return m_atom;
150 }
151 #else // CE specific
152 ATOM Register(WNDPROC* pProc)
153 {
154 if (m_atom == 0)
155 {
156 CWindowCreateCriticalSectionLock lock;
157 if(FAILED(lock.Lock()))
158 {
159 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CFrameWndClassInfo::Register.\n"));
160 ATLASSERT(FALSE);
161 return 0;
162 }
163
164 if(m_atom == 0)
165 {
166 HINSTANCE hInst = ModuleHelper::GetModuleInstance();
167
168 if (m_lpszOrigName != NULL)
169 {
170 ATLASSERT(pProc != NULL);
171 LPCTSTR lpsz = m_wc.lpszClassName;
172 WNDPROC proc = m_wc.lpfnWndProc;
173
174 WNDCLASS wc = { 0 };
175 // try process local class first
176 if(!::GetClassInfo(ModuleHelper::GetModuleInstance(), m_lpszOrigName, &wc))
177 {
178 // try global class
179 if(!::GetClassInfo(NULL, m_lpszOrigName, &wc))
180 {
181 lock.Unlock();
182 return 0;
183 }
184 }
185 m_wc = wc;
186 pWndProc = m_wc.lpfnWndProc;
187 m_wc.lpszClassName = lpsz;
188 m_wc.lpfnWndProc = proc;
189 }
190 else
191 {
192 #if defined(GWES_CURSOR) || defined(GWES_MCURSOR)
193 m_wc.hCursor = ::LoadCursor(m_bSystemCursor ? NULL : hInst, m_lpszCursorID);
194 #else // !(defined(GWES_CURSOR) || defined(GWES_MCURSOR))
195 m_wc.hCursor = NULL;
196 #endif // !(defined(GWES_CURSOR) || defined(GWES_MCURSOR))
197 }
198
199 m_wc.hInstance = hInst;
200 m_wc.style &= ~CS_GLOBALCLASS; // we don't register global classes
201 if (m_wc.lpszClassName == NULL)
202 {
203 wsprintf(m_szAutoName, _T("ATL:%8.8X"), (DWORD_PTR)&m_wc);
204 m_wc.lpszClassName = m_szAutoName;
205 }
206
207 WNDCLASS wcTemp = m_wc;
208 m_atom = (ATOM)::GetClassInfo(m_wc.hInstance, m_wc.lpszClassName, &wcTemp);
209 if (m_atom == 0)
210 {
211 if(m_uCommonResourceID != 0) // use it if not zero
212 m_wc.hIcon = (HICON)::LoadImage(ModuleHelper::GetResourceInstance(),
213 MAKEINTRESOURCE(m_uCommonResourceID), IMAGE_ICON,
214 ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);
215 m_atom = ::RegisterClass(&m_wc);
216 }
217 }
218
219 lock.Unlock();
220 }
221
222 if (m_lpszOrigName != NULL)
223 {
224 ATLASSERT(pProc != NULL);
225 ATLASSERT(pWndProc != NULL);
226 *pProc = pWndProc;
227 }
228
229 return m_atom;
230 }
231 #endif // _WIN32_WCE
232 };
233
234
235 ///////////////////////////////////////////////////////////////////////////////
236 // Macros for declaring frame window WNDCLASS
237
238 #ifndef _WIN32_WCE
239
240 #define DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) \
241 static WTL::CFrameWndClassInfo& GetWndClassInfo() \
242 { \
243 static WTL::CFrameWndClassInfo wc = \
244 { \
245 { sizeof(WNDCLASSEX), 0, StartWindowProc, \
246 0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndClassName, NULL }, \
247 NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \
248 }; \
249 return wc; \
250 }
251
252 #define DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd) \
253 static WTL::CFrameWndClassInfo& GetWndClassInfo() \
254 { \
255 static WTL::CFrameWndClassInfo wc = \
256 { \
257 { sizeof(WNDCLASSEX), style, StartWindowProc, \
258 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName, NULL }, \
259 NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \
260 }; \
261 return wc; \
262 }
263
264 #define DECLARE_FRAME_WND_SUPERCLASS(WndClassName, OrigWndClassName, uCommonResourceID) \
265 static WTL::CFrameWndClassInfo& GetWndClassInfo() \
266 { \
267 static WTL::CFrameWndClassInfo wc = \
268 { \
269 { sizeof(WNDCLASSEX), 0, StartWindowProc, \
270 0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName, NULL }, \
271 OrigWndClassName, NULL, NULL, TRUE, 0, _T(""), uCommonResourceID \
272 }; \
273 return wc; \
274 }
275
276 #else // CE specific
277
278 #define DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) \
279 static WTL::CFrameWndClassInfo& GetWndClassInfo() \
280 { \
281 static WTL::CFrameWndClassInfo wc = \
282 { \
283 { 0, StartWindowProc, \
284 0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndClassName }, \
285 NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \
286 }; \
287 return wc; \
288 }
289
290 #define DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd) \
291 static WTL::CFrameWndClassInfo& GetWndClassInfo() \
292 { \
293 static WTL::CFrameWndClassInfo wc = \
294 { \
295 { style, StartWindowProc, \
296 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName }, \
297 NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \
298 }; \
299 return wc; \
300 }
301
302 #define DECLARE_FRAME_WND_SUPERCLASS(WndClassName, OrigWndClassName, uCommonResourceID) \
303 static WTL::CFrameWndClassInfo& GetWndClassInfo() \
304 { \
305 static WTL::CFrameWndClassInfo wc = \
306 { \
307 { NULL, StartWindowProc, \
308 0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName }, \
309 OrigWndClassName, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \
310 }; \
311 return wc; \
312 }
313
314 #endif // !_WIN32_WCE
315
316
317 ///////////////////////////////////////////////////////////////////////////////
318 // CFrameWindowImpl
319
320 // Client window command chaining macro (only for frame windows)
321 #define CHAIN_CLIENT_COMMANDS() \
322 if(uMsg == WM_COMMAND && m_hWndClient != NULL) \
323 ::SendMessage(m_hWndClient, uMsg, wParam, lParam);
324
325 // standard toolbar styles
326 #define ATL_SIMPLE_TOOLBAR_STYLE \
327 (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS)
328 // toolbar in a rebar pane
329 #define ATL_SIMPLE_TOOLBAR_PANE_STYLE \
330 (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NORESIZE | CCS_NOPARENTALIGN | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT)
331 // standard rebar styles
332 #if (_WIN32_IE >= 0x0400)
333 #define ATL_SIMPLE_REBAR_STYLE \
334 (WS_CHILD | WS_VISIBLE | WS_BORDER | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_AUTOSIZE)
335 #else
336 #define ATL_SIMPLE_REBAR_STYLE \
337 (WS_CHILD | WS_VISIBLE | WS_BORDER | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS)
338 #endif // !(_WIN32_IE >= 0x0400)
339 // rebar without borders
340 #if (_WIN32_IE >= 0x0400)
341 #define ATL_SIMPLE_REBAR_NOBORDER_STYLE \
342 (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_AUTOSIZE | CCS_NODIVIDER)
343 #else
344 #define ATL_SIMPLE_REBAR_NOBORDER_STYLE \
345 (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS | CCS_NODIVIDER)
346 #endif // !(_WIN32_IE >= 0x0400)
347
348 // command bar support
349 #if !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE)
350
351 #define CBRM_GETCMDBAR (WM_USER + 301) // returns command bar HWND
352 #define CBRM_GETMENU (WM_USER + 302) // returns loaded or attached menu
353 #define CBRM_TRACKPOPUPMENU (WM_USER + 303) // displays a popup menu
354
355 struct _AtlFrameWnd_CmdBarPopupMenu
356 {
357 int cbSize;
358 HMENU hMenu;
359 UINT uFlags;
360 int x;
361 int y;
362 LPTPMPARAMS lptpm;
363 };
364
365 #define CBRPOPUPMENU _AtlFrameWnd_CmdBarPopupMenu
366
367 #endif // !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE)
368
369
370 template <class TBase = ATL::CWindow, class TWinTraits = ATL::CFrameWinTraits>
371 class ATL_NO_VTABLE CFrameWindowImplBase : public ATL::CWindowImplBaseT< TBase, TWinTraits >
372 {
373 public:
374 DECLARE_FRAME_WND_CLASS(NULL, 0)
375
376 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
377 struct _ChevronMenuInfo
378 {
379 HMENU hMenu;
380 LPNMREBARCHEVRON lpnm;
381 bool bCmdBar;
382 };
383 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
384
385 // Data members
386 HWND m_hWndToolBar;
387 HWND m_hWndStatusBar;
388 HWND m_hWndClient;
389
390 #ifdef _WIN32_WCE
391 HWND m_hWndCECommandBar;
392 #endif // _WIN32_WCE
393
394 HACCEL m_hAccel;
395
396 // Constructor
397 CFrameWindowImplBase() :
398 m_hWndToolBar(NULL),
399 m_hWndStatusBar(NULL),
400 m_hWndClient(NULL),
401 #ifdef _WIN32_WCE
402 m_hWndCECommandBar(NULL),
403 #endif // _WIN32_WCE
404 m_hAccel(NULL)
405 { }
406
407 // Methods
408 HWND Create(HWND hWndParent, ATL::_U_RECT rect, LPCTSTR szWindowName, DWORD dwStyle, DWORD dwExStyle, ATL::_U_MENUorID MenuOrID, ATOM atom, LPVOID lpCreateParam)
409 {
410 ATLASSERT(m_hWnd == NULL);
411
412 #if (_ATL_VER >= 0x0800)
413 // Allocate the thunk structure here, where we can fail gracefully.
414 BOOL bRet = m_thunk.Init(NULL, NULL);
415 if(bRet == FALSE)
416 {
417 ::SetLastError(ERROR_OUTOFMEMORY);
418 return NULL;
419 }
420 #endif // (_ATL_VER >= 0x0800)
421
422 if(atom == 0)
423 return NULL;
424
425 ModuleHelper::AddCreateWndData(&m_thunk.cd, this);
426
427 if(MenuOrID.m_hMenu == NULL && (dwStyle & WS_CHILD))
428 MenuOrID.m_hMenu = (HMENU)(UINT_PTR)this;
429 if(rect.m_lpRect == NULL)
430 rect.m_lpRect = &TBase::rcDefault;
431
432 HWND hWnd = ::CreateWindowEx(dwExStyle, MAKEINTATOM(atom), szWindowName,
433 dwStyle, rect.m_lpRect->left, rect.m_lpRect->top, rect.m_lpRect->right - rect.m_lpRect->left,
434 rect.m_lpRect->bottom - rect.m_lpRect->top, hWndParent, MenuOrID.m_hMenu,
435 ModuleHelper::GetModuleInstance(), lpCreateParam);
436
437 ATLASSERT(hWnd == NULL || m_hWnd == hWnd);
438
439 return hWnd;
440 }
441
442 static HWND CreateSimpleToolBarCtrl(HWND hWndParent, UINT nResourceID, BOOL bInitialSeparator = FALSE,
443 DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
444 {
445 HINSTANCE hInst = ModuleHelper::GetResourceInstance();
446 HRSRC hRsrc = ::FindResource(hInst, MAKEINTRESOURCE(nResourceID), RT_TOOLBAR);
447 if (hRsrc == NULL)
448 return NULL;
449
450 HGLOBAL hGlobal = ::LoadResource(hInst, hRsrc);
451 if (hGlobal == NULL)
452 return NULL;
453
454 _AtlToolBarData* pData = (_AtlToolBarData*)::LockResource(hGlobal);
455 if (pData == NULL)
456 return NULL;
457 ATLASSERT(pData->wVersion == 1);
458
459 WORD* pItems = pData->items();
460 int nItems = pData->wItemCount + (bInitialSeparator ? 1 : 0);
461 CTempBuffer<TBBUTTON, _WTL_STACK_ALLOC_THRESHOLD> buff;
462 TBBUTTON* pTBBtn = buff.Allocate(nItems);
463 ATLASSERT(pTBBtn != NULL);
464 if(pTBBtn == NULL)
465 return NULL;
466
467 const int cxSeparator = 8;
468
469 // set initial separator (half width)
470 if(bInitialSeparator)
471 {
472 pTBBtn[0].iBitmap = cxSeparator / 2;
473 pTBBtn[0].idCommand = 0;
474 pTBBtn[0].fsState = 0;
475 pTBBtn[0].fsStyle = BTNS_SEP;
476 pTBBtn[0].dwData = 0;
477 pTBBtn[0].iString = 0;
478 }
479
480 int nBmp = 0;
481 for(int i = 0, j = bInitialSeparator ? 1 : 0; i < pData->wItemCount; i++, j++)
482 {
483 if(pItems[i] != 0)
484 {
485 pTBBtn[j].iBitmap = nBmp++;
486 pTBBtn[j].idCommand = pItems[i];
487 pTBBtn[j].fsState = TBSTATE_ENABLED;
488 pTBBtn[j].fsStyle = BTNS_BUTTON;
489 pTBBtn[j].dwData = 0;
490 pTBBtn[j].iString = 0;
491 }
492 else
493 {
494 pTBBtn[j].iBitmap = cxSeparator;
495 pTBBtn[j].idCommand = 0;
496 pTBBtn[j].fsState = 0;
497 pTBBtn[j].fsStyle = BTNS_SEP;
498 pTBBtn[j].dwData = 0;
499 pTBBtn[j].iString = 0;
500 }
501 }
502
503 #ifndef _WIN32_WCE
504 HWND hWnd = ::CreateWindowEx(0, TOOLBARCLASSNAME, NULL, dwStyle, 0, 0, 100, 100, hWndParent, (HMENU)LongToHandle(nID), ModuleHelper::GetModuleInstance(), NULL);
505 if(hWnd == NULL)
506 {
507 ATLASSERT(FALSE);
508 return NULL;
509 }
510 #else // CE specific
511 dwStyle;
512 nID;
513 // The toolbar must go onto the existing CommandBar or MenuBar
514 HWND hWnd = hWndParent;
515 #endif // _WIN32_WCE
516
517 ::SendMessage(hWnd, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0L);
518
519 // check if font is taller than our bitmaps
520 CFontHandle font = (HFONT)::SendMessage(hWnd, WM_GETFONT, 0, 0L);
521 if(font.IsNull())
522 font = (HFONT)::GetStockObject(SYSTEM_FONT);
523 LOGFONT lf = { 0 };
524 font.GetLogFont(lf);
525 WORD cyFontHeight = (WORD)abs(lf.lfHeight);
526
527 #ifndef _WIN32_WCE
528 WORD bitsPerPixel = AtlGetBitmapResourceBitsPerPixel(nResourceID);
529 if(bitsPerPixel > 4)
530 {
531 COLORREF crMask = CLR_DEFAULT;
532 if(bitsPerPixel == 32)
533 {
534 // 32-bit color bitmap with alpha channel (valid for Windows XP and later)
535 crMask = CLR_NONE;
536 }
537 HIMAGELIST hImageList = ImageList_LoadImage(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(nResourceID), pData->wWidth, 1, crMask, IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
538 ATLASSERT(hImageList != NULL);
539 ::SendMessage(hWnd, TB_SETIMAGELIST, 0, (LPARAM)hImageList);
540 }
541 else
542 #endif // !_WIN32_WCE
543 {
544 TBADDBITMAP tbab = { 0 };
545 tbab.hInst = hInst;
546 tbab.nID = nResourceID;
547 ::SendMessage(hWnd, TB_ADDBITMAP, nBmp, (LPARAM)&tbab);
548 }
549
550 ::SendMessage(hWnd, TB_ADDBUTTONS, nItems, (LPARAM)pTBBtn);
551 ::SendMessage(hWnd, TB_SETBITMAPSIZE, 0, MAKELONG(pData->wWidth, __max(pData->wHeight, cyFontHeight)));
552 const int cxyButtonMargin = 7;
553 ::SendMessage(hWnd, TB_SETBUTTONSIZE, 0, MAKELONG(pData->wWidth + cxyButtonMargin, __max(pData->wHeight, cyFontHeight) + cxyButtonMargin));
554
555 return hWnd;
556 }
557
558 #ifndef _WIN32_WCE
559 static HWND CreateSimpleReBarCtrl(HWND hWndParent, DWORD dwStyle = ATL_SIMPLE_REBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
560 {
561 // Ensure style combinations for proper rebar painting
562 if(dwStyle & CCS_NODIVIDER && dwStyle & WS_BORDER)
563 dwStyle &= ~WS_BORDER;
564 else if(!(dwStyle & WS_BORDER) && !(dwStyle & CCS_NODIVIDER))
565 dwStyle |= CCS_NODIVIDER;
566
567 // Create rebar window
568 HWND hWndReBar = ::CreateWindowEx(0, REBARCLASSNAME, NULL, dwStyle, 0, 0, 100, 100, hWndParent, (HMENU)LongToHandle(nID), ModuleHelper::GetModuleInstance(), NULL);
569 if(hWndReBar == NULL)
570 {
571 ATLTRACE2(atlTraceUI, 0, _T("Failed to create rebar.\n"));
572 return NULL;
573 }
574
575 // Initialize and send the REBARINFO structure
576 REBARINFO rbi = { sizeof(REBARINFO), 0 };
577 if(::SendMessage(hWndReBar, RB_SETBARINFO, 0, (LPARAM)&rbi) == 0)
578 {
579 ATLTRACE2(atlTraceUI, 0, _T("Failed to initialize rebar.\n"));
580 ::DestroyWindow(hWndReBar);
581 return NULL;
582 }
583
584 return hWndReBar;
585 }
586
587 BOOL CreateSimpleReBar(DWORD dwStyle = ATL_SIMPLE_REBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
588 {
589 ATLASSERT(!::IsWindow(m_hWndToolBar));
590 m_hWndToolBar = CreateSimpleReBarCtrl(m_hWnd, dwStyle, nID);
591 return (m_hWndToolBar != NULL);
592 }
593
594 static BOOL AddSimpleReBarBandCtrl(HWND hWndReBar, HWND hWndBand, int nID = 0, LPCTSTR lpstrTitle = NULL, BOOL bNewRow = FALSE, int cxWidth = 0, BOOL bFullWidthAlways = FALSE)
595 {
596 ATLASSERT(::IsWindow(hWndReBar)); // must be already created
597 #ifdef _DEBUG
598 // block - check if this is really a rebar
599 {
600 TCHAR lpszClassName[sizeof(REBARCLASSNAME)] = { 0 };
601 ::GetClassName(hWndReBar, lpszClassName, sizeof(REBARCLASSNAME));
602 ATLASSERT(lstrcmp(lpszClassName, REBARCLASSNAME) == 0);
603 }
604 #endif // _DEBUG
605 ATLASSERT(::IsWindow(hWndBand)); // must be already created
606
607 // Get number of buttons on the toolbar
608 int nBtnCount = (int)::SendMessage(hWndBand, TB_BUTTONCOUNT, 0, 0L);
609
610 // Set band info structure
611 REBARBANDINFO rbBand = { RunTimeHelper::SizeOf_REBARBANDINFO() };
612 #if (_WIN32_IE >= 0x0400)
613 rbBand.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_ID | RBBIM_SIZE | RBBIM_IDEALSIZE;
614 #else
615 rbBand.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_ID | RBBIM_SIZE;
616 #endif // !(_WIN32_IE >= 0x0400)
617 if(lpstrTitle != NULL)
618 rbBand.fMask |= RBBIM_TEXT;
619 rbBand.fStyle = RBBS_CHILDEDGE;
620 #if (_WIN32_IE >= 0x0500)
621 if(nBtnCount > 0) // add chevron style for toolbar with buttons
622 rbBand.fStyle |= RBBS_USECHEVRON;
623 #endif // (_WIN32_IE >= 0x0500)
624 if(bNewRow)
625 rbBand.fStyle |= RBBS_BREAK;
626
627 rbBand.lpText = (LPTSTR)lpstrTitle;
628 rbBand.hwndChild = hWndBand;
629 if(nID == 0) // calc band ID
630 nID = ATL_IDW_BAND_FIRST + (int)::SendMessage(hWndReBar, RB_GETBANDCOUNT, 0, 0L);
631 rbBand.wID = nID;
632
633 // Calculate the size of the band
634 BOOL bRet = FALSE;
635 RECT rcTmp = { 0 };
636 if(nBtnCount > 0)
637 {
638 bRet = (BOOL)::SendMessage(hWndBand, TB_GETITEMRECT, nBtnCount - 1, (LPARAM)&rcTmp);
639 ATLASSERT(bRet);
640 rbBand.cx = (cxWidth != 0) ? cxWidth : rcTmp.right;
641 rbBand.cyMinChild = rcTmp.bottom - rcTmp.top;
642 if(bFullWidthAlways)
643 {
644 rbBand.cxMinChild = rbBand.cx;
645 }
646 else if(lpstrTitle == NULL)
647 {
648 bRet = (BOOL)::SendMessage(hWndBand, TB_GETITEMRECT, 0, (LPARAM)&rcTmp);
649 ATLASSERT(bRet);
650 rbBand.cxMinChild = rcTmp.right;
651 }
652 else
653 {
654 rbBand.cxMinChild = 0;
655 }
656 }
657 else // no buttons, either not a toolbar or really has no buttons
658 {
659 bRet = ::GetWindowRect(hWndBand, &rcTmp);
660 ATLASSERT(bRet);
661 rbBand.cx = (cxWidth != 0) ? cxWidth : (rcTmp.right - rcTmp.left);
662 rbBand.cxMinChild = bFullWidthAlways ? rbBand.cx : 0;
663 rbBand.cyMinChild = rcTmp.bottom - rcTmp.top;
664 }
665
666 #if (_WIN32_IE >= 0x0400)
667 rbBand.cxIdeal = rbBand.cx;
668 #endif // (_WIN32_IE >= 0x0400)
669
670 // Add the band
671 LRESULT lRes = ::SendMessage(hWndReBar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);
672 if(lRes == 0)
673 {
674 ATLTRACE2(atlTraceUI, 0, _T("Failed to add a band to the rebar.\n"));
675 return FALSE;
676 }
677
678 #if (_WIN32_IE >= 0x0501)
679 DWORD dwExStyle = (DWORD)::SendMessage(hWndBand, TB_GETEXTENDEDSTYLE, 0, 0L);
680 ::SendMessage(hWndBand, TB_SETEXTENDEDSTYLE, 0, dwExStyle | TBSTYLE_EX_HIDECLIPPEDBUTTONS);
681 #endif // (_WIN32_IE >= 0x0501)
682
683 return TRUE;
684 }
685
686 BOOL AddSimpleReBarBand(HWND hWndBand, LPCTSTR lpstrTitle = NULL, BOOL bNewRow = FALSE, int cxWidth = 0, BOOL bFullWidthAlways = FALSE)
687 {
688 ATLASSERT(::IsWindow(m_hWndToolBar)); // must be an existing rebar
689 ATLASSERT(::IsWindow(hWndBand)); // must be created
690 return AddSimpleReBarBandCtrl(m_hWndToolBar, hWndBand, 0, lpstrTitle, bNewRow, cxWidth, bFullWidthAlways);
691 }
692
693 #if (_WIN32_IE >= 0x0400)
694 void SizeSimpleReBarBands()
695 {
696 ATLASSERT(::IsWindow(m_hWndToolBar)); // must be an existing rebar
697
698 int nCount = (int)::SendMessage(m_hWndToolBar, RB_GETBANDCOUNT, 0, 0L);
699
700 for(int i = 0; i < nCount; i++)
701 {
702 REBARBANDINFO rbBand = { RunTimeHelper::SizeOf_REBARBANDINFO() };
703 rbBand.fMask = RBBIM_SIZE;
704 BOOL bRet = (BOOL)::SendMessage(m_hWndToolBar, RB_GETBANDINFO, i, (LPARAM)&rbBand);
705 ATLASSERT(bRet);
706 RECT rect = { 0 };
707 ::SendMessage(m_hWndToolBar, RB_GETBANDBORDERS, i, (LPARAM)&rect);
708 rbBand.cx += rect.left + rect.right;
709 bRet = (BOOL)::SendMessage(m_hWndToolBar, RB_SETBANDINFO, i, (LPARAM)&rbBand);
710 ATLASSERT(bRet);
711 }
712 }
713 #endif // (_WIN32_IE >= 0x0400)
714 #endif // _WIN32_WCE
715
716 #ifndef _WIN32_WCE
717 BOOL CreateSimpleStatusBar(LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR)
718 #else // CE specific
719 BOOL CreateSimpleStatusBar(LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, UINT nID = ATL_IDW_STATUS_BAR)
720 #endif // _WIN32_WCE
721 {
722 ATLASSERT(!::IsWindow(m_hWndStatusBar));
723 m_hWndStatusBar = ::CreateStatusWindow(dwStyle, lpstrText, m_hWnd, nID);
724 return (m_hWndStatusBar != NULL);
725 }
726
727 #ifndef _WIN32_WCE
728 BOOL CreateSimpleStatusBar(UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR)
729 #else // CE specific
730 BOOL CreateSimpleStatusBar(UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, UINT nID = ATL_IDW_STATUS_BAR)
731 #endif // _WIN32_WCE
732 {
733 const int cchMax = 128; // max text length is 127 for status bars (+1 for null)
734 TCHAR szText[cchMax] = { 0 };
735 ::LoadString(ModuleHelper::GetResourceInstance(), nTextID, szText, cchMax);
736 return CreateSimpleStatusBar(szText, dwStyle, nID);
737 }
738
739 #ifdef _WIN32_WCE
740 BOOL CreateSimpleCECommandBar(LPTSTR pszMenu = NULL, WORD iButton = 0, DWORD dwFlags = 0, int nCmdBarID = 1)
741 {
742 ATLASSERT(m_hWndCECommandBar == NULL);
743 ATLASSERT(m_hWndToolBar == NULL);
744
745 m_hWndCECommandBar = ::CommandBar_Create(ModuleHelper::GetModuleInstance(), m_hWnd, nCmdBarID);
746 if(m_hWndCECommandBar == NULL)
747 return FALSE;
748
749 m_hWndToolBar = m_hWndCECommandBar;
750
751 BOOL bRet = TRUE;
752
753 if(pszMenu != NULL)
754 bRet &= ::CommandBar_InsertMenubarEx(m_hWndCECommandBar, IS_INTRESOURCE(pszMenu) ? ModuleHelper::GetResourceInstance() : NULL, pszMenu, iButton);
755
756 bRet &= ::CommandBar_AddAdornments(m_hWndCECommandBar, dwFlags, 0);
757
758 return bRet;
759 }
760
761 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
762 BOOL CreateSimpleCEMenuBar(UINT nToolBarId = ATL_IDW_MENU_BAR, DWORD dwFlags = 0, int nBmpId = 0, int cBmpImages = 0)
763 {
764 ATLASSERT(m_hWndCECommandBar == NULL);
765
766 SHMENUBARINFO mbi = { 0 };
767 mbi.cbSize = sizeof(mbi);
768 mbi.hwndParent = m_hWnd;
769 mbi.dwFlags = dwFlags;
770 mbi.nToolBarId = nToolBarId;
771 mbi.hInstRes = ModuleHelper::GetResourceInstance();
772 mbi.nBmpId = nBmpId;
773 mbi.cBmpImages = cBmpImages;
774 mbi.hwndMB = NULL; // This gets set by SHCreateMenuBar
775
776 BOOL bRet = ::SHCreateMenuBar(&mbi);
777 if(bRet != FALSE)
778 {
779 m_hWndCECommandBar = mbi.hwndMB;
780 SizeToMenuBar();
781 }
782
783 return bRet;
784 }
785
786 void SizeToMenuBar() // for menu bar only
787 {
788 ATLASSERT(::IsWindow(m_hWnd));
789 ATLASSERT(::IsWindow(m_hWndCECommandBar));
790
791 RECT rect = { 0 };
792 GetWindowRect(&rect);
793 RECT rectMB = { 0 };
794 ::GetWindowRect(m_hWndCECommandBar, &rectMB);
795 int cy = ::IsWindowVisible(m_hWndCECommandBar) ? rectMB.top - rect.top : rectMB.bottom - rect.top;
796 SetWindowPos(NULL, 0, 0, rect.right - rect.left, cy, SWP_NOZORDER | SWP_NOMOVE);
797 }
798 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
799 #endif // _WIN32_WCE
800
801 void UpdateLayout(BOOL bResizeBars = TRUE)
802 {
803 RECT rect = { 0 };
804 GetClientRect(&rect);
805
806 // position bars and offset their dimensions
807 UpdateBarsPosition(rect, bResizeBars);
808
809 // resize client window
810 if(m_hWndClient != NULL)
811 ::SetWindowPos(m_hWndClient, NULL, rect.left, rect.top,
812 rect.right - rect.left, rect.bottom - rect.top,
813 SWP_NOZORDER | SWP_NOACTIVATE);
814 }
815
816 void UpdateBarsPosition(RECT& rect, BOOL bResizeBars = TRUE)
817 {
818 // resize toolbar
819 if(m_hWndToolBar != NULL && ((DWORD)::GetWindowLong(m_hWndToolBar, GWL_STYLE) & WS_VISIBLE))
820 {
821 if(bResizeBars != FALSE)
822 {
823 ::SendMessage(m_hWndToolBar, WM_SIZE, 0, 0);
824 ::InvalidateRect(m_hWndToolBar, NULL, TRUE);
825 }
826 RECT rectTB = { 0 };
827 ::GetWindowRect(m_hWndToolBar, &rectTB);
828 rect.top += rectTB.bottom - rectTB.top;
829 }
830
831 // resize status bar
832 if(m_hWndStatusBar != NULL && ((DWORD)::GetWindowLong(m_hWndStatusBar, GWL_STYLE) & WS_VISIBLE))
833 {
834 if(bResizeBars != FALSE)
835 ::SendMessage(m_hWndStatusBar, WM_SIZE, 0, 0);
836 RECT rectSB = { 0 };
837 ::GetWindowRect(m_hWndStatusBar, &rectSB);
838 rect.bottom -= rectSB.bottom - rectSB.top;
839 }
840 }
841
842 BOOL PreTranslateMessage(MSG* pMsg)
843 {
844 if(m_hAccel != NULL && ::TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
845 return TRUE;
846 return FALSE;
847 }
848
849 BEGIN_MSG_MAP(CFrameWindowImplBase)
850 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
851 #ifndef _WIN32_WCE
852 MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect)
853 #endif // !_WIN32_WCE
854 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
855 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
856 #ifndef _WIN32_WCE
857 NOTIFY_CODE_HANDLER(TTN_GETDISPINFOA, OnToolTipTextA)
858 NOTIFY_CODE_HANDLER(TTN_GETDISPINFOW, OnToolTipTextW)
859 #endif // !_WIN32_WCE
860 END_MSG_MAP()
861
862 LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
863 {
864 if(m_hWndClient != NULL) // view will paint itself instead
865 return 1;
866
867 bHandled = FALSE;
868 return 0;
869 }
870
871 #ifndef _WIN32_WCE
872 LRESULT OnMenuSelect(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
873 {
874 bHandled = FALSE;
875
876 if(m_hWndStatusBar == NULL)
877 return 1;
878
879 WORD wFlags = HIWORD(wParam);
880 if(wFlags == 0xFFFF && lParam == NULL) // menu closing
881 {
882 ::SendMessage(m_hWndStatusBar, SB_SIMPLE, FALSE, 0L);
883 }
884 else
885 {
886 const int cchBuff = 256;
887 TCHAR szBuff[cchBuff] = { 0 };
888 if(!(wFlags & MF_POPUP))
889 {
890 WORD wID = LOWORD(wParam);
891 // check for special cases
892 if(wID >= 0xF000 && wID < 0xF1F0) // system menu IDs
893 wID = (WORD)(((wID - 0xF000) >> 4) + ATL_IDS_SCFIRST);
894 else if(wID >= ID_FILE_MRU_FIRST && wID <= ID_FILE_MRU_LAST) // MRU items
895 wID = ATL_IDS_MRU_FILE;
896 else if(wID >= ATL_IDM_FIRST_MDICHILD && wID <= ATL_IDM_LAST_MDICHILD) // MDI child windows
897 wID = ATL_IDS_MDICHILD;
898
899 int nRet = ::LoadString(ModuleHelper::GetResourceInstance(), wID, szBuff, cchBuff);
900 for(int i = 0; i < nRet; i++)
901 {
902 if(szBuff[i] == _T('\n'))
903 {
904 szBuff[i] = 0;
905 break;
906 }
907 }
908 }
909 ::SendMessage(m_hWndStatusBar, SB_SIMPLE, TRUE, 0L);
910 ::SendMessage(m_hWndStatusBar, SB_SETTEXT, (255 | SBT_NOBORDERS), (LPARAM)szBuff);
911 }
912
913 return 1;
914 }
915 #endif // !_WIN32_WCE
916
917 LRESULT OnSetFocus(UINT, WPARAM, LPARAM, BOOL& bHandled)
918 {
919 if(m_hWndClient != NULL)
920 ::SetFocus(m_hWndClient);
921
922 bHandled = FALSE;
923 return 1;
924 }
925
926 LRESULT OnDestroy(UINT, WPARAM, LPARAM, BOOL& bHandled)
927 {
928 if((GetStyle() & (WS_CHILD | WS_POPUP)) == 0)
929 ::PostQuitMessage(1);
930
931 bHandled = FALSE;
932 return 1;
933 }
934
935 #ifndef _WIN32_WCE
936 LRESULT OnToolTipTextA(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/)
937 {
938 LPNMTTDISPINFOA pDispInfo = (LPNMTTDISPINFOA)pnmh;
939 if((idCtrl != 0) && !(pDispInfo->uFlags & TTF_IDISHWND))
940 {
941 const int cchBuff = 256;
942 char szBuff[cchBuff] = { 0 };
943 int nRet = ::LoadStringA(ModuleHelper::GetResourceInstance(), idCtrl, szBuff, cchBuff);
944 for(int i = 0; i < nRet; i++)
945 {
946 if(szBuff[i] == '\n')
947 {
948 SecureHelper::strncpyA_x(pDispInfo->szText, _countof(pDispInfo->szText), &szBuff[i + 1], _TRUNCATE);
949 break;
950 }
951 }
952 #if (_WIN32_IE >= 0x0300)
953 if(nRet > 0) // string was loaded, save it
954 pDispInfo->uFlags |= TTF_DI_SETITEM;
955 #endif // (_WIN32_IE >= 0x0300)
956 }
957
958 return 0;
959 }
960
961 LRESULT OnToolTipTextW(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/)
962 {
963 LPNMTTDISPINFOW pDispInfo = (LPNMTTDISPINFOW)pnmh;
964 if((idCtrl != 0) && !(pDispInfo->uFlags & TTF_IDISHWND))
965 {
966 const int cchBuff = 256;
967 wchar_t szBuff[cchBuff] = { 0 };
968 int nRet = ::LoadStringW(ModuleHelper::GetResourceInstance(), idCtrl, szBuff, cchBuff);
969 for(int i = 0; i < nRet; i++)
970 {
971 if(szBuff[i] == L'\n')
972 {
973 SecureHelper::strncpyW_x(pDispInfo->szText, _countof(pDispInfo->szText), &szBuff[i + 1], _TRUNCATE);
974 break;
975 }
976 }
977 #if (_WIN32_IE >= 0x0300)
978 if(nRet > 0) // string was loaded, save it
979 pDispInfo->uFlags |= TTF_DI_SETITEM;
980 #endif // (_WIN32_IE >= 0x0300)
981 }
982
983 return 0;
984 }
985 #endif // !_WIN32_WCE
986
987 // Implementation - chevron menu support
988 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
989 bool PrepareChevronMenu(_ChevronMenuInfo& cmi)
990 {
991 // get rebar and toolbar
992 REBARBANDINFO rbbi = { RunTimeHelper::SizeOf_REBARBANDINFO() };
993 rbbi.fMask = RBBIM_CHILD;
994 BOOL bRet = (BOOL)::SendMessage(cmi.lpnm->hdr.hwndFrom, RB_GETBANDINFO, cmi.lpnm->uBand, (LPARAM)&rbbi);
995 ATLASSERT(bRet);
996
997 // assume the band is a toolbar
998 ATL::CWindow wnd = rbbi.hwndChild;
999 int nCount = (int)wnd.SendMessage(TB_BUTTONCOUNT);
1000 if(nCount <= 0) // probably not a toolbar
1001 return false;
1002
1003 // check if it's a command bar
1004 CMenuHandle menuCmdBar = (HMENU)wnd.SendMessage(CBRM_GETMENU);
1005 cmi.bCmdBar = (menuCmdBar.m_hMenu != NULL);
1006
1007 // build a menu from hidden items
1008 CMenuHandle menu;
1009 bRet = menu.CreatePopupMenu();
1010 ATLASSERT(bRet);
1011 RECT rcClient = { 0 };
1012 bRet = wnd.GetClientRect(&rcClient);
1013 ATLASSERT(bRet);
1014 for(int i = 0; i < nCount; i++)
1015 {
1016 TBBUTTON tbb = { 0 };
1017 bRet = (BOOL)wnd.SendMessage(TB_GETBUTTON, i, (LPARAM)&tbb);
1018 ATLASSERT(bRet);
1019 // skip hidden buttons
1020 if((tbb.fsState & TBSTATE_HIDDEN) != 0)
1021 continue;
1022 RECT rcButton = { 0 };
1023 bRet = (BOOL)wnd.SendMessage(TB_GETITEMRECT, i, (LPARAM)&rcButton);
1024 ATLASSERT(bRet);
1025 bool bEnabled = ((tbb.fsState & TBSTATE_ENABLED) != 0);
1026 if((rcButton.right > rcClient.right) || (rcButton.bottom > rcClient.bottom))
1027 {
1028 if(tbb.fsStyle & BTNS_SEP)
1029 {
1030 if(menu.GetMenuItemCount() > 0)
1031 menu.AppendMenu(MF_SEPARATOR);
1032 }
1033 else if(cmi.bCmdBar)
1034 {
1035 const int cchBuff = 200;
1036 TCHAR szBuff[cchBuff] = { 0 };
1037 CMenuItemInfo mii;
1038 mii.fMask = MIIM_TYPE | MIIM_SUBMENU;
1039 mii.dwTypeData = szBuff;
1040 mii.cch = cchBuff;
1041 bRet = menuCmdBar.GetMenuItemInfo(i, TRUE, &mii);
1042 ATLASSERT(bRet);
1043 // Note: CmdBar currently supports only drop-down items
1044 ATLASSERT(::IsMenu(mii.hSubMenu));
1045 bRet = menu.AppendMenu(MF_STRING | MF_POPUP | (bEnabled ? MF_ENABLED : MF_GRAYED), (UINT_PTR)mii.hSubMenu, mii.dwTypeData);
1046 ATLASSERT(bRet);
1047 }
1048 else
1049 {
1050 // get button's text
1051 const int cchBuff = 200;
1052 TCHAR szBuff[cchBuff] = { 0 };
1053 LPCTSTR lpstrText = szBuff;
1054 TBBUTTONINFO tbbi = { 0 };
1055 tbbi.cbSize = sizeof(TBBUTTONINFO);
1056 tbbi.dwMask = TBIF_TEXT;
1057 tbbi.pszText = szBuff;
1058 tbbi.cchText = cchBuff;
1059 if((wnd.SendMessage(TB_GETBUTTONINFO, tbb.idCommand, (LPARAM)&tbbi) == -1) || (szBuff[0] == 0))
1060 {
1061 // no text for this button, try a resource string
1062 lpstrText = _T("");
1063 int nRet = ::LoadString(ModuleHelper::GetResourceInstance(), tbb.idCommand, szBuff, cchBuff);
1064 for(int n = 0; n < nRet; n++)
1065 {
1066 if(szBuff[n] == _T('\n'))
1067 {
1068 lpstrText = &szBuff[n + 1];
1069 break;
1070 }
1071 }
1072 }
1073 bRet = menu.AppendMenu(MF_STRING | (bEnabled ? MF_ENABLED : MF_GRAYED), tbb.idCommand, lpstrText);
1074 ATLASSERT(bRet);
1075 }
1076 }
1077 }
1078
1079 if(menu.GetMenuItemCount() == 0) // no hidden buttons after all
1080 {
1081 menu.DestroyMenu();
1082 ::MessageBeep((UINT)-1);
1083 return false;
1084 }
1085
1086 cmi.hMenu = menu;
1087 return true;
1088 }
1089
1090 void DisplayChevronMenu(_ChevronMenuInfo& cmi)
1091 {
1092 #ifndef TPM_VERPOSANIMATION
1093 const UINT TPM_VERPOSANIMATION = 0x1000L; // Menu animation flag
1094 #endif
1095 // convert chevron rect to screen coordinates
1096 ATL::CWindow wndFrom = cmi.lpnm->hdr.hwndFrom;
1097 POINT pt = { cmi.lpnm->rc.left, cmi.lpnm->rc.bottom };
1098 wndFrom.MapWindowPoints(NULL, &pt, 1);
1099 RECT rc = cmi.lpnm->rc;
1100 wndFrom.MapWindowPoints(NULL, &rc);
1101 // set up flags and rect
1102 UINT uMenuFlags = TPM_LEFTBUTTON | TPM_VERTICAL | TPM_LEFTALIGN | TPM_TOPALIGN | (!AtlIsOldWindows() ? TPM_VERPOSANIMATION : 0);
1103 TPMPARAMS TPMParams = { 0 };
1104 TPMParams.cbSize = sizeof(TPMPARAMS);
1105 TPMParams.rcExclude = rc;
1106 // check if this window has a command bar
1107 HWND hWndCmdBar = (HWND)::SendMessage(m_hWnd, CBRM_GETCMDBAR, 0, 0L);
1108 if(::IsWindow(hWndCmdBar))
1109 {
1110 CBRPOPUPMENU CBRPopupMenu = { sizeof(CBRPOPUPMENU), cmi.hMenu, uMenuFlags, pt.x, pt.y, &TPMParams };
1111 ::SendMessage(hWndCmdBar, CBRM_TRACKPOPUPMENU, 0, (LPARAM)&CBRPopupMenu);
1112 }
1113 else
1114 {
1115 CMenuHandle menu = cmi.hMenu;
1116 menu.TrackPopupMenuEx(uMenuFlags, pt.x, pt.y, m_hWnd, &TPMParams);
1117 }
1118 }
1119
1120 void CleanupChevronMenu(_ChevronMenuInfo& cmi)
1121 {
1122 CMenuHandle menu = cmi.hMenu;
1123 // if menu is from a command bar, detach submenus so they are not destroyed
1124 if(cmi.bCmdBar)
1125 {
1126 for(int i = menu.GetMenuItemCount() - 1; i >=0; i--)
1127 menu.RemoveMenu(i, MF_BYPOSITION);
1128 }
1129 // destroy menu
1130 menu.DestroyMenu();
1131 // convert chevron rect to screen coordinates
1132 ATL::CWindow wndFrom = cmi.lpnm->hdr.hwndFrom;
1133 RECT rc = cmi.lpnm->rc;
1134 wndFrom.MapWindowPoints(NULL, &rc);
1135 // eat next message if click is on the same button
1136 MSG msg = { 0 };
1137 if(::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE) && ::PtInRect(&rc, msg.pt))
1138 ::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_REMOVE);
1139 }
1140 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
1141 };
1142
1143
1144 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CFrameWinTraits>
1145 class ATL_NO_VTABLE CFrameWindowImpl : public CFrameWindowImplBase< TBase, TWinTraits >
1146 {
1147 public:
1148 HWND Create(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
1149 DWORD dwStyle = 0, DWORD dwExStyle = 0,
1150 HMENU hMenu = NULL, LPVOID lpCreateParam = NULL)
1151 {
1152 ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc);
1153
1154 dwStyle = T::GetWndStyle(dwStyle);
1155 dwExStyle = T::GetWndExStyle(dwExStyle);
1156
1157 if(rect.m_lpRect == NULL)
1158 rect.m_lpRect = &TBase::rcDefault;
1159
1160 return CFrameWindowImplBase< TBase, TWinTraits >::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, hMenu, atom, lpCreateParam);
1161 }
1162
1163 HWND CreateEx(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL)
1164 {
1165 const int cchName = 256;
1166 TCHAR szWindowName[cchName] = { 0 };
1167 #ifndef _WIN32_WCE
1168 ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName);
1169 HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
1170 #else // CE specific
1171 ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName);
1172
1173 // This always needs to be NULL for Windows CE.
1174 // Frame Window menus have to go onto the CommandBar.
1175 // Use CreateSimpleCECommandBar
1176 HMENU hMenu = NULL;
1177 #endif // _WIN32_WCE
1178
1179 T* pT = static_cast<T*>(this);
1180 HWND hWnd = pT->Create(hWndParent, rect, szWindowName, dwStyle, dwExStyle, hMenu, lpCreateParam);
1181
1182 if(hWnd != NULL)
1183 m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
1184
1185 return hWnd;
1186 }
1187
1188 BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
1189 {
1190 if(nResourceID == 0)
1191 nResourceID = T::GetWndClassInfo().m_uCommonResourceID;
1192 #ifndef _WIN32_WCE
1193 ATLASSERT(!::IsWindow(m_hWndToolBar));
1194 m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE, dwStyle, nID);
1195 return (m_hWndToolBar != NULL);
1196 #else // CE specific
1197 HWND hWnd= T::CreateSimpleToolBarCtrl(m_hWndCECommandBar, nResourceID, TRUE, dwStyle, nID);
1198 return (hWnd != NULL);
1199 #endif // _WIN32_WCE
1200 }
1201
1202 #ifdef _WIN32_WCE
1203 // CE specific variant that returns the handle of the toolbar
1204 HWND CreateSimpleCEToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
1205 {
1206 if(nResourceID == 0)
1207 nResourceID = T::GetWndClassInfo().m_uCommonResourceID;
1208
1209 return T::CreateSimpleToolBarCtrl(m_hWndCECommandBar, nResourceID, TRUE, dwStyle, nID);
1210 }
1211 #endif // _WIN32_WCE
1212
1213 // message map and handlers
1214 typedef CFrameWindowImplBase< TBase, TWinTraits > _baseClass;
1215
1216 BEGIN_MSG_MAP(CFrameWindowImpl)
1217 MESSAGE_HANDLER(WM_SIZE, OnSize)
1218 #ifndef _ATL_NO_REBAR_SUPPORT
1219 #if (_WIN32_IE >= 0x0400)
1220 NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize)
1221 #endif // (_WIN32_IE >= 0x0400)
1222 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
1223 NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed)
1224 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
1225 #endif // !_ATL_NO_REBAR_SUPPORT
1226 CHAIN_MSG_MAP(_baseClass)
1227 END_MSG_MAP()
1228
1229 LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
1230 {
1231 if(wParam != SIZE_MINIMIZED)
1232 {
1233 T* pT = static_cast<T*>(this);
1234 pT->UpdateLayout();
1235 }
1236 bHandled = FALSE;
1237 return 1;
1238 }
1239
1240 #ifndef _ATL_NO_REBAR_SUPPORT
1241 #if (_WIN32_IE >= 0x0400)
1242 LRESULT OnReBarAutoSize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
1243 {
1244 T* pT = static_cast<T*>(this);
1245 pT->UpdateLayout(FALSE);
1246 return 0;
1247 }
1248 #endif // (_WIN32_IE >= 0x0400)
1249
1250 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
1251 LRESULT OnChevronPushed(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
1252 {
1253 T* pT = static_cast<T*>(this);
1254 _ChevronMenuInfo cmi = { NULL, (LPNMREBARCHEVRON)pnmh, false };
1255 if(!pT->PrepareChevronMenu(cmi))
1256 {
1257 bHandled = FALSE;
1258 return 1;
1259 }
1260 // display a popup menu with hidden items
1261 pT->DisplayChevronMenu(cmi);
1262 // cleanup
1263 pT->CleanupChevronMenu(cmi);
1264 return 0;
1265 }
1266 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
1267 #endif // !_ATL_NO_REBAR_SUPPORT
1268 };
1269
1270
1271 ///////////////////////////////////////////////////////////////////////////////
1272 // AtlCreateSimpleToolBar - helper for creating simple toolbars
1273
1274 #ifndef _WIN32_WCE
1275
1276 inline HWND AtlCreateSimpleToolBar(HWND hWndParent, UINT nResourceID, BOOL bInitialSeparator = FALSE,
1277 DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
1278 {
1279 return CFrameWindowImplBase<>::CreateSimpleToolBarCtrl(hWndParent, nResourceID, bInitialSeparator, dwStyle, nID);
1280 }
1281
1282 #endif // !_WIN32_WCE
1283
1284
1285 ///////////////////////////////////////////////////////////////////////////////
1286 // CMDIWindow
1287
1288 #ifndef _WIN32_WCE
1289
1290 #ifndef _WTL_MDIWINDOWMENU_TEXT
1291 #define _WTL_MDIWINDOWMENU_TEXT _T("&Window")
1292 #endif
1293
1294 class CMDIWindow : public ATL::CWindow
1295 {
1296 public:
1297 // Data members
1298 HWND m_hWndMDIClient;
1299 HMENU m_hMenu;
1300
1301 // Constructors
1302 CMDIWindow(HWND hWnd = NULL) : ATL::CWindow(hWnd), m_hWndMDIClient(NULL), m_hMenu(NULL)
1303 { }
1304
1305 CMDIWindow& operator =(HWND hWnd)
1306 {
1307 m_hWnd = hWnd;
1308 return *this;
1309 }
1310
1311 // Operations
1312 HWND MDIGetActive(BOOL* lpbMaximized = NULL)
1313 {
1314 ATLASSERT(::IsWindow(m_hWndMDIClient));
1315 return (HWND)::SendMessage(m_hWndMDIClient, WM_MDIGETACTIVE, 0, (LPARAM)lpbMaximized);
1316 }
1317
1318 void MDIActivate(HWND hWndChildToActivate)
1319 {
1320 ATLASSERT(::IsWindow(m_hWndMDIClient));
1321 ATLASSERT(::IsWindow(hWndChildToActivate));
1322 ::SendMessage(m_hWndMDIClient, WM_MDIACTIVATE, (WPARAM)hWndChildToActivate, 0);
1323 }
1324
1325 void MDINext(HWND hWndChild, BOOL bPrevious = FALSE)
1326 {
1327 ATLASSERT(::IsWindow(m_hWndMDIClient));
1328 ATLASSERT(hWndChild == NULL || ::IsWindow(hWndChild));
1329 ::SendMessage(m_hWndMDIClient, WM_MDINEXT, (WPARAM)hWndChild, (LPARAM)bPrevious);
1330 }
1331
1332 void MDIMaximize(HWND hWndChildToMaximize)
1333 {
1334 ATLASSERT(::IsWindow(m_hWndMDIClient));
1335 ATLASSERT(::IsWindow(hWndChildToMaximize));
1336 ::SendMessage(m_hWndMDIClient, WM_MDIMAXIMIZE, (WPARAM)hWndChildToMaximize, 0);
1337 }
1338
1339 void MDIRestore(HWND hWndChildToRestore)
1340 {
1341 ATLASSERT(::IsWindow(m_hWndMDIClient));
1342 ATLASSERT(::IsWindow(hWndChildToRestore));
1343 ::SendMessage(m_hWndMDIClient, WM_MDIRESTORE, (WPARAM)hWndChildToRestore, 0);
1344 }
1345
1346 void MDIDestroy(HWND hWndChildToDestroy)
1347 {
1348 ATLASSERT(::IsWindow(m_hWndMDIClient));
1349 ATLASSERT(::IsWindow(hWndChildToDestroy));
1350 ::SendMessage(m_hWndMDIClient, WM_MDIDESTROY, (WPARAM)hWndChildToDestroy, 0);
1351 }
1352
1353 BOOL MDICascade(UINT uFlags = 0)
1354 {
1355 ATLASSERT(::IsWindow(m_hWndMDIClient));
1356 return (BOOL)::SendMessage(m_hWndMDIClient, WM_MDICASCADE, (WPARAM)uFlags, 0);
1357 }
1358
1359 BOOL MDITile(UINT uFlags = MDITILE_HORIZONTAL)
1360 {
1361 ATLASSERT(::IsWindow(m_hWndMDIClient));
1362 return (BOOL)::SendMessage(m_hWndMDIClient, WM_MDITILE, (WPARAM)uFlags, 0);
1363 }
1364
1365 void MDIIconArrange()
1366 {
1367 ATLASSERT(::IsWindow(m_hWndMDIClient));
1368 ::SendMessage(m_hWndMDIClient, WM_MDIICONARRANGE, 0, 0);
1369 }
1370
1371 HMENU MDISetMenu(HMENU hMenuFrame, HMENU hMenuWindow)
1372 {
1373 ATLASSERT(::IsWindow(m_hWndMDIClient));
1374 return (HMENU)::SendMessage(m_hWndMDIClient, WM_MDISETMENU, (WPARAM)hMenuFrame, (LPARAM)hMenuWindow);
1375 }
1376
1377 HMENU MDIRefreshMenu()
1378 {
1379 ATLASSERT(::IsWindow(m_hWndMDIClient));
1380 return (HMENU)::SendMessage(m_hWndMDIClient, WM_MDIREFRESHMENU, 0, 0);
1381 }
1382
1383 // Additional operations
1384 static HMENU GetStandardWindowMenu(HMENU hMenu)
1385 {
1386 int nCount = ::GetMenuItemCount(hMenu);
1387 if(nCount == -1)
1388 return NULL;
1389 int nLen = ::GetMenuString(hMenu, nCount - 2, NULL, 0, MF_BYPOSITION);
1390 if(nLen == 0)
1391 return NULL;
1392 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
1393 LPTSTR lpszText = buff.Allocate(nLen + 1);
1394 if(lpszText == NULL)
1395 return NULL;
1396 if(::GetMenuString(hMenu, nCount - 2, lpszText, nLen + 1, MF_BYPOSITION) != nLen)
1397 return NULL;
1398 if(lstrcmp(lpszText, _WTL_MDIWINDOWMENU_TEXT) != 0)
1399 return NULL;
1400 return ::GetSubMenu(hMenu, nCount - 2);
1401 }
1402
1403 void SetMDIFrameMenu()
1404 {
1405 HMENU hWindowMenu = GetStandardWindowMenu(m_hMenu);
1406 MDISetMenu(m_hMenu, hWindowMenu);
1407 MDIRefreshMenu();
1408 ::DrawMenuBar(GetMDIFrame());
1409 }
1410
1411 HWND GetMDIFrame() const
1412 {
1413 return ::GetParent(m_hWndMDIClient);
1414 }
1415 };
1416
1417 #endif // !_WIN32_WCE
1418
1419
1420 ///////////////////////////////////////////////////////////////////////////////
1421 // CMDIFrameWindowImpl
1422
1423 #ifndef _WIN32_WCE
1424
1425 // MDI child command chaining macro (only for MDI frame windows)
1426 #define CHAIN_MDI_CHILD_COMMANDS() \
1427 if(uMsg == WM_COMMAND) \
1428 { \
1429 HWND hWndChild = MDIGetActive(); \
1430 if(hWndChild != NULL) \
1431 ::SendMessage(hWndChild, uMsg, wParam, lParam); \
1432 }
1433
1434 template <class T, class TBase = CMDIWindow, class TWinTraits = ATL::CFrameWinTraits>
1435 class ATL_NO_VTABLE CMDIFrameWindowImpl : public CFrameWindowImplBase<TBase, TWinTraits >
1436 {
1437 public:
1438 HWND Create(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
1439 DWORD dwStyle = 0, DWORD dwExStyle = 0,
1440 HMENU hMenu = NULL, LPVOID lpCreateParam = NULL)
1441 {
1442 m_hMenu = hMenu;
1443 ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc);
1444
1445 dwStyle = T::GetWndStyle(dwStyle);
1446 dwExStyle = T::GetWndExStyle(dwExStyle);
1447
1448 if(rect.m_lpRect == NULL)
1449 rect.m_lpRect = &TBase::rcDefault;
1450
1451 return CFrameWindowImplBase<TBase, TWinTraits >::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, hMenu, atom, lpCreateParam);
1452 }
1453
1454 HWND CreateEx(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL)
1455 {
1456 const int cchName = 256;
1457 TCHAR szWindowName[cchName] = { 0 };
1458 ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName);
1459 HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
1460
1461 T* pT = static_cast<T*>(this);
1462 HWND hWnd = pT->Create(hWndParent, rect, szWindowName, dwStyle, dwExStyle, hMenu, lpCreateParam);
1463
1464 if(hWnd != NULL)
1465 m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
1466
1467 return hWnd;
1468 }
1469
1470 BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
1471 {
1472 ATLASSERT(!::IsWindow(m_hWndToolBar));
1473 if(nResourceID == 0)
1474 nResourceID = T::GetWndClassInfo().m_uCommonResourceID;
1475 m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE, dwStyle, nID);
1476 return (m_hWndToolBar != NULL);
1477 }
1478
1479 virtual WNDPROC GetWindowProc()
1480 {
1481 return MDIFrameWindowProc;
1482 }
1483
1484 static LRESULT CALLBACK MDIFrameWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1485 {
1486 CMDIFrameWindowImpl< T, TBase, TWinTraits >* pThis = (CMDIFrameWindowImpl< T, TBase, TWinTraits >*)hWnd;
1487 // set a ptr to this message and save the old value
1488 #if (_ATL_VER >= 0x0700)
1489 ATL::_ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam);
1490 const ATL::_ATL_MSG* pOldMsg = pThis->m_pCurrentMsg;
1491 #else // !(_ATL_VER >= 0x0700)
1492 MSG msg = { pThis->m_hWnd, uMsg, wParam, lParam, 0, { 0, 0 } };
1493 const MSG* pOldMsg = pThis->m_pCurrentMsg;
1494 #endif // !(_ATL_VER >= 0x0700)
1495 pThis->m_pCurrentMsg = &msg;
1496 // pass to the message map to process
1497 LRESULT lRes = 0;
1498 BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0);
1499 // restore saved value for the current message
1500 ATLASSERT(pThis->m_pCurrentMsg == &msg);
1501 pThis->m_pCurrentMsg = pOldMsg;
1502 // do the default processing if message was not handled
1503 if(!bRet)
1504 {
1505 if(uMsg != WM_NCDESTROY)
1506 {
1507 lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
1508 }
1509 else
1510 {
1511 // unsubclass, if needed
1512 LONG_PTR pfnWndProc = ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC);
1513 lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
1514 if(pThis->m_pfnSuperWindowProc != ::DefWindowProc && ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC) == pfnWndProc)
1515 ::SetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC, (LONG_PTR)pThis->m_pfnSuperWindowProc);
1516 #if (_ATL_VER >= 0x0700)
1517 // mark window as destryed
1518 pThis->m_dwState |= WINSTATE_DESTROYED;
1519 #else // !(_ATL_VER >= 0x0700)
1520 // clear out window handle
1521 HWND hWnd = pThis->m_hWnd;
1522 pThis->m_hWnd = NULL;
1523 // clean up after window is destroyed
1524 pThis->OnFinalMessage(hWnd);
1525 #endif // !(_ATL_VER >= 0x0700)
1526 }
1527 }
1528 #if (_ATL_VER >= 0x0700)
1529 if(pThis->m_dwState & WINSTATE_DESTROYED && pThis->m_pCurrentMsg == NULL)
1530 {
1531 // clear out window handle
1532 HWND hWndThis = pThis->m_hWnd;
1533 pThis->m_hWnd = NULL;
1534 pThis->m_dwState &= ~WINSTATE_DESTROYED;
1535 // clean up after window is destroyed
1536 pThis->OnFinalMessage(hWndThis);
1537 }
1538 #endif // (_ATL_VER >= 0x0700)
1539 return lRes;
1540 }
1541
1542 // Overriden to call DefWindowProc which uses DefFrameProc
1543 LRESULT DefWindowProc()
1544 {
1545 const MSG* pMsg = m_pCurrentMsg;
1546 LRESULT lRes = 0;
1547 if (pMsg != NULL)
1548 lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg->lParam);
1549 return lRes;
1550 }
1551
1552 LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
1553 {
1554 return ::DefFrameProc(m_hWnd, m_hWndMDIClient, uMsg, wParam, lParam);
1555 }
1556
1557 BOOL PreTranslateMessage(MSG* pMsg)
1558 {
1559 if(CFrameWindowImplBase<TBase, TWinTraits>::PreTranslateMessage(pMsg))
1560 return TRUE;
1561 return ::TranslateMDISysAccel(m_hWndMDIClient, pMsg);
1562 }
1563
1564 HWND CreateMDIClient(HMENU hWindowMenu = NULL, UINT nID = ATL_IDW_CLIENT, UINT nFirstChildID = ATL_IDM_FIRST_MDICHILD)
1565 {
1566 DWORD dwStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | MDIS_ALLCHILDSTYLES;
1567 DWORD dwExStyle = WS_EX_CLIENTEDGE;
1568
1569 CLIENTCREATESTRUCT ccs = { 0 };
1570 ccs.hWindowMenu = hWindowMenu;
1571 ccs.idFirstChild = nFirstChildID;
1572
1573 if((GetStyle() & (WS_HSCROLL | WS_VSCROLL)) != 0)
1574 {
1575 // parent MDI frame's scroll styles move to the MDICLIENT
1576 dwStyle |= (GetStyle() & (WS_HSCROLL | WS_VSCROLL));
1577
1578 // fast way to turn off the scrollbar bits (without a resize)
1579 ModifyStyle(WS_HSCROLL | WS_VSCROLL, 0, SWP_NOREDRAW | SWP_FRAMECHANGED);
1580 }
1581
1582 // Create MDICLIENT window
1583 m_hWndClient = ::CreateWindowEx(dwExStyle, _T("MDIClient"), NULL,
1584 dwStyle, 0, 0, 1, 1, m_hWnd, (HMENU)LongToHandle(nID),
1585 ModuleHelper::GetModuleInstance(), (LPVOID)&ccs);
1586 if (m_hWndClient == NULL)
1587 {
1588 ATLTRACE2(atlTraceUI, 0, _T("MDI Frame failed to create MDICLIENT.\n"));
1589 return NULL;
1590 }
1591
1592 // Move it to the top of z-order
1593 ::BringWindowToTop(m_hWndClient);
1594
1595 // set as MDI client window
1596 m_hWndMDIClient = m_hWndClient;
1597
1598 // update to proper size
1599 T* pT = static_cast<T*>(this);
1600 pT->UpdateLayout();
1601
1602 return m_hWndClient;
1603 }
1604
1605 typedef CFrameWindowImplBase<TBase, TWinTraits > _baseClass;
1606
1607 BEGIN_MSG_MAP(CMDIFrameWindowImpl)
1608 MESSAGE_HANDLER(WM_SIZE, OnSize)
1609 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
1610 MESSAGE_HANDLER(WM_MDISETMENU, OnMDISetMenu)
1611 #ifndef _ATL_NO_REBAR_SUPPORT
1612 #if (_WIN32_IE >= 0x0400)
1613 NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize)
1614 #endif // (_WIN32_IE >= 0x0400)
1615 #if (_WIN32_IE >= 0x0500)
1616 NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed)
1617 #endif // (_WIN32_IE >= 0x0500)
1618 #endif // !_ATL_NO_REBAR_SUPPORT
1619 CHAIN_MSG_MAP(_baseClass)
1620 END_MSG_MAP()
1621
1622 LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1623 {
1624 if(wParam != SIZE_MINIMIZED)
1625 {
1626 T* pT = static_cast<T*>(this);
1627 pT->UpdateLayout();
1628 }
1629 // message must be handled, otherwise DefFrameProc would resize the client again
1630 return 0;
1631 }
1632
1633 LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
1634 {
1635 // don't allow CFrameWindowImplBase to handle this one
1636 return DefWindowProc(uMsg, wParam, lParam);
1637 }
1638
1639 LRESULT OnMDISetMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1640 {
1641 SetMDIFrameMenu();
1642 return 0;
1643 }
1644
1645 #ifndef _ATL_NO_REBAR_SUPPORT
1646 #if (_WIN32_IE >= 0x0400)
1647 LRESULT OnReBarAutoSize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
1648 {
1649 T* pT = static_cast<T*>(this);
1650 pT->UpdateLayout(FALSE);
1651 return 0;
1652 }
1653 #endif // (_WIN32_IE >= 0x0400)
1654
1655 #if (_WIN32_IE >= 0x0500)
1656 LRESULT OnChevronPushed(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
1657 {
1658 T* pT = static_cast<T*>(this);
1659 _ChevronMenuInfo cmi = { NULL, (LPNMREBARCHEVRON)pnmh, false };
1660 if(!pT->PrepareChevronMenu(cmi))
1661 {
1662 bHandled = FALSE;
1663 return 1;
1664 }
1665 // display a popup menu with hidden items
1666 pT->DisplayChevronMenu(cmi);
1667 // cleanup
1668 pT->CleanupChevronMenu(cmi);
1669 return 0;
1670 }
1671 #endif // (_WIN32_IE >= 0x0500)
1672 #endif // !_ATL_NO_REBAR_SUPPORT
1673 };
1674
1675 #endif // !_WIN32_WCE
1676
1677
1678 ///////////////////////////////////////////////////////////////////////////////
1679 // CMDIChildWindowImpl
1680
1681 #ifndef _WIN32_WCE
1682
1683 template <class T, class TBase = CMDIWindow, class TWinTraits = ATL::CMDIChildWinTraits>
1684 class ATL_NO_VTABLE CMDIChildWindowImpl : public CFrameWindowImplBase<TBase, TWinTraits >
1685 {
1686 public:
1687 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
1688 DWORD dwStyle = 0, DWORD dwExStyle = 0,
1689 UINT nMenuID = 0, LPVOID lpCreateParam = NULL)
1690 {
1691 ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc);
1692
1693 if(nMenuID != 0)
1694 m_hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(nMenuID));
1695
1696 dwStyle = T::GetWndStyle(dwStyle);
1697 dwExStyle = T::GetWndExStyle(dwExStyle);
1698
1699 dwExStyle |= WS_EX_MDICHILD; // force this one
1700 m_pfnSuperWindowProc = ::DefMDIChildProc;
1701 m_hWndMDIClient = hWndParent;
1702 ATLASSERT(::IsWindow(m_hWndMDIClient));
1703
1704 if(rect.m_lpRect == NULL)
1705 rect.m_lpRect = &TBase::rcDefault;
1706
1707 // If the currently active MDI child is maximized, we want to create this one maximized too
1708 ATL::CWindow wndParent = hWndParent;
1709 BOOL bMaximized = FALSE;
1710 wndParent.SendMessage(WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized);
1711 if(bMaximized)
1712 wndParent.SetRedraw(FALSE);
1713
1714 HWND hWnd = CFrameWindowImplBase<TBase, TWinTraits >::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, (UINT)0U, atom, lpCreateParam);
1715
1716 if(bMaximized)
1717 {
1718 // Maximize and redraw everything
1719 if(hWnd != NULL)
1720 MDIMaximize(hWnd);
1721 wndParent.SetRedraw(TRUE);
1722 wndParent.RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
1723 ::SetFocus(GetMDIFrame()); // focus will be set back to this window
1724 }
1725 else if(hWnd != NULL && ::IsWindowVisible(m_hWnd) && !::IsChild(hWnd, ::GetFocus()))
1726 {
1727 ::SetFocus(hWnd);
1728 }
1729
1730 return hWnd;
1731 }
1732
1733 HWND CreateEx(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR lpcstrWindowName = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL)
1734 {
1735 const int cchName = 256;
1736 TCHAR szWindowName[cchName] = { 0 };
1737 if(lpcstrWindowName == NULL)
1738 {
1739 ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName);
1740 lpcstrWindowName = szWindowName;
1741 }
1742
1743 T* pT = static_cast<T*>(this);
1744 HWND hWnd = pT->Create(hWndParent, rect, lpcstrWindowName, dwStyle, dwExStyle, T::GetWndClassInfo().m_uCommonResourceID, lpCreateParam);
1745
1746 if(hWnd != NULL)
1747 m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
1748
1749 return hWnd;
1750 }
1751
1752 BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
1753 {
1754 ATLASSERT(!::IsWindow(m_hWndToolBar));
1755 if(nResourceID == 0)
1756 nResourceID = T::GetWndClassInfo().m_uCommonResourceID;
1757 m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE, dwStyle, nID);
1758 return (m_hWndToolBar != NULL);
1759 }
1760
1761 BOOL UpdateClientEdge(LPRECT lpRect = NULL)
1762 {
1763 // only adjust for active MDI child window
1764 HWND hWndChild = MDIGetActive();
1765 if(hWndChild != NULL && hWndChild != m_hWnd)
1766 return FALSE;
1767
1768 // need to adjust the client edge style as max/restore happens
1769 DWORD dwStyle = ::GetWindowLong(m_hWndMDIClient, GWL_EXSTYLE);
1770 DWORD dwNewStyle = dwStyle;
1771 if(hWndChild != NULL && ((GetExStyle() & WS_EX_CLIENTEDGE) == 0) && ((GetStyle() & WS_MAXIMIZE) != 0))
1772 dwNewStyle &= ~(WS_EX_CLIENTEDGE);
1773 else
1774 dwNewStyle |= WS_EX_CLIENTEDGE;
1775
1776 if(dwStyle != dwNewStyle)
1777 {
1778 // SetWindowPos will not move invalid bits
1779 ::RedrawWindow(m_hWndMDIClient, NULL, NULL,
1780 RDW_INVALIDATE | RDW_ALLCHILDREN);
1781 // remove/add WS_EX_CLIENTEDGE to MDI client area
1782 ::SetWindowLong(m_hWndMDIClient, GWL_EXSTYLE, dwNewStyle);
1783 ::SetWindowPos(m_hWndMDIClient, NULL, 0, 0, 0, 0,
1784 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE |
1785 SWP_NOZORDER | SWP_NOCOPYBITS);
1786
1787 // return new client area
1788 if (lpRect != NULL)
1789 ::GetClientRect(m_hWndMDIClient, lpRect);
1790
1791 return TRUE;
1792 }
1793
1794 return FALSE;
1795 }
1796
1797 typedef CFrameWindowImplBase<TBase, TWinTraits > _baseClass;
1798 BEGIN_MSG_MAP(CMDIChildWindowImpl)
1799 MESSAGE_HANDLER(WM_SIZE, OnSize)
1800 MESSAGE_HANDLER(WM_WINDOWPOSCHANGED, OnWindowPosChanged)
1801 MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate)
1802 MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect)
1803 MESSAGE_HANDLER(WM_MDIACTIVATE, OnMDIActivate)
1804 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
1805 #ifndef _ATL_NO_REBAR_SUPPORT
1806 #if (_WIN32_IE >= 0x0400)
1807 NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize)
1808 #endif // (_WIN32_IE >= 0x0400)
1809 #if (_WIN32_IE >= 0x0500)
1810 NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed)
1811 #endif // (_WIN32_IE >= 0x0500)
1812 #endif // !_ATL_NO_REBAR_SUPPORT
1813 CHAIN_MSG_MAP(_baseClass)
1814 END_MSG_MAP()
1815
1816 LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
1817 {
1818 DefWindowProc(uMsg, wParam, lParam); // needed for MDI children
1819 if(wParam != SIZE_MINIMIZED)
1820 {
1821 T* pT = static_cast<T*>(this);
1822 pT->UpdateLayout();
1823 }
1824 return 0;
1825 }
1826
1827 LRESULT OnWindowPosChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
1828 {
1829 // update MDI client edge and adjust MDI child rect
1830 LPWINDOWPOS lpWndPos = (LPWINDOWPOS)lParam;
1831
1832 if(!(lpWndPos->flags & SWP_NOSIZE))
1833 {
1834 RECT rectClient = { 0 };
1835 if(UpdateClientEdge(&rectClient) && ((GetStyle() & WS_MAXIMIZE) != 0))
1836 {
1837 ::AdjustWindowRectEx(&rectClient, GetStyle(), FALSE, GetExStyle());
1838 lpWndPos->x = rectClient.left;
1839 lpWndPos->y = rectClient.top;
1840 lpWndPos->cx = rectClient.right - rectClient.left;
1841 lpWndPos->cy = rectClient.bottom - rectClient.top;
1842 }
1843 }
1844
1845 bHandled = FALSE;
1846 return 1;
1847 }
1848
1849 LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
1850 {
1851 LRESULT lRes = DefWindowProc(uMsg, wParam, lParam);
1852
1853 // Activate this MDI window if needed
1854 if(lRes == MA_ACTIVATE || lRes == MA_ACTIVATEANDEAT)
1855 {
1856 if(MDIGetActive() != m_hWnd)
1857 MDIActivate(m_hWnd);
1858 }
1859
1860 return lRes;
1861 }
1862
1863 LRESULT OnMenuSelect(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
1864 {
1865 return ::SendMessage(GetMDIFrame(), uMsg, wParam, lParam);
1866 }
1867
1868 LRESULT OnMDIActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
1869 {
1870 if((HWND)lParam == m_hWnd && m_hMenu != NULL)
1871 SetMDIFrameMenu();
1872 else if((HWND)lParam == NULL)
1873 ::SendMessage(GetMDIFrame(), WM_MDISETMENU, 0, 0);
1874
1875 bHandled = FALSE;
1876 return 1;
1877 }
1878
1879 LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
1880 {
1881 if(m_hMenu != NULL)
1882 {
1883 ::DestroyMenu(m_hMenu);
1884 m_hMenu = NULL;
1885 }
1886 UpdateClientEdge();
1887 bHandled = FALSE;
1888 return 1;
1889 }
1890
1891 #ifndef _ATL_NO_REBAR_SUPPORT
1892 #if (_WIN32_IE >= 0x0400)
1893 LRESULT OnReBarAutoSize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
1894 {
1895 T* pT = static_cast<T*>(this);
1896 pT->UpdateLayout(FALSE);
1897 return 0;
1898 }
1899 #endif // (_WIN32_IE >= 0x0400)
1900
1901 #if (_WIN32_IE >= 0x0500)
1902 LRESULT OnChevronPushed(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
1903 {
1904 T* pT = static_cast<T*>(this);
1905 _ChevronMenuInfo cmi = { NULL, (LPNMREBARCHEVRON)pnmh, false };
1906 if(!pT->PrepareChevronMenu(cmi))
1907 {
1908 bHandled = FALSE;
1909 return 1;
1910 }
1911 // display a popup menu with hidden items
1912 pT->DisplayChevronMenu(cmi);
1913 // cleanup
1914 pT->CleanupChevronMenu(cmi);
1915 return 0;
1916 }
1917 #endif // (_WIN32_IE >= 0x0500)
1918 #endif // !_ATL_NO_REBAR_SUPPORT
1919 };
1920
1921 #endif // !_WIN32_WCE
1922
1923
1924 ///////////////////////////////////////////////////////////////////////////////
1925 // COwnerDraw - MI class for owner-draw support
1926
1927 template <class T>
1928 class COwnerDraw
1929 {
1930 public:
1931 #if (_ATL_VER < 0x0700)
1932 BOOL m_bHandledOD;
1933
1934 BOOL IsMsgHandled() const
1935 {
1936 return m_bHandledOD;
1937 }
1938 void SetMsgHandled(BOOL bHandled)
1939 {
1940 m_bHandledOD = bHandled;
1941 }
1942 #endif // (_ATL_VER < 0x0700)
1943
1944 // Message map and handlers
1945 BEGIN_MSG_MAP(COwnerDraw< T >)
1946 MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem)
1947 MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem)
1948 MESSAGE_HANDLER(WM_COMPAREITEM, OnCompareItem)
1949 MESSAGE_HANDLER(WM_DELETEITEM, OnDeleteItem)
1950 ALT_MSG_MAP(1)
1951 MESSAGE_HANDLER(OCM_DRAWITEM, OnDrawItem)
1952 MESSAGE_HANDLER(OCM_MEASUREITEM, OnMeasureItem)
1953 MESSAGE_HANDLER(OCM_COMPAREITEM, OnCompareItem)
1954 MESSAGE_HANDLER(OCM_DELETEITEM, OnDeleteItem)
1955 END_MSG_MAP()
1956
1957 LRESULT OnDrawItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
1958 {
1959 T* pT = static_cast<T*>(this);
1960 pT->SetMsgHandled(TRUE);
1961 pT->DrawItem((LPDRAWITEMSTRUCT)lParam);
1962 bHandled = pT->IsMsgHandled();
1963 return (LRESULT)TRUE;
1964 }
1965
1966 LRESULT OnMeasureItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
1967 {
1968 T* pT = static_cast<T*>(this);
1969 pT->SetMsgHandled(TRUE);
1970 pT->MeasureItem((LPMEASUREITEMSTRUCT)lParam);
1971 bHandled = pT->IsMsgHandled();
1972 return (LRESULT)TRUE;
1973 }
1974
1975 LRESULT OnCompareItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
1976 {
1977 T* pT = static_cast<T*>(this);
1978 pT->SetMsgHandled(TRUE);
1979 bHandled = pT->IsMsgHandled();
1980 return (LRESULT)pT->CompareItem((LPCOMPAREITEMSTRUCT)lParam);
1981 }
1982
1983 LRESULT OnDeleteItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
1984 {
1985 T* pT = static_cast<T*>(this);
1986 pT->SetMsgHandled(TRUE);
1987 pT->DeleteItem((LPDELETEITEMSTRUCT)lParam);
1988 bHandled = pT->IsMsgHandled();
1989 return (LRESULT)TRUE;
1990 }
1991
1992 // Overrideables
1993 void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/)
1994 {
1995 // must be implemented
1996 ATLASSERT(FALSE);
1997 }
1998
1999 void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
2000 {
2001 if(lpMeasureItemStruct->CtlType != ODT_MENU)
2002 {
2003 // return default height for a system font
2004 T* pT = static_cast<T*>(this);
2005 HWND hWnd = pT->GetDlgItem(lpMeasureItemStruct->CtlID);
2006 CClientDC dc(hWnd);
2007 TEXTMETRIC tm = { 0 };
2008 dc.GetTextMetrics(&tm);
2009
2010 lpMeasureItemStruct->itemHeight = tm.tmHeight;
2011 }
2012 else
2013 lpMeasureItemStruct->itemHeight = ::GetSystemMetrics(SM_CYMENU);
2014 }
2015
2016 int CompareItem(LPCOMPAREITEMSTRUCT /*lpCompareItemStruct*/)
2017 {
2018 // all items are equal
2019 return 0;
2020 }
2021
2022 void DeleteItem(LPDELETEITEMSTRUCT /*lpDeleteItemStruct*/)
2023 {
2024 // default - nothing
2025 }
2026 };
2027
2028
2029 ///////////////////////////////////////////////////////////////////////////////
2030 // Update UI macros
2031
2032 // these build the Update UI map inside a class definition
2033 #define BEGIN_UPDATE_UI_MAP(thisClass) \
2034 static const CUpdateUIBase::_AtlUpdateUIMap* GetUpdateUIMap() \
2035 { \
2036 static const _AtlUpdateUIMap theMap[] = \
2037 {
2038
2039 #define UPDATE_ELEMENT(nID, wType) \
2040 { nID, wType },
2041
2042 #define END_UPDATE_UI_MAP() \
2043 { (WORD)-1, 0 } \
2044 }; \
2045 return theMap; \
2046 }
2047
2048 ///////////////////////////////////////////////////////////////////////////////
2049 // CUpdateUI - manages UI elements updating
2050
2051 class CUpdateUIBase
2052 {
2053 public:
2054 // constants
2055 enum
2056 {
2057 // UI element type
2058 UPDUI_MENUPOPUP = 0x0001,
2059 UPDUI_MENUBAR = 0x0002,
2060 UPDUI_CHILDWINDOW = 0x0004,
2061 UPDUI_TOOLBAR = 0x0008,
2062 UPDUI_STATUSBAR = 0x0010,
2063 // state
2064 UPDUI_ENABLED = 0x0000,
2065 UPDUI_DISABLED = 0x0100,
2066 UPDUI_CHECKED = 0x0200,
2067 UPDUI_CHECKED2 = 0x0400,
2068 UPDUI_RADIO = 0x0800,
2069 UPDUI_DEFAULT = 0x1000,
2070 UPDUI_TEXT = 0x2000,
2071 // internal state
2072 UPDUI_CLEARDEFAULT = 0x4000,
2073 };
2074
2075 // element data
2076 struct _AtlUpdateUIElement
2077 {
2078 HWND m_hWnd;
2079 WORD m_wType;
2080
2081 bool operator ==(const _AtlUpdateUIElement& e) const
2082 { return (m_hWnd == e.m_hWnd && m_wType == e.m_wType); }
2083 };
2084
2085 // map data
2086 struct _AtlUpdateUIMap
2087 {
2088 WORD m_nID;
2089 WORD m_wType;
2090
2091 bool operator ==(const _AtlUpdateUIMap& e) const
2092 { return (m_nID == e.m_nID && m_wType == e.m_wType); }
2093 };
2094
2095 // instance data
2096 #pragma warning(push)
2097 #pragma warning(disable: 4201) // nameless unions are part of C++
2098
2099 struct _AtlUpdateUIData
2100 {
2101 WORD m_wState;
2102 union
2103 {
2104 void* m_lpData;
2105 LPTSTR m_lpstrText;
2106 struct
2107 {
2108 WORD m_nIDFirst;
2109 WORD m_nIDLast;
2110 };
2111 };
2112
2113 bool operator ==(const _AtlUpdateUIData& e) const
2114 { return (m_wState == e.m_wState && m_lpData == e.m_lpData); }
2115 };
2116
2117 #pragma warning(pop)
2118
2119 ATL::CSimpleArray<_AtlUpdateUIElement> m_UIElements; // elements data
2120 const _AtlUpdateUIMap* m_pUIMap; // static UI data
2121 _AtlUpdateUIData* m_pUIData; // instance UI data
2122 WORD m_wDirtyType; // global dirty flag
2123
2124 bool m_bBlockAccelerators;
2125
2126
2127 // Constructor, destructor
2128 CUpdateUIBase() : m_pUIMap(NULL), m_pUIData(NULL), m_wDirtyType(0), m_bBlockAccelerators(false)
2129 { }
2130
2131 ~CUpdateUIBase()
2132 {
2133 if(m_pUIMap != NULL && m_pUIData != NULL)
2134 {
2135 const _AtlUpdateUIMap* pUIMap = m_pUIMap;
2136 _AtlUpdateUIData* pUIData = m_pUIData;
2137 while(pUIMap->m_nID != (WORD)-1)
2138 {
2139 if(pUIData->m_wState & UPDUI_TEXT)
2140 delete [] pUIData->m_lpstrText;
2141 pUIMap++;
2142 pUIData++;
2143 }
2144 delete [] m_pUIData;
2145 }
2146 }
2147
2148 // Check for disabled commands
2149 bool UIGetBlockAccelerators() const
2150 {
2151 return m_bBlockAccelerators;
2152 }
2153
2154 bool UISetBlockAccelerators(bool bBlock)
2155 {
2156 bool bOld = m_bBlockAccelerators;
2157 m_bBlockAccelerators = bBlock;
2158 return bOld;
2159 }
2160
2161 // Add elements
2162 BOOL UIAddMenuBar(HWND hWnd) // menu bar (main menu)
2163 {
2164 if(hWnd == NULL)
2165 return FALSE;
2166 _AtlUpdateUIElement e;
2167 e.m_hWnd = hWnd;
2168 e.m_wType = UPDUI_MENUBAR;
2169 return m_UIElements.Add(e);
2170 }
2171
2172 BOOL UIAddToolBar(HWND hWnd) // toolbar
2173 {
2174 if(hWnd == NULL)
2175 return FALSE;
2176 _AtlUpdateUIElement e;
2177 e.m_hWnd = hWnd;
2178 e.m_wType = UPDUI_TOOLBAR;
2179 return m_UIElements.Add(e);
2180 }
2181
2182 BOOL UIAddStatusBar(HWND hWnd) // status bar
2183 {
2184 if(hWnd == NULL)
2185 return FALSE;
2186 _AtlUpdateUIElement e;
2187 e.m_hWnd = hWnd;
2188 e.m_wType = UPDUI_STATUSBAR;
2189 return m_UIElements.Add(e);
2190 }
2191
2192 BOOL UIAddChildWindowContainer(HWND hWnd) // child window
2193 {
2194 if(hWnd == NULL)
2195 return FALSE;
2196 _AtlUpdateUIElement e;
2197 e.m_hWnd = hWnd;
2198 e.m_wType = UPDUI_CHILDWINDOW;
2199 return m_UIElements.Add(e);
2200 }
2201
2202 // Message map for popup menu updates and accelerator blocking
2203 BEGIN_MSG_MAP(CUpdateUIBase)
2204 MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup)
2205 MESSAGE_HANDLER(WM_COMMAND, OnCommand)
2206 END_MSG_MAP()
2207
2208 LRESULT OnInitMenuPopup(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
2209 {
2210 bHandled = FALSE;
2211 HMENU hMenu = (HMENU)wParam;
2212 if(hMenu == NULL)
2213 return 1;
2214 _AtlUpdateUIData* pUIData = m_pUIData;
2215 if(pUIData == NULL)
2216 return 1;
2217 const _AtlUpdateUIMap* pMap = m_pUIMap;
2218 while(pMap->m_nID != (WORD)-1)
2219 {
2220 if(pMap->m_wType & UPDUI_MENUPOPUP)
2221 {
2222 UIUpdateMenuBarElement(pMap->m_nID, pUIData, hMenu);
2223
2224 if((pUIData->m_wState & UPDUI_RADIO) != 0)
2225 ::CheckMenuRadioItem(hMenu, pUIData->m_nIDFirst, pUIData->m_nIDLast, pMap->m_nID, MF_BYCOMMAND);
2226 }
2227 pMap++;
2228 pUIData++;
2229 }
2230 return 0;
2231 }
2232
2233 LRESULT OnCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
2234 {
2235 bHandled = FALSE;
2236 if(m_bBlockAccelerators && HIWORD(wParam) == 1) // accelerators only
2237 {
2238 int nID = LOWORD(wParam);
2239 if((UIGetState(nID) & UPDUI_DISABLED) == UPDUI_DISABLED)
2240 {
2241 ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIBase::OnCommand - blocked disabled command 0x%4.4X\n"), nID);
2242 bHandled = TRUE; // eat the command, UI item is disabled
2243 }
2244 }
2245 return 0;
2246 }
2247
2248 // methods for setting UI element state
2249 BOOL UIEnable(int nID, BOOL bEnable, BOOL bForceUpdate = FALSE)
2250 {
2251 const _AtlUpdateUIMap* pMap = m_pUIMap;
2252 _AtlUpdateUIData* pUIData = m_pUIData;
2253 if(pUIData == NULL)
2254 return FALSE;
2255
2256 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++)
2257 {
2258 if(nID == (int)pMap->m_nID)
2259 {
2260 if(bEnable)
2261 {
2262 if(pUIData->m_wState & UPDUI_DISABLED)
2263 {
2264 pUIData->m_wState |= pMap->m_wType;
2265 pUIData->m_wState &= ~UPDUI_DISABLED;
2266 }
2267 }
2268 else
2269 {
2270 if(!(pUIData->m_wState & UPDUI_DISABLED))
2271 {
2272 pUIData->m_wState |= pMap->m_wType;
2273 pUIData->m_wState |= UPDUI_DISABLED;
2274 }
2275 }
2276
2277 if(bForceUpdate)
2278 pUIData->m_wState |= pMap->m_wType;
2279 if(pUIData->m_wState & pMap->m_wType)
2280 m_wDirtyType |= pMap->m_wType;
2281
2282 break; // found
2283 }
2284 }
2285
2286 return TRUE;
2287 }
2288
2289 BOOL UISetCheck(int nID, int nCheck, BOOL bForceUpdate = FALSE)
2290 {
2291 const _AtlUpdateUIMap* pMap = m_pUIMap;
2292 _AtlUpdateUIData* pUIData = m_pUIData;
2293 if(pUIData == NULL)
2294 return FALSE;
2295
2296 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++)
2297 {
2298 if(nID == (int)pMap->m_nID)
2299 {
2300 switch(nCheck)
2301 {
2302 case 0:
2303 if((pUIData->m_wState & UPDUI_CHECKED) || (pUIData->m_wState & UPDUI_CHECKED2))
2304 {
2305 pUIData->m_wState |= pMap->m_wType;
2306 pUIData->m_wState &= ~(UPDUI_CHECKED | UPDUI_CHECKED2);
2307 }
2308 break;
2309 case 1:
2310 if(!(pUIData->m_wState & UPDUI_CHECKED))
2311 {
2312 pUIData->m_wState |= pMap->m_wType;
2313 pUIData->m_wState &= ~UPDUI_CHECKED2;
2314 pUIData->m_wState |= UPDUI_CHECKED;
2315 }
2316 break;
2317 case 2:
2318 if(!(pUIData->m_wState & UPDUI_CHECKED2))
2319 {
2320 pUIData->m_wState |= pMap->m_wType;
2321 pUIData->m_wState &= ~UPDUI_CHECKED;
2322 pUIData->m_wState |= UPDUI_CHECKED2;
2323 }
2324 break;
2325 }
2326
2327 if(bForceUpdate)
2328 pUIData->m_wState |= pMap->m_wType;
2329 if(pUIData->m_wState & pMap->m_wType)
2330 m_wDirtyType |= pMap->m_wType;
2331
2332 break; // found
2333 }
2334 }
2335
2336 return TRUE;
2337 }
2338
2339 // variant that supports bool (checked/not-checked, no intermediate state)
2340 BOOL UISetCheck(int nID, bool bCheck, BOOL bForceUpdate = FALSE)
2341 {
2342 return UISetCheck(nID, bCheck ? 1 : 0, bForceUpdate);
2343 }
2344
2345 BOOL UISetRadio(int nID, BOOL bRadio, BOOL bForceUpdate = FALSE)
2346 {
2347 const _AtlUpdateUIMap* pMap = m_pUIMap;
2348 _AtlUpdateUIData* pUIData = m_pUIData;
2349 if(pUIData == NULL)
2350 return FALSE;
2351
2352 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++)
2353 {
2354 if(nID == (int)pMap->m_nID)
2355 {
2356 if(bRadio)
2357 {
2358 if(!(pUIData->m_wState & UPDUI_RADIO))
2359 {
2360 pUIData->m_wState |= pMap->m_wType;
2361 pUIData->m_wState |= UPDUI_RADIO;
2362 }
2363 }
2364 else
2365 {
2366 if(pUIData->m_wState & UPDUI_RADIO)
2367 {
2368 pUIData->m_wState |= pMap->m_wType;
2369 pUIData->m_wState &= ~UPDUI_RADIO;
2370 }
2371 }
2372
2373 if(bForceUpdate)
2374 pUIData->m_wState |= pMap->m_wType;
2375 if(pUIData->m_wState & pMap->m_wType)
2376 m_wDirtyType |= pMap->m_wType;
2377
2378 break; // found
2379 }
2380 }
2381
2382 return TRUE;
2383 }
2384
2385 // for menu items
2386 BOOL UISetRadioMenuItem(int nID, int nIDFirst, int nIDLast, BOOL bForceUpdate = FALSE)
2387 {
2388 const _AtlUpdateUIMap* pMap = m_pUIMap;
2389 _AtlUpdateUIData* pUIData = m_pUIData;
2390 if(pUIData == NULL)
2391 return FALSE;
2392
2393 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++)
2394 {
2395 if(nID == (int)pMap->m_nID)
2396 {
2397 pUIData->m_wState |= pMap->m_wType;
2398 pUIData->m_wState |= UPDUI_RADIO;
2399 pUIData->m_nIDFirst = (WORD)nIDFirst;
2400 pUIData->m_nIDLast = (WORD)nIDLast;
2401
2402 if(bForceUpdate)
2403 pUIData->m_wState |= pMap->m_wType;
2404 if(pUIData->m_wState & pMap->m_wType)
2405 m_wDirtyType |= pMap->m_wType;
2406 }
2407 else if(pMap->m_nID >= nIDFirst && pMap->m_nID <= nIDLast)
2408 {
2409 if(pUIData->m_wState & UPDUI_RADIO)
2410 {
2411 pUIData->m_wState &= ~pMap->m_wType;
2412 pUIData->m_wState &= ~UPDUI_RADIO;
2413 pUIData->m_nIDFirst = 0;
2414 pUIData->m_nIDLast = 0;
2415 }
2416 }
2417
2418 if(pMap->m_nID == nIDLast)
2419 break;
2420 }
2421
2422 return TRUE;
2423 }
2424
2425 BOOL UISetText(int nID, LPCTSTR lpstrText, BOOL bForceUpdate = FALSE)
2426 {
2427 const _AtlUpdateUIMap* pMap = m_pUIMap;
2428 _AtlUpdateUIData* pUIData = m_pUIData;
2429 if(pUIData == NULL)
2430 return FALSE;
2431 if(lpstrText == NULL)
2432 lpstrText = _T("");
2433
2434 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++)
2435 {
2436 if(nID == (int)pMap->m_nID)
2437 {
2438 if(pUIData->m_lpstrText == NULL || lstrcmp(pUIData->m_lpstrText, lpstrText))
2439 {
2440 delete [] pUIData->m_lpstrText;
2441 pUIData->m_lpstrText = NULL;
2442 int nStrLen = lstrlen(lpstrText);
2443 ATLTRY(pUIData->m_lpstrText = new TCHAR[nStrLen + 1]);
2444 if(pUIData->m_lpstrText == NULL)
2445 {
2446 ATLTRACE2(atlTraceUI, 0, _T("UISetText - memory allocation failed\n"));
2447 break;
2448 }
2449 SecureHelper::strcpy_x(pUIData->m_lpstrText, nStrLen + 1, lpstrText);
2450 pUIData->m_wState |= (UPDUI_TEXT | pMap->m_wType);
2451 }
2452
2453 if(bForceUpdate)
2454 pUIData->m_wState |= (UPDUI_TEXT | pMap->m_wType);
2455 if(pUIData->m_wState & pMap->m_wType)
2456 m_wDirtyType |= pMap->m_wType;
2457
2458 break; // found
2459 }
2460 }
2461
2462 return TRUE;
2463 }
2464
2465 BOOL UISetDefault(int nID, BOOL bDefault, BOOL bForceUpdate = FALSE)
2466 {
2467 const _AtlUpdateUIMap* pMap = m_pUIMap;
2468 _AtlUpdateUIData* pUIData = m_pUIData;
2469 if(pUIData == NULL)
2470 return FALSE;
2471
2472 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++)
2473 {
2474 if(nID == (int)pMap->m_nID)
2475 {
2476 if(bDefault)
2477 {
2478 if((pUIData->m_wState & UPDUI_DEFAULT) == 0)
2479 {
2480 pUIData->m_wState |= pMap->m_wType;
2481 pUIData->m_wState |= UPDUI_DEFAULT;
2482 }
2483 }
2484 else
2485 {
2486 if((pUIData->m_wState & UPDUI_DEFAULT) != 0)
2487 {
2488 pUIData->m_wState |= pMap->m_wType;
2489 pUIData->m_wState &= ~UPDUI_DEFAULT;
2490 pUIData->m_wState |= UPDUI_CLEARDEFAULT;
2491 }
2492 }
2493
2494 if(bForceUpdate)
2495 pUIData->m_wState |= pMap->m_wType;
2496 if(pUIData->m_wState & pMap->m_wType)
2497 m_wDirtyType |= pMap->m_wType;
2498
2499 break; // found
2500 }
2501 }
2502
2503 return TRUE;
2504 }
2505
2506 // methods for complete state set/get
2507 BOOL UISetState(int nID, DWORD dwState)
2508 {
2509 const _AtlUpdateUIMap* pMap = m_pUIMap;
2510 _AtlUpdateUIData* pUIData = m_pUIData;
2511 if(pUIData == NULL)
2512 return FALSE;
2513 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++)
2514 {
2515 if(nID == (int)pMap->m_nID)
2516 {
2517 pUIData->m_wState = (WORD)(dwState | pMap->m_wType);
2518 m_wDirtyType |= pMap->m_wType;
2519 break; // found
2520 }
2521 }
2522 return TRUE;
2523 }
2524
2525 DWORD UIGetState(int nID)
2526 {
2527 const _AtlUpdateUIMap* pMap = m_pUIMap;
2528 _AtlUpdateUIData* pUIData = m_pUIData;
2529 if(pUIData == NULL)
2530 return 0;
2531 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++)
2532 {
2533 if(nID == (int)pMap->m_nID)
2534 return pUIData->m_wState;
2535 }
2536 return 0;
2537 }
2538
2539 // methods for updating UI
2540 #ifndef _WIN32_WCE
2541 BOOL UIUpdateMenuBar(BOOL bForceUpdate = FALSE, BOOL bMainMenu = FALSE)
2542 {
2543 if(!(m_wDirtyType & UPDUI_MENUBAR) && !bForceUpdate)
2544 return TRUE;
2545
2546 const _AtlUpdateUIMap* pMap = m_pUIMap;
2547 _AtlUpdateUIData* pUIData = m_pUIData;
2548 if(pUIData == NULL)
2549 return FALSE;
2550
2551 while(pMap->m_nID != (WORD)-1)
2552 {
2553 for(int i = 0; i < m_UIElements.GetSize(); i++)
2554 {
2555 if(m_UIElements[i].m_wType == UPDUI_MENUBAR)
2556 {
2557 HMENU hMenu = ::GetMenu(m_UIElements[i].m_hWnd);
2558 if(hMenu != NULL && (pUIData->m_wState & UPDUI_MENUBAR) && (pMap->m_wType & UPDUI_MENUBAR))
2559 UIUpdateMenuBarElement(pMap->m_nID, pUIData, hMenu);
2560 }
2561 if(bMainMenu)
2562 ::DrawMenuBar(m_UIElements[i].m_hWnd);
2563 }
2564 pMap++;
2565 pUIData->m_wState &= ~UPDUI_MENUBAR;
2566 if(pUIData->m_wState & UPDUI_TEXT)
2567 {
2568 delete [] pUIData->m_lpstrText;
2569 pUIData->m_lpstrText = NULL;
2570 pUIData->m_wState &= ~UPDUI_TEXT;
2571 }
2572 pUIData++;
2573 }
2574
2575 m_wDirtyType &= ~UPDUI_MENUBAR;
2576 return TRUE;
2577 }
2578 #endif // !_WIN32_WCE
2579
2580 BOOL UIUpdateToolBar(BOOL bForceUpdate = FALSE)
2581 {
2582 if(!(m_wDirtyType & UPDUI_TOOLBAR) && !bForceUpdate)
2583 return TRUE;
2584
2585 const _AtlUpdateUIMap* pMap = m_pUIMap;
2586 _AtlUpdateUIData* pUIData = m_pUIData;
2587 if(pUIData == NULL)
2588 return FALSE;
2589
2590 while(pMap->m_nID != (WORD)-1)
2591 {
2592 for(int i = 0; i < m_UIElements.GetSize(); i++)
2593 {
2594 if(m_UIElements[i].m_wType == UPDUI_TOOLBAR)
2595 {
2596 if((pUIData->m_wState & UPDUI_TOOLBAR) && (pMap->m_wType & UPDUI_TOOLBAR))
2597 UIUpdateToolBarElement(pMap->m_nID, pUIData, m_UIElements[i].m_hWnd);
2598 }
2599 }
2600 pMap++;
2601 pUIData->m_wState &= ~UPDUI_TOOLBAR;
2602 pUIData++;
2603 }
2604
2605 m_wDirtyType &= ~UPDUI_TOOLBAR;
2606 return TRUE;
2607 }
2608
2609 BOOL UIUpdateStatusBar(BOOL bForceUpdate = FALSE)
2610 {
2611 if(!(m_wDirtyType & UPDUI_STATUSBAR) && !bForceUpdate)
2612 return TRUE;
2613
2614 const _AtlUpdateUIMap* pMap = m_pUIMap;
2615 _AtlUpdateUIData* pUIData = m_pUIData;
2616 if(pUIData == NULL)
2617 return FALSE;
2618
2619 while(pMap->m_nID != (WORD)-1)
2620 {
2621 for(int i = 0; i < m_UIElements.GetSize(); i++)
2622 {
2623 if(m_UIElements[i].m_wType == UPDUI_STATUSBAR)
2624 {
2625 if((pUIData->m_wState & UPDUI_STATUSBAR) && (pMap->m_wType & UPDUI_STATUSBAR))
2626 UIUpdateStatusBarElement(pMap->m_nID, pUIData, m_UIElements[i].m_hWnd);
2627 }
2628 }
2629 pMap++;
2630 pUIData->m_wState &= ~UPDUI_STATUSBAR;
2631 if(pUIData->m_wState & UPDUI_TEXT)
2632 {
2633 delete [] pUIData->m_lpstrText;
2634 pUIData->m_lpstrText = NULL;
2635 pUIData->m_wState &= ~UPDUI_TEXT;
2636 }
2637 pUIData++;
2638 }
2639
2640 m_wDirtyType &= ~UPDUI_STATUSBAR;
2641 return TRUE;
2642 }
2643
2644 BOOL UIUpdateChildWindows(BOOL bForceUpdate = FALSE)
2645 {
2646 if(!(m_wDirtyType & UPDUI_CHILDWINDOW) && !bForceUpdate)
2647 return TRUE;
2648
2649 const _AtlUpdateUIMap* pMap = m_pUIMap;
2650 _AtlUpdateUIData* pUIData = m_pUIData;
2651 if(pUIData == NULL)
2652 return FALSE;
2653
2654 while(pMap->m_nID != (WORD)-1)
2655 {
2656 for(int i = 0; i < m_UIElements.GetSize(); i++)
2657 {
2658 if(m_UIElements[i].m_wType == UPDUI_CHILDWINDOW)
2659 {
2660 if((pUIData->m_wState & UPDUI_CHILDWINDOW) && (pMap->m_wType & UPDUI_CHILDWINDOW))
2661 UIUpdateChildWindow(pMap->m_nID, pUIData, m_UIElements[i].m_hWnd);
2662 }
2663 }
2664 pMap++;
2665 pUIData->m_wState &= ~UPDUI_CHILDWINDOW;
2666 if(pUIData->m_wState & UPDUI_TEXT)
2667 {
2668 delete [] pUIData->m_lpstrText;
2669 pUIData->m_lpstrText = NULL;
2670 pUIData->m_wState &= ~UPDUI_TEXT;
2671 }
2672 pUIData++;
2673 }
2674
2675 m_wDirtyType &= ~UPDUI_CHILDWINDOW;
2676 return TRUE;
2677 }
2678
2679 // internal element specific methods
2680 static void UIUpdateMenuBarElement(int nID, _AtlUpdateUIData* pUIData, HMENU hMenu)
2681 {
2682 #ifndef _WIN32_WCE
2683 if((pUIData->m_wState & UPDUI_CLEARDEFAULT) != 0)
2684 {
2685 ::SetMenuDefaultItem(hMenu, (UINT)-1, 0);
2686 pUIData->m_wState &= ~UPDUI_CLEARDEFAULT;
2687 }
2688 #endif // !_WIN32_WCE
2689
2690 CMenuItemInfo mii;
2691 mii.fMask = MIIM_STATE;
2692 mii.wID = nID;
2693
2694 #ifndef _WIN32_WCE
2695 if((pUIData->m_wState & UPDUI_DISABLED) != 0)
2696 mii.fState |= MFS_DISABLED | MFS_GRAYED;
2697 else
2698 mii.fState |= MFS_ENABLED;
2699
2700 if((pUIData->m_wState & UPDUI_CHECKED) != 0)
2701 mii.fState |= MFS_CHECKED;
2702 else
2703 mii.fState |= MFS_UNCHECKED;
2704
2705 if((pUIData->m_wState & UPDUI_DEFAULT) != 0)
2706 mii.fState |= MFS_DEFAULT;
2707 #else // CE specific
2708 // ::SetMenuItemInfo() can't disable or check menu items
2709 // on Windows CE, so we have to do that directly
2710 UINT uEnable = MF_BYCOMMAND;
2711 if((pUIData->m_wState & UPDUI_DISABLED) != 0)
2712 uEnable |= MF_GRAYED;
2713 else
2714 uEnable |= MF_ENABLED;
2715 ::EnableMenuItem(hMenu, nID, uEnable);
2716
2717 UINT uCheck = MF_BYCOMMAND;
2718 if((pUIData->m_wState & UPDUI_CHECKED) != 0)
2719 uCheck |= MF_CHECKED;
2720 else
2721 uCheck |= MF_UNCHECKED;
2722 ::CheckMenuItem(hMenu, nID, uCheck);
2723 #endif // _WIN32_WCE
2724
2725 if((pUIData->m_wState & UPDUI_TEXT) != 0)
2726 {
2727 CMenuItemInfo miiNow;
2728 miiNow.fMask = MIIM_TYPE;
2729 miiNow.wID = nID;
2730 if(::GetMenuItemInfo(hMenu, nID, FALSE, &miiNow))
2731 {
2732 mii.fMask |= MIIM_TYPE;
2733 // MFT_BITMAP and MFT_SEPARATOR don't go together with MFT_STRING
2734 #ifndef _WIN32_WCE
2735 mii.fType |= (miiNow.fType & ~(MFT_BITMAP | MFT_SEPARATOR)) | MFT_STRING;
2736 #else // CE specific
2737 mii.fType |= (miiNow.fType & ~(MFT_SEPARATOR)) | MFT_STRING;
2738 #endif // _WIN32_WCE
2739 mii.dwTypeData = pUIData->m_lpstrText;
2740 }
2741 }
2742
2743 ::SetMenuItemInfo(hMenu, nID, FALSE, &mii);
2744 }
2745
2746 static void UIUpdateToolBarElement(int nID, _AtlUpdateUIData* pUIData, HWND hWndToolBar)
2747 {
2748 // Note: only handles enabled/disabled, checked state, and radio (press)
2749 ::SendMessage(hWndToolBar, TB_ENABLEBUTTON, nID, (LPARAM)(pUIData->m_wState & UPDUI_DISABLED) ? FALSE : TRUE);
2750 ::SendMessage(hWndToolBar, TB_CHECKBUTTON, nID, (LPARAM)(pUIData->m_wState & UPDUI_CHECKED) ? TRUE : FALSE);
2751 ::SendMessage(hWndToolBar, TB_INDETERMINATE, nID, (LPARAM)(pUIData->m_wState & UPDUI_CHECKED2) ? TRUE : FALSE);
2752 ::SendMessage(hWndToolBar, TB_PRESSBUTTON, nID, (LPARAM)(pUIData->m_wState & UPDUI_RADIO) ? TRUE : FALSE);
2753 }
2754
2755 static void UIUpdateStatusBarElement(int nID, _AtlUpdateUIData* pUIData, HWND hWndStatusBar)
2756 {
2757 // Note: only handles text
2758 if(pUIData->m_wState & UPDUI_TEXT)
2759 ::SendMessage(hWndStatusBar, SB_SETTEXT, nID, (LPARAM)pUIData->m_lpstrText);
2760 }
2761
2762 static void UIUpdateChildWindow(int nID, _AtlUpdateUIData* pUIData, HWND hWnd)
2763 {
2764 HWND hChild = ::GetDlgItem(hWnd, nID);
2765
2766 ::EnableWindow(hChild, (pUIData->m_wState & UPDUI_DISABLED) ? FALSE : TRUE);
2767 // for check and radio, assume that window is a button
2768 int nCheck = BST_UNCHECKED;
2769 if(pUIData->m_wState & UPDUI_CHECKED || pUIData->m_wState & UPDUI_RADIO)
2770 nCheck = BST_CHECKED;
2771 else if(pUIData->m_wState & UPDUI_CHECKED2)
2772 nCheck = BST_INDETERMINATE;
2773 ::SendMessage(hChild, BM_SETCHECK, nCheck, 0L);
2774 if(pUIData->m_wState & UPDUI_DEFAULT)
2775 {
2776 DWORD dwRet = (DWORD)::SendMessage(hWnd, DM_GETDEFID, 0, 0L);
2777 if(HIWORD(dwRet) == DC_HASDEFID)
2778 {
2779 HWND hOldDef = ::GetDlgItem(hWnd, (int)(short)LOWORD(dwRet));
2780 // remove BS_DEFPUSHBUTTON
2781 ::SendMessage(hOldDef, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0));
2782 }
2783 ::SendMessage(hWnd, DM_SETDEFID, nID, 0L);
2784 }
2785 if(pUIData->m_wState & UPDUI_TEXT)
2786 ::SetWindowText(hChild, pUIData->m_lpstrText);
2787 }
2788 };
2789
2790 template <class T>
2791 class CUpdateUI : public CUpdateUIBase
2792 {
2793 public:
2794 CUpdateUI()
2795 {
2796 T* pT = static_cast<T*>(this);
2797 pT;
2798 const _AtlUpdateUIMap* pMap = pT->GetUpdateUIMap();
2799 m_pUIMap = pMap;
2800 ATLASSERT(m_pUIMap != NULL);
2801 int nCount = 1;
2802 for( ; pMap->m_nID != (WORD)-1; nCount++)
2803 pMap++;
2804
2805 // check for duplicates (debug only)
2806 #ifdef _DEBUG
2807 for(int i = 0; i < nCount; i++)
2808 {
2809 for(int j = 0; j < nCount; j++)
2810 {
2811 // shouldn't have duplicates in the update UI map
2812 if(i != j)
2813 ATLASSERT(m_pUIMap[j].m_nID != m_pUIMap[i].m_nID);
2814 }
2815 }
2816 #endif // _DEBUG
2817
2818 ATLTRY(m_pUIData = new _AtlUpdateUIData[nCount]);
2819 ATLASSERT(m_pUIData != NULL);
2820
2821 if(m_pUIData != NULL)
2822 memset(m_pUIData, 0, sizeof(_AtlUpdateUIData) * nCount);
2823 }
2824 };
2825
2826
2827 ///////////////////////////////////////////////////////////////////////////////
2828 // CDynamicUpdateUI - allows update elements to dynamically added and removed
2829 // in addition to a static update UI map
2830
2831 template <class T>
2832 class CDynamicUpdateUI : public CUpdateUIBase
2833 {
2834 public:
2835 // Data members
2836 ATL::CSimpleArray<_AtlUpdateUIMap> m_arrUIMap; // copy of the static UI data
2837 ATL::CSimpleArray<_AtlUpdateUIData> m_arrUIData; // instance UI data
2838
2839 // Constructor/destructor
2840 CDynamicUpdateUI()
2841 {
2842 T* pT = static_cast<T*>(this);
2843 pT;
2844 const _AtlUpdateUIMap* pMap = pT->GetUpdateUIMap();
2845 ATLASSERT(pMap != NULL);
2846
2847 for(;;)
2848 {
2849 BOOL bRet = m_arrUIMap.Add(*(_AtlUpdateUIMap*)pMap);
2850 ATLASSERT(bRet);
2851
2852 if(bRet != FALSE)
2853 {
2854 _AtlUpdateUIData data = { 0, NULL };
2855 bRet = m_arrUIData.Add(data);
2856 ATLASSERT(bRet);
2857 }
2858
2859 if(pMap->m_nID == (WORD)-1)
2860 break;
2861
2862 pMap++;
2863 }
2864
2865 ATLASSERT(m_arrUIMap.GetSize() == m_arrUIData.GetSize());
2866
2867 #ifdef _DEBUG
2868 // check for duplicates (debug only)
2869 for(int i = 0; i < m_arrUIMap.GetSize(); i++)
2870 {
2871 for(int j = 0; j < m_arrUIMap.GetSize(); j++)
2872 {
2873 // shouldn't have duplicates in the update UI map
2874 if(i != j)
2875 ATLASSERT(m_arrUIMap[j].m_nID != m_arrUIMap[i].m_nID);
2876 }
2877 }
2878 #endif // _DEBUG
2879
2880 // Set internal data pointers to point to the new data arrays
2881 m_pUIMap = m_arrUIMap.m_aT;
2882 m_pUIData = m_arrUIData.m_aT;
2883 }
2884
2885 ~CDynamicUpdateUI()
2886 {
2887 for(int i = 0; i < m_arrUIData.GetSize(); i++)
2888 {
2889 if((m_arrUIData[i].m_wState & UPDUI_TEXT) != 0)
2890 delete [] m_arrUIData[i].m_lpstrText;
2891 }
2892
2893 // Reset internal data pointers (memory will be released by CSimpleArray d-tor)
2894 m_pUIMap = NULL;
2895 m_pUIData = NULL;
2896 }
2897
2898 // Methods for dynamically adding and removing update elements
2899 bool UIAddUpdateElement(WORD nID, WORD wType)
2900 {
2901 // check for duplicates
2902 for(int i = 0; i < m_arrUIMap.GetSize(); i++)
2903 {
2904 // shouldn't have duplicates in the update UI map
2905 ATLASSERT(m_arrUIMap[i].m_nID != nID);
2906 if(m_arrUIMap[i].m_nID == nID)
2907 return false;
2908 }
2909
2910 bool bRetVal = false;
2911
2912 // Add new end element
2913 _AtlUpdateUIMap uumEnd = { (WORD)-1, 0 };
2914 BOOL bRet = m_arrUIMap.Add(uumEnd);
2915 ATLASSERT(bRet);
2916
2917 if(bRet != FALSE)
2918 {
2919 _AtlUpdateUIData uud = { 0, NULL };
2920 bRet = m_arrUIData.Add(uud);
2921 ATLASSERT(bRet);
2922
2923 // Set new data to the previous end element
2924 if(bRet != FALSE)
2925 {
2926 int nSize = m_arrUIMap.GetSize();
2927 _AtlUpdateUIMap uum = { nID, wType };
2928 m_arrUIMap.SetAtIndex(nSize - 2, uum);
2929 m_arrUIData.SetAtIndex(nSize - 2, uud);
2930
2931 // Set internal data pointers again, just in case that memory moved
2932 m_pUIMap = m_arrUIMap.m_aT;
2933 m_pUIData = m_arrUIData.m_aT;
2934
2935 bRetVal = true;
2936 }
2937 }
2938
2939 return bRetVal;
2940 }
2941
2942 bool UIRemoveUpdateElement(WORD nID)
2943 {
2944 bool bRetVal = false;
2945
2946 for(int i = 0; i < m_arrUIMap.GetSize(); i++)
2947 {
2948 if(m_arrUIMap[i].m_nID == nID)
2949 {
2950 if((m_arrUIData[i].m_wState & UPDUI_TEXT) != 0)
2951 delete [] m_arrUIData[i].m_lpstrText;
2952
2953 BOOL bRet = m_arrUIMap.RemoveAt(i);
2954 ATLASSERT(bRet);
2955 bRet = m_arrUIData.RemoveAt(i);
2956 ATLASSERT(bRet);
2957
2958 bRetVal = true;
2959 break;
2960 }
2961 }
2962
2963 return bRetVal;
2964 }
2965 };
2966
2967
2968 ///////////////////////////////////////////////////////////////////////////////
2969 // CAutoUpdateUI : Automatic mapping of UI elements
2970
2971 template <class T>
2972 class CAutoUpdateUI : public CDynamicUpdateUI<T>
2973 {
2974 public:
2975 LPCTSTR UIGetText(int nID)
2976 {
2977 for(int i = 0; i < m_arrUIMap.GetSize(); i++)
2978 {
2979 if(m_arrUIMap[i].m_nID == nID)
2980 return m_arrUIData[i].m_lpstrText;
2981 }
2982
2983 return NULL;
2984 }
2985
2986 // Element
2987 template <WORD t_wType>
2988 bool UIAddElement(UINT nID)
2989 {
2990 // check for existing UI map element
2991 for(int i = 0; i < m_arrUIMap.GetSize(); i++)
2992 {
2993 if(m_arrUIMap[i].m_nID == nID)
2994 {
2995 // set requested type
2996 m_arrUIMap[i].m_wType |= t_wType;
2997 return true;
2998 }
2999 }
3000
3001 // Add element to UI map with requested type
3002 return UIAddUpdateElement((WORD)nID, t_wType);
3003 }
3004
3005 template <WORD t_wType>
3006 bool UIRemoveElement(UINT nID)
3007 {
3008 for(int i = 0; i < m_arrUIMap.GetSize(); i++)
3009 {
3010 if(m_arrUIMap[i].m_nID == nID) // matching UI map element
3011 {
3012 WORD wType = m_arrUIMap[i].m_wType & ~t_wType;
3013 if (wType != 0) // has other types
3014 {
3015 m_arrUIMap[i].m_wType = wType; // keep other types
3016 return true;
3017 }
3018 else
3019 {
3020 return UIRemoveUpdateElement((WORD)nID);
3021 }
3022 }
3023 }
3024
3025 return false;
3026 }
3027
3028 // Menu
3029 bool UIAddMenu(HMENU hMenu, bool bSetText = false)
3030 {
3031 #if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800)
3032 using ATL::GetMenuString;
3033 #endif
3034 ATLASSERT(::IsMenu(hMenu));
3035 MENUITEMINFO mii = {sizeof(MENUITEMINFO), MIIM_TYPE | MIIM_ID | MIIM_SUBMENU};
3036
3037 // Complete the UI map
3038 for (INT uItem = 0; CMenuHandle(hMenu).GetMenuItemInfo(uItem, TRUE, &mii); uItem++)
3039 {
3040 if(mii.hSubMenu)
3041 {
3042 // Add submenu to UI map
3043 UIAddMenu(mii.hSubMenu, bSetText);
3044 }
3045 else if (mii.wID != 0)
3046 {
3047 // Add element to UI map
3048 UIAddElement<UPDUI_MENUPOPUP>(mii.wID);
3049 #if !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800)
3050 if (bSetText)
3051 {
3052 TCHAR sText[64] = { 0 };
3053 if (GetMenuString(hMenu, uItem, sText, 64, MF_BYPOSITION))
3054 UISetText(mii.wID, sText);
3055 }
3056 #else
3057 bSetText;
3058 #endif // !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800)
3059 }
3060 }
3061
3062 return true;
3063 }
3064
3065 bool UIAddMenu(UINT uID, bool bSetText = false)
3066 {
3067 CMenu menu;
3068 ATLVERIFY(menu.LoadMenu(uID));
3069 return UIAddMenu(menu, bSetText);
3070 }
3071
3072 // ToolBar
3073 #if !defined(_WIN32_WCE) || (defined(_AUTOUI_CE_TOOLBAR) && defined(TBIF_BYINDEX))
3074 bool UIAddToolBar(HWND hWndToolBar)
3075 {
3076 ATLASSERT(::IsWindow(hWndToolBar));
3077 TBBUTTONINFO tbbi = { sizeof(TBBUTTONINFO), TBIF_COMMAND | TBIF_STYLE | TBIF_BYINDEX };
3078
3079 // Add toolbar buttons
3080 for (int uItem = 0; ::SendMessage(hWndToolBar, TB_GETBUTTONINFO, uItem, (LPARAM)&tbbi) != -1; uItem++)
3081 {
3082 if (tbbi.fsStyle ^ BTNS_SEP)
3083 UIAddElement<UPDUI_TOOLBAR>(tbbi.idCommand);
3084 }
3085
3086 // Add embedded controls if any
3087 if (::GetWindow(hWndToolBar, GW_CHILD))
3088 UIAddChildWindowContainer(hWndToolBar);
3089
3090 return (CUpdateUIBase::UIAddToolBar(hWndToolBar) != FALSE);
3091 }
3092 #endif // !defined(_WIN32_WCE) || (defined(_AUTOUI_CE_TOOLBAR) && defined(TBIF_BYINDEX))
3093
3094 // Container
3095 bool UIAddChildWindowContainer(HWND hWnd)
3096 {
3097 ATLASSERT(::IsWindow(hWnd));
3098
3099 // Add children controls if any
3100 for (ATL::CWindow wCtl = ::GetWindow(hWnd, GW_CHILD); wCtl.IsWindow(); wCtl = wCtl.GetWindow(GW_HWNDNEXT))
3101 {
3102 int id = wCtl.GetDlgCtrlID();
3103 if(id != 0)
3104 UIAddElement<UPDUI_CHILDWINDOW>(id);
3105 }
3106
3107 return (CUpdateUIBase::UIAddChildWindowContainer(hWnd) != FALSE);
3108 }
3109
3110 // StatusBar
3111 BOOL UIUpdateStatusBar(BOOL bForceUpdate = FALSE)
3112 {
3113 if(!(m_wDirtyType & UPDUI_STATUSBAR) && !bForceUpdate)
3114 return TRUE;
3115
3116 for(int i = 0; i < m_arrUIMap.GetSize(); i++)
3117 {
3118 for(int e = 0; e < m_UIElements.GetSize(); e++)
3119 {
3120 if((m_UIElements[e].m_wType == UPDUI_STATUSBAR) &&
3121 (m_arrUIMap[i].m_wType & UPDUI_STATUSBAR) &&
3122 (m_arrUIData[i].m_wState & UPDUI_STATUSBAR))
3123 {
3124 UIUpdateStatusBarElement(m_arrUIMap[i].m_nID, &m_arrUIData[i], m_UIElements[e].m_hWnd);
3125 m_arrUIData[i].m_wState &= ~UPDUI_STATUSBAR;
3126 if(m_arrUIData[i].m_wState & UPDUI_TEXT)
3127 m_arrUIData[i].m_wState &= ~UPDUI_TEXT;
3128 }
3129 }
3130 }
3131
3132 m_wDirtyType &= ~UPDUI_STATUSBAR;
3133 return TRUE;
3134 }
3135
3136 bool UIAddStatusBar(HWND hWndStatusBar, INT nPanes = 1)
3137 {
3138 ATLASSERT(::IsWindow(hWndStatusBar));
3139
3140 // Add StatusBar panes
3141 for (int iPane = 0; iPane < nPanes; iPane++)
3142 UIAddElement<UPDUI_STATUSBAR>(ID_DEFAULT_PANE + iPane);
3143
3144 return (CUpdateUIBase::UIAddStatusBar(hWndStatusBar) != FALSE);
3145 }
3146
3147 // UI Map used if derived class has none
3148 BEGIN_UPDATE_UI_MAP(CAutoUpdateUI)
3149 END_UPDATE_UI_MAP()
3150 };
3151
3152
3153 ///////////////////////////////////////////////////////////////////////////////
3154 // CDialogResize - provides support for resizing dialog controls
3155 // (works for any window that has child controls)
3156
3157 // Put CDialogResize in the list of base classes for a dialog (or even plain window),
3158 // then implement DLGRESIZE map by specifying controls and groups of control
3159 // and using DLSZ_* values to specify how are they supposed to be resized.
3160 //
3161 // Notes:
3162 // - Resizeable border (WS_THICKFRAME style) should be set in the dialog template
3163 // for top level dialogs (popup or overlapped), so that users can resize the dialog.
3164 // - Some flags cannot be combined; for instance DLSZ_CENTER_X overrides DLSZ_SIZE_X,
3165 // DLSZ_SIZE_X overrides DLSZ_MOVE_X. X and Y flags can be combined.
3166 // - Order of controls is important - group controls are resized and moved based
3167 // on the position of the previous control in a group.
3168
3169 // dialog resize map macros
3170 #define BEGIN_DLGRESIZE_MAP(thisClass) \
3171 static const _AtlDlgResizeMap* GetDlgResizeMap() \
3172 { \
3173 static const _AtlDlgResizeMap theMap[] = \
3174 {
3175
3176 #define END_DLGRESIZE_MAP() \
3177 { -1, 0 }, \
3178 }; \
3179 return theMap; \
3180 }
3181
3182 #define DLGRESIZE_CONTROL(id, flags) \
3183 { id, flags },
3184
3185 #define BEGIN_DLGRESIZE_GROUP() \
3186 { -1, _DLSZ_BEGIN_GROUP },
3187
3188 #define END_DLGRESIZE_GROUP() \
3189 { -1, _DLSZ_END_GROUP },
3190
3191
3192 template <class T>
3193 class CDialogResize
3194 {
3195 public:
3196 // Data declarations and members
3197 enum
3198 {
3199 DLSZ_SIZE_X = 0x00000001,
3200 DLSZ_SIZE_Y = 0x00000002,
3201 DLSZ_MOVE_X = 0x00000004,
3202 DLSZ_MOVE_Y = 0x00000008,
3203 DLSZ_REPAINT = 0x00000010,
3204 DLSZ_CENTER_X = 0x00000020,
3205 DLSZ_CENTER_Y = 0x00000040,
3206
3207 // internal use only
3208 _DLSZ_BEGIN_GROUP = 0x00001000,
3209 _DLSZ_END_GROUP = 0x00002000,
3210 _DLSZ_GRIPPER = 0x00004000
3211 };
3212
3213 struct _AtlDlgResizeMap
3214 {
3215 int m_nCtlID;
3216 DWORD m_dwResizeFlags;
3217 };
3218
3219 struct _AtlDlgResizeData
3220 {
3221 int m_nCtlID;
3222 DWORD m_dwResizeFlags;
3223 RECT m_rect;
3224
3225 int GetGroupCount() const
3226 {
3227 return (int)LOBYTE(HIWORD(m_dwResizeFlags));
3228 }
3229
3230 void SetGroupCount(int nCount)
3231 {
3232 ATLASSERT(nCount > 0 && nCount < 256);
3233 DWORD dwCount = (DWORD)MAKELONG(0, MAKEWORD(nCount, 0));
3234 m_dwResizeFlags &= 0xFF00FFFF;
3235 m_dwResizeFlags |= dwCount;
3236 }
3237
3238 bool operator ==(const _AtlDlgResizeData& r) const
3239 { return (m_nCtlID == r.m_nCtlID && m_dwResizeFlags == r.m_dwResizeFlags); }
3240 };
3241
3242 ATL::CSimpleArray<_AtlDlgResizeData> m_arrData;
3243 SIZE m_sizeDialog;
3244 POINT m_ptMinTrackSize;
3245 bool m_bGripper;
3246
3247
3248 // Constructor
3249 CDialogResize() : m_bGripper(false)
3250 {
3251 m_sizeDialog.cx = 0;
3252 m_sizeDialog.cy = 0;
3253 m_ptMinTrackSize.x = -1;
3254 m_ptMinTrackSize.y = -1;
3255 }
3256
3257 // Operations
3258 void DlgResize_Init(bool bAddGripper = true, bool bUseMinTrackSize = true, DWORD dwForceStyle = WS_CLIPCHILDREN)
3259 {
3260 T* pT = static_cast<T*>(this);
3261 ATLASSERT(::IsWindow(pT->m_hWnd));
3262
3263 DWORD dwStyle = pT->GetStyle();
3264
3265 #ifdef _DEBUG
3266 // Debug only: Check if top level dialogs have a resizeable border.
3267 if(((dwStyle & WS_CHILD) == 0) && ((dwStyle & WS_THICKFRAME) == 0))
3268 ATLTRACE2(atlTraceUI, 0, _T("DlgResize_Init - warning: top level dialog without the WS_THICKFRAME style - user cannot resize it\n"));
3269 #endif // _DEBUG
3270
3271 // Force specified styles (default WS_CLIPCHILDREN reduces flicker)
3272 if((dwStyle & dwForceStyle) != dwForceStyle)
3273 pT->ModifyStyle(0, dwForceStyle);
3274
3275 #ifndef _WIN32_WCE
3276 // Adding this style removes an empty icon that dialogs with WS_THICKFRAME have.
3277 // Setting icon to NULL is required when XP themes are active.
3278 // Note: This will not prevent adding an icon for the dialog using SetIcon()
3279 if((dwStyle & WS_CHILD) == 0)
3280 {
3281 pT->ModifyStyleEx(0, WS_EX_DLGMODALFRAME);
3282 if(pT->GetIcon(FALSE) == NULL)
3283 pT->SetIcon(NULL, FALSE);
3284 }
3285 #endif
3286
3287 // Cleanup in case of multiple initialization
3288 // block: first check for the gripper control, destroy it if needed
3289 {
3290 ATL::CWindow wndGripper = pT->GetDlgItem(ATL_IDW_STATUS_BAR);
3291 if(wndGripper.IsWindow() && m_arrData.GetSize() > 0 && (m_arrData[0].m_dwResizeFlags & _DLSZ_GRIPPER) != 0)
3292 wndGripper.DestroyWindow();
3293 }
3294 // clear out everything else
3295 m_arrData.RemoveAll();
3296 m_sizeDialog.cx = 0;
3297 m_sizeDialog.cy = 0;
3298 m_ptMinTrackSize.x = -1;
3299 m_ptMinTrackSize.y = -1;
3300
3301 // Get initial dialog client size
3302 RECT rectDlg = { 0 };
3303 pT->GetClientRect(&rectDlg);
3304 m_sizeDialog.cx = rectDlg.right;
3305 m_sizeDialog.cy = rectDlg.bottom;
3306
3307 #ifndef _WIN32_WCE
3308 // Create gripper if requested
3309 m_bGripper = false;
3310 if(bAddGripper)
3311 {
3312 // shouldn't exist already
3313 ATLASSERT(!::IsWindow(pT->GetDlgItem(ATL_IDW_STATUS_BAR)));
3314 if(!::IsWindow(pT->GetDlgItem(ATL_IDW_STATUS_BAR)))
3315 {
3316 ATL::CWindow wndGripper;
3317 wndGripper.Create(_T("SCROLLBAR"), pT->m_hWnd, rectDlg, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SBS_SIZEBOX | SBS_SIZEGRIP | SBS_SIZEBOXBOTTOMRIGHTALIGN, 0, ATL_IDW_STATUS_BAR);
3318 ATLASSERT(wndGripper.IsWindow());
3319 if(wndGripper.IsWindow())
3320 {
3321 m_bGripper = true;
3322 RECT rectCtl = { 0 };
3323 wndGripper.GetWindowRect(&rectCtl);
3324 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rectCtl, 2);
3325 _AtlDlgResizeData data = { ATL_IDW_STATUS_BAR, DLSZ_MOVE_X | DLSZ_MOVE_Y | DLSZ_REPAINT | _DLSZ_GRIPPER, { rectCtl.left, rectCtl.top, rectCtl.right, rectCtl.bottom } };
3326 m_arrData.Add(data);
3327 }
3328 }
3329 }
3330 #else // CE specific
3331 bAddGripper; // avoid level 4 warning
3332 #endif // _WIN32_WCE
3333
3334 // Get min track position if requested
3335 if(bUseMinTrackSize)
3336 {
3337 if((dwStyle & WS_CHILD) != 0)
3338 {
3339 RECT rect = { 0 };
3340 pT->GetClientRect(&rect);
3341 m_ptMinTrackSize.x = rect.right - rect.left;
3342 m_ptMinTrackSize.y = rect.bottom - rect.top;
3343 }
3344 else
3345 {
3346 RECT rect = { 0 };
3347 pT->GetWindowRect(&rect);
3348 m_ptMinTrackSize.x = rect.right - rect.left;
3349 m_ptMinTrackSize.y = rect.bottom - rect.top;
3350 }
3351 }
3352
3353 // Walk the map and initialize data
3354 const _AtlDlgResizeMap* pMap = pT->GetDlgResizeMap();
3355 ATLASSERT(pMap != NULL);
3356 int nGroupStart = -1;
3357 for(int nCount = 1; !(pMap->m_nCtlID == -1 && pMap->m_dwResizeFlags == 0); nCount++, pMap++)
3358 {
3359 if(pMap->m_nCtlID == -1)
3360 {
3361 switch(pMap->m_dwResizeFlags)
3362 {
3363 case _DLSZ_BEGIN_GROUP:
3364 ATLASSERT(nGroupStart == -1);
3365 nGroupStart = m_arrData.GetSize();
3366 break;
3367 case _DLSZ_END_GROUP:
3368 {
3369 ATLASSERT(nGroupStart != -1);
3370 int nGroupCount = m_arrData.GetSize() - nGroupStart;
3371 m_arrData[nGroupStart].SetGroupCount(nGroupCount);
3372 nGroupStart = -1;
3373 }
3374 break;
3375 default:
3376 ATLASSERT(FALSE && _T("Invalid DLGRESIZE Map Entry"));
3377 break;
3378 }
3379 }
3380 else
3381 {
3382 // this ID conflicts with the default gripper one
3383 ATLASSERT(m_bGripper ? (pMap->m_nCtlID != ATL_IDW_STATUS_BAR) : TRUE);
3384
3385 ATL::CWindow ctl = pT->GetDlgItem(pMap->m_nCtlID);
3386 ATLASSERT(ctl.IsWindow());
3387 RECT rectCtl = { 0 };
3388 ctl.GetWindowRect(&rectCtl);
3389 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rectCtl, 2);
3390
3391 DWORD dwGroupFlag = (nGroupStart != -1 && m_arrData.GetSize() == nGroupStart) ? _DLSZ_BEGIN_GROUP : 0;
3392 _AtlDlgResizeData data = { pMap->m_nCtlID, pMap->m_dwResizeFlags | dwGroupFlag, { rectCtl.left, rectCtl.top, rectCtl.right, rectCtl.bottom } };
3393 m_arrData.Add(data);
3394 }
3395 }
3396 ATLASSERT((nGroupStart == -1) && _T("No End Group Entry in the DLGRESIZE Map"));
3397 }
3398
3399 void DlgResize_UpdateLayout(int cxWidth, int cyHeight)
3400 {
3401 T* pT = static_cast<T*>(this);
3402 ATLASSERT(::IsWindow(pT->m_hWnd));
3403
3404 // Restrict minimum size if requested
3405 if(((pT->GetStyle() & WS_CHILD) != 0) && m_ptMinTrackSize.x != -1 && m_ptMinTrackSize.y != -1)
3406 {
3407 if(cxWidth < m_ptMinTrackSize.x)
3408 cxWidth = m_ptMinTrackSize.x;
3409 if(cyHeight < m_ptMinTrackSize.y)
3410 cyHeight = m_ptMinTrackSize.y;
3411 }
3412
3413 BOOL bVisible = pT->IsWindowVisible();
3414 if(bVisible)
3415 pT->SetRedraw(FALSE);
3416
3417 for(int i = 0; i < m_arrData.GetSize(); i++)
3418 {
3419 if((m_arrData[i].m_dwResizeFlags & _DLSZ_BEGIN_GROUP) != 0) // start of a group
3420 {
3421 int nGroupCount = m_arrData[i].GetGroupCount();
3422 ATLASSERT(nGroupCount > 0 && i + nGroupCount - 1 < m_arrData.GetSize());
3423 RECT rectGroup = m_arrData[i].m_rect;
3424
3425 int j = 1;
3426 for(j = 1; j < nGroupCount; j++)
3427 {
3428 rectGroup.left = __min(rectGroup.left, m_arrData[i + j].m_rect.left);
3429 rectGroup.top = __min(rectGroup.top, m_arrData[i + j].m_rect.top);
3430 rectGroup.right = __max(rectGroup.right, m_arrData[i + j].m_rect.right);
3431 rectGroup.bottom = __max(rectGroup.bottom, m_arrData[i + j].m_rect.bottom);
3432 }
3433
3434 for(j = 0; j < nGroupCount; j++)
3435 {
3436 _AtlDlgResizeData* pDataPrev = NULL;
3437 if(j > 0)
3438 pDataPrev = &(m_arrData[i + j - 1]);
3439 pT->DlgResize_PositionControl(cxWidth, cyHeight, rectGroup, m_arrData[i + j], true, pDataPrev);
3440 }
3441
3442 i += nGroupCount - 1; // increment to skip all group controls
3443 }
3444 else // one control entry
3445 {
3446 RECT rectGroup = { 0 };
3447 pT->DlgResize_PositionControl(cxWidth, cyHeight, rectGroup, m_arrData[i], false);
3448 }
3449 }
3450
3451 if(bVisible)
3452 pT->SetRedraw(TRUE);
3453
3454 pT->RedrawWindow(NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
3455 }
3456
3457 // Message map and handlers
3458 BEGIN_MSG_MAP(CDialogResize)
3459 MESSAGE_HANDLER(WM_SIZE, OnSize)
3460 #ifndef _WIN32_WCE
3461 MESSAGE_HANDLER(WM_GETMINMAXINFO, OnGetMinMaxInfo)
3462 #endif // _WIN32_WCE
3463 END_MSG_MAP()
3464
3465 LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
3466 {
3467 T* pT = static_cast<T*>(this);
3468 #ifndef _WIN32_WCE
3469 if(m_bGripper)
3470 {
3471 ATL::CWindow wndGripper = pT->GetDlgItem(ATL_IDW_STATUS_BAR);
3472 if(wParam == SIZE_MAXIMIZED)
3473 wndGripper.ShowWindow(SW_HIDE);
3474 else if(wParam == SIZE_RESTORED)
3475 wndGripper.ShowWindow(SW_SHOW);
3476 }
3477 #endif // _WIN32_WCE
3478 if(wParam != SIZE_MINIMIZED)
3479 {
3480 ATLASSERT(::IsWindow(pT->m_hWnd));
3481 pT->DlgResize_UpdateLayout(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
3482 }
3483 return 0;
3484 }
3485
3486 #ifndef _WIN32_WCE
3487 LRESULT OnGetMinMaxInfo(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
3488 {
3489 if(m_ptMinTrackSize.x != -1 && m_ptMinTrackSize.y != -1)
3490 {
3491 LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam;
3492 lpMMI->ptMinTrackSize = m_ptMinTrackSize;
3493 }
3494 return 0;
3495 }
3496 #endif // _WIN32_WCE
3497
3498 // Implementation
3499 bool DlgResize_PositionControl(int cxWidth, int cyHeight, RECT& rectGroup, _AtlDlgResizeData& data, bool bGroup,
3500 _AtlDlgResizeData* pDataPrev = NULL)
3501 {
3502 T* pT = static_cast<T*>(this);
3503 ATLASSERT(::IsWindow(pT->m_hWnd));
3504 ATL::CWindow ctl;
3505 RECT rectCtl = { 0 };
3506
3507 ctl = pT->GetDlgItem(data.m_nCtlID);
3508 if(!ctl.GetWindowRect(&rectCtl))
3509 return false;
3510 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rectCtl, 2);
3511
3512 if(bGroup)
3513 {
3514 if((data.m_dwResizeFlags & DLSZ_CENTER_X) != 0)
3515 {
3516 int cxRight = rectGroup.right + cxWidth - m_sizeDialog.cx;
3517 int cxCtl = data.m_rect.right - data.m_rect.left;
3518 rectCtl.left = rectGroup.left + (cxRight - rectGroup.left - cxCtl) / 2;
3519 rectCtl.right = rectCtl.left + cxCtl;
3520 }
3521 else if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_MOVE_X)) != 0)
3522 {
3523 rectCtl.left = rectGroup.left + ::MulDiv(data.m_rect.left - rectGroup.left, rectGroup.right - rectGroup.left + (cxWidth - m_sizeDialog.cx), rectGroup.right - rectGroup.left);
3524
3525 if((data.m_dwResizeFlags & DLSZ_SIZE_X) != 0)
3526 {
3527 rectCtl.right = rectGroup.left + ::MulDiv(data.m_rect.right - rectGroup.left, rectGroup.right - rectGroup.left + (cxWidth - m_sizeDialog.cx), rectGroup.right - rectGroup.left);
3528
3529 if(pDataPrev != NULL)
3530 {
3531 ATL::CWindow ctlPrev = pT->GetDlgItem(pDataPrev->m_nCtlID);
3532 RECT rcPrev = { 0 };
3533 ctlPrev.GetWindowRect(&rcPrev);
3534 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rcPrev, 2);
3535 int dxAdjust = (rectCtl.left - rcPrev.right) - (data.m_rect.left - pDataPrev->m_rect.right);
3536 rcPrev.right += dxAdjust;
3537 ctlPrev.SetWindowPos(NULL, &rcPrev, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
3538 }
3539 }
3540 else
3541 {
3542 rectCtl.right = rectCtl.left + (data.m_rect.right - data.m_rect.left);
3543 }
3544 }
3545
3546 if((data.m_dwResizeFlags & DLSZ_CENTER_Y) != 0)
3547 {
3548 int cyBottom = rectGroup.bottom + cyHeight - m_sizeDialog.cy;
3549 int cyCtl = data.m_rect.bottom - data.m_rect.top;
3550 rectCtl.top = rectGroup.top + (cyBottom - rectGroup.top - cyCtl) / 2;
3551 rectCtl.bottom = rectCtl.top + cyCtl;
3552 }
3553 else if((data.m_dwResizeFlags & (DLSZ_SIZE_Y | DLSZ_MOVE_Y)) != 0)
3554 {
3555 rectCtl.top = rectGroup.top + ::MulDiv(data.m_rect.top - rectGroup.top, rectGroup.bottom - rectGroup.top + (cyHeight - m_sizeDialog.cy), rectGroup.bottom - rectGroup.top);
3556
3557 if((data.m_dwResizeFlags & DLSZ_SIZE_Y) != 0)
3558 {
3559 rectCtl.bottom = rectGroup.top + ::MulDiv(data.m_rect.bottom - rectGroup.top, rectGroup.bottom - rectGroup.top + (cyHeight - m_sizeDialog.cy), rectGroup.bottom - rectGroup.top);
3560
3561 if(pDataPrev != NULL)
3562 {
3563 ATL::CWindow ctlPrev = pT->GetDlgItem(pDataPrev->m_nCtlID);
3564 RECT rcPrev = { 0 };
3565 ctlPrev.GetWindowRect(&rcPrev);
3566 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rcPrev, 2);
3567 int dxAdjust = (rectCtl.top - rcPrev.bottom) - (data.m_rect.top - pDataPrev->m_rect.bottom);
3568 rcPrev.bottom += dxAdjust;
3569 ctlPrev.SetWindowPos(NULL, &rcPrev, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
3570 }
3571 }
3572 else
3573 {
3574 rectCtl.bottom = rectCtl.top + (data.m_rect.bottom - data.m_rect.top);
3575 }
3576 }
3577 }
3578 else // no group
3579 {
3580 if((data.m_dwResizeFlags & DLSZ_CENTER_X) != 0)
3581 {
3582 int cxCtl = data.m_rect.right - data.m_rect.left;
3583 rectCtl.left = (cxWidth - cxCtl) / 2;
3584 rectCtl.right = rectCtl.left + cxCtl;
3585 }
3586 else if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_MOVE_X)) != 0)
3587 {
3588 rectCtl.right = data.m_rect.right + (cxWidth - m_sizeDialog.cx);
3589
3590 if((data.m_dwResizeFlags & DLSZ_MOVE_X) != 0)
3591 rectCtl.left = rectCtl.right - (data.m_rect.right - data.m_rect.left);
3592 }
3593
3594 if((data.m_dwResizeFlags & DLSZ_CENTER_Y) != 0)
3595 {
3596 int cyCtl = data.m_rect.bottom - data.m_rect.top;
3597 rectCtl.top = (cyHeight - cyCtl) / 2;
3598 rectCtl.bottom = rectCtl.top + cyCtl;
3599 }
3600 else if((data.m_dwResizeFlags & (DLSZ_SIZE_Y | DLSZ_MOVE_Y)) != 0)
3601 {
3602 rectCtl.bottom = data.m_rect.bottom + (cyHeight - m_sizeDialog.cy);
3603
3604 if((data.m_dwResizeFlags & DLSZ_MOVE_Y) != 0)
3605 rectCtl.top = rectCtl.bottom - (data.m_rect.bottom - data.m_rect.top);
3606 }
3607 }
3608
3609 if((data.m_dwResizeFlags & DLSZ_REPAINT) != 0)
3610 ctl.Invalidate();
3611
3612 if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_SIZE_Y | DLSZ_MOVE_X | DLSZ_MOVE_Y | DLSZ_REPAINT | DLSZ_CENTER_X | DLSZ_CENTER_Y)) != 0)
3613 ctl.SetWindowPos(NULL, &rectCtl, SWP_NOZORDER | SWP_NOACTIVATE);
3614
3615 return true;
3616 }
3617 };
3618
3619
3620 ///////////////////////////////////////////////////////////////////////////////
3621 // CDoubleBufferImpl - Provides double-buffer painting support to any window
3622
3623 template <class T>
3624 class CDoubleBufferImpl
3625 {
3626 public:
3627 // Overrideables
3628 void DoPaint(CDCHandle /*dc*/)
3629 {
3630 // must be implemented in a derived class
3631 ATLASSERT(FALSE);
3632 }
3633
3634 // Message map and handlers
3635 BEGIN_MSG_MAP(CDoubleBufferImpl)
3636 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
3637 MESSAGE_HANDLER(WM_PAINT, OnPaint)
3638 #ifndef _WIN32_WCE
3639 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
3640 #endif // !_WIN32_WCE
3641 END_MSG_MAP()
3642
3643 LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
3644 {
3645 return 1; // no background painting needed
3646 }
3647
3648 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
3649 {
3650 T* pT = static_cast<T*>(this);
3651 ATLASSERT(::IsWindow(pT->m_hWnd));
3652
3653 if(wParam != NULL)
3654 {
3655 RECT rect = { 0 };
3656 pT->GetClientRect(&rect);
3657 CMemoryDC dcMem((HDC)wParam, rect);
3658 pT->DoPaint(dcMem.m_hDC);
3659 }
3660 else
3661 {
3662 CPaintDC dc(pT->m_hWnd);
3663 CMemoryDC dcMem(dc.m_hDC, dc.m_ps.rcPaint);
3664 pT->DoPaint(dcMem.m_hDC);
3665 }
3666
3667 return 0;
3668 }
3669 };
3670
3671
3672 ///////////////////////////////////////////////////////////////////////////////
3673 // CDoubleBufferWindowImpl - Implements a double-buffer painting window
3674
3675 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
3676 class ATL_NO_VTABLE CDoubleBufferWindowImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CDoubleBufferImpl< T >
3677 {
3678 public:
3679 BEGIN_MSG_MAP(CDoubleBufferWindowImpl)
3680 CHAIN_MSG_MAP(CDoubleBufferImpl< T >)
3681 END_MSG_MAP()
3682 };
3683
3684
3685 // command bar support
3686 #if !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE)
3687 #undef CBRM_GETMENU
3688 #undef CBRM_TRACKPOPUPMENU
3689 #undef CBRM_GETCMDBAR
3690 #undef CBRPOPUPMENU
3691 #endif // !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE)
3692
3693 }; // namespace WTL
3694
3695 #endif // __ATLFRAME_H__
+0
-3889
src/third_party/wtl/Include/atlgdi.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLGDI_H__
9 #define __ATLGDI_H__
10
11 #pragma once
12
13 #ifndef __ATLAPP_H__
14 #error atlgdi.h requires atlapp.h to be included first
15 #endif
16
17
18 // protect template members from windowsx.h macros
19 #ifdef _INC_WINDOWSX
20 #undef CopyRgn
21 #undef CreateBrush
22 #undef CreatePen
23 #undef SelectBrush
24 #undef SelectPen
25 #undef SelectFont
26 #undef SelectBitmap
27 #endif // _INC_WINDOWSX
28
29 // required libraries
30 #if !defined(_ATL_NO_MSIMG) && !defined(_WIN32_WCE)
31 #pragma comment(lib, "msimg32.lib")
32 #endif
33 #if !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE)
34 #pragma comment(lib, "opengl32.lib")
35 #endif
36
37
38 ///////////////////////////////////////////////////////////////////////////////
39 // Classes in this file:
40 //
41 // CPenT<t_bManaged>
42 // CBrushT<t_bManaged>
43 // CLogFont
44 // CFontT<t_bManaged>
45 // CBitmapT<t_bManaged>
46 // CPaletteT<t_bManaged>
47 // CRgnT<t_bManaged>
48 // CDCT<t_bManaged>
49 // CPaintDC
50 // CClientDC
51 // CWindowDC
52 // CMemoryDC
53 // CEnhMetaFileInfo
54 // CEnhMetaFileT<t_bManaged>
55 // CEnhMetaFileDC
56 //
57 // Global functions:
58 // AtlGetBitmapResourceInfo()
59 // AtlGetBitmapResourceBitsPerPixel()
60 // AtlIsAlphaBitmapResource()
61 // AtlIsDib16()
62 // AtlGetDibColorTableSize()
63 // AtlGetDibNumColors(),
64 // AtlGetDibBitmap()
65 // AtlCopyBitmap()
66 // AtlCreatePackedDib16()
67 // AtlSetClipboardDib16()
68 // AtlGetClipboardDib()
69
70
71 namespace WTL
72 {
73
74 ///////////////////////////////////////////////////////////////////////////////
75 // Bitmap resource helpers to extract bitmap information for a bitmap resource
76
77 inline LPBITMAPINFOHEADER AtlGetBitmapResourceInfo(HMODULE hModule, ATL::_U_STRINGorID image)
78 {
79 HRSRC hResource = ::FindResource(hModule, image.m_lpstr, RT_BITMAP);
80 ATLASSERT(hResource != NULL);
81 HGLOBAL hGlobal = ::LoadResource(hModule, hResource);
82 ATLASSERT(hGlobal != NULL);
83 LPBITMAPINFOHEADER pBitmapInfoHeader = (LPBITMAPINFOHEADER)::LockResource(hGlobal);
84 ATLASSERT(pBitmapInfoHeader != NULL);
85 return pBitmapInfoHeader;
86 }
87
88 inline WORD AtlGetBitmapResourceBitsPerPixel(HMODULE hModule, ATL::_U_STRINGorID image)
89 {
90 LPBITMAPINFOHEADER pBitmapInfoHeader = AtlGetBitmapResourceInfo(hModule, image);
91 ATLASSERT(pBitmapInfoHeader != NULL);
92 return pBitmapInfoHeader->biBitCount;
93 }
94
95 inline WORD AtlGetBitmapResourceBitsPerPixel(ATL::_U_STRINGorID image)
96 {
97 return AtlGetBitmapResourceBitsPerPixel(ModuleHelper::GetResourceInstance(), image);
98 }
99
100 ///////////////////////////////////////////////////////////////////////////////
101 // 32-bit (alpha channel) bitmap resource helper
102
103 // Note: 32-bit (alpha channel) images work only on Windows XP with Common Controls version 6.
104 // If you want your app to work on older version of Windows, load non-alpha images if Common
105 // Controls version is less than 6.
106
107 inline bool AtlIsAlphaBitmapResource(ATL::_U_STRINGorID image)
108 {
109 return (AtlGetBitmapResourceBitsPerPixel(image) == 32);
110 }
111
112
113 ///////////////////////////////////////////////////////////////////////////////
114 // CPen
115
116 template <bool t_bManaged>
117 class CPenT
118 {
119 public:
120 // Data members
121 HPEN m_hPen;
122
123 // Constructor/destructor/operators
124 CPenT(HPEN hPen = NULL) : m_hPen(hPen)
125 { }
126
127 ~CPenT()
128 {
129 if(t_bManaged && m_hPen != NULL)
130 DeleteObject();
131 }
132
133 CPenT<t_bManaged>& operator =(HPEN hPen)
134 {
135 Attach(hPen);
136 return *this;
137 }
138
139 void Attach(HPEN hPen)
140 {
141 if(t_bManaged && m_hPen != NULL && m_hPen != hPen)
142 ::DeleteObject(m_hPen);
143 m_hPen = hPen;
144 }
145
146 HPEN Detach()
147 {
148 HPEN hPen = m_hPen;
149 m_hPen = NULL;
150 return hPen;
151 }
152
153 operator HPEN() const { return m_hPen; }
154
155 bool IsNull() const { return (m_hPen == NULL); }
156
157 // Create methods
158 HPEN CreatePen(int nPenStyle, int nWidth, COLORREF crColor)
159 {
160 ATLASSERT(m_hPen == NULL);
161 m_hPen = ::CreatePen(nPenStyle, nWidth, crColor);
162 return m_hPen;
163 }
164
165 #ifndef _WIN32_WCE
166 HPEN CreatePen(int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush, int nStyleCount = 0, const DWORD* lpStyle = NULL)
167 {
168 ATLASSERT(m_hPen == NULL);
169 m_hPen = ::ExtCreatePen(nPenStyle, nWidth, pLogBrush, nStyleCount, lpStyle);
170 return m_hPen;
171 }
172 #endif // !_WIN32_WCE
173
174 HPEN CreatePenIndirect(LPLOGPEN lpLogPen)
175 {
176 ATLASSERT(m_hPen == NULL);
177 m_hPen = ::CreatePenIndirect(lpLogPen);
178 return m_hPen;
179 }
180
181 BOOL DeleteObject()
182 {
183 ATLASSERT(m_hPen != NULL);
184 BOOL bRet = ::DeleteObject(m_hPen);
185 if(bRet)
186 m_hPen = NULL;
187 return bRet;
188 }
189
190 // Attributes
191 int GetLogPen(LOGPEN* pLogPen) const
192 {
193 ATLASSERT(m_hPen != NULL);
194 return ::GetObject(m_hPen, sizeof(LOGPEN), pLogPen);
195 }
196
197 bool GetLogPen(LOGPEN& LogPen) const
198 {
199 ATLASSERT(m_hPen != NULL);
200 return (::GetObject(m_hPen, sizeof(LOGPEN), &LogPen) == sizeof(LOGPEN));
201 }
202
203 #ifndef _WIN32_WCE
204 int GetExtLogPen(EXTLOGPEN* pLogPen, int nSize = sizeof(EXTLOGPEN)) const
205 {
206 ATLASSERT(m_hPen != NULL);
207 return ::GetObject(m_hPen, nSize, pLogPen);
208 }
209
210 bool GetExtLogPen(EXTLOGPEN& ExtLogPen, int nSize = sizeof(EXTLOGPEN)) const
211 {
212 ATLASSERT(m_hPen != NULL);
213 int nRet = ::GetObject(m_hPen, nSize, &ExtLogPen);
214 return ((nRet > 0) && (nRet <= nSize));
215 }
216 #endif // !_WIN32_WCE
217 };
218
219 typedef CPenT<false> CPenHandle;
220 typedef CPenT<true> CPen;
221
222
223 ///////////////////////////////////////////////////////////////////////////////
224 // CBrush
225
226 template <bool t_bManaged>
227 class CBrushT
228 {
229 public:
230 // Data members
231 HBRUSH m_hBrush;
232
233 // Constructor/destructor/operators
234 CBrushT(HBRUSH hBrush = NULL) : m_hBrush(hBrush)
235 { }
236
237 ~CBrushT()
238 {
239 if(t_bManaged && m_hBrush != NULL)
240 DeleteObject();
241 }
242
243 CBrushT<t_bManaged>& operator =(HBRUSH hBrush)
244 {
245 Attach(hBrush);
246 return *this;
247 }
248
249 void Attach(HBRUSH hBrush)
250 {
251 if(t_bManaged && m_hBrush != NULL && m_hBrush != hBrush)
252 ::DeleteObject(m_hBrush);
253 m_hBrush = hBrush;
254 }
255
256 HBRUSH Detach()
257 {
258 HBRUSH hBrush = m_hBrush;
259 m_hBrush = NULL;
260 return hBrush;
261 }
262
263 operator HBRUSH() const { return m_hBrush; }
264
265 bool IsNull() const { return (m_hBrush == NULL); }
266
267 // Create methods
268 HBRUSH CreateSolidBrush(COLORREF crColor)
269 {
270 ATLASSERT(m_hBrush == NULL);
271 m_hBrush = ::CreateSolidBrush(crColor);
272 return m_hBrush;
273 }
274
275 #ifndef _WIN32_WCE
276 HBRUSH CreateHatchBrush(int nIndex, COLORREF crColor)
277 {
278 ATLASSERT(m_hBrush == NULL);
279 m_hBrush = ::CreateHatchBrush(nIndex, crColor);
280 return m_hBrush;
281 }
282 #endif // !_WIN32_WCE
283
284 #if !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800)
285 HBRUSH CreateBrushIndirect(const LOGBRUSH* lpLogBrush)
286 {
287 ATLASSERT(m_hBrush == NULL);
288 #ifndef _WIN32_WCE
289 m_hBrush = ::CreateBrushIndirect(lpLogBrush);
290 #else // CE specific
291 m_hBrush = ATL::CreateBrushIndirect(lpLogBrush);
292 #endif // _WIN32_WCE
293 return m_hBrush;
294 }
295 #endif // !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800)
296
297 HBRUSH CreatePatternBrush(HBITMAP hBitmap)
298 {
299 ATLASSERT(m_hBrush == NULL);
300 m_hBrush = ::CreatePatternBrush(hBitmap);
301 return m_hBrush;
302 }
303
304 HBRUSH CreateDIBPatternBrush(HGLOBAL hPackedDIB, UINT nUsage)
305 {
306 ATLASSERT(hPackedDIB != NULL);
307 const void* lpPackedDIB = GlobalLock(hPackedDIB);
308 ATLASSERT(lpPackedDIB != NULL);
309 m_hBrush = ::CreateDIBPatternBrushPt(lpPackedDIB, nUsage);
310 GlobalUnlock(hPackedDIB);
311 return m_hBrush;
312 }
313
314 HBRUSH CreateDIBPatternBrush(const void* lpPackedDIB, UINT nUsage)
315 {
316 ATLASSERT(m_hBrush == NULL);
317 m_hBrush = ::CreateDIBPatternBrushPt(lpPackedDIB, nUsage);
318 return m_hBrush;
319 }
320
321 HBRUSH CreateSysColorBrush(int nIndex)
322 {
323 ATLASSERT(m_hBrush == NULL);
324 m_hBrush = ::GetSysColorBrush(nIndex);
325 return m_hBrush;
326 }
327
328 BOOL DeleteObject()
329 {
330 ATLASSERT(m_hBrush != NULL);
331 BOOL bRet = ::DeleteObject(m_hBrush);
332 if(bRet)
333 m_hBrush = NULL;
334 return bRet;
335 }
336
337 // Attributes
338 int GetLogBrush(LOGBRUSH* pLogBrush) const
339 {
340 ATLASSERT(m_hBrush != NULL);
341 return ::GetObject(m_hBrush, sizeof(LOGBRUSH), pLogBrush);
342 }
343
344 bool GetLogBrush(LOGBRUSH& LogBrush) const
345 {
346 ATLASSERT(m_hBrush != NULL);
347 return (::GetObject(m_hBrush, sizeof(LOGBRUSH), &LogBrush) == sizeof(LOGBRUSH));
348 }
349 };
350
351 typedef CBrushT<false> CBrushHandle;
352 typedef CBrushT<true> CBrush;
353
354
355 ///////////////////////////////////////////////////////////////////////////////
356 // CFont
357
358 class CLogFont : public LOGFONT
359 {
360 public:
361 CLogFont()
362 {
363 memset(this, 0, sizeof(LOGFONT));
364 }
365
366 CLogFont(const LOGFONT& lf)
367 {
368 Copy(&lf);
369 }
370
371 CLogFont(HFONT hFont)
372 {
373 ATLASSERT(::GetObjectType(hFont) == OBJ_FONT);
374 ::GetObject(hFont, sizeof(LOGFONT), (LOGFONT*)this);
375 }
376
377 HFONT CreateFontIndirect()
378 {
379 return ::CreateFontIndirect(this);
380 }
381
382 void SetBold()
383 {
384 lfWeight = FW_BOLD;
385 }
386
387 bool IsBold() const
388 {
389 return (lfWeight >= FW_BOLD);
390 }
391
392 void MakeBolder(int iScale = 1)
393 {
394 lfWeight += FW_BOLD * iScale;
395 }
396
397 void MakeLarger(int iScale)
398 {
399 if(lfHeight > 0)
400 lfHeight += iScale;
401 else
402 lfHeight -= iScale;
403 }
404
405 void SetHeight(LONG nPointSize, HDC hDC = NULL)
406 {
407 HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL);
408 // For MM_TEXT mapping mode
409 lfHeight = -::MulDiv(nPointSize, ::GetDeviceCaps(hDC1, LOGPIXELSY), 72);
410 if(hDC == NULL)
411 ::ReleaseDC(NULL, hDC1);
412 }
413
414 LONG GetHeight(HDC hDC = NULL) const
415 {
416 HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL);
417 // For MM_TEXT mapping mode
418 LONG nPointSize = ::MulDiv(-lfHeight, 72, ::GetDeviceCaps(hDC1, LOGPIXELSY));
419 if(hDC == NULL)
420 ::ReleaseDC(NULL, hDC1);
421
422 return nPointSize;
423 }
424
425 LONG GetDeciPointHeight(HDC hDC = NULL) const
426 {
427 HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL);
428 #ifndef _WIN32_WCE
429 POINT ptOrg = { 0, 0 };
430 ::DPtoLP(hDC1, &ptOrg, 1);
431 POINT pt = { 0, 0 };
432 pt.y = abs(lfHeight) + ptOrg.y;
433 ::LPtoDP(hDC1, &pt,1);
434 LONG nDeciPoint = ::MulDiv(pt.y, 720, ::GetDeviceCaps(hDC1, LOGPIXELSY)); // 72 points/inch, 10 decipoints/point
435 #else // CE specific
436 // DP and LP are always the same on CE
437 LONG nDeciPoint = ::MulDiv(abs(lfHeight), 720, ::GetDeviceCaps(hDC1, LOGPIXELSY)); // 72 points/inch, 10 decipoints/point
438 #endif // _WIN32_WCE
439 if(hDC == NULL)
440 ::ReleaseDC(NULL, hDC1);
441
442 return nDeciPoint;
443 }
444
445 void SetHeightFromDeciPoint(LONG nDeciPtHeight, HDC hDC = NULL)
446 {
447 HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL);
448 #ifndef _WIN32_WCE
449 POINT pt = { 0, 0 };
450 pt.y = ::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), nDeciPtHeight, 720); // 72 points/inch, 10 decipoints/point
451 ::DPtoLP(hDC1, &pt, 1);
452 POINT ptOrg = { 0, 0 };
453 ::DPtoLP(hDC1, &ptOrg, 1);
454 lfHeight = -abs(pt.y - ptOrg.y);
455 #else // CE specific
456 // DP and LP are always the same on CE
457 lfHeight = -abs(::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), nDeciPtHeight, 720)); // 72 points/inch, 10 decipoints/point
458 #endif // _WIN32_WCE
459 if(hDC == NULL)
460 ::ReleaseDC(NULL, hDC1);
461 }
462
463 #ifndef _WIN32_WCE
464 void SetCaptionFont()
465 {
466 NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() };
467 ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0));
468 Copy(&ncm.lfCaptionFont);
469 }
470
471 void SetMenuFont()
472 {
473 NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() };
474 ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0));
475 Copy(&ncm.lfMenuFont);
476 }
477
478 void SetStatusFont()
479 {
480 NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() };
481 ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0));
482 Copy(&ncm.lfStatusFont);
483 }
484
485 void SetMessageBoxFont()
486 {
487 NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() };
488 ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0));
489 Copy(&ncm.lfMessageFont);
490 }
491 #endif // !_WIN32_WCE
492
493 void Copy(const LOGFONT* pLogFont)
494 {
495 ATLASSERT(pLogFont != NULL);
496 *(LOGFONT*)this = *pLogFont;
497 }
498
499 CLogFont& operator =(const CLogFont& src)
500 {
501 Copy(&src);
502 return *this;
503 }
504
505 CLogFont& operator =(const LOGFONT& src)
506 {
507 Copy(&src);
508 return *this;
509 }
510
511 CLogFont& operator =(HFONT hFont)
512 {
513 ATLASSERT(::GetObjectType(hFont) == OBJ_FONT);
514 ::GetObject(hFont, sizeof(LOGFONT), (LOGFONT*)this);
515 return *this;
516 }
517
518 bool operator ==(const LOGFONT& logfont) const
519 {
520 return(logfont.lfHeight == lfHeight &&
521 logfont.lfWidth == lfWidth &&
522 logfont.lfEscapement == lfEscapement &&
523 logfont.lfOrientation == lfOrientation &&
524 logfont.lfWeight == lfWeight &&
525 logfont.lfItalic == lfItalic &&
526 logfont.lfUnderline == lfUnderline &&
527 logfont.lfStrikeOut == lfStrikeOut &&
528 logfont.lfCharSet == lfCharSet &&
529 logfont.lfOutPrecision == lfOutPrecision &&
530 logfont.lfClipPrecision == lfClipPrecision &&
531 logfont.lfQuality == lfQuality &&
532 logfont.lfPitchAndFamily == lfPitchAndFamily &&
533 lstrcmp(logfont.lfFaceName, lfFaceName) == 0);
534 }
535 };
536
537
538 template <bool t_bManaged>
539 class CFontT
540 {
541 public:
542 // Data members
543 HFONT m_hFont;
544
545 // Constructor/destructor/operators
546 CFontT(HFONT hFont = NULL) : m_hFont(hFont)
547 { }
548
549 ~CFontT()
550 {
551 if(t_bManaged && m_hFont != NULL)
552 DeleteObject();
553 }
554
555 CFontT<t_bManaged>& operator =(HFONT hFont)
556 {
557 Attach(hFont);
558 return *this;
559 }
560
561 void Attach(HFONT hFont)
562 {
563 if(t_bManaged && m_hFont != NULL && m_hFont != hFont)
564 ::DeleteObject(m_hFont);
565 m_hFont = hFont;
566 }
567
568 HFONT Detach()
569 {
570 HFONT hFont = m_hFont;
571 m_hFont = NULL;
572 return hFont;
573 }
574
575 operator HFONT() const { return m_hFont; }
576
577 bool IsNull() const { return (m_hFont == NULL); }
578
579 // Create methods
580 HFONT CreateFontIndirect(const LOGFONT* lpLogFont)
581 {
582 ATLASSERT(m_hFont == NULL);
583 m_hFont = ::CreateFontIndirect(lpLogFont);
584 return m_hFont;
585 }
586
587 #if !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0500)
588 HFONT CreateFontIndirectEx(CONST ENUMLOGFONTEXDV* penumlfex)
589 {
590 ATLASSERT(m_hFont == NULL);
591 m_hFont = ::CreateFontIndirectEx(penumlfex);
592 return m_hFont;
593 }
594 #endif // !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0500)
595
596 #if !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800)
597 HFONT CreateFont(int nHeight, int nWidth, int nEscapement,
598 int nOrientation, int nWeight, BYTE bItalic, BYTE bUnderline,
599 BYTE cStrikeOut, BYTE nCharSet, BYTE nOutPrecision,
600 BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily,
601 LPCTSTR lpszFacename)
602 {
603 ATLASSERT(m_hFont == NULL);
604 #ifndef _WIN32_WCE
605 m_hFont = ::CreateFont(nHeight, nWidth, nEscapement,
606 nOrientation, nWeight, bItalic, bUnderline, cStrikeOut,
607 nCharSet, nOutPrecision, nClipPrecision, nQuality,
608 nPitchAndFamily, lpszFacename);
609 #else // CE specific
610 m_hFont = ATL::CreateFont(nHeight, nWidth, nEscapement,
611 nOrientation, nWeight, bItalic, bUnderline, cStrikeOut,
612 nCharSet, nOutPrecision, nClipPrecision, nQuality,
613 nPitchAndFamily, lpszFacename);
614 #endif // _WIN32_WCE
615 return m_hFont;
616 }
617 #endif // !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800)
618
619 HFONT CreatePointFont(int nPointSize, LPCTSTR lpszFaceName, HDC hDC = NULL, bool bBold = false, bool bItalic = false)
620 {
621 LOGFONT logFont = { 0 };
622 logFont.lfCharSet = DEFAULT_CHARSET;
623 logFont.lfHeight = nPointSize;
624 SecureHelper::strncpy_x(logFont.lfFaceName, _countof(logFont.lfFaceName), lpszFaceName, _TRUNCATE);
625
626 if(bBold)
627 logFont.lfWeight = FW_BOLD;
628 if(bItalic)
629 logFont.lfItalic = (BYTE)TRUE;
630
631 return CreatePointFontIndirect(&logFont, hDC);
632 }
633
634 HFONT CreatePointFontIndirect(const LOGFONT* lpLogFont, HDC hDC = NULL)
635 {
636 HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL);
637
638 // convert nPointSize to logical units based on hDC
639 LOGFONT logFont = *lpLogFont;
640 #ifndef _WIN32_WCE
641 POINT pt = { 0, 0 };
642 pt.y = ::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), logFont.lfHeight, 720); // 72 points/inch, 10 decipoints/point
643 ::DPtoLP(hDC1, &pt, 1);
644 POINT ptOrg = { 0, 0 };
645 ::DPtoLP(hDC1, &ptOrg, 1);
646 logFont.lfHeight = -abs(pt.y - ptOrg.y);
647 #else // CE specific
648 // DP and LP are always the same on CE
649 logFont.lfHeight = -abs(::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), logFont.lfHeight, 720)); // 72 points/inch, 10 decipoints/point
650 #endif // _WIN32_WCE
651
652 if(hDC == NULL)
653 ::ReleaseDC(NULL, hDC1);
654
655 return CreateFontIndirect(&logFont);
656 }
657
658 BOOL DeleteObject()
659 {
660 ATLASSERT(m_hFont != NULL);
661 BOOL bRet = ::DeleteObject(m_hFont);
662 if(bRet)
663 m_hFont = NULL;
664 return bRet;
665 }
666
667 // Attributes
668 int GetLogFont(LOGFONT* pLogFont) const
669 {
670 ATLASSERT(m_hFont != NULL);
671 return ::GetObject(m_hFont, sizeof(LOGFONT), pLogFont);
672 }
673
674 bool GetLogFont(LOGFONT& LogFont) const
675 {
676 ATLASSERT(m_hFont != NULL);
677 return (::GetObject(m_hFont, sizeof(LOGFONT), &LogFont) == sizeof(LOGFONT));
678 }
679 };
680
681 typedef CFontT<false> CFontHandle;
682 typedef CFontT<true> CFont;
683
684
685 ///////////////////////////////////////////////////////////////////////////////
686 // CBitmap
687
688 template <bool t_bManaged>
689 class CBitmapT
690 {
691 public:
692 // Data members
693 HBITMAP m_hBitmap;
694
695 // Constructor/destructor/operators
696 CBitmapT(HBITMAP hBitmap = NULL) : m_hBitmap(hBitmap)
697 { }
698
699 ~CBitmapT()
700 {
701 if(t_bManaged && m_hBitmap != NULL)
702 DeleteObject();
703 }
704
705 CBitmapT<t_bManaged>& operator =(HBITMAP hBitmap)
706 {
707 Attach(hBitmap);
708 return *this;
709 }
710
711 void Attach(HBITMAP hBitmap)
712 {
713 if(t_bManaged && m_hBitmap != NULL&& m_hBitmap != hBitmap)
714 ::DeleteObject(m_hBitmap);
715 m_hBitmap = hBitmap;
716 }
717
718 HBITMAP Detach()
719 {
720 HBITMAP hBitmap = m_hBitmap;
721 m_hBitmap = NULL;
722 return hBitmap;
723 }
724
725 operator HBITMAP() const { return m_hBitmap; }
726
727 bool IsNull() const { return (m_hBitmap == NULL); }
728
729 // Create and load methods
730 HBITMAP LoadBitmap(ATL::_U_STRINGorID bitmap)
731 {
732 ATLASSERT(m_hBitmap == NULL);
733 m_hBitmap = ::LoadBitmap(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr);
734 return m_hBitmap;
735 }
736
737 HBITMAP LoadOEMBitmap(UINT nIDBitmap) // for OBM_/OCR_/OIC_
738 {
739 ATLASSERT(m_hBitmap == NULL);
740 m_hBitmap = ::LoadBitmap(NULL, MAKEINTRESOURCE(nIDBitmap));
741 return m_hBitmap;
742 }
743
744 #ifndef _WIN32_WCE
745 HBITMAP LoadMappedBitmap(UINT nIDBitmap, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0)
746 {
747 ATLASSERT(m_hBitmap == NULL);
748 m_hBitmap = ::CreateMappedBitmap(ModuleHelper::GetResourceInstance(), nIDBitmap, (WORD)nFlags, lpColorMap, nMapSize);
749 return m_hBitmap;
750 }
751 #endif // !_WIN32_WCE
752
753 HBITMAP CreateBitmap(int nWidth, int nHeight, UINT nPlanes, UINT nBitsPerPixel, const void* lpBits)
754 {
755 ATLASSERT(m_hBitmap == NULL);
756 m_hBitmap = ::CreateBitmap(nWidth, nHeight, nPlanes, nBitsPerPixel, lpBits);
757 return m_hBitmap;
758 }
759
760 #ifndef _WIN32_WCE
761 HBITMAP CreateBitmapIndirect(LPBITMAP lpBitmap)
762 {
763 ATLASSERT(m_hBitmap == NULL);
764 m_hBitmap = ::CreateBitmapIndirect(lpBitmap);
765 return m_hBitmap;
766 }
767 #endif // !_WIN32_WCE
768
769 HBITMAP CreateCompatibleBitmap(HDC hDC, int nWidth, int nHeight)
770 {
771 ATLASSERT(m_hBitmap == NULL);
772 m_hBitmap = ::CreateCompatibleBitmap(hDC, nWidth, nHeight);
773 return m_hBitmap;
774 }
775
776 #ifndef _WIN32_WCE
777 HBITMAP CreateDiscardableBitmap(HDC hDC, int nWidth, int nHeight)
778 {
779 ATLASSERT(m_hBitmap == NULL);
780 m_hBitmap = ::CreateDiscardableBitmap(hDC, nWidth, nHeight);
781 return m_hBitmap;
782 }
783 #endif // !_WIN32_WCE
784
785 BOOL DeleteObject()
786 {
787 ATLASSERT(m_hBitmap != NULL);
788 BOOL bRet = ::DeleteObject(m_hBitmap);
789 if(bRet)
790 m_hBitmap = NULL;
791 return bRet;
792 }
793
794 // Attributes
795 int GetBitmap(BITMAP* pBitMap) const
796 {
797 ATLASSERT(m_hBitmap != NULL);
798 return ::GetObject(m_hBitmap, sizeof(BITMAP), pBitMap);
799 }
800
801 bool GetBitmap(BITMAP& bm) const
802 {
803 ATLASSERT(m_hBitmap != NULL);
804 return (::GetObject(m_hBitmap, sizeof(BITMAP), &bm) == sizeof(BITMAP));
805 }
806
807 bool GetSize(SIZE& size) const
808 {
809 ATLASSERT(m_hBitmap != NULL);
810 BITMAP bm = { 0 };
811 if(!GetBitmap(&bm))
812 return false;
813 size.cx = bm.bmWidth;
814 size.cy = bm.bmHeight;
815 return true;
816 }
817
818 #ifndef _WIN32_WCE
819 DWORD GetBitmapBits(DWORD dwCount, LPVOID lpBits) const
820 {
821 ATLASSERT(m_hBitmap != NULL);
822 return ::GetBitmapBits(m_hBitmap, dwCount, lpBits);
823 }
824 #endif // !_WIN32_WCE
825
826 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 410)
827 DWORD SetBitmapBits(DWORD dwCount, const void* lpBits)
828 {
829 ATLASSERT(m_hBitmap != NULL);
830 return ::SetBitmapBits(m_hBitmap, dwCount, lpBits);
831 }
832 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 410)
833
834 #ifndef _WIN32_WCE
835 BOOL GetBitmapDimension(LPSIZE lpSize) const
836 {
837 ATLASSERT(m_hBitmap != NULL);
838 return ::GetBitmapDimensionEx(m_hBitmap, lpSize);
839 }
840
841 BOOL SetBitmapDimension(int nWidth, int nHeight, LPSIZE lpSize = NULL)
842 {
843 ATLASSERT(m_hBitmap != NULL);
844 return ::SetBitmapDimensionEx(m_hBitmap, nWidth, nHeight, lpSize);
845 }
846
847 // DIB support
848 HBITMAP CreateDIBitmap(HDC hDC, CONST BITMAPINFOHEADER* lpbmih, DWORD dwInit, CONST VOID* lpbInit, CONST BITMAPINFO* lpbmi, UINT uColorUse)
849 {
850 ATLASSERT(m_hBitmap == NULL);
851 m_hBitmap = ::CreateDIBitmap(hDC, lpbmih, dwInit, lpbInit, lpbmi, uColorUse);
852 return m_hBitmap;
853 }
854 #endif // !_WIN32_WCE
855
856 HBITMAP CreateDIBSection(HDC hDC, CONST BITMAPINFO* lpbmi, UINT uColorUse, VOID** ppvBits, HANDLE hSection, DWORD dwOffset)
857 {
858 ATLASSERT(m_hBitmap == NULL);
859 m_hBitmap = ::CreateDIBSection(hDC, lpbmi, uColorUse, ppvBits, hSection, dwOffset);
860 return m_hBitmap;
861 }
862
863 #ifndef _WIN32_WCE
864 int GetDIBits(HDC hDC, UINT uStartScan, UINT cScanLines, LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT uColorUse) const
865 {
866 ATLASSERT(m_hBitmap != NULL);
867 return ::GetDIBits(hDC, m_hBitmap, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
868 }
869
870 int SetDIBits(HDC hDC, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse)
871 {
872 ATLASSERT(m_hBitmap != NULL);
873 return ::SetDIBits(hDC, m_hBitmap, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
874 }
875 #endif // !_WIN32_WCE
876 };
877
878 typedef CBitmapT<false> CBitmapHandle;
879 typedef CBitmapT<true> CBitmap;
880
881
882 ///////////////////////////////////////////////////////////////////////////////
883 // CPalette
884
885 template <bool t_bManaged>
886 class CPaletteT
887 {
888 public:
889 // Data members
890 HPALETTE m_hPalette;
891
892 // Constructor/destructor/operators
893 CPaletteT(HPALETTE hPalette = NULL) : m_hPalette(hPalette)
894 { }
895
896 ~CPaletteT()
897 {
898 if(t_bManaged && m_hPalette != NULL)
899 DeleteObject();
900 }
901
902 CPaletteT<t_bManaged>& operator =(HPALETTE hPalette)
903 {
904 Attach(hPalette);
905 return *this;
906 }
907
908 void Attach(HPALETTE hPalette)
909 {
910 if(t_bManaged && m_hPalette != NULL && m_hPalette != hPalette)
911 ::DeleteObject(m_hPalette);
912 m_hPalette = hPalette;
913 }
914
915 HPALETTE Detach()
916 {
917 HPALETTE hPalette = m_hPalette;
918 m_hPalette = NULL;
919 return hPalette;
920 }
921
922 operator HPALETTE() const { return m_hPalette; }
923
924 bool IsNull() const { return (m_hPalette == NULL); }
925
926 // Create methods
927 HPALETTE CreatePalette(LPLOGPALETTE lpLogPalette)
928 {
929 ATLASSERT(m_hPalette == NULL);
930 m_hPalette = ::CreatePalette(lpLogPalette);
931 return m_hPalette;
932 }
933
934 #ifndef _WIN32_WCE
935 HPALETTE CreateHalftonePalette(HDC hDC)
936 {
937 ATLASSERT(m_hPalette == NULL);
938 ATLASSERT(hDC != NULL);
939 m_hPalette = ::CreateHalftonePalette(hDC);
940 return m_hPalette;
941 }
942 #endif // !_WIN32_WCE
943
944 BOOL DeleteObject()
945 {
946 ATLASSERT(m_hPalette != NULL);
947 BOOL bRet = ::DeleteObject(m_hPalette);
948 if(bRet)
949 m_hPalette = NULL;
950 return bRet;
951 }
952
953 // Attributes
954 int GetEntryCount() const
955 {
956 ATLASSERT(m_hPalette != NULL);
957 WORD nEntries = 0;
958 ::GetObject(m_hPalette, sizeof(WORD), &nEntries);
959 return (int)nEntries;
960 }
961
962 UINT GetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors) const
963 {
964 ATLASSERT(m_hPalette != NULL);
965 return ::GetPaletteEntries(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors);
966 }
967
968 UINT SetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors)
969 {
970 ATLASSERT(m_hPalette != NULL);
971 return ::SetPaletteEntries(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors);
972 }
973
974 // Operations
975 #ifndef _WIN32_WCE
976 void AnimatePalette(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors)
977 {
978 ATLASSERT(m_hPalette != NULL);
979 ::AnimatePalette(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors);
980 }
981
982 BOOL ResizePalette(UINT nNumEntries)
983 {
984 ATLASSERT(m_hPalette != NULL);
985 return ::ResizePalette(m_hPalette, nNumEntries);
986 }
987 #endif // !_WIN32_WCE
988
989 UINT GetNearestPaletteIndex(COLORREF crColor) const
990 {
991 ATLASSERT(m_hPalette != NULL);
992 return ::GetNearestPaletteIndex(m_hPalette, crColor);
993 }
994 };
995
996 typedef CPaletteT<false> CPaletteHandle;
997 typedef CPaletteT<true> CPalette;
998
999
1000 ///////////////////////////////////////////////////////////////////////////////
1001 // CRgn
1002
1003 template <bool t_bManaged>
1004 class CRgnT
1005 {
1006 public:
1007 // Data members
1008 HRGN m_hRgn;
1009
1010 // Constructor/destructor/operators
1011 CRgnT(HRGN hRgn = NULL) : m_hRgn(hRgn)
1012 { }
1013
1014 ~CRgnT()
1015 {
1016 if(t_bManaged && m_hRgn != NULL)
1017 DeleteObject();
1018 }
1019
1020 CRgnT<t_bManaged>& operator =(HRGN hRgn)
1021 {
1022 Attach(hRgn);
1023 return *this;
1024 }
1025
1026 void Attach(HRGN hRgn)
1027 {
1028 if(t_bManaged && m_hRgn != NULL && m_hRgn != hRgn)
1029 ::DeleteObject(m_hRgn);
1030 m_hRgn = hRgn;
1031 }
1032
1033 HRGN Detach()
1034 {
1035 HRGN hRgn = m_hRgn;
1036 m_hRgn = NULL;
1037 return hRgn;
1038 }
1039
1040 operator HRGN() const { return m_hRgn; }
1041
1042 bool IsNull() const { return (m_hRgn == NULL); }
1043
1044 // Create methods
1045 HRGN CreateRectRgn(int x1, int y1, int x2, int y2)
1046 {
1047 ATLASSERT(m_hRgn == NULL);
1048 m_hRgn = ::CreateRectRgn(x1, y1, x2, y2);
1049 return m_hRgn;
1050 }
1051
1052 HRGN CreateRectRgnIndirect(LPCRECT lpRect)
1053 {
1054 ATLASSERT(m_hRgn == NULL);
1055 m_hRgn = ::CreateRectRgnIndirect(lpRect);
1056 return m_hRgn;
1057 }
1058
1059 #ifndef _WIN32_WCE
1060 HRGN CreateEllipticRgn(int x1, int y1, int x2, int y2)
1061 {
1062 ATLASSERT(m_hRgn == NULL);
1063 m_hRgn = ::CreateEllipticRgn(x1, y1, x2, y2);
1064 return m_hRgn;
1065 }
1066
1067 HRGN CreateEllipticRgnIndirect(LPCRECT lpRect)
1068 {
1069 ATLASSERT(m_hRgn == NULL);
1070 m_hRgn = ::CreateEllipticRgnIndirect(lpRect);
1071 return m_hRgn;
1072 }
1073
1074 HRGN CreatePolygonRgn(LPPOINT lpPoints, int nCount, int nMode)
1075 {
1076 ATLASSERT(m_hRgn == NULL);
1077 m_hRgn = ::CreatePolygonRgn(lpPoints, nCount, nMode);
1078 return m_hRgn;
1079 }
1080
1081 HRGN CreatePolyPolygonRgn(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount, int nPolyFillMode)
1082 {
1083 ATLASSERT(m_hRgn == NULL);
1084 m_hRgn = ::CreatePolyPolygonRgn(lpPoints, lpPolyCounts, nCount, nPolyFillMode);
1085 return m_hRgn;
1086 }
1087
1088 HRGN CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3)
1089 {
1090 ATLASSERT(m_hRgn == NULL);
1091 m_hRgn = ::CreateRoundRectRgn(x1, y1, x2, y2, x3, y3);
1092 return m_hRgn;
1093 }
1094
1095 HRGN CreateFromPath(HDC hDC)
1096 {
1097 ATLASSERT(m_hRgn == NULL);
1098 ATLASSERT(hDC != NULL);
1099 m_hRgn = ::PathToRegion(hDC);
1100 return m_hRgn;
1101 }
1102
1103 HRGN CreateFromData(const XFORM* lpXForm, int nCount, const RGNDATA* pRgnData)
1104 {
1105 ATLASSERT(m_hRgn == NULL);
1106 m_hRgn = ::ExtCreateRegion(lpXForm, nCount, pRgnData);
1107 return m_hRgn;
1108 }
1109 #endif // !_WIN32_WCE
1110
1111 BOOL DeleteObject()
1112 {
1113 ATLASSERT(m_hRgn != NULL);
1114 BOOL bRet = ::DeleteObject(m_hRgn);
1115 if(bRet)
1116 m_hRgn = NULL;
1117 return bRet;
1118 }
1119
1120 // Operations
1121 void SetRectRgn(int x1, int y1, int x2, int y2)
1122 {
1123 ATLASSERT(m_hRgn != NULL);
1124 ::SetRectRgn(m_hRgn, x1, y1, x2, y2);
1125 }
1126
1127 void SetRectRgn(LPCRECT lpRect)
1128 {
1129 ATLASSERT(m_hRgn != NULL);
1130 ::SetRectRgn(m_hRgn, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
1131 }
1132
1133 int CombineRgn(HRGN hRgnSrc1, HRGN hRgnSrc2, int nCombineMode)
1134 {
1135 ATLASSERT(m_hRgn != NULL);
1136 return ::CombineRgn(m_hRgn, hRgnSrc1, hRgnSrc2, nCombineMode);
1137 }
1138
1139 int CombineRgn(HRGN hRgnSrc, int nCombineMode)
1140 {
1141 ATLASSERT(m_hRgn != NULL);
1142 return ::CombineRgn(m_hRgn, m_hRgn, hRgnSrc, nCombineMode);
1143 }
1144
1145 int CopyRgn(HRGN hRgnSrc)
1146 {
1147 ATLASSERT(m_hRgn != NULL);
1148 return ::CombineRgn(m_hRgn, hRgnSrc, NULL, RGN_COPY);
1149 }
1150
1151 BOOL EqualRgn(HRGN hRgn) const
1152 {
1153 ATLASSERT(m_hRgn != NULL);
1154 return ::EqualRgn(m_hRgn, hRgn);
1155 }
1156
1157 int OffsetRgn(int x, int y)
1158 {
1159 ATLASSERT(m_hRgn != NULL);
1160 return ::OffsetRgn(m_hRgn, x, y);
1161 }
1162
1163 int OffsetRgn(POINT point)
1164 {
1165 ATLASSERT(m_hRgn != NULL);
1166 return ::OffsetRgn(m_hRgn, point.x, point.y);
1167 }
1168
1169 int GetRgnBox(LPRECT lpRect) const
1170 {
1171 ATLASSERT(m_hRgn != NULL);
1172 return ::GetRgnBox(m_hRgn, lpRect);
1173 }
1174
1175 BOOL PtInRegion(int x, int y) const
1176 {
1177 ATLASSERT(m_hRgn != NULL);
1178 return ::PtInRegion(m_hRgn, x, y);
1179 }
1180
1181 BOOL PtInRegion(POINT point) const
1182 {
1183 ATLASSERT(m_hRgn != NULL);
1184 return ::PtInRegion(m_hRgn, point.x, point.y);
1185 }
1186
1187 BOOL RectInRegion(LPCRECT lpRect) const
1188 {
1189 ATLASSERT(m_hRgn != NULL);
1190 return ::RectInRegion(m_hRgn, lpRect);
1191 }
1192
1193 int GetRegionData(LPRGNDATA lpRgnData, int nDataSize) const
1194 {
1195 ATLASSERT(m_hRgn != NULL);
1196 return (int)::GetRegionData(m_hRgn, nDataSize, lpRgnData);
1197 }
1198 };
1199
1200 typedef CRgnT<false> CRgnHandle;
1201 typedef CRgnT<true> CRgn;
1202
1203
1204 ///////////////////////////////////////////////////////////////////////////////
1205 // CDC - The device context class
1206
1207 template <bool t_bManaged>
1208 class CDCT
1209 {
1210 public:
1211 // Data members
1212 HDC m_hDC;
1213
1214 // Constructor/destructor/operators
1215 CDCT(HDC hDC = NULL) : m_hDC(hDC)
1216 {
1217 }
1218
1219 ~CDCT()
1220 {
1221 if(t_bManaged && m_hDC != NULL)
1222 ::DeleteDC(Detach());
1223 }
1224
1225 CDCT<t_bManaged>& operator =(HDC hDC)
1226 {
1227 Attach(hDC);
1228 return *this;
1229 }
1230
1231 void Attach(HDC hDC)
1232 {
1233 if(t_bManaged && m_hDC != NULL && m_hDC != hDC)
1234 ::DeleteDC(m_hDC);
1235 m_hDC = hDC;
1236 }
1237
1238 HDC Detach()
1239 {
1240 HDC hDC = m_hDC;
1241 m_hDC = NULL;
1242 return hDC;
1243 }
1244
1245 operator HDC() const { return m_hDC; }
1246
1247 bool IsNull() const { return (m_hDC == NULL); }
1248
1249 // Operations
1250 #ifndef _WIN32_WCE
1251 HWND WindowFromDC() const
1252 {
1253 ATLASSERT(m_hDC != NULL);
1254 return ::WindowFromDC(m_hDC);
1255 }
1256 #endif // !_WIN32_WCE
1257
1258 CPenHandle GetCurrentPen() const
1259 {
1260 ATLASSERT(m_hDC != NULL);
1261 return CPenHandle((HPEN)::GetCurrentObject(m_hDC, OBJ_PEN));
1262 }
1263
1264 CBrushHandle GetCurrentBrush() const
1265 {
1266 ATLASSERT(m_hDC != NULL);
1267 return CBrushHandle((HBRUSH)::GetCurrentObject(m_hDC, OBJ_BRUSH));
1268 }
1269
1270 CPaletteHandle GetCurrentPalette() const
1271 {
1272 ATLASSERT(m_hDC != NULL);
1273 return CPaletteHandle((HPALETTE)::GetCurrentObject(m_hDC, OBJ_PAL));
1274 }
1275
1276 CFontHandle GetCurrentFont() const
1277 {
1278 ATLASSERT(m_hDC != NULL);
1279 return CFontHandle((HFONT)::GetCurrentObject(m_hDC, OBJ_FONT));
1280 }
1281
1282 CBitmapHandle GetCurrentBitmap() const
1283 {
1284 ATLASSERT(m_hDC != NULL);
1285 return CBitmapHandle((HBITMAP)::GetCurrentObject(m_hDC, OBJ_BITMAP));
1286 }
1287
1288 HDC CreateDC(LPCTSTR lpszDriverName, LPCTSTR lpszDeviceName, LPCTSTR lpszOutput, const DEVMODE* lpInitData)
1289 {
1290 ATLASSERT(m_hDC == NULL);
1291 m_hDC = ::CreateDC(lpszDriverName, lpszDeviceName, lpszOutput, lpInitData);
1292 return m_hDC;
1293 }
1294
1295 HDC CreateCompatibleDC(HDC hDC = NULL)
1296 {
1297 ATLASSERT(m_hDC == NULL);
1298 m_hDC = ::CreateCompatibleDC(hDC);
1299 return m_hDC;
1300 }
1301
1302 BOOL DeleteDC()
1303 {
1304 if(m_hDC == NULL)
1305 return FALSE;
1306 BOOL bRet = ::DeleteDC(m_hDC);
1307 if(bRet)
1308 m_hDC = NULL;
1309 return bRet;
1310 }
1311
1312 // Device-Context Functions
1313 int SaveDC()
1314 {
1315 ATLASSERT(m_hDC != NULL);
1316 return ::SaveDC(m_hDC);
1317 }
1318
1319 BOOL RestoreDC(int nSavedDC)
1320 {
1321 ATLASSERT(m_hDC != NULL);
1322 return ::RestoreDC(m_hDC, nSavedDC);
1323 }
1324
1325 int GetDeviceCaps(int nIndex) const
1326 {
1327 ATLASSERT(m_hDC != NULL);
1328 return ::GetDeviceCaps(m_hDC, nIndex);
1329 }
1330
1331 #ifndef _WIN32_WCE
1332 UINT SetBoundsRect(LPCRECT lpRectBounds, UINT flags)
1333 {
1334 ATLASSERT(m_hDC != NULL);
1335 return ::SetBoundsRect(m_hDC, lpRectBounds, flags);
1336 }
1337
1338 UINT GetBoundsRect(LPRECT lpRectBounds, UINT flags) const
1339 {
1340 ATLASSERT(m_hDC != NULL);
1341 return ::GetBoundsRect(m_hDC, lpRectBounds, flags);
1342 }
1343
1344 BOOL ResetDC(const DEVMODE* lpDevMode)
1345 {
1346 ATLASSERT(m_hDC != NULL);
1347 return ::ResetDC(m_hDC, lpDevMode) != NULL;
1348 }
1349
1350 // Drawing-Tool Functions
1351 BOOL GetBrushOrg(LPPOINT lpPoint) const
1352 {
1353 ATLASSERT(m_hDC != NULL);
1354 return ::GetBrushOrgEx(m_hDC, lpPoint);
1355 }
1356 #endif // !_WIN32_WCE
1357
1358 BOOL SetBrushOrg(int x, int y, LPPOINT lpPoint = NULL)
1359 {
1360 ATLASSERT(m_hDC != NULL);
1361 return ::SetBrushOrgEx(m_hDC, x, y, lpPoint);
1362 }
1363
1364 BOOL SetBrushOrg(POINT point, LPPOINT lpPointRet = NULL)
1365 {
1366 ATLASSERT(m_hDC != NULL);
1367 return ::SetBrushOrgEx(m_hDC, point.x, point.y, lpPointRet);
1368 }
1369
1370 #ifndef _WIN32_WCE
1371 int EnumObjects(int nObjectType, int (CALLBACK* lpfn)(LPVOID, LPARAM), LPARAM lpData)
1372 {
1373 ATLASSERT(m_hDC != NULL);
1374 #ifdef STRICT
1375 return ::EnumObjects(m_hDC, nObjectType, (GOBJENUMPROC)lpfn, lpData);
1376 #else
1377 return ::EnumObjects(m_hDC, nObjectType, (GOBJENUMPROC)lpfn, (LPVOID)lpData);
1378 #endif
1379 }
1380 #endif // !_WIN32_WCE
1381
1382 // Type-safe selection helpers
1383 HPEN SelectPen(HPEN hPen)
1384 {
1385 ATLASSERT(m_hDC != NULL);
1386 #ifndef _WIN32_WCE
1387 ATLASSERT(hPen == NULL || ::GetObjectType(hPen) == OBJ_PEN || ::GetObjectType(hPen) == OBJ_EXTPEN);
1388 #else // CE specific
1389 ATLASSERT(hPen == NULL || ::GetObjectType(hPen) == OBJ_PEN);
1390 #endif // _WIN32_WCE
1391 return (HPEN)::SelectObject(m_hDC, hPen);
1392 }
1393
1394 HBRUSH SelectBrush(HBRUSH hBrush)
1395 {
1396 ATLASSERT(m_hDC != NULL);
1397 ATLASSERT(hBrush == NULL || ::GetObjectType(hBrush) == OBJ_BRUSH);
1398 return (HBRUSH)::SelectObject(m_hDC, hBrush);
1399 }
1400
1401 HFONT SelectFont(HFONT hFont)
1402 {
1403 ATLASSERT(m_hDC != NULL);
1404 ATLASSERT(hFont == NULL || ::GetObjectType(hFont) == OBJ_FONT);
1405 return (HFONT)::SelectObject(m_hDC, hFont);
1406 }
1407
1408 HBITMAP SelectBitmap(HBITMAP hBitmap)
1409 {
1410 ATLASSERT(m_hDC != NULL);
1411 ATLASSERT(hBitmap == NULL || ::GetObjectType(hBitmap) == OBJ_BITMAP);
1412 return (HBITMAP)::SelectObject(m_hDC, hBitmap);
1413 }
1414
1415 int SelectRgn(HRGN hRgn) // special return for regions
1416 {
1417 ATLASSERT(m_hDC != NULL);
1418 ATLASSERT(hRgn == NULL || ::GetObjectType(hRgn) == OBJ_REGION);
1419 return PtrToInt(::SelectObject(m_hDC, hRgn));
1420 }
1421
1422 // Type-safe selection helpers for stock objects
1423 HPEN SelectStockPen(int nPen)
1424 {
1425 ATLASSERT(m_hDC != NULL);
1426 #if (_WIN32_WINNT >= 0x0500)
1427 ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN || nPen == DC_PEN);
1428 #else
1429 ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN);
1430 #endif // !(_WIN32_WINNT >= 0x0500)
1431 return SelectPen((HPEN)::GetStockObject(nPen));
1432 }
1433
1434 HBRUSH SelectStockBrush(int nBrush)
1435 {
1436 #if (_WIN32_WINNT >= 0x0500)
1437 ATLASSERT((nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH) || nBrush == DC_BRUSH);
1438 #else
1439 ATLASSERT(nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH);
1440 #endif // !(_WIN32_WINNT >= 0x0500)
1441 return SelectBrush((HBRUSH)::GetStockObject(nBrush));
1442 }
1443
1444 HFONT SelectStockFont(int nFont)
1445 {
1446 #ifndef _WIN32_WCE
1447 ATLASSERT((nFont >= OEM_FIXED_FONT && nFont <= SYSTEM_FIXED_FONT) || nFont == DEFAULT_GUI_FONT);
1448 #else // CE specific
1449 ATLASSERT(nFont == SYSTEM_FONT);
1450 #endif // _WIN32_WCE
1451 return SelectFont((HFONT)::GetStockObject(nFont));
1452 }
1453
1454 HPALETTE SelectStockPalette(int nPalette, BOOL bForceBackground)
1455 {
1456 ATLASSERT(nPalette == DEFAULT_PALETTE); // the only one supported
1457 return SelectPalette((HPALETTE)::GetStockObject(nPalette), bForceBackground);
1458 }
1459
1460 // Color and Color Palette Functions
1461 COLORREF GetNearestColor(COLORREF crColor) const
1462 {
1463 ATLASSERT(m_hDC != NULL);
1464 return ::GetNearestColor(m_hDC, crColor);
1465 }
1466
1467 HPALETTE SelectPalette(HPALETTE hPalette, BOOL bForceBackground)
1468 {
1469 ATLASSERT(m_hDC != NULL);
1470
1471 return ::SelectPalette(m_hDC, hPalette, bForceBackground);
1472 }
1473
1474 UINT RealizePalette()
1475 {
1476 ATLASSERT(m_hDC != NULL);
1477 return ::RealizePalette(m_hDC);
1478 }
1479
1480 #ifndef _WIN32_WCE
1481 void UpdateColors()
1482 {
1483 ATLASSERT(m_hDC != NULL);
1484 ::UpdateColors(m_hDC);
1485 }
1486 #endif // !_WIN32_WCE
1487
1488 // Drawing-Attribute Functions
1489 COLORREF GetBkColor() const
1490 {
1491 ATLASSERT(m_hDC != NULL);
1492 return ::GetBkColor(m_hDC);
1493 }
1494
1495 int GetBkMode() const
1496 {
1497 ATLASSERT(m_hDC != NULL);
1498 return ::GetBkMode(m_hDC);
1499 }
1500
1501 #ifndef _WIN32_WCE
1502 int GetPolyFillMode() const
1503 {
1504 ATLASSERT(m_hDC != NULL);
1505 return ::GetPolyFillMode(m_hDC);
1506 }
1507
1508 int GetROP2() const
1509 {
1510 ATLASSERT(m_hDC != NULL);
1511 return ::GetROP2(m_hDC);
1512 }
1513
1514 int GetStretchBltMode() const
1515 {
1516 ATLASSERT(m_hDC != NULL);
1517 return ::GetStretchBltMode(m_hDC);
1518 }
1519 #endif // !_WIN32_WCE
1520
1521 COLORREF GetTextColor() const
1522 {
1523 ATLASSERT(m_hDC != NULL);
1524 return ::GetTextColor(m_hDC);
1525 }
1526
1527 COLORREF SetBkColor(COLORREF crColor)
1528 {
1529 ATLASSERT(m_hDC != NULL);
1530 return ::SetBkColor(m_hDC, crColor);
1531 }
1532
1533 int SetBkMode(int nBkMode)
1534 {
1535 ATLASSERT(m_hDC != NULL);
1536 return ::SetBkMode(m_hDC, nBkMode);
1537 }
1538
1539 #ifndef _WIN32_WCE
1540 int SetPolyFillMode(int nPolyFillMode)
1541 {
1542 ATLASSERT(m_hDC != NULL);
1543 return ::SetPolyFillMode(m_hDC, nPolyFillMode);
1544 }
1545 #endif // !_WIN32_WCE
1546
1547 int SetROP2(int nDrawMode)
1548 {
1549 ATLASSERT(m_hDC != NULL);
1550 return ::SetROP2(m_hDC, nDrawMode);
1551 }
1552
1553 #ifndef _WIN32_WCE
1554 int SetStretchBltMode(int nStretchMode)
1555 {
1556 ATLASSERT(m_hDC != NULL);
1557 return ::SetStretchBltMode(m_hDC, nStretchMode);
1558 }
1559 #endif // !_WIN32_WCE
1560
1561 COLORREF SetTextColor(COLORREF crColor)
1562 {
1563 ATLASSERT(m_hDC != NULL);
1564 return ::SetTextColor(m_hDC, crColor);
1565 }
1566
1567 #ifndef _WIN32_WCE
1568 BOOL GetColorAdjustment(LPCOLORADJUSTMENT lpColorAdjust) const
1569 {
1570 ATLASSERT(m_hDC != NULL);
1571 return ::GetColorAdjustment(m_hDC, lpColorAdjust);
1572 }
1573
1574 BOOL SetColorAdjustment(const COLORADJUSTMENT* lpColorAdjust)
1575 {
1576 ATLASSERT(m_hDC != NULL);
1577 return ::SetColorAdjustment(m_hDC, lpColorAdjust);
1578 }
1579
1580 // Mapping Functions
1581 int GetMapMode() const
1582 {
1583 ATLASSERT(m_hDC != NULL);
1584 return ::GetMapMode(m_hDC);
1585 }
1586
1587 BOOL GetViewportOrg(LPPOINT lpPoint) const
1588 {
1589 ATLASSERT(m_hDC != NULL);
1590 return ::GetViewportOrgEx(m_hDC, lpPoint);
1591 }
1592
1593 int SetMapMode(int nMapMode)
1594 {
1595 ATLASSERT(m_hDC != NULL);
1596 return ::SetMapMode(m_hDC, nMapMode);
1597 }
1598 #endif // !_WIN32_WCE
1599
1600 // Viewport Origin
1601 BOOL SetViewportOrg(int x, int y, LPPOINT lpPoint = NULL)
1602 {
1603 ATLASSERT(m_hDC != NULL);
1604 return ::SetViewportOrgEx(m_hDC, x, y, lpPoint);
1605 }
1606
1607 BOOL SetViewportOrg(POINT point, LPPOINT lpPointRet = NULL)
1608 {
1609 ATLASSERT(m_hDC != NULL);
1610 return SetViewportOrg(point.x, point.y, lpPointRet);
1611 }
1612
1613 #ifndef _WIN32_WCE
1614 BOOL OffsetViewportOrg(int nWidth, int nHeight, LPPOINT lpPoint = NULL)
1615 {
1616 ATLASSERT(m_hDC != NULL);
1617 return ::OffsetViewportOrgEx(m_hDC, nWidth, nHeight, lpPoint);
1618 }
1619
1620 // Viewport Extent
1621 BOOL GetViewportExt(LPSIZE lpSize) const
1622 {
1623 ATLASSERT(m_hDC != NULL);
1624 return ::GetViewportExtEx(m_hDC, lpSize);
1625 }
1626
1627 BOOL SetViewportExt(int x, int y, LPSIZE lpSize = NULL)
1628 {
1629 ATLASSERT(m_hDC != NULL);
1630 return ::SetViewportExtEx(m_hDC, x, y, lpSize);
1631 }
1632
1633 BOOL SetViewportExt(SIZE size, LPSIZE lpSizeRet = NULL)
1634 {
1635 ATLASSERT(m_hDC != NULL);
1636 return SetViewportExt(size.cx, size.cy, lpSizeRet);
1637 }
1638
1639 BOOL ScaleViewportExt(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize = NULL)
1640 {
1641 ATLASSERT(m_hDC != NULL);
1642 return ::ScaleViewportExtEx(m_hDC, xNum, xDenom, yNum, yDenom, lpSize);
1643 }
1644 #endif // !_WIN32_WCE
1645
1646 // Window Origin
1647 #ifndef _WIN32_WCE
1648 BOOL GetWindowOrg(LPPOINT lpPoint) const
1649 {
1650 ATLASSERT(m_hDC != NULL);
1651 return ::GetWindowOrgEx(m_hDC, lpPoint);
1652 }
1653
1654 BOOL SetWindowOrg(int x, int y, LPPOINT lpPoint = NULL)
1655 {
1656 ATLASSERT(m_hDC != NULL);
1657 return ::SetWindowOrgEx(m_hDC, x, y, lpPoint);
1658 }
1659
1660 BOOL SetWindowOrg(POINT point, LPPOINT lpPointRet = NULL)
1661 {
1662 ATLASSERT(m_hDC != NULL);
1663 return SetWindowOrg(point.x, point.y, lpPointRet);
1664 }
1665
1666 BOOL OffsetWindowOrg(int nWidth, int nHeight, LPPOINT lpPoint = NULL)
1667 {
1668 ATLASSERT(m_hDC != NULL);
1669 return ::OffsetWindowOrgEx(m_hDC, nWidth, nHeight, lpPoint);
1670 }
1671
1672 // Window extent
1673 BOOL GetWindowExt(LPSIZE lpSize) const
1674 {
1675 ATLASSERT(m_hDC != NULL);
1676 return ::GetWindowExtEx(m_hDC, lpSize);
1677 }
1678
1679 BOOL SetWindowExt(int x, int y, LPSIZE lpSize = NULL)
1680 {
1681 ATLASSERT(m_hDC != NULL);
1682 return ::SetWindowExtEx(m_hDC, x, y, lpSize);
1683 }
1684
1685 BOOL SetWindowExt(SIZE size, LPSIZE lpSizeRet = NULL)
1686 {
1687 ATLASSERT(m_hDC != NULL);
1688 return SetWindowExt(size.cx, size.cy, lpSizeRet);
1689 }
1690
1691 BOOL ScaleWindowExt(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize = NULL)
1692 {
1693 ATLASSERT(m_hDC != NULL);
1694 return ::ScaleWindowExtEx(m_hDC, xNum, xDenom, yNum, yDenom, lpSize);
1695 }
1696
1697 // Coordinate Functions
1698 BOOL DPtoLP(LPPOINT lpPoints, int nCount = 1) const
1699 {
1700 ATLASSERT(m_hDC != NULL);
1701 return ::DPtoLP(m_hDC, lpPoints, nCount);
1702 }
1703
1704 BOOL DPtoLP(LPRECT lpRect) const
1705 {
1706 ATLASSERT(m_hDC != NULL);
1707 return ::DPtoLP(m_hDC, (LPPOINT)lpRect, 2);
1708 }
1709
1710 BOOL DPtoLP(LPSIZE lpSize) const
1711 {
1712 SIZE sizeWinExt = { 0, 0 };
1713 if(!GetWindowExt(&sizeWinExt))
1714 return FALSE;
1715 SIZE sizeVpExt = { 0, 0 };
1716 if(!GetViewportExt(&sizeVpExt))
1717 return FALSE;
1718 lpSize->cx = ::MulDiv(lpSize->cx, abs(sizeWinExt.cx), abs(sizeVpExt.cx));
1719 lpSize->cy = ::MulDiv(lpSize->cy, abs(sizeWinExt.cy), abs(sizeVpExt.cy));
1720 return TRUE;
1721 }
1722
1723 BOOL LPtoDP(LPPOINT lpPoints, int nCount = 1) const
1724 {
1725 ATLASSERT(m_hDC != NULL);
1726 return ::LPtoDP(m_hDC, lpPoints, nCount);
1727 }
1728
1729 BOOL LPtoDP(LPRECT lpRect) const
1730 {
1731 ATLASSERT(m_hDC != NULL);
1732 return ::LPtoDP(m_hDC, (LPPOINT)lpRect, 2);
1733 }
1734
1735 BOOL LPtoDP(LPSIZE lpSize) const
1736 {
1737 SIZE sizeWinExt = { 0, 0 };
1738 if(!GetWindowExt(&sizeWinExt))
1739 return FALSE;
1740 SIZE sizeVpExt = { 0, 0 };
1741 if(!GetViewportExt(&sizeVpExt))
1742 return FALSE;
1743 lpSize->cx = ::MulDiv(lpSize->cx, abs(sizeVpExt.cx), abs(sizeWinExt.cx));
1744 lpSize->cy = ::MulDiv(lpSize->cy, abs(sizeVpExt.cy), abs(sizeWinExt.cy));
1745 return TRUE;
1746 }
1747
1748 // Special Coordinate Functions (useful for dealing with metafiles and OLE)
1749 #define HIMETRIC_INCH 2540 // HIMETRIC units per inch
1750
1751 void DPtoHIMETRIC(LPSIZE lpSize) const
1752 {
1753 ATLASSERT(m_hDC != NULL);
1754 int nMapMode;
1755 if((nMapMode = GetMapMode()) < MM_ISOTROPIC && nMapMode != MM_TEXT)
1756 {
1757 // when using a constrained map mode, map against physical inch
1758 ((CDCHandle*)this)->SetMapMode(MM_HIMETRIC);
1759 DPtoLP(lpSize);
1760 ((CDCHandle*)this)->SetMapMode(nMapMode);
1761 }
1762 else
1763 {
1764 // map against logical inch for non-constrained mapping modes
1765 int cxPerInch = GetDeviceCaps(LOGPIXELSX);
1766 int cyPerInch = GetDeviceCaps(LOGPIXELSY);
1767 ATLASSERT(cxPerInch != 0 && cyPerInch != 0);
1768 lpSize->cx = ::MulDiv(lpSize->cx, HIMETRIC_INCH, cxPerInch);
1769 lpSize->cy = ::MulDiv(lpSize->cy, HIMETRIC_INCH, cyPerInch);
1770 }
1771 }
1772
1773 void HIMETRICtoDP(LPSIZE lpSize) const
1774 {
1775 ATLASSERT(m_hDC != NULL);
1776 int nMapMode;
1777 if((nMapMode = GetMapMode()) < MM_ISOTROPIC && nMapMode != MM_TEXT)
1778 {
1779 // when using a constrained map mode, map against physical inch
1780 ((CDCHandle*)this)->SetMapMode(MM_HIMETRIC);
1781 LPtoDP(lpSize);
1782 ((CDCHandle*)this)->SetMapMode(nMapMode);
1783 }
1784 else
1785 {
1786 // map against logical inch for non-constrained mapping modes
1787 int cxPerInch = GetDeviceCaps(LOGPIXELSX);
1788 int cyPerInch = GetDeviceCaps(LOGPIXELSY);
1789 ATLASSERT(cxPerInch != 0 && cyPerInch != 0);
1790 lpSize->cx = ::MulDiv(lpSize->cx, cxPerInch, HIMETRIC_INCH);
1791 lpSize->cy = ::MulDiv(lpSize->cy, cyPerInch, HIMETRIC_INCH);
1792 }
1793 }
1794
1795 void LPtoHIMETRIC(LPSIZE lpSize) const
1796 {
1797 LPtoDP(lpSize);
1798 DPtoHIMETRIC(lpSize);
1799 }
1800
1801 void HIMETRICtoLP(LPSIZE lpSize) const
1802 {
1803 HIMETRICtoDP(lpSize);
1804 DPtoLP(lpSize);
1805 }
1806 #endif // !_WIN32_WCE
1807
1808 // Region Functions
1809 BOOL FillRgn(HRGN hRgn, HBRUSH hBrush)
1810 {
1811 ATLASSERT(m_hDC != NULL);
1812 return ::FillRgn(m_hDC, hRgn, hBrush);
1813 }
1814
1815 #ifndef _WIN32_WCE
1816 BOOL FrameRgn(HRGN hRgn, HBRUSH hBrush, int nWidth, int nHeight)
1817 {
1818 ATLASSERT(m_hDC != NULL);
1819 return ::FrameRgn(m_hDC, hRgn, hBrush, nWidth, nHeight);
1820 }
1821
1822 BOOL InvertRgn(HRGN hRgn)
1823 {
1824 ATLASSERT(m_hDC != NULL);
1825 return ::InvertRgn(m_hDC, hRgn);
1826 }
1827
1828 BOOL PaintRgn(HRGN hRgn)
1829 {
1830 ATLASSERT(m_hDC != NULL);
1831 return ::PaintRgn(m_hDC, hRgn);
1832 }
1833 #endif // !_WIN32_WCE
1834
1835 // Clipping Functions
1836 int GetClipBox(LPRECT lpRect) const
1837 {
1838 ATLASSERT(m_hDC != NULL);
1839 return ::GetClipBox(m_hDC, lpRect);
1840 }
1841
1842 int GetClipRgn(CRgn& region) const
1843 {
1844 ATLASSERT(m_hDC != NULL);
1845 if(region.IsNull())
1846 region.CreateRectRgn(0, 0, 0, 0);
1847
1848 int nRet = ::GetClipRgn(m_hDC, region);
1849 if(nRet != 1)
1850 region.DeleteObject();
1851
1852 return nRet;
1853 }
1854
1855 #ifndef _WIN32_WCE
1856 BOOL PtVisible(int x, int y) const
1857 {
1858 ATLASSERT(m_hDC != NULL);
1859 return ::PtVisible(m_hDC, x, y);
1860 }
1861
1862 BOOL PtVisible(POINT point) const
1863 {
1864 ATLASSERT(m_hDC != NULL);
1865 return ::PtVisible(m_hDC, point.x, point.y);
1866 }
1867 #endif // !_WIN32_WCE
1868
1869 BOOL RectVisible(LPCRECT lpRect) const
1870 {
1871 ATLASSERT(m_hDC != NULL);
1872 return ::RectVisible(m_hDC, lpRect);
1873 }
1874
1875 int SelectClipRgn(HRGN hRgn)
1876 {
1877 ATLASSERT(m_hDC != NULL);
1878 return ::SelectClipRgn(m_hDC, (HRGN)hRgn);
1879 }
1880
1881 int ExcludeClipRect(int x1, int y1, int x2, int y2)
1882 {
1883 ATLASSERT(m_hDC != NULL);
1884 return ::ExcludeClipRect(m_hDC, x1, y1, x2, y2);
1885 }
1886
1887 int ExcludeClipRect(LPCRECT lpRect)
1888 {
1889 ATLASSERT(m_hDC != NULL);
1890 return ::ExcludeClipRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
1891 }
1892
1893 #ifndef _WIN32_WCE
1894 int ExcludeUpdateRgn(HWND hWnd)
1895 {
1896 ATLASSERT(m_hDC != NULL);
1897 return ::ExcludeUpdateRgn(m_hDC, hWnd);
1898 }
1899 #endif // !_WIN32_WCE
1900
1901 int IntersectClipRect(int x1, int y1, int x2, int y2)
1902 {
1903 ATLASSERT(m_hDC != NULL);
1904 return ::IntersectClipRect(m_hDC, x1, y1, x2, y2);
1905 }
1906
1907 int IntersectClipRect(LPCRECT lpRect)
1908 {
1909 ATLASSERT(m_hDC != NULL);
1910 return ::IntersectClipRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
1911 }
1912
1913 #ifndef _WIN32_WCE
1914 int OffsetClipRgn(int x, int y)
1915 {
1916 ATLASSERT(m_hDC != NULL);
1917 return ::OffsetClipRgn(m_hDC, x, y);
1918 }
1919
1920 int OffsetClipRgn(SIZE size)
1921 {
1922 ATLASSERT(m_hDC != NULL);
1923 return ::OffsetClipRgn(m_hDC, size.cx, size.cy);
1924 }
1925
1926 int SelectClipRgn(HRGN hRgn, int nMode)
1927 {
1928 ATLASSERT(m_hDC != NULL);
1929 return ::ExtSelectClipRgn(m_hDC, hRgn, nMode);
1930 }
1931 #endif // !_WIN32_WCE
1932
1933 // Line-Output Functions
1934 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
1935 BOOL GetCurrentPosition(LPPOINT lpPoint) const
1936 {
1937 ATLASSERT(m_hDC != NULL);
1938 return ::GetCurrentPositionEx(m_hDC, lpPoint);
1939 }
1940
1941 BOOL MoveTo(int x, int y, LPPOINT lpPoint = NULL)
1942 {
1943 ATLASSERT(m_hDC != NULL);
1944 return ::MoveToEx(m_hDC, x, y, lpPoint);
1945 }
1946
1947 BOOL MoveTo(POINT point, LPPOINT lpPointRet = NULL)
1948 {
1949 ATLASSERT(m_hDC != NULL);
1950 return MoveTo(point.x, point.y, lpPointRet);
1951 }
1952
1953 BOOL LineTo(int x, int y)
1954 {
1955 ATLASSERT(m_hDC != NULL);
1956 return ::LineTo(m_hDC, x, y);
1957 }
1958
1959 BOOL LineTo(POINT point)
1960 {
1961 ATLASSERT(m_hDC != NULL);
1962 return LineTo(point.x, point.y);
1963 }
1964 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
1965
1966 #ifndef _WIN32_WCE
1967 BOOL Arc(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
1968 {
1969 ATLASSERT(m_hDC != NULL);
1970 return ::Arc(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
1971 }
1972
1973 BOOL Arc(LPCRECT lpRect, POINT ptStart, POINT ptEnd)
1974 {
1975 ATLASSERT(m_hDC != NULL);
1976 return ::Arc(m_hDC, lpRect->left, lpRect->top,
1977 lpRect->right, lpRect->bottom, ptStart.x, ptStart.y,
1978 ptEnd.x, ptEnd.y);
1979 }
1980 #endif // !_WIN32_WCE
1981
1982 BOOL Polyline(const POINT* lpPoints, int nCount)
1983 {
1984 ATLASSERT(m_hDC != NULL);
1985 return ::Polyline(m_hDC, lpPoints, nCount);
1986 }
1987
1988 #ifndef _WIN32_WCE
1989 BOOL AngleArc(int x, int y, int nRadius, float fStartAngle, float fSweepAngle)
1990 {
1991 ATLASSERT(m_hDC != NULL);
1992 return ::AngleArc(m_hDC, x, y, nRadius, fStartAngle, fSweepAngle);
1993 }
1994
1995 BOOL ArcTo(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
1996 {
1997 ATLASSERT(m_hDC != NULL);
1998 return ::ArcTo(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
1999 }
2000
2001 BOOL ArcTo(LPCRECT lpRect, POINT ptStart, POINT ptEnd)
2002 {
2003 ATLASSERT(m_hDC != NULL);
2004 return ArcTo(lpRect->left, lpRect->top, lpRect->right,
2005 lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
2006 }
2007
2008 int GetArcDirection() const
2009 {
2010 ATLASSERT(m_hDC != NULL);
2011 return ::GetArcDirection(m_hDC);
2012 }
2013
2014 int SetArcDirection(int nArcDirection)
2015 {
2016 ATLASSERT(m_hDC != NULL);
2017 return ::SetArcDirection(m_hDC, nArcDirection);
2018 }
2019
2020 BOOL PolyDraw(const POINT* lpPoints, const BYTE* lpTypes, int nCount)
2021 {
2022 ATLASSERT(m_hDC != NULL);
2023 return ::PolyDraw(m_hDC, lpPoints, lpTypes, nCount);
2024 }
2025
2026 BOOL PolylineTo(const POINT* lpPoints, int nCount)
2027 {
2028 ATLASSERT(m_hDC != NULL);
2029 return ::PolylineTo(m_hDC, lpPoints, nCount);
2030 }
2031
2032 BOOL PolyPolyline(const POINT* lpPoints,
2033 const DWORD* lpPolyPoints, int nCount)
2034 {
2035 ATLASSERT(m_hDC != NULL);
2036 return ::PolyPolyline(m_hDC, lpPoints, lpPolyPoints, nCount);
2037 }
2038
2039 BOOL PolyBezier(const POINT* lpPoints, int nCount)
2040 {
2041 ATLASSERT(m_hDC != NULL);
2042 return ::PolyBezier(m_hDC, lpPoints, nCount);
2043 }
2044
2045 BOOL PolyBezierTo(const POINT* lpPoints, int nCount)
2046 {
2047 ATLASSERT(m_hDC != NULL);
2048 return ::PolyBezierTo(m_hDC, lpPoints, nCount);
2049 }
2050 #endif // !_WIN32_WCE
2051
2052 // Simple Drawing Functions
2053 BOOL FillRect(LPCRECT lpRect, HBRUSH hBrush)
2054 {
2055 ATLASSERT(m_hDC != NULL);
2056 return ::FillRect(m_hDC, lpRect, hBrush);
2057 }
2058
2059 BOOL FillRect(LPCRECT lpRect, int nColorIndex)
2060 {
2061 ATLASSERT(m_hDC != NULL);
2062 #ifndef _WIN32_WCE
2063 return ::FillRect(m_hDC, lpRect, (HBRUSH)LongToPtr(nColorIndex + 1));
2064 #else // CE specific
2065 return ::FillRect(m_hDC, lpRect, ::GetSysColorBrush(nColorIndex));
2066 #endif // _WIN32_WCE
2067 }
2068
2069 #ifndef _WIN32_WCE
2070 BOOL FrameRect(LPCRECT lpRect, HBRUSH hBrush)
2071 {
2072 ATLASSERT(m_hDC != NULL);
2073 return ::FrameRect(m_hDC, lpRect, hBrush);
2074 }
2075 #endif // !_WIN32_WCE
2076
2077 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 420)
2078 BOOL InvertRect(LPCRECT lpRect)
2079 {
2080 ATLASSERT(m_hDC != NULL);
2081 return ::InvertRect(m_hDC, lpRect);
2082 }
2083 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 420)
2084
2085 BOOL DrawIcon(int x, int y, HICON hIcon)
2086 {
2087 ATLASSERT(m_hDC != NULL);
2088 #ifndef _WIN32_WCE
2089 return ::DrawIcon(m_hDC, x, y, hIcon);
2090 #else // CE specific
2091 return ::DrawIconEx(m_hDC, x, y, hIcon, 0, 0, 0, NULL, DI_NORMAL);
2092 #endif // _WIN32_WCE
2093 }
2094
2095 BOOL DrawIcon(POINT point, HICON hIcon)
2096 {
2097 ATLASSERT(m_hDC != NULL);
2098 #ifndef _WIN32_WCE
2099 return ::DrawIcon(m_hDC, point.x, point.y, hIcon);
2100 #else // CE specific
2101 return ::DrawIconEx(m_hDC, point.x, point.y, hIcon, 0, 0, 0, NULL, DI_NORMAL);
2102 #endif // _WIN32_WCE
2103 }
2104
2105 BOOL DrawIconEx(int x, int y, HICON hIcon, int cxWidth, int cyWidth, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL)
2106 {
2107 ATLASSERT(m_hDC != NULL);
2108 return ::DrawIconEx(m_hDC, x, y, hIcon, cxWidth, cyWidth, uStepIfAniCur, hbrFlickerFreeDraw, uFlags);
2109 }
2110
2111 BOOL DrawIconEx(POINT point, HICON hIcon, SIZE size, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL)
2112 {
2113 ATLASSERT(m_hDC != NULL);
2114 return ::DrawIconEx(m_hDC, point.x, point.y, hIcon, size.cx, size.cy, uStepIfAniCur, hbrFlickerFreeDraw, uFlags);
2115 }
2116
2117 #ifndef _WIN32_WCE
2118 BOOL DrawState(POINT pt, SIZE size, HBITMAP hBitmap, UINT nFlags, HBRUSH hBrush = NULL)
2119 {
2120 ATLASSERT(m_hDC != NULL);
2121 return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)hBitmap, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_BITMAP);
2122 }
2123
2124 BOOL DrawState(POINT pt, SIZE size, HICON hIcon, UINT nFlags, HBRUSH hBrush = NULL)
2125 {
2126 ATLASSERT(m_hDC != NULL);
2127 return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)hIcon, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_ICON);
2128 }
2129
2130 BOOL DrawState(POINT pt, SIZE size, LPCTSTR lpszText, UINT nFlags, BOOL bPrefixText = TRUE, int nTextLen = 0, HBRUSH hBrush = NULL)
2131 {
2132 ATLASSERT(m_hDC != NULL);
2133 return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)lpszText, (WPARAM)nTextLen, pt.x, pt.y, size.cx, size.cy, nFlags | (bPrefixText ? DST_PREFIXTEXT : DST_TEXT));
2134 }
2135
2136 BOOL DrawState(POINT pt, SIZE size, DRAWSTATEPROC lpDrawProc, LPARAM lData, UINT nFlags, HBRUSH hBrush = NULL)
2137 {
2138 ATLASSERT(m_hDC != NULL);
2139 return ::DrawState(m_hDC, hBrush, lpDrawProc, lData, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_COMPLEX);
2140 }
2141 #endif // !_WIN32_WCE
2142
2143 // Ellipse and Polygon Functions
2144 #ifndef _WIN32_WCE
2145 BOOL Chord(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
2146 {
2147 ATLASSERT(m_hDC != NULL);
2148 return ::Chord(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
2149 }
2150
2151 BOOL Chord(LPCRECT lpRect, POINT ptStart, POINT ptEnd)
2152 {
2153 ATLASSERT(m_hDC != NULL);
2154 return ::Chord(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
2155 }
2156 #endif // !_WIN32_WCE
2157
2158 void DrawFocusRect(LPCRECT lpRect)
2159 {
2160 ATLASSERT(m_hDC != NULL);
2161 ::DrawFocusRect(m_hDC, lpRect);
2162 }
2163
2164 BOOL Ellipse(int x1, int y1, int x2, int y2)
2165 {
2166 ATLASSERT(m_hDC != NULL);
2167 return ::Ellipse(m_hDC, x1, y1, x2, y2);
2168 }
2169
2170 BOOL Ellipse(LPCRECT lpRect)
2171 {
2172 ATLASSERT(m_hDC != NULL);
2173 return ::Ellipse(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
2174 }
2175
2176 #ifndef _WIN32_WCE
2177 BOOL Pie(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
2178 {
2179 ATLASSERT(m_hDC != NULL);
2180 return ::Pie(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
2181 }
2182
2183 BOOL Pie(LPCRECT lpRect, POINT ptStart, POINT ptEnd)
2184 {
2185 ATLASSERT(m_hDC != NULL);
2186 return ::Pie(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
2187 }
2188 #endif // !_WIN32_WCE
2189
2190 BOOL Polygon(const POINT* lpPoints, int nCount)
2191 {
2192 ATLASSERT(m_hDC != NULL);
2193 return ::Polygon(m_hDC, lpPoints, nCount);
2194 }
2195
2196 #ifndef _WIN32_WCE
2197 BOOL PolyPolygon(const POINT* lpPoints, const INT* lpPolyCounts, int nCount)
2198 {
2199 ATLASSERT(m_hDC != NULL);
2200 return ::PolyPolygon(m_hDC, lpPoints, lpPolyCounts, nCount);
2201 }
2202 #endif // !_WIN32_WCE
2203
2204 BOOL Rectangle(int x1, int y1, int x2, int y2)
2205 {
2206 ATLASSERT(m_hDC != NULL);
2207 return ::Rectangle(m_hDC, x1, y1, x2, y2);
2208 }
2209
2210 BOOL Rectangle(LPCRECT lpRect)
2211 {
2212 ATLASSERT(m_hDC != NULL);
2213 return ::Rectangle(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
2214 }
2215
2216 BOOL RoundRect(int x1, int y1, int x2, int y2, int x3, int y3)
2217 {
2218 ATLASSERT(m_hDC != NULL);
2219 return ::RoundRect(m_hDC, x1, y1, x2, y2, x3, y3);
2220 }
2221
2222 BOOL RoundRect(LPCRECT lpRect, POINT point)
2223 {
2224 ATLASSERT(m_hDC != NULL);
2225 return ::RoundRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, point.x, point.y);
2226 }
2227
2228 // Bitmap Functions
2229 BOOL PatBlt(int x, int y, int nWidth, int nHeight, DWORD dwRop)
2230 {
2231 ATLASSERT(m_hDC != NULL);
2232 return ::PatBlt(m_hDC, x, y, nWidth, nHeight, dwRop);
2233 }
2234
2235 BOOL BitBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC,
2236 int xSrc, int ySrc, DWORD dwRop)
2237 {
2238 ATLASSERT(m_hDC != NULL);
2239 return ::BitBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, dwRop);
2240 }
2241
2242 BOOL StretchBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop)
2243 {
2244 ATLASSERT(m_hDC != NULL);
2245 return ::StretchBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, dwRop);
2246 }
2247
2248 COLORREF GetPixel(int x, int y) const
2249 {
2250 ATLASSERT(m_hDC != NULL);
2251 return ::GetPixel(m_hDC, x, y);
2252 }
2253
2254 COLORREF GetPixel(POINT point) const
2255 {
2256 ATLASSERT(m_hDC != NULL);
2257 return ::GetPixel(m_hDC, point.x, point.y);
2258 }
2259
2260 COLORREF SetPixel(int x, int y, COLORREF crColor)
2261 {
2262 ATLASSERT(m_hDC != NULL);
2263 return ::SetPixel(m_hDC, x, y, crColor);
2264 }
2265
2266 COLORREF SetPixel(POINT point, COLORREF crColor)
2267 {
2268 ATLASSERT(m_hDC != NULL);
2269 return ::SetPixel(m_hDC, point.x, point.y, crColor);
2270 }
2271
2272 #ifndef _WIN32_WCE
2273 BOOL FloodFill(int x, int y, COLORREF crColor)
2274 {
2275 ATLASSERT(m_hDC != NULL);
2276 return ::FloodFill(m_hDC, x, y, crColor);
2277 }
2278
2279 BOOL ExtFloodFill(int x, int y, COLORREF crColor, UINT nFillType)
2280 {
2281 ATLASSERT(m_hDC != NULL);
2282 return ::ExtFloodFill(m_hDC, x, y, crColor, nFillType);
2283 }
2284 #endif // !_WIN32_WCE
2285
2286 BOOL MaskBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, HBITMAP hMaskBitmap, int xMask, int yMask, DWORD dwRop)
2287 {
2288 ATLASSERT(m_hDC != NULL);
2289 return ::MaskBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, hMaskBitmap, xMask, yMask, dwRop);
2290 }
2291
2292 #ifndef _WIN32_WCE
2293 BOOL PlgBlt(LPPOINT lpPoint, HDC hSrcDC, int xSrc, int ySrc, int nWidth, int nHeight, HBITMAP hMaskBitmap, int xMask, int yMask)
2294 {
2295 ATLASSERT(m_hDC != NULL);
2296 return ::PlgBlt(m_hDC, lpPoint, hSrcDC, xSrc, ySrc, nWidth, nHeight, hMaskBitmap, xMask, yMask);
2297 }
2298
2299 BOOL SetPixelV(int x, int y, COLORREF crColor)
2300 {
2301 ATLASSERT(m_hDC != NULL);
2302 return ::SetPixelV(m_hDC, x, y, crColor);
2303 }
2304
2305 BOOL SetPixelV(POINT point, COLORREF crColor)
2306 {
2307 ATLASSERT(m_hDC != NULL);
2308 return ::SetPixelV(m_hDC, point.x, point.y, crColor);
2309 }
2310 #endif // !_WIN32_WCE
2311
2312 #if !defined(_ATL_NO_MSIMG) || defined(_WIN32_WCE)
2313 #ifndef _WIN32_WCE
2314 BOOL TransparentBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, UINT crTransparent)
2315 {
2316 ATLASSERT(m_hDC != NULL);
2317 return ::TransparentBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, crTransparent);
2318 }
2319 #else // CE specific
2320 BOOL TransparentImage(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, UINT crTransparent)
2321 {
2322 ATLASSERT(m_hDC != NULL);
2323 return ::TransparentImage(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, crTransparent);
2324 }
2325 #endif // _WIN32_WCE
2326
2327 #if (!defined(_WIN32_WCE) || (_WIN32_WCE >= 420))
2328 BOOL GradientFill(const PTRIVERTEX pVertices, DWORD nVertices, void* pMeshElements, DWORD nMeshElements, DWORD dwMode)
2329 {
2330 ATLASSERT(m_hDC != NULL);
2331 return ::GradientFill(m_hDC, pVertices, nVertices, pMeshElements, nMeshElements, dwMode);
2332 }
2333
2334 BOOL GradientFillRect(RECT& rect, COLORREF clr1, COLORREF clr2, bool bHorizontal)
2335 {
2336 ATLASSERT(m_hDC != NULL);
2337
2338 TRIVERTEX arrTvx[2] = { { 0 }, { 0 } };
2339
2340 arrTvx[0].x = rect.left;
2341 arrTvx[0].y = rect.top;
2342 arrTvx[0].Red = MAKEWORD(0, GetRValue(clr1));
2343 arrTvx[0].Green = MAKEWORD(0, GetGValue(clr1));
2344 arrTvx[0].Blue = MAKEWORD(0, GetBValue(clr1));
2345 arrTvx[0].Alpha = 0;
2346
2347 arrTvx[1].x = rect.right;
2348 arrTvx[1].y = rect.bottom;
2349 arrTvx[1].Red = MAKEWORD(0, GetRValue(clr2));
2350 arrTvx[1].Green = MAKEWORD(0, GetGValue(clr2));
2351 arrTvx[1].Blue = MAKEWORD(0, GetBValue(clr2));
2352 arrTvx[1].Alpha = 0;
2353
2354 GRADIENT_RECT gr = { 0, 1 };
2355
2356 return ::GradientFill(m_hDC, arrTvx, 2, &gr, 1, bHorizontal ? GRADIENT_FILL_RECT_H : GRADIENT_FILL_RECT_V);
2357 }
2358 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 420)
2359
2360 #if !defined(_WIN32_WCE) || (_WIN32_WCE > 0x500)
2361 BOOL AlphaBlend(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, BLENDFUNCTION bf)
2362 {
2363 ATLASSERT(m_hDC != NULL);
2364 return ::AlphaBlend(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, bf);
2365 }
2366 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE > 0x500)
2367 #endif // !defined(_ATL_NO_MSIMG) || defined(_WIN32_WCE)
2368
2369 // Extra bitmap functions
2370 // Helper function for painting a disabled toolbar or menu bitmap
2371 // This function can take either an HBITMAP (for SS) or a DC with
2372 // the bitmap already painted (for cmdbar)
2373 BOOL DitherBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, HBITMAP hBitmap, int xSrc, int ySrc,
2374 HBRUSH hBrushBackground = ::GetSysColorBrush(COLOR_3DFACE),
2375 HBRUSH hBrush3DEffect = ::GetSysColorBrush(COLOR_3DHILIGHT),
2376 HBRUSH hBrushDisabledImage = ::GetSysColorBrush(COLOR_3DSHADOW))
2377 {
2378 ATLASSERT(m_hDC != NULL || hBitmap != NULL);
2379 ATLASSERT(nWidth > 0 && nHeight > 0);
2380
2381 // Create a generic DC for all BitBlts
2382 CDCHandle dc = (hSrcDC != NULL) ? hSrcDC : ::CreateCompatibleDC(m_hDC);
2383 ATLASSERT(dc.m_hDC != NULL);
2384 if(dc.m_hDC == NULL)
2385 return FALSE;
2386
2387 // Create a DC for the monochrome DIB section
2388 CDC dcBW = ::CreateCompatibleDC(m_hDC);
2389 ATLASSERT(dcBW.m_hDC != NULL);
2390 if(dcBW.m_hDC == NULL)
2391 {
2392 if(hSrcDC == NULL)
2393 dc.DeleteDC();
2394 return FALSE;
2395 }
2396
2397 // Create the monochrome DIB section with a black and white palette
2398 struct RGBBWBITMAPINFO
2399 {
2400 BITMAPINFOHEADER bmiHeader;
2401 RGBQUAD bmiColors[2];
2402 };
2403
2404 RGBBWBITMAPINFO rgbBWBitmapInfo =
2405 {
2406 { sizeof(BITMAPINFOHEADER), nWidth, nHeight, 1, 1, BI_RGB, 0, 0, 0, 0, 0 },
2407 { { 0x00, 0x00, 0x00, 0x00 }, { 0xFF, 0xFF, 0xFF, 0x00 } }
2408 };
2409
2410 VOID* pbitsBW;
2411 CBitmap bmpBW = ::CreateDIBSection(dcBW, (LPBITMAPINFO)&rgbBWBitmapInfo, DIB_RGB_COLORS, &pbitsBW, NULL, 0);
2412 ATLASSERT(bmpBW.m_hBitmap != NULL);
2413 if(bmpBW.m_hBitmap == NULL)
2414 {
2415 if(hSrcDC == NULL)
2416 dc.DeleteDC();
2417 return FALSE;
2418 }
2419
2420 // Attach the monochrome DIB section and the bitmap to the DCs
2421 HBITMAP hbmOldBW = dcBW.SelectBitmap(bmpBW);
2422 HBITMAP hbmOldDC = NULL;
2423 if(hBitmap != NULL)
2424 hbmOldDC = dc.SelectBitmap(hBitmap);
2425
2426 // Block: Dark gray removal: we want (128, 128, 128) pixels to become black and not white
2427 {
2428 CDC dcTemp1 = ::CreateCompatibleDC(m_hDC);
2429 CDC dcTemp2 = ::CreateCompatibleDC(m_hDC);
2430 CBitmap bmpTemp1;
2431 bmpTemp1.CreateCompatibleBitmap(dc, nWidth, nHeight);
2432 CBitmap bmpTemp2;
2433 bmpTemp2.CreateBitmap(nWidth, nHeight, 1, 1, NULL);
2434 HBITMAP hOldBmp1 = dcTemp1.SelectBitmap(bmpTemp1);
2435 HBITMAP hOldBmp2 = dcTemp2.SelectBitmap(bmpTemp2);
2436 // Let's copy our image, it will be altered
2437 dcTemp1.BitBlt(0, 0, nWidth, nHeight, dc, xSrc, ySrc, SRCCOPY);
2438
2439 // All dark gray pixels will become white, the others black
2440 dcTemp1.SetBkColor(RGB(128, 128, 128));
2441 dcTemp2.BitBlt(0, 0, nWidth, nHeight, dcTemp1, 0, 0, SRCCOPY);
2442 // Do an XOR to set to black these white pixels
2443 dcTemp1.BitBlt(0, 0, nWidth, nHeight, dcTemp2, 0, 0, SRCINVERT);
2444
2445 // BitBlt the bitmap into the monochrome DIB section
2446 // The DIB section will do a true monochrome conversion
2447 // The magenta background being closer to white will become white
2448 dcBW.BitBlt(0, 0, nWidth, nHeight, dcTemp1, 0, 0, SRCCOPY);
2449
2450 // Cleanup
2451 dcTemp1.SelectBitmap(hOldBmp1);
2452 dcTemp2.SelectBitmap(hOldBmp2);
2453 }
2454
2455 // Paint the destination rectangle using hBrushBackground
2456 if(hBrushBackground != NULL)
2457 {
2458 RECT rc = { x, y, x + nWidth, y + nHeight };
2459 FillRect(&rc, hBrushBackground);
2460 }
2461
2462 // BitBlt the black bits in the monochrome bitmap into hBrush3DEffect color in the destination DC
2463 // The magic ROP comes from the Charles Petzold's book
2464 HBRUSH hOldBrush = SelectBrush(hBrush3DEffect);
2465 BitBlt(x + 1, y + 1, nWidth, nHeight, dcBW, 0, 0, 0xB8074A);
2466
2467 // BitBlt the black bits in the monochrome bitmap into hBrushDisabledImage color in the destination DC
2468 SelectBrush(hBrushDisabledImage);
2469 BitBlt(x, y, nWidth, nHeight, dcBW, 0, 0, 0xB8074A);
2470
2471 SelectBrush(hOldBrush);
2472 dcBW.SelectBitmap(hbmOldBW);
2473 dc.SelectBitmap(hbmOldDC);
2474
2475 if(hSrcDC == NULL)
2476 dc.DeleteDC();
2477
2478 return TRUE;
2479 }
2480
2481 // Text Functions
2482 #ifndef _WIN32_WCE
2483 BOOL TextOut(int x, int y, LPCTSTR lpszString, int nCount = -1)
2484 {
2485 ATLASSERT(m_hDC != NULL);
2486 if(nCount == -1)
2487 nCount = lstrlen(lpszString);
2488 return ::TextOut(m_hDC, x, y, lpszString, nCount);
2489 }
2490 #endif // !_WIN32_WCE
2491
2492 BOOL ExtTextOut(int x, int y, UINT nOptions, LPCRECT lpRect, LPCTSTR lpszString, UINT nCount = -1, LPINT lpDxWidths = NULL)
2493 {
2494 ATLASSERT(m_hDC != NULL);
2495 if(nCount == -1)
2496 nCount = lstrlen(lpszString);
2497 return ::ExtTextOut(m_hDC, x, y, nOptions, lpRect, lpszString, nCount, lpDxWidths);
2498 }
2499
2500 #ifndef _WIN32_WCE
2501 SIZE TabbedTextOut(int x, int y, LPCTSTR lpszString, int nCount = -1, int nTabPositions = 0, LPINT lpnTabStopPositions = NULL, int nTabOrigin = 0)
2502 {
2503 ATLASSERT(m_hDC != NULL);
2504 if(nCount == -1)
2505 nCount = lstrlen(lpszString);
2506 LONG lRes = ::TabbedTextOut(m_hDC, x, y, lpszString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin);
2507 SIZE size = { GET_X_LPARAM(lRes), GET_Y_LPARAM(lRes) };
2508 return size;
2509 }
2510 #endif // !_WIN32_WCE
2511
2512 int DrawText(LPCTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat)
2513 {
2514 ATLASSERT(m_hDC != NULL);
2515 #ifndef _WIN32_WCE
2516 ATLASSERT((uFormat & DT_MODIFYSTRING) == 0);
2517 #endif // !_WIN32_WCE
2518 return ::DrawText(m_hDC, lpstrText, cchText, lpRect, uFormat);
2519 }
2520
2521 int DrawText(LPTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat)
2522 {
2523 ATLASSERT(m_hDC != NULL);
2524 return ::DrawText(m_hDC, lpstrText, cchText, lpRect, uFormat);
2525 }
2526
2527 #ifndef _WIN32_WCE
2528 int DrawTextEx(LPTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat, LPDRAWTEXTPARAMS lpDTParams = NULL)
2529 {
2530 ATLASSERT(m_hDC != NULL);
2531 return ::DrawTextEx(m_hDC, lpstrText, cchText, lpRect, uFormat, lpDTParams);
2532 }
2533 #endif // !_WIN32_WCE
2534
2535 #if (_WIN32_WINNT >= 0x0501)
2536 int DrawShadowText(LPCWSTR lpstrText, int cchText, LPRECT lpRect, DWORD dwFlags, COLORREF clrText, COLORREF clrShadow, int xOffset, int yOffset)
2537 {
2538 ATLASSERT(m_hDC != NULL);
2539 // This function is present only if comctl32.dll version 6 is loaded;
2540 // we use LoadLibrary/GetProcAddress to allow apps compiled with
2541 // _WIN32_WINNT >= 0x0501 to run on older Windows/CommCtrl
2542 int nRet = 0;
2543 HMODULE hCommCtrlDLL = ::LoadLibrary(_T("comctl32.dll"));
2544 ATLASSERT(hCommCtrlDLL != NULL);
2545 if(hCommCtrlDLL != NULL)
2546 {
2547 typedef int (WINAPI *PFN_DrawShadowText)(HDC hDC, LPCWSTR lpstrText, UINT cchText, LPRECT lpRect, DWORD dwFlags, COLORREF clrText, COLORREF clrShadow, int xOffset, int yOffset);
2548 PFN_DrawShadowText pfnDrawShadowText = (PFN_DrawShadowText)::GetProcAddress(hCommCtrlDLL, "DrawShadowText");
2549 ATLASSERT(pfnDrawShadowText != NULL); // this function requires CommCtrl6
2550 if(pfnDrawShadowText != NULL)
2551 nRet = pfnDrawShadowText(m_hDC, lpstrText, cchText, lpRect, dwFlags, clrText, clrShadow, xOffset, yOffset);
2552 ::FreeLibrary(hCommCtrlDLL);
2553 }
2554 return nRet;
2555 }
2556 #endif // (_WIN32_WINNT >= 0x0501)
2557
2558 BOOL GetTextExtent(LPCTSTR lpszString, int nCount, LPSIZE lpSize) const
2559 {
2560 ATLASSERT(m_hDC != NULL);
2561 if(nCount == -1)
2562 nCount = lstrlen(lpszString);
2563 return ::GetTextExtentPoint32(m_hDC, lpszString, nCount, lpSize);
2564 }
2565
2566 BOOL GetTextExtentExPoint(LPCTSTR lpszString, int cchString, LPSIZE lpSize, int nMaxExtent, LPINT lpnFit = NULL, LPINT alpDx = NULL)
2567 {
2568 ATLASSERT(m_hDC != NULL);
2569 return ::GetTextExtentExPoint(m_hDC, lpszString, cchString, nMaxExtent, lpnFit, alpDx, lpSize);
2570 }
2571
2572 #ifndef _WIN32_WCE
2573 DWORD GetTabbedTextExtent(LPCTSTR lpszString, int nCount = -1, int nTabPositions = 0, LPINT lpnTabStopPositions = NULL) const
2574 {
2575 ATLASSERT(m_hDC != NULL);
2576 if(nCount == -1)
2577 nCount = lstrlen(lpszString);
2578 return ::GetTabbedTextExtent(m_hDC, lpszString, nCount, nTabPositions, lpnTabStopPositions);
2579 }
2580
2581 BOOL GrayString(HBRUSH hBrush, BOOL (CALLBACK* lpfnOutput)(HDC, LPARAM, int), LPARAM lpData, int nCount, int x, int y, int nWidth, int nHeight)
2582 {
2583 ATLASSERT(m_hDC != NULL);
2584 return ::GrayString(m_hDC, hBrush, (GRAYSTRINGPROC)lpfnOutput, lpData, nCount, x, y, nWidth, nHeight);
2585 }
2586 #endif // !_WIN32_WCE
2587
2588 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
2589 UINT GetTextAlign() const
2590 {
2591 ATLASSERT(m_hDC != NULL);
2592 return ::GetTextAlign(m_hDC);
2593 }
2594
2595 UINT SetTextAlign(UINT nFlags)
2596 {
2597 ATLASSERT(m_hDC != NULL);
2598 return ::SetTextAlign(m_hDC, nFlags);
2599 }
2600 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
2601
2602 int GetTextFace(LPTSTR lpszFacename, int nCount) const
2603 {
2604 ATLASSERT(m_hDC != NULL);
2605 return ::GetTextFace(m_hDC, nCount, lpszFacename);
2606 }
2607
2608 int GetTextFaceLen() const
2609 {
2610 ATLASSERT(m_hDC != NULL);
2611 return ::GetTextFace(m_hDC, 0, NULL);
2612 }
2613
2614 #ifndef _ATL_NO_COM
2615 #ifdef _OLEAUTO_H_
2616 BOOL GetTextFace(BSTR& bstrFace) const
2617 {
2618 USES_CONVERSION;
2619 ATLASSERT(m_hDC != NULL);
2620 ATLASSERT(bstrFace == NULL);
2621
2622 int nLen = GetTextFaceLen();
2623 if(nLen == 0)
2624 return FALSE;
2625
2626 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
2627 LPTSTR lpszText = buff.Allocate(nLen);
2628 if(lpszText == NULL)
2629 return FALSE;
2630
2631 if(!GetTextFace(lpszText, nLen))
2632 return FALSE;
2633
2634 bstrFace = ::SysAllocString(T2OLE(lpszText));
2635 return (bstrFace != NULL) ? TRUE : FALSE;
2636 }
2637 #endif
2638 #endif // !_ATL_NO_COM
2639
2640 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
2641 int GetTextFace(_CSTRING_NS::CString& strFace) const
2642 {
2643 ATLASSERT(m_hDC != NULL);
2644
2645 int nLen = GetTextFaceLen();
2646 if(nLen == 0)
2647 return 0;
2648
2649 LPTSTR lpstr = strFace.GetBufferSetLength(nLen);
2650 if(lpstr == NULL)
2651 return 0;
2652 int nRet = GetTextFace(lpstr, nLen);
2653 strFace.ReleaseBuffer();
2654 return nRet;
2655 }
2656 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
2657
2658 BOOL GetTextMetrics(LPTEXTMETRIC lpMetrics) const
2659 {
2660 ATLASSERT(m_hDC != NULL);
2661 return ::GetTextMetrics(m_hDC, lpMetrics);
2662 }
2663
2664 #ifndef _WIN32_WCE
2665 int SetTextJustification(int nBreakExtra, int nBreakCount)
2666 {
2667 ATLASSERT(m_hDC != NULL);
2668 return ::SetTextJustification(m_hDC, nBreakExtra, nBreakCount);
2669 }
2670
2671 int GetTextCharacterExtra() const
2672 {
2673 ATLASSERT(m_hDC != NULL);
2674 return ::GetTextCharacterExtra(m_hDC);
2675 }
2676
2677 int SetTextCharacterExtra(int nCharExtra)
2678 {
2679 ATLASSERT(m_hDC != NULL);
2680 return ::SetTextCharacterExtra(m_hDC, nCharExtra);
2681 }
2682 #endif // !_WIN32_WCE
2683
2684 // Advanced Drawing
2685 BOOL DrawEdge(LPRECT lpRect, UINT nEdge, UINT nFlags)
2686 {
2687 ATLASSERT(m_hDC != NULL);
2688 return ::DrawEdge(m_hDC, lpRect, nEdge, nFlags);
2689 }
2690
2691 BOOL DrawFrameControl(LPRECT lpRect, UINT nType, UINT nState)
2692 {
2693 ATLASSERT(m_hDC != NULL);
2694 return ::DrawFrameControl(m_hDC, lpRect, nType, nState);
2695 }
2696
2697 // Scrolling Functions
2698 BOOL ScrollDC(int dx, int dy, LPCRECT lpRectScroll, LPCRECT lpRectClip, HRGN hRgnUpdate, LPRECT lpRectUpdate)
2699 {
2700 ATLASSERT(m_hDC != NULL);
2701 return ::ScrollDC(m_hDC, dx, dy, lpRectScroll, lpRectClip, hRgnUpdate, lpRectUpdate);
2702 }
2703
2704 // Font Functions
2705 #ifndef _WIN32_WCE
2706 BOOL GetCharWidth(UINT nFirstChar, UINT nLastChar, LPINT lpBuffer) const
2707 {
2708 ATLASSERT(m_hDC != NULL);
2709 return ::GetCharWidth(m_hDC, nFirstChar, nLastChar, lpBuffer);
2710 }
2711
2712 // GetCharWidth32 is not supported under Win9x
2713 BOOL GetCharWidth32(UINT nFirstChar, UINT nLastChar, LPINT lpBuffer) const
2714 {
2715 ATLASSERT(m_hDC != NULL);
2716 return ::GetCharWidth32(m_hDC, nFirstChar, nLastChar, lpBuffer);
2717 }
2718
2719 DWORD SetMapperFlags(DWORD dwFlag)
2720 {
2721 ATLASSERT(m_hDC != NULL);
2722 return ::SetMapperFlags(m_hDC, dwFlag);
2723 }
2724
2725 BOOL GetAspectRatioFilter(LPSIZE lpSize) const
2726 {
2727 ATLASSERT(m_hDC != NULL);
2728 return ::GetAspectRatioFilterEx(m_hDC, lpSize);
2729 }
2730
2731 BOOL GetCharABCWidths(UINT nFirstChar, UINT nLastChar, LPABC lpabc) const
2732 {
2733 ATLASSERT(m_hDC != NULL);
2734 return ::GetCharABCWidths(m_hDC, nFirstChar, nLastChar, lpabc);
2735 }
2736
2737 DWORD GetFontData(DWORD dwTable, DWORD dwOffset, LPVOID lpData, DWORD cbData) const
2738 {
2739 ATLASSERT(m_hDC != NULL);
2740 return ::GetFontData(m_hDC, dwTable, dwOffset, lpData, cbData);
2741 }
2742
2743 int GetKerningPairs(int nPairs, LPKERNINGPAIR lpkrnpair) const
2744 {
2745 ATLASSERT(m_hDC != NULL);
2746 return ::GetKerningPairs(m_hDC, nPairs, lpkrnpair);
2747 }
2748
2749 UINT GetOutlineTextMetrics(UINT cbData, LPOUTLINETEXTMETRIC lpotm) const
2750 {
2751 ATLASSERT(m_hDC != NULL);
2752 return ::GetOutlineTextMetrics(m_hDC, cbData, lpotm);
2753 }
2754
2755 DWORD GetGlyphOutline(UINT nChar, UINT nFormat, LPGLYPHMETRICS lpgm, DWORD cbBuffer, LPVOID lpBuffer, const MAT2* lpmat2) const
2756 {
2757 ATLASSERT(m_hDC != NULL);
2758 return ::GetGlyphOutline(m_hDC, nChar, nFormat, lpgm, cbBuffer, lpBuffer, lpmat2);
2759 }
2760
2761 BOOL GetCharABCWidths(UINT nFirstChar, UINT nLastChar, LPABCFLOAT lpABCF) const
2762 {
2763 ATLASSERT(m_hDC != NULL);
2764 return ::GetCharABCWidthsFloat(m_hDC, nFirstChar, nLastChar, lpABCF);
2765 }
2766
2767 BOOL GetCharWidth(UINT nFirstChar, UINT nLastChar, float* lpFloatBuffer) const
2768 {
2769 ATLASSERT(m_hDC != NULL);
2770 return ::GetCharWidthFloat(m_hDC, nFirstChar, nLastChar, lpFloatBuffer);
2771 }
2772 #endif // !_WIN32_WCE
2773
2774 // Printer/Device Escape Functions
2775 #ifndef _WIN32_WCE
2776 int Escape(int nEscape, int nCount, LPCSTR lpszInData, LPVOID lpOutData)
2777 {
2778 ATLASSERT(m_hDC != NULL);
2779 return ::Escape(m_hDC, nEscape, nCount, lpszInData, lpOutData);
2780 }
2781 #endif // !_WIN32_WCE
2782
2783 int Escape(int nEscape, int nInputSize, LPCSTR lpszInputData,
2784 int nOutputSize, LPSTR lpszOutputData)
2785 {
2786 ATLASSERT(m_hDC != NULL);
2787 return ::ExtEscape(m_hDC, nEscape, nInputSize, lpszInputData, nOutputSize, lpszOutputData);
2788 }
2789
2790 #ifndef _WIN32_WCE
2791 int DrawEscape(int nEscape, int nInputSize, LPCSTR lpszInputData)
2792 {
2793 ATLASSERT(m_hDC != NULL);
2794 return ::DrawEscape(m_hDC, nEscape, nInputSize, lpszInputData);
2795 }
2796 #endif // !_WIN32_WCE
2797
2798 // Escape helpers
2799 #if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 200) && defined(StartDoc))
2800 int StartDoc(LPCTSTR lpszDocName) // old Win3.0 version
2801 {
2802 DOCINFO di = { 0 };
2803 di.cbSize = sizeof(DOCINFO);
2804 di.lpszDocName = lpszDocName;
2805 return StartDoc(&di);
2806 }
2807
2808 int StartDoc(LPDOCINFO lpDocInfo)
2809 {
2810 ATLASSERT(m_hDC != NULL);
2811 return ::StartDoc(m_hDC, lpDocInfo);
2812 }
2813
2814 int StartPage()
2815 {
2816 ATLASSERT(m_hDC != NULL);
2817 return ::StartPage(m_hDC);
2818 }
2819
2820 int EndPage()
2821 {
2822 ATLASSERT(m_hDC != NULL);
2823 return ::EndPage(m_hDC);
2824 }
2825
2826 int SetAbortProc(BOOL (CALLBACK* lpfn)(HDC, int))
2827 {
2828 ATLASSERT(m_hDC != NULL);
2829 return ::SetAbortProc(m_hDC, (ABORTPROC)lpfn);
2830 }
2831
2832 int AbortDoc()
2833 {
2834 ATLASSERT(m_hDC != NULL);
2835 return ::AbortDoc(m_hDC);
2836 }
2837
2838 int EndDoc()
2839 {
2840 ATLASSERT(m_hDC != NULL);
2841 return ::EndDoc(m_hDC);
2842 }
2843 #endif // !defined(_WIN32_WCE) || ((_WIN32_WCE >= 200) && defined(StartDoc))
2844
2845 // MetaFile Functions
2846 #ifndef _WIN32_WCE
2847 BOOL PlayMetaFile(HMETAFILE hMF)
2848 {
2849 ATLASSERT(m_hDC != NULL);
2850 if(::GetDeviceCaps(m_hDC, TECHNOLOGY) == DT_METAFILE)
2851 {
2852 // playing metafile in metafile, just use core windows API
2853 return ::PlayMetaFile(m_hDC, hMF);
2854 }
2855
2856 // for special playback, lParam == pDC
2857 return ::EnumMetaFile(m_hDC, hMF, EnumMetaFileProc, (LPARAM)this);
2858 }
2859
2860 BOOL PlayMetaFile(HENHMETAFILE hEnhMetaFile, LPCRECT lpBounds)
2861 {
2862 ATLASSERT(m_hDC != NULL);
2863 return ::PlayEnhMetaFile(m_hDC, hEnhMetaFile, lpBounds);
2864 }
2865
2866 BOOL AddMetaFileComment(UINT nDataSize, const BYTE* pCommentData) // can be used for enhanced metafiles only
2867 {
2868 ATLASSERT(m_hDC != NULL);
2869 return ::GdiComment(m_hDC, nDataSize, pCommentData);
2870 }
2871
2872 // Special handling for metafile playback
2873 static int CALLBACK EnumMetaFileProc(HDC hDC, HANDLETABLE* pHandleTable, METARECORD* pMetaRec, int nHandles, LPARAM lParam)
2874 {
2875 CDCHandle* pDC = (CDCHandle*)lParam;
2876
2877 switch (pMetaRec->rdFunction)
2878 {
2879 case META_SETMAPMODE:
2880 pDC->SetMapMode((int)(short)pMetaRec->rdParm[0]);
2881 break;
2882 case META_SETWINDOWEXT:
2883 pDC->SetWindowExt((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
2884 break;
2885 case META_SETWINDOWORG:
2886 pDC->SetWindowOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
2887 break;
2888 case META_SETVIEWPORTEXT:
2889 pDC->SetViewportExt((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
2890 break;
2891 case META_SETVIEWPORTORG:
2892 pDC->SetViewportOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
2893 break;
2894 case META_SCALEWINDOWEXT:
2895 pDC->ScaleWindowExt((int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2],
2896 (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
2897 break;
2898 case META_SCALEVIEWPORTEXT:
2899 pDC->ScaleViewportExt((int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2],
2900 (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
2901 break;
2902 case META_OFFSETVIEWPORTORG:
2903 pDC->OffsetViewportOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
2904 break;
2905 case META_SAVEDC:
2906 pDC->SaveDC();
2907 break;
2908 case META_RESTOREDC:
2909 pDC->RestoreDC((int)(short)pMetaRec->rdParm[0]);
2910 break;
2911 case META_SETBKCOLOR:
2912 pDC->SetBkColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]);
2913 break;
2914 case META_SETTEXTCOLOR:
2915 pDC->SetTextColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]);
2916 break;
2917
2918 // need to watch out for SelectObject(HFONT), for custom font mapping
2919 case META_SELECTOBJECT:
2920 {
2921 HGDIOBJ hObject = pHandleTable->objectHandle[pMetaRec->rdParm[0]];
2922 UINT nObjType = ::GetObjectType(hObject);
2923 if(nObjType == 0)
2924 {
2925 // object type is unknown, determine if it is a font
2926 HFONT hStockFont = (HFONT)::GetStockObject(SYSTEM_FONT);
2927 HFONT hFontOld = (HFONT)::SelectObject(pDC->m_hDC, hStockFont);
2928 HGDIOBJ hObjOld = ::SelectObject(pDC->m_hDC, hObject);
2929 if(hObjOld == hStockFont)
2930 {
2931 // got the stock object back, so must be selecting a font
2932 pDC->SelectFont((HFONT)hObject);
2933 break; // don't play the default record
2934 }
2935 else
2936 {
2937 // didn't get the stock object back, so restore everything
2938 ::SelectObject(pDC->m_hDC, hFontOld);
2939 ::SelectObject(pDC->m_hDC, hObjOld);
2940 }
2941 // and fall through to PlayMetaFileRecord...
2942 }
2943 else if(nObjType == OBJ_FONT)
2944 {
2945 // play back as CDCHandle::SelectFont(HFONT)
2946 pDC->SelectFont((HFONT)hObject);
2947 break; // don't play the default record
2948 }
2949 }
2950 // fall through...
2951
2952 default:
2953 ::PlayMetaFileRecord(hDC, pHandleTable, pMetaRec, nHandles);
2954 break;
2955 }
2956
2957 return 1;
2958 }
2959 #endif // !_WIN32_WCE
2960
2961 // Path Functions
2962 #ifndef _WIN32_WCE
2963 BOOL AbortPath()
2964 {
2965 ATLASSERT(m_hDC != NULL);
2966 return ::AbortPath(m_hDC);
2967 }
2968
2969 BOOL BeginPath()
2970 {
2971 ATLASSERT(m_hDC != NULL);
2972 return ::BeginPath(m_hDC);
2973 }
2974
2975 BOOL CloseFigure()
2976 {
2977 ATLASSERT(m_hDC != NULL);
2978 return ::CloseFigure(m_hDC);
2979 }
2980
2981 BOOL EndPath()
2982 {
2983 ATLASSERT(m_hDC != NULL);
2984 return ::EndPath(m_hDC);
2985 }
2986
2987 BOOL FillPath()
2988 {
2989 ATLASSERT(m_hDC != NULL);
2990 return ::FillPath(m_hDC);
2991 }
2992
2993 BOOL FlattenPath()
2994 {
2995 ATLASSERT(m_hDC != NULL);
2996 return ::FlattenPath(m_hDC);
2997 }
2998
2999 BOOL StrokeAndFillPath()
3000 {
3001 ATLASSERT(m_hDC != NULL);
3002 return ::StrokeAndFillPath(m_hDC);
3003 }
3004
3005 BOOL StrokePath()
3006 {
3007 ATLASSERT(m_hDC != NULL);
3008 return ::StrokePath(m_hDC);
3009 }
3010
3011 BOOL WidenPath()
3012 {
3013 ATLASSERT(m_hDC != NULL);
3014 return ::WidenPath(m_hDC);
3015 }
3016
3017 BOOL GetMiterLimit(PFLOAT pfMiterLimit) const
3018 {
3019 ATLASSERT(m_hDC != NULL);
3020 return ::GetMiterLimit(m_hDC, pfMiterLimit);
3021 }
3022
3023 BOOL SetMiterLimit(float fMiterLimit)
3024 {
3025 ATLASSERT(m_hDC != NULL);
3026 return ::SetMiterLimit(m_hDC, fMiterLimit, NULL);
3027 }
3028
3029 int GetPath(LPPOINT lpPoints, LPBYTE lpTypes, int nCount) const
3030 {
3031 ATLASSERT(m_hDC != NULL);
3032 return ::GetPath(m_hDC, lpPoints, lpTypes, nCount);
3033 }
3034
3035 BOOL SelectClipPath(int nMode)
3036 {
3037 ATLASSERT(m_hDC != NULL);
3038 return ::SelectClipPath(m_hDC, nMode);
3039 }
3040 #endif // !_WIN32_WCE
3041
3042 // Misc Helper Functions
3043 static CBrushHandle PASCAL GetHalftoneBrush()
3044 {
3045 HBRUSH halftoneBrush = NULL;
3046 WORD grayPattern[8] = { 0 };
3047 for(int i = 0; i < 8; i++)
3048 grayPattern[i] = (WORD)(0x5555 << (i & 1));
3049 HBITMAP grayBitmap = CreateBitmap(8, 8, 1, 1, &grayPattern);
3050 if(grayBitmap != NULL)
3051 {
3052 halftoneBrush = ::CreatePatternBrush(grayBitmap);
3053 DeleteObject(grayBitmap);
3054 }
3055 return CBrushHandle(halftoneBrush);
3056 }
3057
3058 void DrawDragRect(LPCRECT lpRect, SIZE size, LPCRECT lpRectLast, SIZE sizeLast, HBRUSH hBrush = NULL, HBRUSH hBrushLast = NULL)
3059 {
3060 // first, determine the update region and select it
3061 CRgn rgnOutside;
3062 rgnOutside.CreateRectRgnIndirect(lpRect);
3063 RECT rect = *lpRect;
3064 ::InflateRect(&rect, -size.cx, -size.cy);
3065 ::IntersectRect(&rect, &rect, lpRect);
3066 CRgn rgnInside;
3067 rgnInside.CreateRectRgnIndirect(&rect);
3068 CRgn rgnNew;
3069 rgnNew.CreateRectRgn(0, 0, 0, 0);
3070 rgnNew.CombineRgn(rgnOutside, rgnInside, RGN_XOR);
3071
3072 HBRUSH hBrushOld = NULL;
3073 CBrush brushHalftone;
3074 if(hBrush == NULL)
3075 brushHalftone = hBrush = CDCHandle::GetHalftoneBrush();
3076 if(hBrushLast == NULL)
3077 hBrushLast = hBrush;
3078
3079 CRgn rgnLast;
3080 CRgn rgnUpdate;
3081 if(lpRectLast != NULL)
3082 {
3083 // find difference between new region and old region
3084 rgnLast.CreateRectRgn(0, 0, 0, 0);
3085 rgnOutside.SetRectRgn(lpRectLast->left, lpRectLast->top, lpRectLast->right, lpRectLast->bottom);
3086 rect = *lpRectLast;
3087 ::InflateRect(&rect, -sizeLast.cx, -sizeLast.cy);
3088 ::IntersectRect(&rect, &rect, lpRectLast);
3089 rgnInside.SetRectRgn(rect.left, rect.top, rect.right, rect.bottom);
3090 rgnLast.CombineRgn(rgnOutside, rgnInside, RGN_XOR);
3091
3092 // only diff them if brushes are the same
3093 if(hBrush == hBrushLast)
3094 {
3095 rgnUpdate.CreateRectRgn(0, 0, 0, 0);
3096 rgnUpdate.CombineRgn(rgnLast, rgnNew, RGN_XOR);
3097 }
3098 }
3099 if(hBrush != hBrushLast && lpRectLast != NULL)
3100 {
3101 // brushes are different -- erase old region first
3102 SelectClipRgn(rgnLast);
3103 GetClipBox(&rect);
3104 hBrushOld = SelectBrush(hBrushLast);
3105 PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT);
3106 SelectBrush(hBrushOld);
3107 hBrushOld = NULL;
3108 }
3109
3110 // draw into the update/new region
3111 SelectClipRgn(rgnUpdate.IsNull() ? rgnNew : rgnUpdate);
3112 GetClipBox(&rect);
3113 hBrushOld = SelectBrush(hBrush);
3114 PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT);
3115
3116 // cleanup DC
3117 if(hBrushOld != NULL)
3118 SelectBrush(hBrushOld);
3119 SelectClipRgn(NULL);
3120 }
3121
3122 void FillSolidRect(LPCRECT lpRect, COLORREF clr)
3123 {
3124 ATLASSERT(m_hDC != NULL);
3125
3126 COLORREF clrOld = ::SetBkColor(m_hDC, clr);
3127 ATLASSERT(clrOld != CLR_INVALID);
3128 if(clrOld != CLR_INVALID)
3129 {
3130 ::ExtTextOut(m_hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL);
3131 ::SetBkColor(m_hDC, clrOld);
3132 }
3133 }
3134
3135 void FillSolidRect(int x, int y, int cx, int cy, COLORREF clr)
3136 {
3137 ATLASSERT(m_hDC != NULL);
3138
3139 RECT rect = { x, y, x + cx, y + cy };
3140 FillSolidRect(&rect, clr);
3141 }
3142
3143 void Draw3dRect(LPCRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight)
3144 {
3145 Draw3dRect(lpRect->left, lpRect->top, lpRect->right - lpRect->left,
3146 lpRect->bottom - lpRect->top, clrTopLeft, clrBottomRight);
3147 }
3148
3149 void Draw3dRect(int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight)
3150 {
3151 FillSolidRect(x, y, cx - 1, 1, clrTopLeft);
3152 FillSolidRect(x, y, 1, cy - 1, clrTopLeft);
3153 FillSolidRect(x + cx, y, -1, cy, clrBottomRight);
3154 FillSolidRect(x, y + cy, cx, -1, clrBottomRight);
3155 }
3156
3157 // DIB support
3158 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 410)
3159 int SetDIBitsToDevice(int x, int y, DWORD dwWidth, DWORD dwHeight, int xSrc, int ySrc, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse)
3160 {
3161 ATLASSERT(m_hDC != NULL);
3162 return ::SetDIBitsToDevice(m_hDC, x, y, dwWidth, dwHeight, xSrc, ySrc, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
3163 }
3164 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 410)
3165
3166 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
3167 int StretchDIBits(int x, int y, int nWidth, int nHeight, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse, DWORD dwRop)
3168 {
3169 ATLASSERT(m_hDC != NULL);
3170 return ::StretchDIBits(m_hDC, x, y, nWidth, nHeight, xSrc, ySrc, nSrcWidth, nSrcHeight, lpvBits, lpbmi, uColorUse, dwRop);
3171 }
3172
3173 UINT GetDIBColorTable(UINT uStartIndex, UINT cEntries, RGBQUAD* pColors) const
3174 {
3175 ATLASSERT(m_hDC != NULL);
3176 return ::GetDIBColorTable(m_hDC, uStartIndex, cEntries, pColors);
3177 }
3178
3179 UINT SetDIBColorTable(UINT uStartIndex, UINT cEntries, CONST RGBQUAD* pColors)
3180 {
3181 ATLASSERT(m_hDC != NULL);
3182 return ::SetDIBColorTable(m_hDC, uStartIndex, cEntries, pColors);
3183 }
3184 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
3185
3186 // OpenGL support
3187 #if !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE)
3188 int ChoosePixelFormat(CONST PIXELFORMATDESCRIPTOR* ppfd)
3189 {
3190 ATLASSERT(m_hDC != NULL);
3191 return ::ChoosePixelFormat(m_hDC, ppfd);
3192 }
3193
3194 int DescribePixelFormat(int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd)
3195 {
3196 ATLASSERT(m_hDC != NULL);
3197 return ::DescribePixelFormat(m_hDC, iPixelFormat, nBytes, ppfd);
3198 }
3199
3200 int GetPixelFormat() const
3201 {
3202 ATLASSERT(m_hDC != NULL);
3203 return ::GetPixelFormat(m_hDC);
3204 }
3205
3206 BOOL SetPixelFormat(int iPixelFormat, CONST PIXELFORMATDESCRIPTOR* ppfd)
3207 {
3208 ATLASSERT(m_hDC != NULL);
3209 return ::SetPixelFormat(m_hDC, iPixelFormat, ppfd);
3210 }
3211
3212 BOOL SwapBuffers()
3213 {
3214 ATLASSERT(m_hDC != NULL);
3215 return ::SwapBuffers(m_hDC);
3216 }
3217
3218 HGLRC wglCreateContext()
3219 {
3220 ATLASSERT(m_hDC != NULL);
3221 return ::wglCreateContext(m_hDC);
3222 }
3223
3224 HGLRC wglCreateLayerContext(int iLayerPlane)
3225 {
3226 ATLASSERT(m_hDC != NULL);
3227 return ::wglCreateLayerContext(m_hDC, iLayerPlane);
3228 }
3229
3230 BOOL wglMakeCurrent(HGLRC hglrc)
3231 {
3232 ATLASSERT(m_hDC != NULL);
3233 return ::wglMakeCurrent(m_hDC, hglrc);
3234 }
3235
3236 BOOL wglUseFontBitmaps(DWORD dwFirst, DWORD dwCount, DWORD listBase)
3237 {
3238 ATLASSERT(m_hDC != NULL);
3239 return ::wglUseFontBitmaps(m_hDC, dwFirst, dwCount, listBase);
3240 }
3241
3242 BOOL wglUseFontOutlines(DWORD dwFirst, DWORD dwCount, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf)
3243 {
3244 ATLASSERT(m_hDC != NULL);
3245 return ::wglUseFontOutlines(m_hDC, dwFirst, dwCount, listBase, deviation, extrusion, format, lpgmf);
3246 }
3247
3248 BOOL wglDescribeLayerPlane(int iPixelFormat, int iLayerPlane, UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd)
3249 {
3250 ATLASSERT(m_hDC != NULL);
3251 return ::wglDescribeLayerPlane(m_hDC, iPixelFormat, iLayerPlane, nBytes, plpd);
3252 }
3253
3254 int wglSetLayerPaletteEntries(int iLayerPlane, int iStart, int cEntries, CONST COLORREF* pclr)
3255 {
3256 ATLASSERT(m_hDC != NULL);
3257 return ::wglSetLayerPaletteEntries(m_hDC, iLayerPlane, iStart, cEntries, pclr);
3258 }
3259
3260 int wglGetLayerPaletteEntries(int iLayerPlane, int iStart, int cEntries, COLORREF* pclr)
3261 {
3262 ATLASSERT(m_hDC != NULL);
3263 return ::wglGetLayerPaletteEntries(m_hDC, iLayerPlane, iStart, cEntries, pclr);
3264 }
3265
3266 BOOL wglRealizeLayerPalette(int iLayerPlane, BOOL bRealize)
3267 {
3268 ATLASSERT(m_hDC != NULL);
3269 return ::wglRealizeLayerPalette(m_hDC, iLayerPlane, bRealize);
3270 }
3271
3272 BOOL wglSwapLayerBuffers(UINT uPlanes)
3273 {
3274 ATLASSERT(m_hDC != NULL);
3275 return ::wglSwapLayerBuffers(m_hDC, uPlanes);
3276 }
3277 #endif // !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE)
3278
3279 // New for Windows 2000 only
3280 #if (_WIN32_WINNT >= 0x0500)
3281 COLORREF GetDCPenColor() const
3282 {
3283 ATLASSERT(m_hDC != NULL);
3284 return ::GetDCPenColor(m_hDC);
3285 }
3286
3287 COLORREF SetDCPenColor(COLORREF clr)
3288 {
3289 ATLASSERT(m_hDC != NULL);
3290 return ::SetDCPenColor(m_hDC, clr);
3291 }
3292
3293 COLORREF GetDCBrushColor() const
3294 {
3295 ATLASSERT(m_hDC != NULL);
3296 return ::GetDCBrushColor(m_hDC);
3297 }
3298
3299 COLORREF SetDCBrushColor(COLORREF clr)
3300 {
3301 ATLASSERT(m_hDC != NULL);
3302 return ::SetDCBrushColor(m_hDC, clr);
3303 }
3304
3305 #ifndef _WIN32_WCE
3306 DWORD GetFontUnicodeRanges(LPGLYPHSET lpgs) const
3307 {
3308 ATLASSERT(m_hDC != NULL);
3309 return ::GetFontUnicodeRanges(m_hDC, lpgs);
3310 }
3311 #endif // !_WIN32_WCE
3312
3313 DWORD GetGlyphIndices(LPCTSTR lpstr, int cch, LPWORD pgi, DWORD dwFlags) const
3314 {
3315 ATLASSERT(m_hDC != NULL);
3316 return ::GetGlyphIndices(m_hDC, lpstr, cch, pgi, dwFlags);
3317 }
3318
3319 BOOL GetTextExtentPointI(LPWORD pgiIn, int cgi, LPSIZE lpSize) const
3320 {
3321 ATLASSERT(m_hDC != NULL);
3322 return ::GetTextExtentPointI(m_hDC, pgiIn, cgi, lpSize);
3323 }
3324
3325 BOOL GetTextExtentExPointI(LPWORD pgiIn, int cgi, int nMaxExtent, LPINT lpnFit, LPINT alpDx, LPSIZE lpSize) const
3326 {
3327 ATLASSERT(m_hDC != NULL);
3328 return ::GetTextExtentExPointI(m_hDC, pgiIn, cgi, nMaxExtent, lpnFit, alpDx, lpSize);
3329 }
3330
3331 BOOL GetCharWidthI(UINT giFirst, UINT cgi, LPWORD pgi, LPINT lpBuffer) const
3332 {
3333 ATLASSERT(m_hDC != NULL);
3334 return ::GetCharWidthI(m_hDC, giFirst, cgi, pgi, lpBuffer);
3335 }
3336
3337 BOOL GetCharABCWidthsI(UINT giFirst, UINT cgi, LPWORD pgi, LPABC lpabc) const
3338 {
3339 ATLASSERT(m_hDC != NULL);
3340 return ::GetCharABCWidthsI(m_hDC, giFirst, cgi, pgi, lpabc);
3341 }
3342 #endif // (_WIN32_WINNT >= 0x0500)
3343
3344 // New for Windows 2000 and Windows 98
3345 #if (WINVER >= 0x0500) && !defined(_WIN32_WCE)
3346 BOOL ColorCorrectPalette(HPALETTE hPalette, DWORD dwFirstEntry, DWORD dwNumOfEntries)
3347 {
3348 ATLASSERT(m_hDC != NULL);
3349 return ::ColorCorrectPalette(m_hDC, hPalette, dwFirstEntry, dwNumOfEntries);
3350 }
3351 #endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE)
3352 };
3353
3354 typedef CDCT<false> CDCHandle;
3355 typedef CDCT<true> CDC;
3356
3357
3358 ///////////////////////////////////////////////////////////////////////////////
3359 // CDC Helpers
3360
3361 class CPaintDC : public CDC
3362 {
3363 public:
3364 // Data members
3365 HWND m_hWnd;
3366 PAINTSTRUCT m_ps;
3367
3368 // Constructor/destructor
3369 CPaintDC(HWND hWnd)
3370 {
3371 ATLASSERT(::IsWindow(hWnd));
3372 m_hWnd = hWnd;
3373 m_hDC = ::BeginPaint(hWnd, &m_ps);
3374 }
3375
3376 ~CPaintDC()
3377 {
3378 ATLASSERT(m_hDC != NULL);
3379 ATLASSERT(::IsWindow(m_hWnd));
3380 ::EndPaint(m_hWnd, &m_ps);
3381 Detach();
3382 }
3383 };
3384
3385 class CClientDC : public CDC
3386 {
3387 public:
3388 // Data members
3389 HWND m_hWnd;
3390
3391 // Constructor/destructor
3392 CClientDC(HWND hWnd)
3393 {
3394 ATLASSERT(hWnd == NULL || ::IsWindow(hWnd));
3395 m_hWnd = hWnd;
3396 m_hDC = ::GetDC(hWnd);
3397 }
3398
3399 ~CClientDC()
3400 {
3401 ATLASSERT(m_hDC != NULL);
3402 ::ReleaseDC(m_hWnd, Detach());
3403 }
3404 };
3405
3406 class CWindowDC : public CDC
3407 {
3408 public:
3409 // Data members
3410 HWND m_hWnd;
3411
3412 // Constructor/destructor
3413 CWindowDC(HWND hWnd)
3414 {
3415 ATLASSERT(hWnd == NULL || ::IsWindow(hWnd));
3416 m_hWnd = hWnd;
3417 m_hDC = ::GetWindowDC(hWnd);
3418 }
3419
3420 ~CWindowDC()
3421 {
3422 ATLASSERT(m_hDC != NULL);
3423 ::ReleaseDC(m_hWnd, Detach());
3424 }
3425 };
3426
3427 class CMemoryDC : public CDC
3428 {
3429 public:
3430 // Data members
3431 HDC m_hDCOriginal;
3432 RECT m_rcPaint;
3433 CBitmap m_bmp;
3434 HBITMAP m_hBmpOld;
3435
3436 // Constructor/destructor
3437 CMemoryDC(HDC hDC, const RECT& rcPaint) : m_hDCOriginal(hDC), m_hBmpOld(NULL)
3438 {
3439 m_rcPaint = rcPaint;
3440 CreateCompatibleDC(m_hDCOriginal);
3441 ATLASSERT(m_hDC != NULL);
3442 m_bmp.CreateCompatibleBitmap(m_hDCOriginal, m_rcPaint.right - m_rcPaint.left, m_rcPaint.bottom - m_rcPaint.top);
3443 ATLASSERT(m_bmp.m_hBitmap != NULL);
3444 m_hBmpOld = SelectBitmap(m_bmp);
3445 SetViewportOrg(-m_rcPaint.left, -m_rcPaint.top);
3446 }
3447
3448 ~CMemoryDC()
3449 {
3450 ::BitBlt(m_hDCOriginal, m_rcPaint.left, m_rcPaint.top, m_rcPaint.right - m_rcPaint.left, m_rcPaint.bottom - m_rcPaint.top, m_hDC, m_rcPaint.left, m_rcPaint.top, SRCCOPY);
3451 SelectBitmap(m_hBmpOld);
3452 }
3453 };
3454
3455
3456 ///////////////////////////////////////////////////////////////////////////////
3457 // Enhanced metafile support
3458
3459 #ifndef _WIN32_WCE
3460
3461 class CEnhMetaFileInfo
3462 {
3463 public:
3464 // Data members
3465 HENHMETAFILE m_hEMF;
3466 BYTE* m_pBits;
3467 TCHAR* m_pDesc;
3468 ENHMETAHEADER m_header;
3469 PIXELFORMATDESCRIPTOR m_pfd;
3470
3471 // Constructor/destructor
3472 CEnhMetaFileInfo(HENHMETAFILE hEMF) : m_pBits(NULL), m_pDesc(NULL), m_hEMF(hEMF)
3473 { }
3474
3475 ~CEnhMetaFileInfo()
3476 {
3477 delete [] m_pBits;
3478 delete [] m_pDesc;
3479 }
3480
3481 // Operations
3482 BYTE* GetEnhMetaFileBits()
3483 {
3484 ATLASSERT(m_hEMF != NULL);
3485 UINT nBytes = ::GetEnhMetaFileBits(m_hEMF, 0, NULL);
3486 delete [] m_pBits;
3487 m_pBits = NULL;
3488 ATLTRY(m_pBits = new BYTE[nBytes]);
3489 if (m_pBits != NULL)
3490 ::GetEnhMetaFileBits(m_hEMF, nBytes, m_pBits);
3491 return m_pBits;
3492 }
3493
3494 LPTSTR GetEnhMetaFileDescription()
3495 {
3496 ATLASSERT(m_hEMF != NULL);
3497 UINT nLen = ::GetEnhMetaFileDescription(m_hEMF, 0, NULL);
3498 delete [] m_pDesc;
3499 m_pDesc = NULL;
3500 ATLTRY(m_pDesc = new TCHAR[nLen]);
3501 if (m_pDesc != NULL)
3502 nLen = ::GetEnhMetaFileDescription(m_hEMF, nLen, m_pDesc);
3503 return m_pDesc;
3504 }
3505
3506 ENHMETAHEADER* GetEnhMetaFileHeader()
3507 {
3508 ATLASSERT(m_hEMF != NULL);
3509 memset(&m_header, 0, sizeof(m_header));
3510 m_header.iType = EMR_HEADER;
3511 m_header.nSize = sizeof(ENHMETAHEADER);
3512 UINT n = ::GetEnhMetaFileHeader(m_hEMF, sizeof(ENHMETAHEADER), &m_header);
3513 return (n != 0) ? &m_header : NULL;
3514 }
3515
3516 PIXELFORMATDESCRIPTOR* GetEnhMetaFilePixelFormat()
3517 {
3518 ATLASSERT(m_hEMF != NULL);
3519 memset(&m_pfd, 0, sizeof(m_pfd));
3520 UINT n = ::GetEnhMetaFilePixelFormat(m_hEMF, sizeof(m_pfd), &m_pfd);
3521 return (n != 0) ? &m_pfd : NULL;
3522 }
3523 };
3524
3525
3526 template <bool t_bManaged>
3527 class CEnhMetaFileT
3528 {
3529 public:
3530 // Data members
3531 HENHMETAFILE m_hEMF;
3532
3533 // Constructor/destructor
3534 CEnhMetaFileT(HENHMETAFILE hEMF = NULL) : m_hEMF(hEMF)
3535 {
3536 }
3537
3538 ~CEnhMetaFileT()
3539 {
3540 if(t_bManaged && m_hEMF != NULL)
3541 DeleteObject();
3542 }
3543
3544 // Operations
3545 CEnhMetaFileT<t_bManaged>& operator =(HENHMETAFILE hEMF)
3546 {
3547 Attach(hEMF);
3548 return *this;
3549 }
3550
3551 void Attach(HENHMETAFILE hEMF)
3552 {
3553 if(t_bManaged && m_hEMF != NULL && m_hEMF != hEMF)
3554 DeleteObject();
3555 m_hEMF = hEMF;
3556 }
3557
3558 HENHMETAFILE Detach()
3559 {
3560 HENHMETAFILE hEMF = m_hEMF;
3561 m_hEMF = NULL;
3562 return hEMF;
3563 }
3564
3565 operator HENHMETAFILE() const { return m_hEMF; }
3566
3567 bool IsNull() const { return (m_hEMF == NULL); }
3568
3569 BOOL DeleteObject()
3570 {
3571 ATLASSERT(m_hEMF != NULL);
3572 BOOL bRet = ::DeleteEnhMetaFile(m_hEMF);
3573 m_hEMF = NULL;
3574 return bRet;
3575 }
3576
3577 UINT GetEnhMetaFileBits(UINT cbBuffer, LPBYTE lpbBuffer) const
3578 {
3579 ATLASSERT(m_hEMF != NULL);
3580 return ::GetEnhMetaFileBits(m_hEMF, cbBuffer, lpbBuffer);
3581 }
3582
3583 UINT GetEnhMetaFileDescription(UINT cchBuffer, LPTSTR lpszDescription) const
3584 {
3585 ATLASSERT(m_hEMF != NULL);
3586 return ::GetEnhMetaFileDescription(m_hEMF, cchBuffer, lpszDescription);
3587 }
3588
3589 UINT GetEnhMetaFileHeader(LPENHMETAHEADER lpemh) const
3590 {
3591 ATLASSERT(m_hEMF != NULL);
3592 lpemh->iType = EMR_HEADER;
3593 lpemh->nSize = sizeof(ENHMETAHEADER);
3594 return ::GetEnhMetaFileHeader(m_hEMF, sizeof(ENHMETAHEADER), lpemh);
3595 }
3596
3597 UINT GetEnhMetaFilePaletteEntries(UINT cEntries, LPPALETTEENTRY lppe) const
3598 {
3599 ATLASSERT(m_hEMF != NULL);
3600 return ::GetEnhMetaFilePaletteEntries(m_hEMF, cEntries, lppe);
3601 }
3602
3603 UINT GetEnhMetaFilePixelFormat(DWORD cbBuffer, PIXELFORMATDESCRIPTOR* ppfd) const
3604 {
3605 ATLASSERT(m_hEMF != NULL);
3606 return ::GetEnhMetaFilePixelFormat(m_hEMF, cbBuffer, ppfd);
3607 }
3608 };
3609
3610 typedef CEnhMetaFileT<false> CEnhMetaFileHandle;
3611 typedef CEnhMetaFileT<true> CEnhMetaFile;
3612
3613
3614 class CEnhMetaFileDC : public CDC
3615 {
3616 public:
3617 // Constructor/destructor
3618 CEnhMetaFileDC()
3619 {
3620 }
3621
3622 CEnhMetaFileDC(HDC hdc, LPCRECT lpRect)
3623 {
3624 Create(hdc, NULL, lpRect, NULL);
3625 ATLASSERT(m_hDC != NULL);
3626 }
3627
3628 CEnhMetaFileDC(HDC hdcRef, LPCTSTR lpFilename, LPCRECT lpRect, LPCTSTR lpDescription)
3629 {
3630 Create(hdcRef, lpFilename, lpRect, lpDescription);
3631 ATLASSERT(m_hDC != NULL);
3632 }
3633
3634 ~CEnhMetaFileDC()
3635 {
3636 HENHMETAFILE hEMF = Close();
3637 if (hEMF != NULL)
3638 ::DeleteEnhMetaFile(hEMF);
3639 }
3640
3641 // Operations
3642 void Create(HDC hdcRef, LPCTSTR lpFilename, LPCRECT lpRect, LPCTSTR lpDescription)
3643 {
3644 ATLASSERT(m_hDC == NULL);
3645 m_hDC = ::CreateEnhMetaFile(hdcRef, lpFilename, lpRect, lpDescription);
3646 }
3647
3648 HENHMETAFILE Close()
3649 {
3650 HENHMETAFILE hEMF = NULL;
3651 if (m_hDC != NULL)
3652 {
3653 hEMF = ::CloseEnhMetaFile(m_hDC);
3654 m_hDC = NULL;
3655 }
3656 return hEMF;
3657 }
3658 };
3659
3660 #endif // !_WIN32_WCE
3661
3662
3663 ///////////////////////////////////////////////////////////////////////////////
3664 // WinCE compatible clipboard CF_DIB format support functions
3665
3666 #ifndef _WTL_NO_DIB16
3667
3668 #define DIBINFO16_BITFIELDS { 31744, 992, 31 }
3669
3670 // DIBINFO16 - To avoid color table problems in WinCE we only create this type of Dib
3671 struct DIBINFO16 // a BITMAPINFO with 2 additional color bitfields
3672 {
3673 BITMAPINFOHEADER bmiHeader;
3674 RGBQUAD bmiColors[3];
3675
3676 DIBINFO16(SIZE size)
3677 {
3678 BITMAPINFOHEADER bmih = { sizeof(BITMAPINFOHEADER), size.cx, size.cy,
3679 1, 16, BI_BITFIELDS, (DWORD)(2 * size.cx * size.cy), 0, 0, 3 };
3680 DWORD dw[3] = DIBINFO16_BITFIELDS ;
3681
3682 bmiHeader = bmih;
3683 SecureHelper::memcpy_x(bmiColors, sizeof(bmiColors), dw, 3 * sizeof(DWORD));
3684 }
3685 };
3686
3687
3688 // AtlxxxDibxxx minimal packed DIB implementation and helpers to copy and paste CF_DIB
3689
3690 inline bool AtlIsDib16(LPBITMAPINFOHEADER pbmih)
3691 {
3692 return (pbmih->biBitCount == 16) && (pbmih->biCompression == BI_BITFIELDS);
3693 }
3694
3695 inline int AtlGetDibColorTableSize(LPBITMAPINFOHEADER pbmih)
3696 {
3697 switch (pbmih->biBitCount)
3698 {
3699 case 2:
3700 case 4:
3701 case 8:
3702 return pbmih->biClrUsed ? pbmih->biClrUsed : 1 << pbmih->biBitCount;
3703 case 24:
3704 break;
3705 case 16:
3706 case 32:
3707 return pbmih->biCompression == BI_BITFIELDS ? 3 : 0;
3708 default:
3709 ATLASSERT(FALSE); // should never come here
3710 }
3711
3712 return 0;
3713 }
3714
3715 inline int AtlGetDibNumColors(LPBITMAPINFOHEADER pbmih)
3716 {
3717 switch (pbmih->biBitCount)
3718 {
3719 case 2:
3720 case 4:
3721 case 8:
3722 if (pbmih->biClrUsed)
3723 return pbmih->biClrUsed;
3724 else
3725 break;
3726 case 16:
3727 if (pbmih->biCompression == BI_BITFIELDS )
3728 return 1 << 15;
3729 else
3730 break;
3731 case 24:
3732 break;
3733 case 32:
3734 if (pbmih->biCompression == BI_BITFIELDS )
3735 return 1 << 24;
3736 else
3737 break;
3738 default:
3739 ATLASSERT(FALSE);
3740 }
3741
3742 return 1 << pbmih->biBitCount;
3743 }
3744
3745 inline HBITMAP AtlGetDibBitmap(LPBITMAPINFO pbmi)
3746 {
3747 CDC dc(NULL);
3748 void* pBits = NULL;
3749
3750 LPBYTE pDibBits = (LPBYTE)pbmi + sizeof(BITMAPINFOHEADER) + AtlGetDibColorTableSize(&pbmi->bmiHeader) * sizeof(RGBQUAD);
3751 HBITMAP hbm = CreateDIBSection(dc, pbmi, DIB_RGB_COLORS, &pBits, NULL, NULL);
3752 if (hbm != NULL)
3753 {
3754 int cbBits = pbmi->bmiHeader.biWidth * pbmi->bmiHeader.biHeight * pbmi->bmiHeader.biBitCount / 8;
3755 SecureHelper::memcpy_x(pBits, cbBits, pDibBits, pbmi->bmiHeader.biSizeImage);
3756 }
3757
3758 return hbm;
3759 }
3760
3761 inline HBITMAP AtlCopyBitmap(HBITMAP hbm, SIZE sizeDst, bool bAsBitmap = false)
3762 {
3763 CDC hdcSrc = CreateCompatibleDC(NULL);
3764 CDC hdcDst = CreateCompatibleDC(NULL);
3765
3766 CBitmapHandle hbmOld = NULL, hbmOld2 = NULL, bmSrc = hbm;
3767
3768 CBitmap bmNew = NULL;
3769
3770 SIZE sizeSrc = { 0 };
3771 bmSrc.GetSize(sizeSrc);
3772
3773 hbmOld = hdcSrc.SelectBitmap(bmSrc);
3774
3775 if (bAsBitmap)
3776 {
3777 bmNew.CreateCompatibleBitmap(hdcSrc, sizeDst.cx, sizeDst.cy);
3778 }
3779 else
3780 {
3781 DIBINFO16 dib16(sizeDst);
3782 LPVOID pBits = NULL;
3783 bmNew = CreateDIBSection(hdcDst, (const BITMAPINFO*)&dib16, DIB_RGB_COLORS, &pBits, NULL, NULL);
3784 }
3785
3786 ATLASSERT(!bmNew.IsNull());
3787
3788 hbmOld2 = hdcDst.SelectBitmap(bmNew);
3789 BOOL bOK = FALSE;
3790
3791 if ((sizeDst.cx == sizeSrc.cx) && (sizeDst.cy == sizeSrc.cy))
3792 bOK = hdcDst.BitBlt(0, 0, sizeDst.cx, sizeDst.cy, hdcSrc, 0, 0, SRCCOPY);
3793 else
3794 bOK = hdcDst.StretchBlt(0, 0, sizeDst.cx, sizeDst.cy, hdcSrc, 0, 0, sizeSrc.cx, sizeSrc.cy, SRCCOPY);
3795
3796 hdcSrc.SelectBitmap(hbmOld);
3797 hdcDst.SelectBitmap(hbmOld2);
3798
3799 if (bOK == FALSE)
3800 bmNew.DeleteObject();
3801
3802 return bmNew.Detach();
3803 }
3804
3805 inline HLOCAL AtlCreatePackedDib16(HBITMAP hbm, SIZE size)
3806 {
3807 DIBSECTION ds = { 0 };
3808 LPBYTE pDib = NULL;
3809 bool bCopied = false;
3810
3811 bool bOK = GetObject(hbm, sizeof(ds), &ds) == sizeof(ds);
3812 if ((bOK == FALSE) || (ds.dsBm.bmBits == NULL) || (AtlIsDib16(&ds.dsBmih) == FALSE) ||
3813 (ds.dsBmih.biWidth != size.cx ) || (ds.dsBmih.biHeight != size.cy ))
3814 {
3815 if ((hbm = AtlCopyBitmap(hbm, size)) != NULL)
3816 {
3817 bCopied = true;
3818 bOK = GetObject(hbm, sizeof(ds), &ds) == sizeof(ds);
3819 }
3820 else
3821 {
3822 bOK = FALSE;
3823 }
3824 }
3825
3826 if((bOK != FALSE) && (AtlIsDib16(&ds.dsBmih) != FALSE) && (ds.dsBm.bmBits != NULL))
3827 {
3828 pDib = (LPBYTE)LocalAlloc(LMEM_ZEROINIT, sizeof(DIBINFO16) + ds.dsBmih.biSizeImage);
3829 if (pDib != NULL)
3830 {
3831 SecureHelper::memcpy_x(pDib, sizeof(DIBINFO16) + ds.dsBmih.biSizeImage, &ds.dsBmih, sizeof(DIBINFO16));
3832 SecureHelper::memcpy_x(pDib + sizeof(DIBINFO16), ds.dsBmih.biSizeImage, ds.dsBm.bmBits, ds.dsBmih.biSizeImage);
3833 }
3834 }
3835
3836 if (bCopied == true)
3837 DeleteObject(hbm);
3838
3839 return (HLOCAL)pDib;
3840 }
3841
3842 inline bool AtlSetClipboardDib16(HBITMAP hbm, SIZE size, HWND hWnd)
3843 {
3844 ATLASSERT(::IsWindow(hWnd));
3845 BOOL bOK = OpenClipboard(hWnd);
3846 if (bOK != FALSE)
3847 {
3848 bOK = EmptyClipboard();
3849 if (bOK != FALSE)
3850 {
3851 HLOCAL hDib = AtlCreatePackedDib16(hbm, size);
3852 if (hDib != NULL)
3853 {
3854 bOK = SetClipboardData(CF_DIB, hDib) != NULL;
3855 if (bOK == FALSE)
3856 LocalFree(hDib);
3857 }
3858 else
3859 {
3860 bOK = FALSE;
3861 }
3862 }
3863 CloseClipboard();
3864 }
3865
3866 return (bOK != FALSE);
3867 }
3868
3869 inline HBITMAP AtlGetClipboardDib(HWND hWnd)
3870 {
3871 ATLASSERT(::IsWindow(hWnd) != FALSE);
3872 HBITMAP hbm = NULL;
3873 if (OpenClipboard(hWnd) != FALSE)
3874 {
3875 LPBITMAPINFO pbmi = (LPBITMAPINFO)GetClipboardData(CF_DIB);
3876 if (pbmi != NULL)
3877 hbm = AtlGetDibBitmap(pbmi);
3878 CloseClipboard();
3879 }
3880
3881 return hbm;
3882 }
3883
3884 #endif // _WTL_NO_DIB16
3885
3886 }; // namespace WTL
3887
3888 #endif // __ATLGDI_H__
+0
-3756
src/third_party/wtl/Include/atlmisc.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLMISC_H__
9 #define __ATLMISC_H__
10
11 #pragma once
12
13 #ifndef __ATLAPP_H__
14 #error atlmisc.h requires atlapp.h to be included first
15 #endif
16
17
18 #ifdef _ATL_TMP_NO_CSTRING
19 #define _WTL_NO_CSTRING
20 #endif
21
22 #if defined(_WTL_USE_CSTRING) && defined(_WTL_NO_CSTRING)
23 #error Conflicting options - both _WTL_USE_CSTRING and _WTL_NO_CSTRING are defined
24 #endif // defined(_WTL_USE_CSTRING) && defined(_WTL_NO_CSTRING)
25
26 #if !defined(_WTL_USE_CSTRING) && !defined(_WTL_NO_CSTRING)
27 #define _WTL_USE_CSTRING
28 #endif // !defined(_WTL_USE_CSTRING) && !defined(_WTL_NO_CSTRING)
29
30 #ifndef _WTL_NO_CSTRING
31 #if defined(_ATL_USE_CSTRING_FLOAT) && defined(_ATL_MIN_CRT)
32 #error Cannot use CString floating point formatting with _ATL_MIN_CRT defined
33 #endif // defined(_ATL_USE_CSTRING_FLOAT) && defined(_ATL_MIN_CRT)
34 #endif // !_WTL_NO_CSTRING
35
36
37 ///////////////////////////////////////////////////////////////////////////////
38 // Classes in this file:
39 //
40 // CSize
41 // CPoint
42 // CRect
43 // CString
44 //
45 // CRecentDocumentListBase<T, t_cchItemLen, t_nFirstID, t_nLastID>
46 // CRecentDocumentList
47 // CFindFile
48 //
49 // Global functions:
50 // AtlGetStockPen()
51 // AtlGetStockBrush()
52 // AtlGetStockFont()
53 // AtlGetStockPalette()
54 //
55 // AtlCompactPath()
56
57
58 namespace WTL
59 {
60
61 #ifndef _WTL_NO_WTYPES
62
63 // forward declarations
64 class CSize;
65 class CPoint;
66 class CRect;
67
68 ///////////////////////////////////////////////////////////////////////////////
69 // CSize - Wrapper for Windows SIZE structure.
70
71 class CSize : public SIZE
72 {
73 public:
74 // Constructors
75 CSize()
76 {
77 cx = 0;
78 cy = 0;
79 }
80
81 CSize(int initCX, int initCY)
82 {
83 cx = initCX;
84 cy = initCY;
85 }
86
87 CSize(SIZE initSize)
88 {
89 *(SIZE*)this = initSize;
90 }
91
92 CSize(POINT initPt)
93 {
94 *(POINT*)this = initPt;
95 }
96
97 CSize(DWORD dwSize)
98 {
99 cx = (short)LOWORD(dwSize);
100 cy = (short)HIWORD(dwSize);
101 }
102
103 // Operations
104 BOOL operator ==(SIZE size) const
105 {
106 return (cx == size.cx && cy == size.cy);
107 }
108
109 BOOL operator !=(SIZE size) const
110 {
111 return (cx != size.cx || cy != size.cy);
112 }
113
114 void operator +=(SIZE size)
115 {
116 cx += size.cx;
117 cy += size.cy;
118 }
119
120 void operator -=(SIZE size)
121 {
122 cx -= size.cx;
123 cy -= size.cy;
124 }
125
126 void SetSize(int CX, int CY)
127 {
128 cx = CX;
129 cy = CY;
130 }
131
132 // Operators returning CSize values
133 CSize operator +(SIZE size) const
134 {
135 return CSize(cx + size.cx, cy + size.cy);
136 }
137
138 CSize operator -(SIZE size) const
139 {
140 return CSize(cx - size.cx, cy - size.cy);
141 }
142
143 CSize operator -() const
144 {
145 return CSize(-cx, -cy);
146 }
147
148 // Operators returning CPoint values
149 CPoint operator +(POINT point) const;
150 CPoint operator -(POINT point) const;
151
152 // Operators returning CRect values
153 CRect operator +(const RECT* lpRect) const;
154 CRect operator -(const RECT* lpRect) const;
155 };
156
157
158 ///////////////////////////////////////////////////////////////////////////////
159 // CPoint - Wrapper for Windows POINT structure.
160
161 class CPoint : public POINT
162 {
163 public:
164 // Constructors
165 CPoint()
166 {
167 x = 0;
168 y = 0;
169 }
170
171 CPoint(int initX, int initY)
172 {
173 x = initX;
174 y = initY;
175 }
176
177 CPoint(POINT initPt)
178 {
179 *(POINT*)this = initPt;
180 }
181
182 CPoint(SIZE initSize)
183 {
184 *(SIZE*)this = initSize;
185 }
186
187 CPoint(DWORD dwPoint)
188 {
189 x = (short)LOWORD(dwPoint);
190 y = (short)HIWORD(dwPoint);
191 }
192
193 // Operations
194 void Offset(int xOffset, int yOffset)
195 {
196 x += xOffset;
197 y += yOffset;
198 }
199
200 void Offset(POINT point)
201 {
202 x += point.x;
203 y += point.y;
204 }
205
206 void Offset(SIZE size)
207 {
208 x += size.cx;
209 y += size.cy;
210 }
211
212 BOOL operator ==(POINT point) const
213 {
214 return (x == point.x && y == point.y);
215 }
216
217 BOOL operator !=(POINT point) const
218 {
219 return (x != point.x || y != point.y);
220 }
221
222 void operator +=(SIZE size)
223 {
224 x += size.cx;
225 y += size.cy;
226 }
227
228 void operator -=(SIZE size)
229 {
230 x -= size.cx;
231 y -= size.cy;
232 }
233
234 void operator +=(POINT point)
235 {
236 x += point.x;
237 y += point.y;
238 }
239
240 void operator -=(POINT point)
241 {
242 x -= point.x;
243 y -= point.y;
244 }
245
246 void SetPoint(int X, int Y)
247 {
248 x = X;
249 y = Y;
250 }
251
252 // Operators returning CPoint values
253 CPoint operator +(SIZE size) const
254 {
255 return CPoint(x + size.cx, y + size.cy);
256 }
257
258 CPoint operator -(SIZE size) const
259 {
260 return CPoint(x - size.cx, y - size.cy);
261 }
262
263 CPoint operator -() const
264 {
265 return CPoint(-x, -y);
266 }
267
268 CPoint operator +(POINT point) const
269 {
270 return CPoint(x + point.x, y + point.y);
271 }
272
273 // Operators returning CSize values
274 CSize operator -(POINT point) const
275 {
276 return CSize(x - point.x, y - point.y);
277 }
278
279 // Operators returning CRect values
280 CRect operator +(const RECT* lpRect) const;
281 CRect operator -(const RECT* lpRect) const;
282 };
283
284
285 ///////////////////////////////////////////////////////////////////////////////
286 // CRect - Wrapper for Windows RECT structure.
287
288 class CRect : public RECT
289 {
290 public:
291 // Constructors
292 CRect()
293 {
294 left = 0;
295 top = 0;
296 right = 0;
297 bottom = 0;
298 }
299
300 CRect(int l, int t, int r, int b)
301 {
302 left = l;
303 top = t;
304 right = r;
305 bottom = b;
306 }
307
308 CRect(const RECT& srcRect)
309 {
310 ::CopyRect(this, &srcRect);
311 }
312
313 CRect(LPCRECT lpSrcRect)
314 {
315 ::CopyRect(this, lpSrcRect);
316 }
317
318 CRect(POINT point, SIZE size)
319 {
320 right = (left = point.x) + size.cx;
321 bottom = (top = point.y) + size.cy;
322 }
323
324 CRect(POINT topLeft, POINT bottomRight)
325 {
326 left = topLeft.x;
327 top = topLeft.y;
328 right = bottomRight.x;
329 bottom = bottomRight.y;
330 }
331
332 // Attributes (in addition to RECT members)
333 int Width() const
334 {
335 return right - left;
336 }
337
338 int Height() const
339 {
340 return bottom - top;
341 }
342
343 CSize Size() const
344 {
345 return CSize(right - left, bottom - top);
346 }
347
348 CPoint& TopLeft()
349 {
350 return *((CPoint*)this);
351 }
352
353 CPoint& BottomRight()
354 {
355 return *((CPoint*)this + 1);
356 }
357
358 const CPoint& TopLeft() const
359 {
360 return *((CPoint*)this);
361 }
362
363 const CPoint& BottomRight() const
364 {
365 return *((CPoint*)this + 1);
366 }
367
368 CPoint CenterPoint() const
369 {
370 return CPoint((left + right) / 2, (top + bottom) / 2);
371 }
372
373 // convert between CRect and LPRECT/LPCRECT (no need for &)
374 operator LPRECT()
375 {
376 return this;
377 }
378
379 operator LPCRECT() const
380 {
381 return this;
382 }
383
384 BOOL IsRectEmpty() const
385 {
386 return ::IsRectEmpty(this);
387 }
388
389 BOOL IsRectNull() const
390 {
391 return (left == 0 && right == 0 && top == 0 && bottom == 0);
392 }
393
394 BOOL PtInRect(POINT point) const
395 {
396 return ::PtInRect(this, point);
397 }
398
399 // Operations
400 void SetRect(int x1, int y1, int x2, int y2)
401 {
402 ::SetRect(this, x1, y1, x2, y2);
403 }
404
405 void SetRect(POINT topLeft, POINT bottomRight)
406 {
407 ::SetRect(this, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
408 }
409
410 void SetRectEmpty()
411 {
412 ::SetRectEmpty(this);
413 }
414
415 void CopyRect(LPCRECT lpSrcRect)
416 {
417 ::CopyRect(this, lpSrcRect);
418 }
419
420 BOOL EqualRect(LPCRECT lpRect) const
421 {
422 return ::EqualRect(this, lpRect);
423 }
424
425 void InflateRect(int x, int y)
426 {
427 ::InflateRect(this, x, y);
428 }
429
430 void InflateRect(SIZE size)
431 {
432 ::InflateRect(this, size.cx, size.cy);
433 }
434
435 void InflateRect(LPCRECT lpRect)
436 {
437 left -= lpRect->left;
438 top -= lpRect->top;
439 right += lpRect->right;
440 bottom += lpRect->bottom;
441 }
442
443 void InflateRect(int l, int t, int r, int b)
444 {
445 left -= l;
446 top -= t;
447 right += r;
448 bottom += b;
449 }
450
451 void DeflateRect(int x, int y)
452 {
453 ::InflateRect(this, -x, -y);
454 }
455
456 void DeflateRect(SIZE size)
457 {
458 ::InflateRect(this, -size.cx, -size.cy);
459 }
460
461 void DeflateRect(LPCRECT lpRect)
462 {
463 left += lpRect->left;
464 top += lpRect->top;
465 right -= lpRect->right;
466 bottom -= lpRect->bottom;
467 }
468
469 void DeflateRect(int l, int t, int r, int b)
470 {
471 left += l;
472 top += t;
473 right -= r;
474 bottom -= b;
475 }
476
477 void OffsetRect(int x, int y)
478 {
479 ::OffsetRect(this, x, y);
480 }
481 void OffsetRect(SIZE size)
482 {
483 ::OffsetRect(this, size.cx, size.cy);
484 }
485
486 void OffsetRect(POINT point)
487 {
488 ::OffsetRect(this, point.x, point.y);
489 }
490
491 void NormalizeRect()
492 {
493 int nTemp;
494 if (left > right)
495 {
496 nTemp = left;
497 left = right;
498 right = nTemp;
499 }
500 if (top > bottom)
501 {
502 nTemp = top;
503 top = bottom;
504 bottom = nTemp;
505 }
506 }
507
508 // absolute position of rectangle
509 void MoveToY(int y)
510 {
511 bottom = Height() + y;
512 top = y;
513 }
514
515 void MoveToX(int x)
516 {
517 right = Width() + x;
518 left = x;
519 }
520
521 void MoveToXY(int x, int y)
522 {
523 MoveToX(x);
524 MoveToY(y);
525 }
526
527 void MoveToXY(POINT pt)
528 {
529 MoveToX(pt.x);
530 MoveToY(pt.y);
531 }
532
533 // operations that fill '*this' with result
534 BOOL IntersectRect(LPCRECT lpRect1, LPCRECT lpRect2)
535 {
536 return ::IntersectRect(this, lpRect1, lpRect2);
537 }
538
539 BOOL UnionRect(LPCRECT lpRect1, LPCRECT lpRect2)
540 {
541 return ::UnionRect(this, lpRect1, lpRect2);
542 }
543
544 BOOL SubtractRect(LPCRECT lpRectSrc1, LPCRECT lpRectSrc2)
545 {
546 return ::SubtractRect(this, lpRectSrc1, lpRectSrc2);
547 }
548
549 // Additional Operations
550 void operator =(const RECT& srcRect)
551 {
552 ::CopyRect(this, &srcRect);
553 }
554
555 BOOL operator ==(const RECT& rect) const
556 {
557 return ::EqualRect(this, &rect);
558 }
559
560 BOOL operator !=(const RECT& rect) const
561 {
562 return !::EqualRect(this, &rect);
563 }
564
565 void operator +=(POINT point)
566 {
567 ::OffsetRect(this, point.x, point.y);
568 }
569
570 void operator +=(SIZE size)
571 {
572 ::OffsetRect(this, size.cx, size.cy);
573 }
574
575 void operator +=(LPCRECT lpRect)
576 {
577 InflateRect(lpRect);
578 }
579
580 void operator -=(POINT point)
581 {
582 ::OffsetRect(this, -point.x, -point.y);
583 }
584
585 void operator -=(SIZE size)
586 {
587 ::OffsetRect(this, -size.cx, -size.cy);
588 }
589
590 void operator -=(LPCRECT lpRect)
591 {
592 DeflateRect(lpRect);
593 }
594
595 void operator &=(const RECT& rect)
596 {
597 ::IntersectRect(this, this, &rect);
598 }
599
600 void operator |=(const RECT& rect)
601 {
602 ::UnionRect(this, this, &rect);
603 }
604
605 // Operators returning CRect values
606 CRect operator +(POINT pt) const
607 {
608 CRect rect(*this);
609 ::OffsetRect(&rect, pt.x, pt.y);
610 return rect;
611 }
612
613 CRect operator -(POINT pt) const
614 {
615 CRect rect(*this);
616 ::OffsetRect(&rect, -pt.x, -pt.y);
617 return rect;
618 }
619
620 CRect operator +(LPCRECT lpRect) const
621 {
622 CRect rect(this);
623 rect.InflateRect(lpRect);
624 return rect;
625 }
626
627 CRect operator +(SIZE size) const
628 {
629 CRect rect(*this);
630 ::OffsetRect(&rect, size.cx, size.cy);
631 return rect;
632 }
633
634 CRect operator -(SIZE size) const
635 {
636 CRect rect(*this);
637 ::OffsetRect(&rect, -size.cx, -size.cy);
638 return rect;
639 }
640
641 CRect operator -(LPCRECT lpRect) const
642 {
643 CRect rect(this);
644 rect.DeflateRect(lpRect);
645 return rect;
646 }
647
648 CRect operator &(const RECT& rect2) const
649 {
650 CRect rect;
651 ::IntersectRect(&rect, this, &rect2);
652 return rect;
653 }
654
655 CRect operator |(const RECT& rect2) const
656 {
657 CRect rect;
658 ::UnionRect(&rect, this, &rect2);
659 return rect;
660 }
661
662 CRect MulDiv(int nMultiplier, int nDivisor) const
663 {
664 return CRect(
665 ::MulDiv(left, nMultiplier, nDivisor),
666 ::MulDiv(top, nMultiplier, nDivisor),
667 ::MulDiv(right, nMultiplier, nDivisor),
668 ::MulDiv(bottom, nMultiplier, nDivisor));
669 }
670 };
671
672
673 // CSize implementation
674
675 inline CPoint CSize::operator +(POINT point) const
676 { return CPoint(cx + point.x, cy + point.y); }
677
678 inline CPoint CSize::operator -(POINT point) const
679 { return CPoint(cx - point.x, cy - point.y); }
680
681 inline CRect CSize::operator +(const RECT* lpRect) const
682 { return CRect(lpRect) + *this; }
683
684 inline CRect CSize::operator -(const RECT* lpRect) const
685 { return CRect(lpRect) - *this; }
686
687
688 // CPoint implementation
689
690 inline CRect CPoint::operator +(const RECT* lpRect) const
691 { return CRect(lpRect) + *this; }
692
693 inline CRect CPoint::operator -(const RECT* lpRect) const
694 { return CRect(lpRect) - *this; }
695
696 #endif // !_WTL_NO_WTYPES
697
698
699 // WTL::CSize or ATL::CSize scalar operators
700
701 #if !defined(_WTL_NO_SIZE_SCALAR) && (!defined(_WTL_NO_WTYPES) || defined(__ATLTYPES_H__))
702
703 template <class Num>
704 inline CSize operator *(SIZE s, Num n)
705 {
706 return CSize((int)(s.cx * n), (int)(s.cy * n));
707 };
708
709 template <class Num>
710 inline void operator *=(SIZE & s, Num n)
711 {
712 s = s * n;
713 };
714
715 template <class Num>
716 inline CSize operator /(SIZE s, Num n)
717 {
718 return CSize((int)(s.cx / n), (int)(s.cy / n));
719 };
720
721 template <class Num>
722 inline void operator /=(SIZE & s, Num n)
723 {
724 s = s / n;
725 };
726
727 #endif // !defined(_WTL_NO_SIZE_SCALAR) && (!defined(_WTL_NO_WTYPES) || defined(__ATLTYPES_H__))
728
729
730 ///////////////////////////////////////////////////////////////////////////////
731 // CString - String class
732
733 #ifndef _WTL_NO_CSTRING
734
735 struct CStringData
736 {
737 long nRefs; // reference count
738 int nDataLength;
739 int nAllocLength;
740 // TCHAR data[nAllocLength]
741
742 TCHAR* data()
743 { return (TCHAR*)(this + 1); }
744 };
745
746 // Globals
747
748 // For an empty string, m_pchData will point here
749 // (note: avoids special case of checking for NULL m_pchData)
750 // empty string data (and locked)
751 _declspec(selectany) int rgInitData[] = { -1, 0, 0, 0 };
752 _declspec(selectany) CStringData* _atltmpDataNil = (CStringData*)&rgInitData;
753 _declspec(selectany) LPCTSTR _atltmpPchNil = (LPCTSTR)(((BYTE*)&rgInitData) + sizeof(CStringData));
754
755
756 class CString
757 {
758 public:
759 // Constructors
760 CString()
761 {
762 Init();
763 }
764
765 CString(const CString& stringSrc)
766 {
767 ATLASSERT(stringSrc.GetData()->nRefs != 0);
768 if (stringSrc.GetData()->nRefs >= 0)
769 {
770 ATLASSERT(stringSrc.GetData() != _atltmpDataNil);
771 m_pchData = stringSrc.m_pchData;
772 InterlockedIncrement(&GetData()->nRefs);
773 }
774 else
775 {
776 Init();
777 *this = stringSrc.m_pchData;
778 }
779 }
780
781 CString(TCHAR ch, int nRepeat = 1)
782 {
783 ATLASSERT(!_istlead(ch)); // can't create a lead byte string
784 Init();
785 if (nRepeat >= 1)
786 {
787 if(AllocBuffer(nRepeat))
788 {
789 #ifdef _UNICODE
790 for (int i = 0; i < nRepeat; i++)
791 m_pchData[i] = ch;
792 #else
793 memset(m_pchData, ch, nRepeat);
794 #endif
795 }
796 }
797 }
798
799 CString(LPCTSTR lpsz)
800 {
801 Init();
802 if (lpsz != NULL && HIWORD(lpsz) == NULL)
803 {
804 UINT nID = LOWORD((DWORD_PTR)lpsz);
805 if (!LoadString(nID))
806 ATLTRACE2(atlTraceUI, 0, _T("Warning: implicit LoadString(%u) in CString failed\n"), nID);
807 }
808 else
809 {
810 int nLen = SafeStrlen(lpsz);
811 if (nLen != 0)
812 {
813 if(AllocBuffer(nLen))
814 SecureHelper::memcpy_x(m_pchData, (nLen + 1) * sizeof(TCHAR), lpsz, nLen * sizeof(TCHAR));
815 }
816 }
817 }
818
819 #ifdef _UNICODE
820 CString(LPCSTR lpsz)
821 {
822 Init();
823 #if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800)
824 int nSrcLen = (lpsz != NULL) ? ATL::lstrlenA(lpsz) : 0;
825 #else
826 int nSrcLen = (lpsz != NULL) ? lstrlenA(lpsz) : 0;
827 #endif
828 if (nSrcLen != 0)
829 {
830 if(AllocBuffer(nSrcLen))
831 {
832 _mbstowcsz(m_pchData, lpsz, nSrcLen + 1);
833 ReleaseBuffer();
834 }
835 }
836 }
837 #else // !_UNICODE
838 CString(LPCWSTR lpsz)
839 {
840 Init();
841 int nSrcLen = (lpsz != NULL) ? (int)wcslen(lpsz) : 0;
842 if (nSrcLen != 0)
843 {
844 if(AllocBuffer(nSrcLen * 2))
845 {
846 _wcstombsz(m_pchData, lpsz, (nSrcLen * 2) + 1);
847 ReleaseBuffer();
848 }
849 }
850 }
851 #endif // !_UNICODE
852
853 CString(LPCTSTR lpch, int nLength)
854 {
855 Init();
856 if (nLength != 0)
857 {
858 if(AllocBuffer(nLength))
859 SecureHelper::memcpy_x(m_pchData, (nLength + 1) * sizeof(TCHAR), lpch, nLength * sizeof(TCHAR));
860 }
861 }
862
863 #ifdef _UNICODE
864 CString(LPCSTR lpsz, int nLength)
865 {
866 Init();
867 if (nLength != 0)
868 {
869 if(AllocBuffer(nLength))
870 {
871 int n = ::MultiByteToWideChar(CP_ACP, 0, lpsz, nLength, m_pchData, nLength + 1);
872 ReleaseBuffer((n >= 0) ? n : -1);
873 }
874 }
875 }
876 #else // !_UNICODE
877 CString(LPCWSTR lpsz, int nLength)
878 {
879 Init();
880 if (nLength != 0)
881 {
882 if(((nLength * 2) > nLength) && AllocBuffer(nLength * 2))
883 {
884 int n = ::WideCharToMultiByte(CP_ACP, 0, lpsz, nLength, m_pchData, (nLength * 2) + 1, NULL, NULL);
885 ReleaseBuffer((n >= 0) ? n : -1);
886 }
887 }
888 }
889 #endif // !_UNICODE
890
891 CString(const unsigned char* lpsz)
892 {
893 Init();
894 *this = (LPCSTR)lpsz;
895 }
896
897 // Attributes & Operations
898 int GetLength() const // as an array of characters
899 {
900 return GetData()->nDataLength;
901 }
902
903 BOOL IsEmpty() const
904 {
905 return GetData()->nDataLength == 0;
906 }
907
908 void Empty() // free up the data
909 {
910 if (GetData()->nDataLength == 0)
911 return;
912
913 if (GetData()->nRefs >= 0)
914 Release();
915 else
916 *this = _T("");
917
918 ATLASSERT(GetData()->nDataLength == 0);
919 ATLASSERT(GetData()->nRefs < 0 || GetData()->nAllocLength == 0);
920 }
921
922 TCHAR GetAt(int nIndex) const // 0 based
923 {
924 ATLASSERT(nIndex >= 0);
925 ATLASSERT(nIndex < GetData()->nDataLength);
926 return m_pchData[nIndex];
927 }
928
929 TCHAR operator [](int nIndex) const // same as GetAt
930 {
931 // same as GetAt
932 ATLASSERT(nIndex >= 0);
933 ATLASSERT(nIndex < GetData()->nDataLength);
934 return m_pchData[nIndex];
935 }
936
937 void SetAt(int nIndex, TCHAR ch)
938 {
939 ATLASSERT(nIndex >= 0);
940 ATLASSERT(nIndex < GetData()->nDataLength);
941
942 CopyBeforeWrite();
943 m_pchData[nIndex] = ch;
944 }
945
946 operator LPCTSTR() const // as a C string
947 {
948 return m_pchData;
949 }
950
951 // overloaded assignment
952 CString& operator =(const CString& stringSrc)
953 {
954 if (m_pchData != stringSrc.m_pchData)
955 {
956 if ((GetData()->nRefs < 0 && GetData() != _atltmpDataNil) || stringSrc.GetData()->nRefs < 0)
957 {
958 // actual copy necessary since one of the strings is locked
959 AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData);
960 }
961 else
962 {
963 // can just copy references around
964 Release();
965 ATLASSERT(stringSrc.GetData() != _atltmpDataNil);
966 m_pchData = stringSrc.m_pchData;
967 InterlockedIncrement(&GetData()->nRefs);
968 }
969 }
970 return *this;
971 }
972
973 CString& operator =(TCHAR ch)
974 {
975 ATLASSERT(!_istlead(ch)); // can't set single lead byte
976 AssignCopy(1, &ch);
977 return *this;
978 }
979
980 #ifdef _UNICODE
981 CString& operator =(char ch)
982 {
983 *this = (TCHAR)ch;
984 return *this;
985 }
986 #endif
987
988 CString& operator =(LPCTSTR lpsz)
989 {
990 ATLASSERT(lpsz == NULL || _IsValidString(lpsz));
991 AssignCopy(SafeStrlen(lpsz), lpsz);
992 return *this;
993 }
994
995 #ifdef _UNICODE
996 CString& operator =(LPCSTR lpsz)
997 {
998 #if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800)
999 int nSrcLen = (lpsz != NULL) ? ATL::lstrlenA(lpsz) : 0;
1000 #else
1001 int nSrcLen = (lpsz != NULL) ? lstrlenA(lpsz) : 0;
1002 #endif
1003 if(AllocBeforeWrite(nSrcLen))
1004 {
1005 _mbstowcsz(m_pchData, lpsz, nSrcLen + 1);
1006 ReleaseBuffer();
1007 }
1008 return *this;
1009 }
1010 #else // !_UNICODE
1011 CString& operator =(LPCWSTR lpsz)
1012 {
1013 int nSrcLen = (lpsz != NULL) ? (int)wcslen(lpsz) : 0;
1014 if(AllocBeforeWrite(nSrcLen * 2))
1015 {
1016 _wcstombsz(m_pchData, lpsz, (nSrcLen * 2) + 1);
1017 ReleaseBuffer();
1018 }
1019 return *this;
1020 }
1021 #endif // !_UNICODE
1022
1023 CString& operator =(const unsigned char* lpsz)
1024 {
1025 *this = (LPCSTR)lpsz;
1026 return *this;
1027 }
1028
1029 // string concatenation
1030 CString& operator +=(const CString& string)
1031 {
1032 ConcatInPlace(string.GetData()->nDataLength, string.m_pchData);
1033 return *this;
1034 }
1035
1036 CString& operator +=(TCHAR ch)
1037 {
1038 ConcatInPlace(1, &ch);
1039 return *this;
1040 }
1041
1042 #ifdef _UNICODE
1043 CString& operator +=(char ch)
1044 {
1045 *this += (TCHAR)ch;
1046 return *this;
1047 }
1048 #endif
1049
1050 CString& operator +=(LPCTSTR lpsz)
1051 {
1052 ATLASSERT(lpsz == NULL || _IsValidString(lpsz));
1053 ConcatInPlace(SafeStrlen(lpsz), lpsz);
1054 return *this;
1055 }
1056
1057 friend CString __stdcall operator +(const CString& string1, const CString& string2);
1058 friend CString __stdcall operator +(const CString& string, TCHAR ch);
1059 friend CString __stdcall operator +(TCHAR ch, const CString& string);
1060 #ifdef _UNICODE
1061 friend CString __stdcall operator +(const CString& string, char ch);
1062 friend CString __stdcall operator +(char ch, const CString& string);
1063 #endif
1064 friend CString __stdcall operator +(const CString& string, LPCTSTR lpsz);
1065 friend CString __stdcall operator +(LPCTSTR lpsz, const CString& string);
1066
1067 // string comparison
1068 int Compare(LPCTSTR lpsz) const // straight character (MBCS/Unicode aware)
1069 {
1070 return _cstrcmp(m_pchData, lpsz);
1071 }
1072
1073 int CompareNoCase(LPCTSTR lpsz) const // ignore case (MBCS/Unicode aware)
1074 {
1075 return _cstrcmpi(m_pchData, lpsz);
1076 }
1077
1078 #ifndef _WIN32_WCE
1079 // CString::Collate is often slower than Compare but is MBSC/Unicode
1080 // aware as well as locale-sensitive with respect to sort order.
1081 int Collate(LPCTSTR lpsz) const // NLS aware
1082 {
1083 return _cstrcoll(m_pchData, lpsz);
1084 }
1085
1086 int CollateNoCase(LPCTSTR lpsz) const // ignore case
1087 {
1088 return _cstrcolli(m_pchData, lpsz);
1089 }
1090 #endif // !_WIN32_WCE
1091
1092 // simple sub-string extraction
1093 CString Mid(int nFirst, int nCount) const
1094 {
1095 // out-of-bounds requests return sensible things
1096 if (nFirst < 0)
1097 nFirst = 0;
1098 if (nCount < 0)
1099 nCount = 0;
1100
1101 if (nFirst + nCount > GetData()->nDataLength)
1102 nCount = GetData()->nDataLength - nFirst;
1103 if (nFirst > GetData()->nDataLength)
1104 nCount = 0;
1105
1106 CString dest;
1107 AllocCopy(dest, nCount, nFirst, 0);
1108 return dest;
1109 }
1110
1111 CString Mid(int nFirst) const
1112 {
1113 return Mid(nFirst, GetData()->nDataLength - nFirst);
1114 }
1115
1116 CString Left(int nCount) const
1117 {
1118 if (nCount < 0)
1119 nCount = 0;
1120 else if (nCount > GetData()->nDataLength)
1121 nCount = GetData()->nDataLength;
1122
1123 CString dest;
1124 AllocCopy(dest, nCount, 0, 0);
1125 return dest;
1126 }
1127
1128 CString Right(int nCount) const
1129 {
1130 if (nCount < 0)
1131 nCount = 0;
1132 else if (nCount > GetData()->nDataLength)
1133 nCount = GetData()->nDataLength;
1134
1135 CString dest;
1136 AllocCopy(dest, nCount, GetData()->nDataLength-nCount, 0);
1137 return dest;
1138 }
1139
1140 CString SpanIncluding(LPCTSTR lpszCharSet) const // strspn equivalent
1141 {
1142 ATLASSERT(_IsValidString(lpszCharSet));
1143 return Left(_cstrspn(m_pchData, lpszCharSet));
1144 }
1145
1146 CString SpanExcluding(LPCTSTR lpszCharSet) const // strcspn equivalent
1147 {
1148 ATLASSERT(_IsValidString(lpszCharSet));
1149 return Left(_cstrcspn(m_pchData, lpszCharSet));
1150 }
1151
1152 // upper/lower/reverse conversion
1153 void MakeUpper()
1154 {
1155 CopyBeforeWrite();
1156 CharUpper(m_pchData);
1157 }
1158
1159 void MakeLower()
1160 {
1161 CopyBeforeWrite();
1162 CharLower(m_pchData);
1163 }
1164
1165 void MakeReverse()
1166 {
1167 CopyBeforeWrite();
1168 _cstrrev(m_pchData);
1169 }
1170
1171 // trimming whitespace (either side)
1172 void TrimRight()
1173 {
1174 CopyBeforeWrite();
1175
1176 // find beginning of trailing spaces by starting at beginning (DBCS aware)
1177 LPTSTR lpsz = m_pchData;
1178 LPTSTR lpszLast = NULL;
1179 while (*lpsz != _T('\0'))
1180 {
1181 if (_cstrisspace(*lpsz))
1182 {
1183 if (lpszLast == NULL)
1184 lpszLast = lpsz;
1185 }
1186 else
1187 {
1188 lpszLast = NULL;
1189 }
1190 lpsz = ::CharNext(lpsz);
1191 }
1192
1193 if (lpszLast != NULL)
1194 {
1195 // truncate at trailing space start
1196 *lpszLast = _T('\0');
1197 GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData);
1198 }
1199 }
1200
1201 void TrimLeft()
1202 {
1203 CopyBeforeWrite();
1204
1205 // find first non-space character
1206 LPCTSTR lpsz = m_pchData;
1207 while (_cstrisspace(*lpsz))
1208 lpsz = ::CharNext(lpsz);
1209
1210 // fix up data and length
1211 int nDataLength = GetData()->nDataLength - (int)(DWORD_PTR)(lpsz - m_pchData);
1212 SecureHelper::memmove_x(m_pchData, (GetData()->nAllocLength + 1) * sizeof(TCHAR), lpsz, (nDataLength + 1) * sizeof(TCHAR));
1213 GetData()->nDataLength = nDataLength;
1214 }
1215
1216 // remove continuous occurrences of chTarget starting from right
1217 void TrimRight(TCHAR chTarget)
1218 {
1219 // find beginning of trailing matches
1220 // by starting at beginning (DBCS aware)
1221
1222 CopyBeforeWrite();
1223 LPTSTR lpsz = m_pchData;
1224 LPTSTR lpszLast = NULL;
1225
1226 while (*lpsz != _T('\0'))
1227 {
1228 if (*lpsz == chTarget)
1229 {
1230 if (lpszLast == NULL)
1231 lpszLast = lpsz;
1232 }
1233 else
1234 lpszLast = NULL;
1235 lpsz = ::CharNext(lpsz);
1236 }
1237
1238 if (lpszLast != NULL)
1239 {
1240 // truncate at left-most matching character
1241 *lpszLast = _T('\0');
1242 GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData);
1243 }
1244 }
1245
1246 // remove continuous occcurrences of characters in passed string, starting from right
1247 void TrimRight(LPCTSTR lpszTargetList)
1248 {
1249 // find beginning of trailing matches by starting at beginning (DBCS aware)
1250
1251 CopyBeforeWrite();
1252 LPTSTR lpsz = m_pchData;
1253 LPTSTR lpszLast = NULL;
1254
1255 while (*lpsz != _T('\0'))
1256 {
1257 TCHAR* pNext = ::CharNext(lpsz);
1258 if(pNext > lpsz + 1)
1259 {
1260 if (_cstrchr_db(lpszTargetList, *lpsz, *(lpsz + 1)) != NULL)
1261 {
1262 if (lpszLast == NULL)
1263 lpszLast = lpsz;
1264 }
1265 else
1266 {
1267 lpszLast = NULL;
1268 }
1269 }
1270 else
1271 {
1272 if (_cstrchr(lpszTargetList, *lpsz) != NULL)
1273 {
1274 if (lpszLast == NULL)
1275 lpszLast = lpsz;
1276 }
1277 else
1278 {
1279 lpszLast = NULL;
1280 }
1281 }
1282
1283 lpsz = pNext;
1284 }
1285
1286 if (lpszLast != NULL)
1287 {
1288 // truncate at left-most matching character
1289 *lpszLast = _T('\0');
1290 GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData);
1291 }
1292 }
1293
1294 // remove continuous occurrences of chTarget starting from left
1295 void TrimLeft(TCHAR chTarget)
1296 {
1297 // find first non-matching character
1298
1299 CopyBeforeWrite();
1300 LPCTSTR lpsz = m_pchData;
1301
1302 while (chTarget == *lpsz)
1303 lpsz = ::CharNext(lpsz);
1304
1305 if (lpsz != m_pchData)
1306 {
1307 // fix up data and length
1308 int nDataLength = GetData()->nDataLength - (int)(DWORD_PTR)(lpsz - m_pchData);
1309 SecureHelper::memmove_x(m_pchData, (GetData()->nAllocLength + 1) * sizeof(TCHAR), lpsz, (nDataLength + 1) * sizeof(TCHAR));
1310 GetData()->nDataLength = nDataLength;
1311 }
1312 }
1313
1314 // remove continuous occcurrences of characters in passed string, starting from left
1315 void TrimLeft(LPCTSTR lpszTargets)
1316 {
1317 // if we're not trimming anything, we're not doing any work
1318 if (SafeStrlen(lpszTargets) == 0)
1319 return;
1320
1321 CopyBeforeWrite();
1322 LPCTSTR lpsz = m_pchData;
1323
1324 while (*lpsz != _T('\0'))
1325 {
1326 TCHAR* pNext = ::CharNext(lpsz);
1327 if(pNext > lpsz + 1)
1328 {
1329 if (_cstrchr_db(lpszTargets, *lpsz, *(lpsz + 1)) == NULL)
1330 break;
1331 }
1332 else
1333 {
1334 if (_cstrchr(lpszTargets, *lpsz) == NULL)
1335 break;
1336 }
1337 lpsz = pNext;
1338 }
1339
1340 if (lpsz != m_pchData)
1341 {
1342 // fix up data and length
1343 int nDataLength = GetData()->nDataLength - (int)(DWORD_PTR)(lpsz - m_pchData);
1344 SecureHelper::memmove_x(m_pchData, (GetData()->nAllocLength + 1) * sizeof(TCHAR), lpsz, (nDataLength + 1) * sizeof(TCHAR));
1345 GetData()->nDataLength = nDataLength;
1346 }
1347 }
1348
1349 // advanced manipulation
1350 // replace occurrences of chOld with chNew
1351 int Replace(TCHAR chOld, TCHAR chNew)
1352 {
1353 int nCount = 0;
1354
1355 // short-circuit the nop case
1356 if (chOld != chNew)
1357 {
1358 // otherwise modify each character that matches in the string
1359 CopyBeforeWrite();
1360 LPTSTR psz = m_pchData;
1361 LPTSTR pszEnd = psz + GetData()->nDataLength;
1362 while (psz < pszEnd)
1363 {
1364 // replace instances of the specified character only
1365 if (*psz == chOld)
1366 {
1367 *psz = chNew;
1368 nCount++;
1369 }
1370 psz = ::CharNext(psz);
1371 }
1372 }
1373 return nCount;
1374 }
1375
1376 // replace occurrences of substring lpszOld with lpszNew;
1377 // empty lpszNew removes instances of lpszOld
1378 int Replace(LPCTSTR lpszOld, LPCTSTR lpszNew)
1379 {
1380 // can't have empty or NULL lpszOld
1381
1382 int nSourceLen = SafeStrlen(lpszOld);
1383 if (nSourceLen == 0)
1384 return 0;
1385 int nReplacementLen = SafeStrlen(lpszNew);
1386
1387 // loop once to figure out the size of the result string
1388 int nCount = 0;
1389 LPTSTR lpszStart = m_pchData;
1390 LPTSTR lpszEnd = m_pchData + GetData()->nDataLength;
1391 LPTSTR lpszTarget = NULL;
1392 while (lpszStart < lpszEnd)
1393 {
1394 while ((lpszTarget = (TCHAR*)_cstrstr(lpszStart, lpszOld)) != NULL)
1395 {
1396 nCount++;
1397 lpszStart = lpszTarget + nSourceLen;
1398 }
1399 lpszStart += lstrlen(lpszStart) + 1;
1400 }
1401
1402 // if any changes were made, make them
1403 if (nCount > 0)
1404 {
1405 CopyBeforeWrite();
1406
1407 // if the buffer is too small, just allocate a new buffer (slow but sure)
1408 int nOldLength = GetData()->nDataLength;
1409 int nNewLength = nOldLength + (nReplacementLen - nSourceLen) * nCount;
1410 if (GetData()->nAllocLength < nNewLength || GetData()->nRefs > 1)
1411 {
1412 CStringData* pOldData = GetData();
1413 LPTSTR pstr = m_pchData;
1414 if(!AllocBuffer(nNewLength))
1415 return -1;
1416 SecureHelper::memcpy_x(m_pchData, (nNewLength + 1) * sizeof(TCHAR), pstr, pOldData->nDataLength * sizeof(TCHAR));
1417 CString::Release(pOldData);
1418 }
1419 // else, we just do it in-place
1420 lpszStart = m_pchData;
1421 lpszEnd = m_pchData + GetData()->nDataLength;
1422
1423 // loop again to actually do the work
1424 while (lpszStart < lpszEnd)
1425 {
1426 while ((lpszTarget = (TCHAR*)_cstrstr(lpszStart, lpszOld)) != NULL)
1427 {
1428 int nBalance = nOldLength - ((int)(DWORD_PTR)(lpszTarget - m_pchData) + nSourceLen);
1429 int cchBuffLen = GetData()->nAllocLength - (int)(DWORD_PTR)(lpszTarget - m_pchData);
1430 SecureHelper::memmove_x(lpszTarget + nReplacementLen, (cchBuffLen - nReplacementLen + 1) * sizeof(TCHAR), lpszTarget + nSourceLen, nBalance * sizeof(TCHAR));
1431 SecureHelper::memcpy_x(lpszTarget, (cchBuffLen + 1) * sizeof(TCHAR), lpszNew, nReplacementLen * sizeof(TCHAR));
1432 lpszStart = lpszTarget + nReplacementLen;
1433 lpszStart[nBalance] = _T('\0');
1434 nOldLength += (nReplacementLen - nSourceLen);
1435 }
1436 lpszStart += lstrlen(lpszStart) + 1;
1437 }
1438 ATLASSERT(m_pchData[nNewLength] == _T('\0'));
1439 GetData()->nDataLength = nNewLength;
1440 }
1441
1442 return nCount;
1443 }
1444
1445 // remove occurrences of chRemove
1446 int Remove(TCHAR chRemove)
1447 {
1448 CopyBeforeWrite();
1449
1450 LPTSTR pstrSource = m_pchData;
1451 LPTSTR pstrDest = m_pchData;
1452 LPTSTR pstrEnd = m_pchData + GetData()->nDataLength;
1453
1454 while (pstrSource < pstrEnd)
1455 {
1456 if (*pstrSource != chRemove)
1457 {
1458 *pstrDest = *pstrSource;
1459 pstrDest = ::CharNext(pstrDest);
1460 }
1461 pstrSource = ::CharNext(pstrSource);
1462 }
1463 *pstrDest = _T('\0');
1464 int nCount = (int)(DWORD_PTR)(pstrSource - pstrDest);
1465 GetData()->nDataLength -= nCount;
1466
1467 return nCount;
1468 }
1469
1470 // insert character at zero-based index; concatenates if index is past end of string
1471 int Insert(int nIndex, TCHAR ch)
1472 {
1473 CopyBeforeWrite();
1474
1475 if (nIndex < 0)
1476 nIndex = 0;
1477
1478 int nNewLength = GetData()->nDataLength;
1479 if (nIndex > nNewLength)
1480 nIndex = nNewLength;
1481 nNewLength++;
1482
1483 if (GetData()->nAllocLength < nNewLength)
1484 {
1485 CStringData* pOldData = GetData();
1486 LPTSTR pstr = m_pchData;
1487 if(!AllocBuffer(nNewLength))
1488 return -1;
1489 SecureHelper::memcpy_x(m_pchData, (nNewLength + 1) * sizeof(TCHAR), pstr, (pOldData->nDataLength + 1) * sizeof(TCHAR));
1490 CString::Release(pOldData);
1491 }
1492
1493 // move existing bytes down
1494 SecureHelper::memmove_x(m_pchData + nIndex + 1, (GetData()->nAllocLength - nIndex) * sizeof(TCHAR), m_pchData + nIndex, (nNewLength - nIndex) * sizeof(TCHAR));
1495 m_pchData[nIndex] = ch;
1496 GetData()->nDataLength = nNewLength;
1497
1498 return nNewLength;
1499 }
1500
1501 // insert substring at zero-based index; concatenates if index is past end of string
1502 int Insert(int nIndex, LPCTSTR pstr)
1503 {
1504 if (nIndex < 0)
1505 nIndex = 0;
1506
1507 int nInsertLength = SafeStrlen(pstr);
1508 int nNewLength = GetData()->nDataLength;
1509 if (nInsertLength > 0)
1510 {
1511 CopyBeforeWrite();
1512 if (nIndex > nNewLength)
1513 nIndex = nNewLength;
1514 nNewLength += nInsertLength;
1515
1516 if (GetData()->nAllocLength < nNewLength)
1517 {
1518 CStringData* pOldData = GetData();
1519 LPTSTR pstrTmp = m_pchData;
1520 if(!AllocBuffer(nNewLength))
1521 return -1;
1522 SecureHelper::memcpy_x(m_pchData, (nNewLength + 1) * sizeof(TCHAR), pstrTmp, (pOldData->nDataLength + 1) * sizeof(TCHAR));
1523 CString::Release(pOldData);
1524 }
1525
1526 // move existing bytes down
1527 SecureHelper::memmove_x(m_pchData + nIndex + nInsertLength, (GetData()->nAllocLength + 1 - nIndex - nInsertLength) * sizeof(TCHAR), m_pchData + nIndex, (nNewLength - nIndex - nInsertLength + 1) * sizeof(TCHAR));
1528 SecureHelper::memcpy_x(m_pchData + nIndex, (GetData()->nAllocLength + 1 - nIndex) * sizeof(TCHAR), pstr, nInsertLength * sizeof(TCHAR));
1529 GetData()->nDataLength = nNewLength;
1530 }
1531
1532 return nNewLength;
1533 }
1534
1535 // delete nCount characters starting at zero-based index
1536 int Delete(int nIndex, int nCount = 1)
1537 {
1538 if (nIndex < 0)
1539 nIndex = 0;
1540 int nLength = GetData()->nDataLength;
1541 if (nCount > 0 && nIndex < nLength)
1542 {
1543 if((nIndex + nCount) > nLength)
1544 nCount = nLength - nIndex;
1545 CopyBeforeWrite();
1546 int nBytesToCopy = nLength - (nIndex + nCount) + 1;
1547
1548 SecureHelper::memmove_x(m_pchData + nIndex, (GetData()->nAllocLength + 1 - nIndex) * sizeof(TCHAR), m_pchData + nIndex + nCount, nBytesToCopy * sizeof(TCHAR));
1549 nLength -= nCount;
1550 GetData()->nDataLength = nLength;
1551 }
1552
1553 return nLength;
1554 }
1555
1556 // searching (return starting index, or -1 if not found)
1557 // look for a single character match
1558 int Find(TCHAR ch) const // like "C" strchr
1559 {
1560 return Find(ch, 0);
1561 }
1562
1563 int ReverseFind(TCHAR ch) const
1564 {
1565 // find last single character
1566 LPCTSTR lpsz = _cstrrchr(m_pchData, (_TUCHAR)ch);
1567
1568 // return -1 if not found, distance from beginning otherwise
1569 return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
1570 }
1571
1572 int Find(TCHAR ch, int nStart) const // starting at index
1573 {
1574 int nLength = GetData()->nDataLength;
1575 if (nStart < 0 || nStart >= nLength)
1576 return -1;
1577
1578 // find first single character
1579 LPCTSTR lpsz = _cstrchr(m_pchData + nStart, (_TUCHAR)ch);
1580
1581 // return -1 if not found and index otherwise
1582 return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
1583 }
1584
1585 int FindOneOf(LPCTSTR lpszCharSet) const
1586 {
1587 ATLASSERT(_IsValidString(lpszCharSet));
1588 LPCTSTR lpsz = _cstrpbrk(m_pchData, lpszCharSet);
1589 return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
1590 }
1591
1592 // look for a specific sub-string
1593 // find a sub-string (like strstr)
1594 int Find(LPCTSTR lpszSub) const // like "C" strstr
1595 {
1596 return Find(lpszSub, 0);
1597 }
1598
1599 int Find(LPCTSTR lpszSub, int nStart) const // starting at index
1600 {
1601 ATLASSERT(_IsValidString(lpszSub));
1602
1603 int nLength = GetData()->nDataLength;
1604 if (nStart < 0 || nStart > nLength)
1605 return -1;
1606
1607 // find first matching substring
1608 LPCTSTR lpsz = _cstrstr(m_pchData + nStart, lpszSub);
1609
1610 // return -1 for not found, distance from beginning otherwise
1611 return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
1612 }
1613
1614 // Concatentation for non strings
1615 CString& Append(int n)
1616 {
1617 const int cchBuff = 12;
1618 TCHAR szBuffer[cchBuff] = { 0 };
1619 SecureHelper::wsprintf_x(szBuffer, cchBuff, _T("%d"), n);
1620 ConcatInPlace(SafeStrlen(szBuffer), szBuffer);
1621 return *this;
1622 }
1623
1624 // simple formatting
1625 // formatting (using wsprintf style formatting)
1626 BOOL __cdecl Format(LPCTSTR lpszFormat, ...)
1627 {
1628 ATLASSERT(_IsValidString(lpszFormat));
1629
1630 va_list argList;
1631 va_start(argList, lpszFormat);
1632 BOOL bRet = FormatV(lpszFormat, argList);
1633 va_end(argList);
1634 return bRet;
1635 }
1636
1637 BOOL __cdecl Format(UINT nFormatID, ...)
1638 {
1639 CString strFormat;
1640 BOOL bRet = strFormat.LoadString(nFormatID);
1641 ATLASSERT(bRet != 0);
1642
1643 va_list argList;
1644 va_start(argList, nFormatID);
1645 bRet = FormatV(strFormat, argList);
1646 va_end(argList);
1647 return bRet;
1648 }
1649
1650 BOOL FormatV(LPCTSTR lpszFormat, va_list argList)
1651 {
1652 ATLASSERT(_IsValidString(lpszFormat));
1653
1654 enum _FormatModifiers
1655 {
1656 FORCE_ANSI = 0x10000,
1657 FORCE_UNICODE = 0x20000,
1658 FORCE_INT64 = 0x40000
1659 };
1660
1661 va_list argListSave = argList;
1662
1663 // make a guess at the maximum length of the resulting string
1664 int nMaxLen = 0;
1665 for (LPCTSTR lpsz = lpszFormat; *lpsz != _T('\0'); lpsz = ::CharNext(lpsz))
1666 {
1667 // handle '%' character, but watch out for '%%'
1668 if (*lpsz != _T('%') || *(lpsz = ::CharNext(lpsz)) == _T('%'))
1669 {
1670 nMaxLen += (int)(::CharNext(lpsz) - lpsz);
1671 continue;
1672 }
1673
1674 int nItemLen = 0;
1675
1676 // handle '%' character with format
1677 int nWidth = 0;
1678 for (; *lpsz != _T('\0'); lpsz = ::CharNext(lpsz))
1679 {
1680 // check for valid flags
1681 if (*lpsz == _T('#'))
1682 nMaxLen += 2; // for '0x'
1683 else if (*lpsz == _T('*'))
1684 nWidth = va_arg(argList, int);
1685 else if (*lpsz == _T('-') || *lpsz == _T('+') || *lpsz == _T('0') || *lpsz == _T(' '))
1686 ;
1687 else // hit non-flag character
1688 break;
1689 }
1690 // get width and skip it
1691 if (nWidth == 0)
1692 {
1693 // width indicated by
1694 nWidth = _cstrtoi(lpsz);
1695 for (; *lpsz != _T('\0') && _cstrisdigit(*lpsz); lpsz = ::CharNext(lpsz))
1696 ;
1697 }
1698 ATLASSERT(nWidth >= 0);
1699
1700 int nPrecision = 0;
1701 if (*lpsz == _T('.'))
1702 {
1703 // skip past '.' separator (width.precision)
1704 lpsz = ::CharNext(lpsz);
1705
1706 // get precision and skip it
1707 if (*lpsz == _T('*'))
1708 {
1709 nPrecision = va_arg(argList, int);
1710 lpsz = ::CharNext(lpsz);
1711 }
1712 else
1713 {
1714 nPrecision = _cstrtoi(lpsz);
1715 for (; *lpsz != _T('\0') && _cstrisdigit(*lpsz); lpsz = ::CharNext(lpsz))
1716 ;
1717 }
1718 ATLASSERT(nPrecision >= 0);
1719 }
1720
1721 // should be on type modifier or specifier
1722 int nModifier = 0;
1723 if(lpsz[0] == _T('I'))
1724 {
1725 if((lpsz[1] == _T('6')) && (lpsz[2] == _T('4')))
1726 {
1727 lpsz += 3;
1728 nModifier = FORCE_INT64;
1729 }
1730 else if((lpsz[1] == _T('3')) && (lpsz[2] == _T('2')))
1731 {
1732 lpsz += 3;
1733 }
1734 else
1735 {
1736 lpsz++;
1737 if(sizeof(size_t) == 8)
1738 nModifier = FORCE_INT64;
1739 }
1740 }
1741 else
1742 {
1743 switch (*lpsz)
1744 {
1745 // modifiers that affect size
1746 case _T('h'):
1747 nModifier = FORCE_ANSI;
1748 lpsz = ::CharNext(lpsz);
1749 break;
1750 case _T('l'):
1751 nModifier = FORCE_UNICODE;
1752 lpsz = ::CharNext(lpsz);
1753 break;
1754
1755 // modifiers that do not affect size
1756 case _T('F'):
1757 case _T('N'):
1758 case _T('L'):
1759 lpsz = ::CharNext(lpsz);
1760 break;
1761 }
1762 }
1763
1764 // now should be on specifier
1765 switch (*lpsz | nModifier)
1766 {
1767 // single characters
1768 case _T('c'):
1769 case _T('C'):
1770 nItemLen = 2;
1771 va_arg(argList, TCHAR);
1772 break;
1773 case _T('c') | FORCE_ANSI:
1774 case _T('C') | FORCE_ANSI:
1775 nItemLen = 2;
1776 va_arg(argList, char);
1777 break;
1778 case _T('c') | FORCE_UNICODE:
1779 case _T('C') | FORCE_UNICODE:
1780 nItemLen = 2;
1781 va_arg(argList, WCHAR);
1782 break;
1783
1784 // strings
1785 case _T('s'):
1786 {
1787 LPCTSTR pstrNextArg = va_arg(argList, LPCTSTR);
1788 if (pstrNextArg == NULL)
1789 {
1790 nItemLen = 6; // "(null)"
1791 }
1792 else
1793 {
1794 nItemLen = lstrlen(pstrNextArg);
1795 nItemLen = __max(1, nItemLen);
1796 }
1797 break;
1798 }
1799
1800 case _T('S'):
1801 {
1802 #ifndef _UNICODE
1803 LPWSTR pstrNextArg = va_arg(argList, LPWSTR);
1804 if (pstrNextArg == NULL)
1805 {
1806 nItemLen = 6; // "(null)"
1807 }
1808 else
1809 {
1810 nItemLen = (int)wcslen(pstrNextArg);
1811 nItemLen = __max(1, nItemLen);
1812 }
1813 #else // _UNICODE
1814 LPCSTR pstrNextArg = va_arg(argList, LPCSTR);
1815 if (pstrNextArg == NULL)
1816 {
1817 nItemLen = 6; // "(null)"
1818 }
1819 else
1820 {
1821 #if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800)
1822 nItemLen = ATL::lstrlenA(pstrNextArg);
1823 #else
1824 nItemLen = lstrlenA(pstrNextArg);
1825 #endif
1826 nItemLen = __max(1, nItemLen);
1827 }
1828 #endif // _UNICODE
1829 break;
1830 }
1831
1832 case _T('s') | FORCE_ANSI:
1833 case _T('S') | FORCE_ANSI:
1834 {
1835 LPCSTR pstrNextArg = va_arg(argList, LPCSTR);
1836 if (pstrNextArg == NULL)
1837 {
1838 nItemLen = 6; // "(null)"
1839 }
1840 else
1841 {
1842 #if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800)
1843 nItemLen = ATL::lstrlenA(pstrNextArg);
1844 #else
1845 nItemLen = lstrlenA(pstrNextArg);
1846 #endif
1847 nItemLen = __max(1, nItemLen);
1848 }
1849 break;
1850 }
1851
1852 case _T('s') | FORCE_UNICODE:
1853 case _T('S') | FORCE_UNICODE:
1854 {
1855 LPWSTR pstrNextArg = va_arg(argList, LPWSTR);
1856 if (pstrNextArg == NULL)
1857 {
1858 nItemLen = 6; // "(null)"
1859 }
1860 else
1861 {
1862 nItemLen = (int)wcslen(pstrNextArg);
1863 nItemLen = __max(1, nItemLen);
1864 }
1865 break;
1866 }
1867 }
1868
1869 // adjust nItemLen for strings
1870 if (nItemLen != 0)
1871 {
1872 nItemLen = __max(nItemLen, nWidth);
1873 if (nPrecision != 0)
1874 nItemLen = __min(nItemLen, nPrecision);
1875 }
1876 else
1877 {
1878 switch (*lpsz)
1879 {
1880 // integers
1881 case _T('d'):
1882 case _T('i'):
1883 case _T('u'):
1884 case _T('x'):
1885 case _T('X'):
1886 case _T('o'):
1887 if (nModifier & FORCE_INT64)
1888 va_arg(argList, __int64);
1889 else
1890 va_arg(argList, int);
1891 nItemLen = 32;
1892 nItemLen = __max(nItemLen, nWidth + nPrecision);
1893 break;
1894
1895 #ifndef _ATL_USE_CSTRING_FLOAT
1896 case _T('e'):
1897 case _T('E'):
1898 case _T('f'):
1899 case _T('g'):
1900 case _T('G'):
1901 ATLASSERT(!"Floating point (%%e, %%E, %%f, %%g, and %%G) is not supported by the WTL::CString class.");
1902 #ifndef _DEBUG
1903 ::OutputDebugString(_T("Floating point (%%e, %%f, %%g, and %%G) is not supported by the WTL::CString class."));
1904 #ifndef _WIN32_WCE
1905 ::DebugBreak();
1906 #else // CE specific
1907 DebugBreak();
1908 #endif // _WIN32_WCE
1909 #endif // !_DEBUG
1910 break;
1911 #else // _ATL_USE_CSTRING_FLOAT
1912 case _T('e'):
1913 case _T('E'):
1914 case _T('g'):
1915 case _T('G'):
1916 va_arg(argList, double);
1917 nItemLen = 128;
1918 nItemLen = __max(nItemLen, nWidth + nPrecision);
1919 break;
1920 case _T('f'):
1921 {
1922 double f = va_arg(argList, double);
1923 // 312 == strlen("-1+(309 zeroes).")
1924 // 309 zeroes == max precision of a double
1925 // 6 == adjustment in case precision is not specified,
1926 // which means that the precision defaults to 6
1927 int cchLen = __max(nWidth, 312 + nPrecision + 6);
1928 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
1929 LPTSTR pszTemp = buff.Allocate(cchLen);
1930 if(pszTemp != NULL)
1931 {
1932 SecureHelper::sprintf_x(pszTemp, cchLen, _T("%*.*f"), nWidth, nPrecision + 6, f);
1933 nItemLen = (int)_tcslen(pszTemp);
1934 }
1935 else
1936 {
1937 nItemLen = cchLen;
1938 }
1939 }
1940 break;
1941 #endif // _ATL_USE_CSTRING_FLOAT
1942
1943 case _T('p'):
1944 va_arg(argList, void*);
1945 nItemLen = 32;
1946 nItemLen = __max(nItemLen, nWidth + nPrecision);
1947 break;
1948
1949 // no output
1950 case _T('n'):
1951 va_arg(argList, int*);
1952 break;
1953
1954 default:
1955 ATLASSERT(FALSE); // unknown formatting option
1956 }
1957 }
1958
1959 // adjust nMaxLen for output nItemLen
1960 nMaxLen += nItemLen;
1961 }
1962
1963 if(GetBuffer(nMaxLen) == NULL)
1964 return FALSE;
1965 #ifndef _ATL_USE_CSTRING_FLOAT
1966 int nRet = SecureHelper::wvsprintf_x(m_pchData, GetAllocLength() + 1, lpszFormat, argListSave);
1967 #else // _ATL_USE_CSTRING_FLOAT
1968 int nRet = SecureHelper::vsprintf_x(m_pchData, GetAllocLength() + 1, lpszFormat, argListSave);
1969 #endif // _ATL_USE_CSTRING_FLOAT
1970 nRet; // ref
1971 ATLASSERT(nRet <= GetAllocLength());
1972 ReleaseBuffer();
1973
1974 va_end(argListSave);
1975 return TRUE;
1976 }
1977
1978 // formatting for localization (uses FormatMessage API)
1979 // formatting (using FormatMessage style formatting)
1980 BOOL __cdecl FormatMessage(LPCTSTR lpszFormat, ...)
1981 {
1982 // format message into temporary buffer lpszTemp
1983 va_list argList;
1984 va_start(argList, lpszFormat);
1985 LPTSTR lpszTemp = NULL;
1986 BOOL bRet = TRUE;
1987
1988 if ((::FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1989 lpszFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0) || (lpszTemp == NULL))
1990 bRet = FALSE;
1991
1992 // assign lpszTemp into the resulting string and free the temporary
1993 *this = lpszTemp;
1994 LocalFree(lpszTemp);
1995 va_end(argList);
1996 return bRet;
1997 }
1998
1999 BOOL __cdecl FormatMessage(UINT nFormatID, ...)
2000 {
2001 // get format string from string table
2002 CString strFormat;
2003 BOOL bRetTmp = strFormat.LoadString(nFormatID);
2004 bRetTmp; // ref
2005 ATLASSERT(bRetTmp != 0);
2006
2007 // format message into temporary buffer lpszTemp
2008 va_list argList;
2009 va_start(argList, nFormatID);
2010 LPTSTR lpszTemp = NULL;
2011 BOOL bRet = TRUE;
2012
2013 if ((::FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
2014 strFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0) || (lpszTemp == NULL))
2015 bRet = FALSE;
2016
2017 // assign lpszTemp into the resulting string and free lpszTemp
2018 *this = lpszTemp;
2019 LocalFree(lpszTemp);
2020 va_end(argList);
2021 return bRet;
2022 }
2023
2024 // Windows support
2025 BOOL LoadString(UINT nID) // load from string resource (255 chars max.)
2026 {
2027 #ifdef _UNICODE
2028 const int CHAR_FUDGE = 1; // one TCHAR unused is good enough
2029 #else
2030 const int CHAR_FUDGE = 2; // two BYTES unused for case of DBC last char
2031 #endif
2032
2033 // try fixed buffer first (to avoid wasting space in the heap)
2034 TCHAR szTemp[256] = { 0 };
2035 int nCount = sizeof(szTemp) / sizeof(szTemp[0]);
2036 int nLen = _LoadString(nID, szTemp, nCount);
2037 if (nCount - nLen > CHAR_FUDGE)
2038 {
2039 *this = szTemp;
2040 return (nLen > 0);
2041 }
2042
2043 // try buffer size of 512, then larger size until entire string is retrieved
2044 int nSize = 256;
2045 do
2046 {
2047 nSize += 256;
2048 LPTSTR lpstr = GetBuffer(nSize - 1);
2049 if(lpstr == NULL)
2050 {
2051 nLen = 0;
2052 break;
2053 }
2054 nLen = _LoadString(nID, lpstr, nSize);
2055 } while (nSize - nLen <= CHAR_FUDGE);
2056 ReleaseBuffer();
2057
2058 return (nLen > 0);
2059 }
2060
2061 #ifndef _UNICODE
2062 // ANSI <-> OEM support (convert string in place)
2063 void AnsiToOem()
2064 {
2065 CopyBeforeWrite();
2066 ::AnsiToOem(m_pchData, m_pchData);
2067 }
2068
2069 void OemToAnsi()
2070 {
2071 CopyBeforeWrite();
2072 ::OemToAnsi(m_pchData, m_pchData);
2073 }
2074 #endif
2075
2076 #ifndef _ATL_NO_COM
2077 // OLE BSTR support (use for OLE automation)
2078 BSTR AllocSysString() const
2079 {
2080 #if defined(_UNICODE) || defined(OLE2ANSI)
2081 BSTR bstr = ::SysAllocStringLen(m_pchData, GetData()->nDataLength);
2082 #else
2083 int nLen = MultiByteToWideChar(CP_ACP, 0, m_pchData,
2084 GetData()->nDataLength, NULL, NULL);
2085 BSTR bstr = ::SysAllocStringLen(NULL, nLen);
2086 if(bstr != NULL)
2087 MultiByteToWideChar(CP_ACP, 0, m_pchData, GetData()->nDataLength, bstr, nLen);
2088 #endif
2089 return bstr;
2090 }
2091
2092 BSTR SetSysString(BSTR* pbstr) const
2093 {
2094 #if defined(_UNICODE) || defined(OLE2ANSI)
2095 ::SysReAllocStringLen(pbstr, m_pchData, GetData()->nDataLength);
2096 #else
2097 int nLen = MultiByteToWideChar(CP_ACP, 0, m_pchData,
2098 GetData()->nDataLength, NULL, NULL);
2099 if(::SysReAllocStringLen(pbstr, NULL, nLen))
2100 MultiByteToWideChar(CP_ACP, 0, m_pchData, GetData()->nDataLength, *pbstr, nLen);
2101 #endif
2102 ATLASSERT(*pbstr != NULL);
2103 return *pbstr;
2104 }
2105 #endif // !_ATL_NO_COM
2106
2107 // Access to string implementation buffer as "C" character array
2108 LPTSTR GetBuffer(int nMinBufLength)
2109 {
2110 ATLASSERT(nMinBufLength >= 0);
2111
2112 if (GetData()->nRefs > 1 || nMinBufLength > GetData()->nAllocLength)
2113 {
2114 // we have to grow the buffer
2115 CStringData* pOldData = GetData();
2116 int nOldLen = GetData()->nDataLength; // AllocBuffer will tromp it
2117 if (nMinBufLength < nOldLen)
2118 nMinBufLength = nOldLen;
2119
2120 if(!AllocBuffer(nMinBufLength))
2121 return NULL;
2122
2123 SecureHelper::memcpy_x(m_pchData, (nMinBufLength + 1) * sizeof(TCHAR), pOldData->data(), (nOldLen + 1) * sizeof(TCHAR));
2124 GetData()->nDataLength = nOldLen;
2125 CString::Release(pOldData);
2126 }
2127 ATLASSERT(GetData()->nRefs <= 1);
2128
2129 // return a pointer to the character storage for this string
2130 ATLASSERT(m_pchData != NULL);
2131 return m_pchData;
2132 }
2133
2134 void ReleaseBuffer(int nNewLength = -1)
2135 {
2136 CopyBeforeWrite(); // just in case GetBuffer was not called
2137
2138 if (nNewLength == -1)
2139 nNewLength = lstrlen(m_pchData); // zero terminated
2140
2141 ATLASSERT(nNewLength <= GetData()->nAllocLength);
2142 GetData()->nDataLength = nNewLength;
2143 m_pchData[nNewLength] = _T('\0');
2144 }
2145
2146 LPTSTR GetBufferSetLength(int nNewLength)
2147 {
2148 ATLASSERT(nNewLength >= 0);
2149
2150 if(GetBuffer(nNewLength) == NULL)
2151 return NULL;
2152
2153 GetData()->nDataLength = nNewLength;
2154 m_pchData[nNewLength] = _T('\0');
2155 return m_pchData;
2156 }
2157
2158 void FreeExtra()
2159 {
2160 ATLASSERT(GetData()->nDataLength <= GetData()->nAllocLength);
2161 if (GetData()->nDataLength != GetData()->nAllocLength)
2162 {
2163 CStringData* pOldData = GetData();
2164 if(AllocBuffer(GetData()->nDataLength))
2165 {
2166 SecureHelper::memcpy_x(m_pchData, (GetData()->nAllocLength + 1) * sizeof(TCHAR), pOldData->data(), pOldData->nDataLength * sizeof(TCHAR));
2167 ATLASSERT(m_pchData[GetData()->nDataLength] == _T('\0'));
2168 CString::Release(pOldData);
2169 }
2170 }
2171 ATLASSERT(GetData() != NULL);
2172 }
2173
2174 // Use LockBuffer/UnlockBuffer to turn refcounting off
2175 LPTSTR LockBuffer()
2176 {
2177 LPTSTR lpsz = GetBuffer(0);
2178 if(lpsz != NULL)
2179 GetData()->nRefs = -1;
2180 return lpsz;
2181 }
2182
2183 void UnlockBuffer()
2184 {
2185 ATLASSERT(GetData()->nRefs == -1);
2186 if (GetData() != _atltmpDataNil)
2187 GetData()->nRefs = 1;
2188 }
2189
2190 // Implementation
2191 public:
2192 ~CString() // free any attached data
2193 {
2194 if (GetData() != _atltmpDataNil)
2195 {
2196 if (InterlockedDecrement(&GetData()->nRefs) <= 0)
2197 delete[] (BYTE*)GetData();
2198 }
2199 }
2200
2201 int GetAllocLength() const
2202 {
2203 return GetData()->nAllocLength;
2204 }
2205
2206 static BOOL __stdcall _IsValidString(LPCTSTR lpsz, int /*nLength*/ = -1)
2207 {
2208 return (lpsz != NULL) ? TRUE : FALSE;
2209 }
2210
2211 protected:
2212 LPTSTR m_pchData; // pointer to ref counted string data
2213
2214 // implementation helpers
2215 CStringData* GetData() const
2216 {
2217 ATLASSERT(m_pchData != NULL);
2218 return ((CStringData*)m_pchData) - 1;
2219 }
2220
2221 void Init()
2222 {
2223 m_pchData = _GetEmptyString().m_pchData;
2224 }
2225
2226 BOOL AllocCopy(CString& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const
2227 {
2228 // will clone the data attached to this string
2229 // allocating 'nExtraLen' characters
2230 // Places results in uninitialized string 'dest'
2231 // Will copy the part or all of original data to start of new string
2232
2233 BOOL bRet = FALSE;
2234 int nNewLen = nCopyLen + nExtraLen;
2235 if (nNewLen == 0)
2236 {
2237 dest.Init();
2238 bRet = TRUE;
2239 }
2240 else if(nNewLen >= nCopyLen)
2241 {
2242 if(dest.AllocBuffer(nNewLen))
2243 {
2244 SecureHelper::memcpy_x(dest.m_pchData, (nNewLen + 1) * sizeof(TCHAR), m_pchData + nCopyIndex, nCopyLen * sizeof(TCHAR));
2245 bRet = TRUE;
2246 }
2247 }
2248
2249 return bRet;
2250 }
2251
2252 // always allocate one extra character for '\0' termination
2253 // assumes [optimistically] that data length will equal allocation length
2254 BOOL AllocBuffer(int nLen)
2255 {
2256 ATLASSERT(nLen >= 0);
2257 ATLASSERT(nLen <= INT_MAX - 1); // max size (enough room for 1 extra)
2258
2259 if (nLen == 0)
2260 {
2261 Init();
2262 }
2263 else
2264 {
2265 CStringData* pData = NULL;
2266 ATLTRY(pData = (CStringData*)new BYTE[sizeof(CStringData) + (nLen + 1) * sizeof(TCHAR)]);
2267 if(pData == NULL)
2268 return FALSE;
2269
2270 pData->nRefs = 1;
2271 pData->data()[nLen] = _T('\0');
2272 pData->nDataLength = nLen;
2273 pData->nAllocLength = nLen;
2274 m_pchData = pData->data();
2275 }
2276
2277 return TRUE;
2278 }
2279
2280 // Assignment operators
2281 // All assign a new value to the string
2282 // (a) first see if the buffer is big enough
2283 // (b) if enough room, copy on top of old buffer, set size and type
2284 // (c) otherwise free old string data, and create a new one
2285 //
2286 // All routines return the new string (but as a 'const CString&' so that
2287 // assigning it again will cause a copy, eg: s1 = s2 = "hi there".
2288 //
2289 void AssignCopy(int nSrcLen, LPCTSTR lpszSrcData)
2290 {
2291 if(AllocBeforeWrite(nSrcLen))
2292 {
2293 SecureHelper::memcpy_x(m_pchData, (nSrcLen + 1) * sizeof(TCHAR), lpszSrcData, nSrcLen * sizeof(TCHAR));
2294 GetData()->nDataLength = nSrcLen;
2295 m_pchData[nSrcLen] = _T('\0');
2296 }
2297 }
2298
2299 // Concatenation
2300 // NOTE: "operator +" is done as friend functions for simplicity
2301 // There are three variants:
2302 // CString + CString
2303 // and for ? = TCHAR, LPCTSTR
2304 // CString + ?
2305 // ? + CString
2306 BOOL ConcatCopy(int nSrc1Len, LPCTSTR lpszSrc1Data, int nSrc2Len, LPCTSTR lpszSrc2Data)
2307 {
2308 // -- master concatenation routine
2309 // Concatenate two sources
2310 // -- assume that 'this' is a new CString object
2311
2312 BOOL bRet = TRUE;
2313 int nNewLen = nSrc1Len + nSrc2Len;
2314 if(nNewLen < nSrc1Len || nNewLen < nSrc2Len)
2315 {
2316 bRet = FALSE;
2317 }
2318 else if(nNewLen != 0)
2319 {
2320 bRet = AllocBuffer(nNewLen);
2321 if (bRet)
2322 {
2323 SecureHelper::memcpy_x(m_pchData, (nNewLen + 1) * sizeof(TCHAR), lpszSrc1Data, nSrc1Len * sizeof(TCHAR));
2324 SecureHelper::memcpy_x(m_pchData + nSrc1Len, (nNewLen + 1 - nSrc1Len) * sizeof(TCHAR), lpszSrc2Data, nSrc2Len * sizeof(TCHAR));
2325 }
2326 }
2327 return bRet;
2328 }
2329
2330 void ConcatInPlace(int nSrcLen, LPCTSTR lpszSrcData)
2331 {
2332 // -- the main routine for += operators
2333
2334 // concatenating an empty string is a no-op!
2335 if (nSrcLen == 0)
2336 return;
2337
2338 // if the buffer is too small, or we have a width mis-match, just
2339 // allocate a new buffer (slow but sure)
2340 if (GetData()->nRefs > 1 || GetData()->nDataLength + nSrcLen > GetData()->nAllocLength)
2341 {
2342 // we have to grow the buffer, use the ConcatCopy routine
2343 CStringData* pOldData = GetData();
2344 if (ConcatCopy(GetData()->nDataLength, m_pchData, nSrcLen, lpszSrcData))
2345 {
2346 ATLASSERT(pOldData != NULL);
2347 CString::Release(pOldData);
2348 }
2349 }
2350 else
2351 {
2352 // fast concatenation when buffer big enough
2353 SecureHelper::memcpy_x(m_pchData + GetData()->nDataLength, (GetData()->nAllocLength + 1) * sizeof(TCHAR), lpszSrcData, nSrcLen * sizeof(TCHAR));
2354 GetData()->nDataLength += nSrcLen;
2355 ATLASSERT(GetData()->nDataLength <= GetData()->nAllocLength);
2356 m_pchData[GetData()->nDataLength] = _T('\0');
2357 }
2358 }
2359
2360 void CopyBeforeWrite()
2361 {
2362 if (GetData()->nRefs > 1)
2363 {
2364 CStringData* pData = GetData();
2365 Release();
2366 if(AllocBuffer(pData->nDataLength))
2367 SecureHelper::memcpy_x(m_pchData, (GetData()->nAllocLength + 1) * sizeof(TCHAR), pData->data(), (pData->nDataLength + 1) * sizeof(TCHAR));
2368 }
2369 ATLASSERT(GetData()->nRefs <= 1);
2370 }
2371
2372 BOOL AllocBeforeWrite(int nLen)
2373 {
2374 BOOL bRet = TRUE;
2375 if (GetData()->nRefs > 1 || nLen > GetData()->nAllocLength)
2376 {
2377 Release();
2378 bRet = AllocBuffer(nLen);
2379 }
2380 ATLASSERT(GetData()->nRefs <= 1);
2381 return bRet;
2382 }
2383
2384 void Release()
2385 {
2386 if (GetData() != _atltmpDataNil)
2387 {
2388 ATLASSERT(GetData()->nRefs != 0);
2389 if (InterlockedDecrement(&GetData()->nRefs) <= 0)
2390 delete[] (BYTE*)GetData();
2391 Init();
2392 }
2393 }
2394
2395 static void PASCAL Release(CStringData* pData)
2396 {
2397 if (pData != _atltmpDataNil)
2398 {
2399 ATLASSERT(pData->nRefs != 0);
2400 if (InterlockedDecrement(&pData->nRefs) <= 0)
2401 delete[] (BYTE*)pData;
2402 }
2403 }
2404
2405 static int PASCAL SafeStrlen(LPCTSTR lpsz)
2406 {
2407 return (lpsz == NULL) ? 0 : lstrlen(lpsz);
2408 }
2409
2410 static int __stdcall _LoadString(UINT nID, LPTSTR lpszBuf, UINT nMaxBuf)
2411 {
2412 #ifdef _DEBUG
2413 // LoadString without annoying warning from the Debug kernel if the
2414 // segment containing the string is not present
2415 if (::FindResource(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE((nID >> 4) + 1), RT_STRING) == NULL)
2416 {
2417 lpszBuf[0] = _T('\0');
2418 return 0; // not found
2419 }
2420 #endif // _DEBUG
2421
2422 int nLen = ::LoadString(ModuleHelper::GetResourceInstance(), nID, lpszBuf, nMaxBuf);
2423 if (nLen == 0)
2424 lpszBuf[0] = _T('\0');
2425
2426 return nLen;
2427 }
2428
2429 static const CString& __stdcall _GetEmptyString()
2430 {
2431 return *(CString*)&_atltmpPchNil;
2432 }
2433
2434 // CString conversion helpers
2435 static int __cdecl _wcstombsz(char* mbstr, const wchar_t* wcstr, size_t count)
2436 {
2437 if (count == 0 && mbstr != NULL)
2438 return 0;
2439
2440 int result = ::WideCharToMultiByte(CP_ACP, 0, wcstr, -1, mbstr, (int)count, NULL, NULL);
2441 ATLASSERT(mbstr == NULL || result <= (int)count);
2442 if ((mbstr != NULL) && (result > 0))
2443 mbstr[result - 1] = 0;
2444 return result;
2445 }
2446
2447 static int __cdecl _mbstowcsz(wchar_t* wcstr, const char* mbstr, size_t count)
2448 {
2449 if (count == 0 && wcstr != NULL)
2450 return 0;
2451
2452 int result = ::MultiByteToWideChar(CP_ACP, 0, mbstr, -1, wcstr, (int)count);
2453 ATLASSERT(wcstr == NULL || result <= (int)count);
2454 if ((wcstr != NULL) && (result > 0))
2455 wcstr[result - 1] = 0;
2456 return result;
2457 }
2458
2459 // Helpers to avoid CRT startup code
2460 #ifdef _ATL_MIN_CRT
2461 static const TCHAR* _cstrchr(const TCHAR* p, TCHAR ch)
2462 {
2463 // strchr for '\0' should succeed
2464 while (*p != 0)
2465 {
2466 if (*p == ch)
2467 break;
2468 p = ::CharNext(p);
2469 }
2470 return (*p == ch) ? p : NULL;
2471 }
2472
2473 static TCHAR* _cstrrev(TCHAR* pStr)
2474 {
2475 // optimize NULL, zero-length, and single-char case
2476 if ((pStr == NULL) || (pStr[0] == _T('\0')) || (pStr[1] == _T('\0')))
2477 return pStr;
2478
2479 TCHAR* p = pStr;
2480
2481 while (*p != 0)
2482 {
2483 TCHAR* pNext = ::CharNext(p);
2484 if(pNext > p + 1)
2485 {
2486 char p1 = *(char*)p;
2487 *(char*)p = *(char*)(p + 1);
2488 *(char*)(p + 1) = p1;
2489 }
2490 p = pNext;
2491 }
2492
2493 p--;
2494 TCHAR* q = pStr;
2495
2496 while (q < p)
2497 {
2498 TCHAR t = *q;
2499 *q = *p;
2500 *p = t;
2501 q++;
2502 p--;
2503 }
2504 return pStr;
2505 }
2506
2507 static const TCHAR* _cstrstr(const TCHAR* pStr, const TCHAR* pCharSet)
2508 {
2509 int nLen = lstrlen(pCharSet);
2510 if (nLen == 0)
2511 return (TCHAR*)pStr;
2512
2513 const TCHAR* pRet = NULL;
2514 const TCHAR* pCur = pStr;
2515 while((pCur = _cstrchr(pCur, *pCharSet)) != NULL)
2516 {
2517 if(memcmp(pCur, pCharSet, nLen * sizeof(TCHAR)) == 0)
2518 {
2519 pRet = pCur;
2520 break;
2521 }
2522 pCur = ::CharNext(pCur);
2523 }
2524 return pRet;
2525 }
2526
2527 static int _cstrspn(const TCHAR* pStr, const TCHAR* pCharSet)
2528 {
2529 int nRet = 0;
2530 const TCHAR* p = pStr;
2531 while (*p != 0)
2532 {
2533 const TCHAR* pNext = ::CharNext(p);
2534 if(pNext > p + 1)
2535 {
2536 if(_cstrchr_db(pCharSet, *p, *(p + 1)) == NULL)
2537 break;
2538 nRet += 2;
2539 }
2540 else
2541 {
2542 if(_cstrchr(pCharSet, *p) == NULL)
2543 break;
2544 nRet++;
2545 }
2546 p = pNext;
2547 }
2548 return nRet;
2549 }
2550
2551 static int _cstrcspn(const TCHAR* pStr, const TCHAR* pCharSet)
2552 {
2553 int nRet = 0;
2554 TCHAR* p = (TCHAR*)pStr;
2555 while (*p != 0)
2556 {
2557 TCHAR* pNext = ::CharNext(p);
2558 if(pNext > p + 1)
2559 {
2560 if(_cstrchr_db(pCharSet, *p, *(p + 1)) != NULL)
2561 break;
2562 nRet += 2;
2563 }
2564 else
2565 {
2566 if(_cstrchr(pCharSet, *p) != NULL)
2567 break;
2568 nRet++;
2569 }
2570 p = pNext;
2571 }
2572 return nRet;
2573 }
2574
2575 static const TCHAR* _cstrpbrk(const TCHAR* p, const TCHAR* lpszCharSet)
2576 {
2577 int n = _cstrcspn(p, lpszCharSet);
2578 return (p[n] != 0) ? &p[n] : NULL;
2579 }
2580
2581 static int _cstrcmp(const TCHAR* pstrOne, const TCHAR* pstrOther)
2582 {
2583 return lstrcmp(pstrOne, pstrOther);
2584 }
2585
2586 static int _cstrcmpi(const TCHAR* pstrOne, const TCHAR* pstrOther)
2587 {
2588 return lstrcmpi(pstrOne, pstrOther);
2589 }
2590
2591 static int _cstrcoll(const TCHAR* pstrOne, const TCHAR* pstrOther)
2592 {
2593 int nRet = CompareString(GetThreadLocale(), 0, pstrOne, -1, pstrOther, -1);
2594 ATLASSERT(nRet != 0);
2595 return nRet - 2; // convert to strcmp convention
2596 }
2597
2598 static int _cstrcolli(const TCHAR* pstrOne, const TCHAR* pstrOther)
2599 {
2600 int nRet = CompareString(GetThreadLocale(), NORM_IGNORECASE, pstrOne, -1, pstrOther, -1);
2601 ATLASSERT(nRet != 0);
2602 return nRet - 2; // convert to strcmp convention
2603 }
2604 #else // !_ATL_MIN_CRT
2605 static const TCHAR* _cstrchr(const TCHAR* p, TCHAR ch)
2606 {
2607 return _tcschr(p, ch);
2608 }
2609
2610 static TCHAR* _cstrrev(TCHAR* pStr)
2611 {
2612 return _tcsrev(pStr);
2613 }
2614
2615 static const TCHAR* _cstrstr(const TCHAR* pStr, const TCHAR* pCharSet)
2616 {
2617 return _tcsstr(pStr, pCharSet);
2618 }
2619
2620 static int _cstrspn(const TCHAR* pStr, const TCHAR* pCharSet)
2621 {
2622 return (int)_tcsspn(pStr, pCharSet);
2623 }
2624
2625 static int _cstrcspn(const TCHAR* pStr, const TCHAR* pCharSet)
2626 {
2627 return (int)_tcscspn(pStr, pCharSet);
2628 }
2629
2630 static const TCHAR* _cstrpbrk(const TCHAR* p, const TCHAR* lpszCharSet)
2631 {
2632 return _tcspbrk(p, lpszCharSet);
2633 }
2634
2635 static int _cstrcmp(const TCHAR* pstrOne, const TCHAR* pstrOther)
2636 {
2637 return _tcscmp(pstrOne, pstrOther);
2638 }
2639
2640 static int _cstrcmpi(const TCHAR* pstrOne, const TCHAR* pstrOther)
2641 {
2642 return _tcsicmp(pstrOne, pstrOther);
2643 }
2644
2645 #ifndef _WIN32_WCE
2646 static int _cstrcoll(const TCHAR* pstrOne, const TCHAR* pstrOther)
2647 {
2648 return _tcscoll(pstrOne, pstrOther);
2649 }
2650
2651 static int _cstrcolli(const TCHAR* pstrOne, const TCHAR* pstrOther)
2652 {
2653 return _tcsicoll(pstrOne, pstrOther);
2654 }
2655 #endif // !_WIN32_WCE
2656 #endif // !_ATL_MIN_CRT
2657
2658 static const TCHAR* _cstrrchr(const TCHAR* p, TCHAR ch)
2659 {
2660 return MinCrtHelper::_strrchr(p, ch);
2661 }
2662
2663 static int _cstrisdigit(TCHAR ch)
2664 {
2665 return MinCrtHelper::_isdigit(ch);
2666 }
2667
2668 static int _cstrisspace(TCHAR ch)
2669 {
2670 return MinCrtHelper::_isspace(ch);
2671 }
2672
2673 static int _cstrtoi(const TCHAR* nptr)
2674 {
2675 return MinCrtHelper::_atoi(nptr);
2676 }
2677
2678 static const TCHAR* _cstrchr_db(const TCHAR* p, TCHAR ch1, TCHAR ch2)
2679 {
2680 const TCHAR* lpsz = NULL;
2681 while (*p != 0)
2682 {
2683 if (*p == ch1 && *(p + 1) == ch2)
2684 {
2685 lpsz = p;
2686 break;
2687 }
2688 p = ::CharNext(p);
2689 }
2690 return lpsz;
2691 }
2692 };
2693
2694
2695 // Compare helpers
2696
2697 inline bool __stdcall operator ==(const CString& s1, const CString& s2)
2698 { return s1.Compare(s2) == 0; }
2699
2700 inline bool __stdcall operator ==(const CString& s1, LPCTSTR s2)
2701 { return s1.Compare(s2) == 0; }
2702
2703 inline bool __stdcall operator ==(LPCTSTR s1, const CString& s2)
2704 { return s2.Compare(s1) == 0; }
2705
2706 inline bool __stdcall operator !=(const CString& s1, const CString& s2)
2707 { return s1.Compare(s2) != 0; }
2708
2709 inline bool __stdcall operator !=(const CString& s1, LPCTSTR s2)
2710 { return s1.Compare(s2) != 0; }
2711
2712 inline bool __stdcall operator !=(LPCTSTR s1, const CString& s2)
2713 { return s2.Compare(s1) != 0; }
2714
2715 inline bool __stdcall operator <(const CString& s1, const CString& s2)
2716 { return s1.Compare(s2) < 0; }
2717
2718 inline bool __stdcall operator <(const CString& s1, LPCTSTR s2)
2719 { return s1.Compare(s2) < 0; }
2720
2721 inline bool __stdcall operator <(LPCTSTR s1, const CString& s2)
2722 { return s2.Compare(s1) > 0; }
2723
2724 inline bool __stdcall operator >(const CString& s1, const CString& s2)
2725 { return s1.Compare(s2) > 0; }
2726
2727 inline bool __stdcall operator >(const CString& s1, LPCTSTR s2)
2728 { return s1.Compare(s2) > 0; }
2729
2730 inline bool __stdcall operator >(LPCTSTR s1, const CString& s2)
2731 { return s2.Compare(s1) < 0; }
2732
2733 inline bool __stdcall operator <=(const CString& s1, const CString& s2)
2734 { return s1.Compare(s2) <= 0; }
2735
2736 inline bool __stdcall operator <=(const CString& s1, LPCTSTR s2)
2737 { return s1.Compare(s2) <= 0; }
2738
2739 inline bool __stdcall operator <=(LPCTSTR s1, const CString& s2)
2740 { return s2.Compare(s1) >= 0; }
2741
2742 inline bool __stdcall operator >=(const CString& s1, const CString& s2)
2743 { return s1.Compare(s2) >= 0; }
2744
2745 inline bool __stdcall operator >=(const CString& s1, LPCTSTR s2)
2746 { return s1.Compare(s2) >= 0; }
2747
2748 inline bool __stdcall operator >=(LPCTSTR s1, const CString& s2)
2749 { return s2.Compare(s1) <= 0; }
2750
2751
2752 // CString "operator +" functions
2753
2754 inline CString __stdcall operator +(const CString& string1, const CString& string2)
2755 {
2756 CString s;
2757 s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, string2.GetData()->nDataLength, string2.m_pchData);
2758 return s;
2759 }
2760
2761 inline CString __stdcall operator +(const CString& string, TCHAR ch)
2762 {
2763 CString s;
2764 s.ConcatCopy(string.GetData()->nDataLength, string.m_pchData, 1, &ch);
2765 return s;
2766 }
2767
2768 inline CString __stdcall operator +(TCHAR ch, const CString& string)
2769 {
2770 CString s;
2771 s.ConcatCopy(1, &ch, string.GetData()->nDataLength, string.m_pchData);
2772 return s;
2773 }
2774
2775 #ifdef _UNICODE
2776 inline CString __stdcall operator +(const CString& string, char ch)
2777 {
2778 return string + (TCHAR)ch;
2779 }
2780
2781 inline CString __stdcall operator +(char ch, const CString& string)
2782 {
2783 return (TCHAR)ch + string;
2784 }
2785 #endif // _UNICODE
2786
2787 inline CString __stdcall operator +(const CString& string, LPCTSTR lpsz)
2788 {
2789 ATLASSERT(lpsz == NULL || CString::_IsValidString(lpsz));
2790 CString s;
2791 s.ConcatCopy(string.GetData()->nDataLength, string.m_pchData, CString::SafeStrlen(lpsz), lpsz);
2792 return s;
2793 }
2794
2795 inline CString __stdcall operator +(LPCTSTR lpsz, const CString& string)
2796 {
2797 ATLASSERT(lpsz == NULL || CString::_IsValidString(lpsz));
2798 CString s;
2799 s.ConcatCopy(CString::SafeStrlen(lpsz), lpsz, string.GetData()->nDataLength, string.m_pchData);
2800 return s;
2801 }
2802
2803 #endif // !_WTL_NO_CSTRING
2804
2805
2806 ///////////////////////////////////////////////////////////////////////////////
2807 // CRecentDocumentList - MRU List Support
2808
2809 #ifndef _WIN32_WCE
2810
2811 #ifndef _WTL_MRUEMPTY_TEXT
2812 #define _WTL_MRUEMPTY_TEXT _T("(empty)")
2813 #endif
2814
2815 // forward declaration
2816 inline bool AtlCompactPath(LPTSTR lpstrOut, LPCTSTR lpstrIn, int cchLen);
2817
2818 template <class T, int t_cchItemLen = MAX_PATH, int t_nFirstID = ID_FILE_MRU_FIRST, int t_nLastID = ID_FILE_MRU_LAST>
2819 class CRecentDocumentListBase
2820 {
2821 public:
2822 // Declarations
2823 struct _DocEntry
2824 {
2825 TCHAR szDocName[t_cchItemLen];
2826 bool operator ==(const _DocEntry& de) const
2827 { return (lstrcmpi(szDocName, de.szDocName) == 0); }
2828 };
2829
2830 enum
2831 {
2832 m_nMaxEntries_Min = 2,
2833 m_nMaxEntries_Max = t_nLastID - t_nFirstID + 1,
2834 m_cchMaxItemLen_Min = 6,
2835 m_cchMaxItemLen_Max = t_cchItemLen,
2836 m_cchItemNameLen = 11
2837 };
2838
2839 // Data members
2840 ATL::CSimpleArray<_DocEntry> m_arrDocs;
2841 int m_nMaxEntries; // default is 4
2842 HMENU m_hMenu;
2843
2844 TCHAR m_szNoEntries[t_cchItemLen];
2845
2846 int m_cchMaxItemLen;
2847
2848 // Constructor
2849 CRecentDocumentListBase() : m_hMenu(NULL), m_nMaxEntries(4), m_cchMaxItemLen(-1)
2850 {
2851 // These ASSERTs verify values of the template arguments
2852 ATLASSERT(t_cchItemLen > m_cchMaxItemLen_Min);
2853 ATLASSERT(m_nMaxEntries_Max > m_nMaxEntries_Min);
2854 }
2855
2856 // Attributes
2857 HMENU GetMenuHandle() const
2858 {
2859 return m_hMenu;
2860 }
2861
2862 void SetMenuHandle(HMENU hMenu)
2863 {
2864 ATLASSERT(hMenu == NULL || ::IsMenu(hMenu));
2865 m_hMenu = hMenu;
2866 if(m_hMenu == NULL || (::GetMenuString(m_hMenu, t_nFirstID, m_szNoEntries, t_cchItemLen, MF_BYCOMMAND) == 0))
2867 {
2868 T* pT = static_cast<T*>(this);
2869 pT; // avoid level 4 warning
2870 SecureHelper::strncpy_x(m_szNoEntries, _countof(m_szNoEntries), pT->GetMRUEmptyText(), _TRUNCATE);
2871 }
2872 }
2873
2874 int GetMaxEntries() const
2875 {
2876 return m_nMaxEntries;
2877 }
2878
2879 void SetMaxEntries(int nMaxEntries)
2880 {
2881 ATLASSERT(nMaxEntries >= m_nMaxEntries_Min && nMaxEntries <= m_nMaxEntries_Max);
2882 if(nMaxEntries < m_nMaxEntries_Min)
2883 nMaxEntries = m_nMaxEntries_Min;
2884 else if(nMaxEntries > m_nMaxEntries_Max)
2885 nMaxEntries = m_nMaxEntries_Max;
2886 m_nMaxEntries = nMaxEntries;
2887 }
2888
2889 int GetMaxItemLength() const
2890 {
2891 return m_cchMaxItemLen;
2892 }
2893
2894 void SetMaxItemLength(int cchMaxLen)
2895 {
2896 ATLASSERT((cchMaxLen >= m_cchMaxItemLen_Min && cchMaxLen <= m_cchMaxItemLen_Max) || cchMaxLen == -1);
2897 if(cchMaxLen != -1)
2898 {
2899 if(cchMaxLen < m_cchMaxItemLen_Min)
2900 cchMaxLen = m_cchMaxItemLen_Min;
2901 else if(cchMaxLen > m_cchMaxItemLen_Max)
2902 cchMaxLen = m_cchMaxItemLen_Max;
2903 }
2904 m_cchMaxItemLen = cchMaxLen;
2905 T* pT = static_cast<T*>(this);
2906 pT->UpdateMenu();
2907 }
2908
2909 // Operations
2910 BOOL AddToList(LPCTSTR lpstrDocName)
2911 {
2912 _DocEntry de;
2913 errno_t nRet = SecureHelper::strncpy_x(de.szDocName, _countof(de.szDocName), lpstrDocName, _TRUNCATE);
2914 if(nRet != 0 && nRet != STRUNCATE)
2915 return FALSE;
2916
2917 for(int i = 0; i < m_arrDocs.GetSize(); i++)
2918 {
2919 if(lstrcmpi(m_arrDocs[i].szDocName, lpstrDocName) == 0)
2920 {
2921 m_arrDocs.RemoveAt(i);
2922 break;
2923 }
2924 }
2925
2926 if(m_arrDocs.GetSize() == m_nMaxEntries)
2927 m_arrDocs.RemoveAt(0);
2928
2929 BOOL bRet = m_arrDocs.Add(de);
2930 if(bRet)
2931 {
2932 T* pT = static_cast<T*>(this);
2933 bRet = pT->UpdateMenu();
2934 }
2935 return bRet;
2936 }
2937
2938 // This function is deprecated because it is not safe.
2939 // Use the version below that accepts the buffer length.
2940 #if (_MSC_VER >= 1300)
2941 __declspec(deprecated)
2942 #endif
2943 BOOL GetFromList(int /*nItemID*/, LPTSTR /*lpstrDocName*/)
2944 {
2945 ATLASSERT(FALSE);
2946 return FALSE;
2947 }
2948
2949 BOOL GetFromList(int nItemID, LPTSTR lpstrDocName, int cchLength)
2950 {
2951 int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1;
2952 if(nIndex < 0 || nIndex >= m_arrDocs.GetSize())
2953 return FALSE;
2954 if(lstrlen(m_arrDocs[nIndex].szDocName) >= cchLength)
2955 return FALSE;
2956 SecureHelper::strcpy_x(lpstrDocName, cchLength, m_arrDocs[nIndex].szDocName);
2957
2958 return TRUE;
2959 }
2960
2961 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
2962 BOOL GetFromList(int nItemID, _CSTRING_NS::CString& strDocName)
2963 {
2964 int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1;
2965 if(nIndex < 0 || nIndex >= m_arrDocs.GetSize())
2966 return FALSE;
2967 strDocName = m_arrDocs[nIndex].szDocName;
2968 return TRUE;
2969 }
2970 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
2971
2972 BOOL RemoveFromList(int nItemID)
2973 {
2974 int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1;
2975 BOOL bRet = m_arrDocs.RemoveAt(nIndex);
2976 if(bRet)
2977 {
2978 T* pT = static_cast<T*>(this);
2979 bRet = pT->UpdateMenu();
2980 }
2981 return bRet;
2982 }
2983
2984 BOOL MoveToTop(int nItemID)
2985 {
2986 int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1;
2987 if(nIndex < 0 || nIndex >= m_arrDocs.GetSize())
2988 return FALSE;
2989 _DocEntry de;
2990 de = m_arrDocs[nIndex];
2991 m_arrDocs.RemoveAt(nIndex);
2992 BOOL bRet = m_arrDocs.Add(de);
2993 if(bRet)
2994 {
2995 T* pT = static_cast<T*>(this);
2996 bRet = pT->UpdateMenu();
2997 }
2998 return bRet;
2999 }
3000
3001 BOOL ReadFromRegistry(LPCTSTR lpstrRegKey)
3002 {
3003 T* pT = static_cast<T*>(this);
3004 CRegKeyEx rkParent;
3005 CRegKeyEx rk;
3006
3007 LONG lRet = rkParent.Open(HKEY_CURRENT_USER, lpstrRegKey);
3008 if(lRet != ERROR_SUCCESS)
3009 return FALSE;
3010 lRet = rk.Open(rkParent, pT->GetRegKeyName());
3011 if(lRet != ERROR_SUCCESS)
3012 return FALSE;
3013
3014 DWORD dwRet = 0;
3015 lRet = rk.QueryDWORDValue(pT->GetRegCountName(), dwRet);
3016 if(lRet != ERROR_SUCCESS)
3017 return FALSE;
3018 SetMaxEntries(dwRet);
3019
3020 m_arrDocs.RemoveAll();
3021
3022 TCHAR szRetString[t_cchItemLen] = { 0 };
3023 _DocEntry de;
3024
3025 for(int nItem = m_nMaxEntries; nItem > 0; nItem--)
3026 {
3027 TCHAR szBuff[m_cchItemNameLen] = { 0 };
3028 SecureHelper::wsprintf_x(szBuff, m_cchItemNameLen, pT->GetRegItemName(), nItem);
3029 ULONG ulCount = t_cchItemLen;
3030 lRet = rk.QueryStringValue(szBuff, szRetString, &ulCount);
3031 if(lRet == ERROR_SUCCESS)
3032 {
3033 SecureHelper::strcpy_x(de.szDocName, _countof(de.szDocName), szRetString);
3034 m_arrDocs.Add(de);
3035 }
3036 }
3037
3038 rk.Close();
3039 rkParent.Close();
3040
3041 return pT->UpdateMenu();
3042 }
3043
3044 BOOL WriteToRegistry(LPCTSTR lpstrRegKey)
3045 {
3046 T* pT = static_cast<T*>(this);
3047 pT; // avoid level 4 warning
3048 CRegKeyEx rkParent;
3049 CRegKeyEx rk;
3050
3051 LONG lRet = rkParent.Create(HKEY_CURRENT_USER, lpstrRegKey);
3052 if(lRet != ERROR_SUCCESS)
3053 return FALSE;
3054 lRet = rk.Create(rkParent, pT->GetRegKeyName());
3055 if(lRet != ERROR_SUCCESS)
3056 return FALSE;
3057
3058 lRet = rk.SetDWORDValue(pT->GetRegCountName(), m_nMaxEntries);
3059 ATLASSERT(lRet == ERROR_SUCCESS);
3060
3061 // set new values
3062 int nItem;
3063 for(nItem = m_arrDocs.GetSize(); nItem > 0; nItem--)
3064 {
3065 TCHAR szBuff[m_cchItemNameLen] = { 0 };
3066 SecureHelper::wsprintf_x(szBuff, m_cchItemNameLen, pT->GetRegItemName(), nItem);
3067 TCHAR szDocName[t_cchItemLen] = { 0 };
3068 GetFromList(t_nFirstID + nItem - 1, szDocName, t_cchItemLen);
3069 lRet = rk.SetStringValue(szBuff, szDocName);
3070 ATLASSERT(lRet == ERROR_SUCCESS);
3071 }
3072
3073 // delete unused keys
3074 for(nItem = m_arrDocs.GetSize() + 1; nItem <= m_nMaxEntries_Max; nItem++)
3075 {
3076 TCHAR szBuff[m_cchItemNameLen] = { 0 };
3077 SecureHelper::wsprintf_x(szBuff, m_cchItemNameLen, pT->GetRegItemName(), nItem);
3078 rk.DeleteValue(szBuff);
3079 }
3080
3081 rk.Close();
3082 rkParent.Close();
3083
3084 return TRUE;
3085 }
3086
3087 // Implementation
3088 BOOL UpdateMenu()
3089 {
3090 if(m_hMenu == NULL)
3091 return FALSE;
3092 ATLASSERT(::IsMenu(m_hMenu));
3093
3094 int nItems = ::GetMenuItemCount(m_hMenu);
3095 int nInsertPoint = 0;
3096 for(int i = 0; i < nItems; i++)
3097 {
3098 CMenuItemInfo mi;
3099 mi.fMask = MIIM_ID;
3100 ::GetMenuItemInfo(m_hMenu, i, TRUE, &mi);
3101 if (mi.wID == t_nFirstID)
3102 {
3103 nInsertPoint = i;
3104 break;
3105 }
3106 }
3107
3108 ATLASSERT(nInsertPoint < nItems && "You need a menu item with an ID = t_nFirstID");
3109
3110 for(int j = t_nFirstID; j < (t_nFirstID + m_nMaxEntries); j++)
3111 {
3112 // keep the first one as an insertion point
3113 if (j != t_nFirstID)
3114 ::DeleteMenu(m_hMenu, j, MF_BYCOMMAND);
3115 }
3116
3117 TCHAR szItemText[t_cchItemLen + 6] = { 0 }; // add space for &, 2 digits, and a space
3118 int nSize = m_arrDocs.GetSize();
3119 int nItem = 0;
3120 if(nSize > 0)
3121 {
3122 for(nItem = 0; nItem < nSize; nItem++)
3123 {
3124 if(m_cchMaxItemLen == -1)
3125 {
3126 SecureHelper::wsprintf_x(szItemText, t_cchItemLen + 6, _T("&%i %s"), nItem + 1, m_arrDocs[nSize - 1 - nItem].szDocName);
3127 }
3128 else
3129 {
3130 TCHAR szBuff[t_cchItemLen] = { 0 };
3131 T* pT = static_cast<T*>(this);
3132 pT; // avoid level 4 warning
3133 bool bRet = pT->CompactDocumentName(szBuff, m_arrDocs[nSize - 1 - nItem].szDocName, m_cchMaxItemLen);
3134 bRet; // avoid level 4 warning
3135 ATLASSERT(bRet);
3136 SecureHelper::wsprintf_x(szItemText, t_cchItemLen + 6, _T("&%i %s"), nItem + 1, szBuff);
3137 }
3138
3139 ::InsertMenu(m_hMenu, nInsertPoint + nItem, MF_BYPOSITION | MF_STRING, t_nFirstID + nItem, szItemText);
3140 }
3141 }
3142 else // empty
3143 {
3144 ::InsertMenu(m_hMenu, nInsertPoint, MF_BYPOSITION | MF_STRING, t_nFirstID, m_szNoEntries);
3145 ::EnableMenuItem(m_hMenu, t_nFirstID, MF_GRAYED);
3146 nItem++;
3147 }
3148 ::DeleteMenu(m_hMenu, nInsertPoint + nItem, MF_BYPOSITION);
3149
3150 return TRUE;
3151 }
3152
3153 // Overrideables
3154 // override to provide a different method of compacting document names
3155 static bool CompactDocumentName(LPTSTR lpstrOut, LPCTSTR lpstrIn, int cchLen)
3156 {
3157 return AtlCompactPath(lpstrOut, lpstrIn, cchLen);
3158 }
3159
3160 static LPCTSTR GetRegKeyName()
3161 {
3162 return _T("Recent Document List");
3163 }
3164
3165 static LPCTSTR GetRegCountName()
3166 {
3167 return _T("DocumentCount");
3168 }
3169
3170 static LPCTSTR GetRegItemName()
3171 {
3172 // Note: This string is a format string used with wsprintf().
3173 // Resulting formatted string must be m_cchItemNameLen or less
3174 // characters long, including the terminating null character.
3175 return _T("Document%i");
3176 }
3177
3178 static LPCTSTR GetMRUEmptyText()
3179 {
3180 return _WTL_MRUEMPTY_TEXT;
3181 }
3182 };
3183
3184 class CRecentDocumentList : public CRecentDocumentListBase<CRecentDocumentList>
3185 {
3186 public:
3187 // nothing here
3188 };
3189
3190 #endif // _WIN32_WCE
3191
3192
3193 ///////////////////////////////////////////////////////////////////////////////
3194 // CFindFile - file search helper class
3195
3196 class CFindFile
3197 {
3198 public:
3199 // Data members
3200 WIN32_FIND_DATA m_fd;
3201 TCHAR m_lpszRoot[MAX_PATH];
3202 TCHAR m_chDirSeparator;
3203 HANDLE m_hFind;
3204 BOOL m_bFound;
3205
3206 // Constructor/destructor
3207 CFindFile() : m_hFind(NULL), m_chDirSeparator(_T('\\')), m_bFound(FALSE)
3208 { }
3209
3210 ~CFindFile()
3211 {
3212 Close();
3213 }
3214
3215 // Attributes
3216 ULONGLONG GetFileSize() const
3217 {
3218 ATLASSERT(m_hFind != NULL);
3219
3220 ULARGE_INTEGER nFileSize = { 0 };
3221
3222 if(m_bFound)
3223 {
3224 nFileSize.LowPart = m_fd.nFileSizeLow;
3225 nFileSize.HighPart = m_fd.nFileSizeHigh;
3226 }
3227 else
3228 {
3229 nFileSize.QuadPart = 0;
3230 }
3231
3232 return nFileSize.QuadPart;
3233 }
3234
3235 BOOL GetFileName(LPTSTR lpstrFileName, int cchLength) const
3236 {
3237 ATLASSERT(m_hFind != NULL);
3238 if(lstrlen(m_fd.cFileName) >= cchLength)
3239 return FALSE;
3240
3241 if(m_bFound)
3242 SecureHelper::strcpy_x(lpstrFileName, cchLength, m_fd.cFileName);
3243
3244 return m_bFound;
3245 }
3246
3247 BOOL GetFilePath(LPTSTR lpstrFilePath, int cchLength) const
3248 {
3249 ATLASSERT(m_hFind != NULL);
3250
3251 int nLen = lstrlen(m_lpszRoot);
3252 #ifndef _WIN32_WCE
3253 ATLASSERT(nLen > 0);
3254 if(nLen == 0)
3255 return FALSE;
3256
3257 bool bAddSep = (m_lpszRoot[nLen - 1] != _T('\\') && m_lpszRoot[nLen - 1] !=_T('/'));
3258 #else // CE specific
3259 // allow diskless devices (nLen == 0)
3260 bool bAddSep = ((nLen == 0) || (m_lpszRoot[nLen - 1] != _T('\\') && m_lpszRoot[nLen - 1] !=_T('/')));
3261 #endif // _WIN32_WCE
3262
3263 if((lstrlen(m_lpszRoot) + (bAddSep ? 1 : 0)) >= cchLength)
3264 return FALSE;
3265
3266 SecureHelper::strcpy_x(lpstrFilePath, cchLength, m_lpszRoot);
3267
3268 if(bAddSep)
3269 {
3270 TCHAR szSeparator[2] = { m_chDirSeparator, 0 };
3271 SecureHelper::strcat_x(lpstrFilePath, cchLength, szSeparator);
3272 }
3273
3274 SecureHelper::strcat_x(lpstrFilePath, cchLength, m_fd.cFileName);
3275
3276 return TRUE;
3277 }
3278
3279 #ifndef _WIN32_WCE
3280 BOOL GetFileTitle(LPTSTR lpstrFileTitle, int cchLength) const
3281 {
3282 ATLASSERT(m_hFind != NULL);
3283
3284 TCHAR szBuff[MAX_PATH] = { 0 };
3285 if(!GetFileName(szBuff, MAX_PATH))
3286 return FALSE;
3287
3288 if(lstrlen(szBuff) >= cchLength || cchLength < 1)
3289 return FALSE;
3290
3291 // find the last dot
3292 LPTSTR pstrDot = MinCrtHelper::_strrchr(szBuff, _T('.'));
3293 if(pstrDot != NULL)
3294 *pstrDot = 0;
3295
3296 SecureHelper::strcpy_x(lpstrFileTitle, cchLength, szBuff);
3297
3298 return TRUE;
3299 }
3300 #endif // !_WIN32_WCE
3301
3302 BOOL GetFileURL(LPTSTR lpstrFileURL, int cchLength) const
3303 {
3304 ATLASSERT(m_hFind != NULL);
3305
3306 TCHAR szBuff[MAX_PATH] = { 0 };
3307 if(!GetFilePath(szBuff, MAX_PATH))
3308 return FALSE;
3309 LPCTSTR lpstrFileURLPrefix = _T("file://");
3310 if(lstrlen(szBuff) + lstrlen(lpstrFileURLPrefix) >= cchLength)
3311 return FALSE;
3312 SecureHelper::strcpy_x(lpstrFileURL, cchLength, lpstrFileURLPrefix);
3313 SecureHelper::strcat_x(lpstrFileURL, cchLength, szBuff);
3314
3315 return TRUE;
3316 }
3317
3318 BOOL GetRoot(LPTSTR lpstrRoot, int cchLength) const
3319 {
3320 ATLASSERT(m_hFind != NULL);
3321 if(lstrlen(m_lpszRoot) >= cchLength)
3322 return FALSE;
3323
3324 SecureHelper::strcpy_x(lpstrRoot, cchLength, m_lpszRoot);
3325
3326 return TRUE;
3327 }
3328
3329 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
3330 _CSTRING_NS::CString GetFileName() const
3331 {
3332 ATLASSERT(m_hFind != NULL);
3333
3334 _CSTRING_NS::CString ret;
3335
3336 if(m_bFound)
3337 ret = m_fd.cFileName;
3338 return ret;
3339 }
3340
3341 _CSTRING_NS::CString GetFilePath() const
3342 {
3343 ATLASSERT(m_hFind != NULL);
3344
3345 _CSTRING_NS::CString strResult = m_lpszRoot;
3346 int nLen = strResult.GetLength();
3347 #ifndef _WIN32_WCE
3348 ATLASSERT(nLen > 0);
3349 if(nLen == 0)
3350 return strResult;
3351
3352 if((strResult[nLen - 1] != _T('\\')) && (strResult[nLen - 1] != _T('/')))
3353 #else // CE specific
3354 // allow diskless devices (nLen == 0)
3355 if((nLen == 0) || ((strResult[nLen - 1] != _T('\\')) && (strResult[nLen - 1] != _T('/'))))
3356 #endif // _WIN32_WCE
3357 strResult += m_chDirSeparator;
3358 strResult += GetFileName();
3359 return strResult;
3360 }
3361
3362 #ifndef _WIN32_WCE
3363 _CSTRING_NS::CString GetFileTitle() const
3364 {
3365 ATLASSERT(m_hFind != NULL);
3366
3367 _CSTRING_NS::CString strResult;
3368 GetFileTitle(strResult.GetBuffer(MAX_PATH), MAX_PATH);
3369 strResult.ReleaseBuffer();
3370
3371 return strResult;
3372 }
3373 #endif // !_WIN32_WCE
3374
3375 _CSTRING_NS::CString GetFileURL() const
3376 {
3377 ATLASSERT(m_hFind != NULL);
3378
3379 _CSTRING_NS::CString strResult("file://");
3380 strResult += GetFilePath();
3381 return strResult;
3382 }
3383
3384 _CSTRING_NS::CString GetRoot() const
3385 {
3386 ATLASSERT(m_hFind != NULL);
3387
3388 _CSTRING_NS::CString str = m_lpszRoot;
3389 return str;
3390 }
3391 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
3392
3393 BOOL GetLastWriteTime(FILETIME* pTimeStamp) const
3394 {
3395 ATLASSERT(m_hFind != NULL);
3396 ATLASSERT(pTimeStamp != NULL);
3397
3398 if(m_bFound && pTimeStamp != NULL)
3399 {
3400 *pTimeStamp = m_fd.ftLastWriteTime;
3401 return TRUE;
3402 }
3403
3404 return FALSE;
3405 }
3406
3407 BOOL GetLastAccessTime(FILETIME* pTimeStamp) const
3408 {
3409 ATLASSERT(m_hFind != NULL);
3410 ATLASSERT(pTimeStamp != NULL);
3411
3412 if(m_bFound && pTimeStamp != NULL)
3413 {
3414 *pTimeStamp = m_fd.ftLastAccessTime;
3415 return TRUE;
3416 }
3417
3418 return FALSE;
3419 }
3420
3421 BOOL GetCreationTime(FILETIME* pTimeStamp) const
3422 {
3423 ATLASSERT(m_hFind != NULL);
3424
3425 if(m_bFound && pTimeStamp != NULL)
3426 {
3427 *pTimeStamp = m_fd.ftCreationTime;
3428 return TRUE;
3429 }
3430
3431 return FALSE;
3432 }
3433
3434 BOOL MatchesMask(DWORD dwMask) const
3435 {
3436 ATLASSERT(m_hFind != NULL);
3437
3438 if(m_bFound)
3439 return ((m_fd.dwFileAttributes & dwMask) != 0);
3440
3441 return FALSE;
3442 }
3443
3444 BOOL IsDots() const
3445 {
3446 ATLASSERT(m_hFind != NULL);
3447
3448 // return TRUE if the file name is "." or ".." and
3449 // the file is a directory
3450
3451 BOOL bResult = FALSE;
3452 if(m_bFound && IsDirectory())
3453 {
3454 if(m_fd.cFileName[0] == _T('.') && (m_fd.cFileName[1] == _T('\0') || (m_fd.cFileName[1] == _T('.') && m_fd.cFileName[2] == _T('\0'))))
3455 bResult = TRUE;
3456 }
3457
3458 return bResult;
3459 }
3460
3461 BOOL IsReadOnly() const
3462 {
3463 return MatchesMask(FILE_ATTRIBUTE_READONLY);
3464 }
3465
3466 BOOL IsDirectory() const
3467 {
3468 return MatchesMask(FILE_ATTRIBUTE_DIRECTORY);
3469 }
3470
3471 BOOL IsCompressed() const
3472 {
3473 return MatchesMask(FILE_ATTRIBUTE_COMPRESSED);
3474 }
3475
3476 BOOL IsSystem() const
3477 {
3478 return MatchesMask(FILE_ATTRIBUTE_SYSTEM);
3479 }
3480
3481 BOOL IsHidden() const
3482 {
3483 return MatchesMask(FILE_ATTRIBUTE_HIDDEN);
3484 }
3485
3486 BOOL IsTemporary() const
3487 {
3488 return MatchesMask(FILE_ATTRIBUTE_TEMPORARY);
3489 }
3490
3491 BOOL IsNormal() const
3492 {
3493 return MatchesMask(FILE_ATTRIBUTE_NORMAL);
3494 }
3495
3496 BOOL IsArchived() const
3497 {
3498 return MatchesMask(FILE_ATTRIBUTE_ARCHIVE);
3499 }
3500
3501 // Operations
3502 BOOL FindFile(LPCTSTR pstrName = NULL)
3503 {
3504 Close();
3505
3506 if(pstrName == NULL)
3507 {
3508 pstrName = _T("*.*");
3509 }
3510 else if(lstrlen(pstrName) >= MAX_PATH)
3511 {
3512 ATLASSERT(FALSE);
3513 return FALSE;
3514 }
3515
3516 SecureHelper::strcpy_x(m_fd.cFileName, _countof(m_fd.cFileName), pstrName);
3517
3518 m_hFind = ::FindFirstFile(pstrName, &m_fd);
3519
3520 if(m_hFind == INVALID_HANDLE_VALUE)
3521 return FALSE;
3522
3523 #ifndef _WIN32_WCE
3524 bool bFullPath = (::GetFullPathName(pstrName, MAX_PATH, m_lpszRoot, NULL) != 0);
3525 #else // CE specific
3526 errno_t nRet = SecureHelper::strncpy_x(m_lpszRoot, _countof(m_lpszRoot), pstrName, _TRUNCATE);
3527 bool bFullPath = (nRet == 0 || nRet == STRUNCATE);
3528 #endif // _WIN32_WCE
3529
3530 // passed name isn't a valid path but was found by the API
3531 ATLASSERT(bFullPath);
3532 if(!bFullPath)
3533 {
3534 Close();
3535 ::SetLastError(ERROR_INVALID_NAME);
3536 return FALSE;
3537 }
3538 else
3539 {
3540 // find the last forward or backward whack
3541 LPTSTR pstrBack = MinCrtHelper::_strrchr(m_lpszRoot, _T('\\'));
3542 LPTSTR pstrFront = MinCrtHelper::_strrchr(m_lpszRoot, _T('/'));
3543
3544 if(pstrFront != NULL || pstrBack != NULL)
3545 {
3546 if(pstrFront == NULL)
3547 pstrFront = m_lpszRoot;
3548 if(pstrBack == NULL)
3549 pstrBack = m_lpszRoot;
3550
3551 // from the start to the last whack is the root
3552
3553 if(pstrFront >= pstrBack)
3554 *pstrFront = _T('\0');
3555 else
3556 *pstrBack = _T('\0');
3557 }
3558 }
3559
3560 m_bFound = TRUE;
3561
3562 return TRUE;
3563 }
3564
3565 BOOL FindNextFile()
3566 {
3567 ATLASSERT(m_hFind != NULL);
3568
3569 if(m_hFind == NULL)
3570 return FALSE;
3571
3572 if(!m_bFound)
3573 return FALSE;
3574
3575 m_bFound = ::FindNextFile(m_hFind, &m_fd);
3576
3577 return m_bFound;
3578 }
3579
3580 void Close()
3581 {
3582 m_bFound = FALSE;
3583
3584 if(m_hFind != NULL && m_hFind != INVALID_HANDLE_VALUE)
3585 {
3586 ::FindClose(m_hFind);
3587 m_hFind = NULL;
3588 }
3589 }
3590 };
3591
3592
3593 ///////////////////////////////////////////////////////////////////////////////
3594 // Global functions for stock GDI objects
3595
3596 inline HPEN AtlGetStockPen(int nPen)
3597 {
3598 #if (_WIN32_WINNT >= 0x0500) && !defined(_WIN32_WCE)
3599 ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN || nPen == DC_PEN);
3600 #else
3601 ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN);
3602 #endif
3603 return (HPEN)::GetStockObject(nPen);
3604 }
3605
3606 inline HBRUSH AtlGetStockBrush(int nBrush)
3607 {
3608 #if (_WIN32_WINNT >= 0x0500) && !defined(_WIN32_WCE)
3609 ATLASSERT((nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH) || nBrush == DC_BRUSH);
3610 #else
3611 ATLASSERT(nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH);
3612 #endif
3613 return (HBRUSH)::GetStockObject(nBrush);
3614 }
3615
3616 inline HFONT AtlGetStockFont(int nFont)
3617 {
3618 #ifndef _WIN32_WCE
3619 ATLASSERT((nFont >= OEM_FIXED_FONT && nFont <= SYSTEM_FIXED_FONT) || nFont == DEFAULT_GUI_FONT);
3620 #else // CE specific
3621 ATLASSERT(nFont == SYSTEM_FONT);
3622 #endif // _WIN32_WCE
3623 return (HFONT)::GetStockObject(nFont);
3624 }
3625
3626 inline HPALETTE AtlGetStockPalette(int nPalette)
3627 {
3628 ATLASSERT(nPalette == DEFAULT_PALETTE); // the only one supported
3629 return (HPALETTE)::GetStockObject(nPalette);
3630 }
3631
3632
3633 ///////////////////////////////////////////////////////////////////////////////
3634 // Global function for compacting a path by replacing parts with ellipsis
3635
3636 // helper for multi-byte character sets
3637 inline bool _IsDBCSTrailByte(LPCTSTR lpstr, int nChar)
3638 {
3639 #ifndef _UNICODE
3640 int i = nChar;
3641 for( ; i > 0; i--)
3642 {
3643 if(!::IsDBCSLeadByte(lpstr[i - 1]))
3644 break;
3645 }
3646 return ((nChar > 0) && (((nChar - i) & 1) != 0));
3647 #else // _UNICODE
3648 lpstr; nChar;
3649 return false;
3650 #endif // _UNICODE
3651 }
3652
3653 inline bool AtlCompactPath(LPTSTR lpstrOut, LPCTSTR lpstrIn, int cchLen)
3654 {
3655 ATLASSERT(lpstrOut != NULL);
3656 ATLASSERT(lpstrIn != NULL);
3657 ATLASSERT(cchLen > 0);
3658
3659 LPCTSTR szEllipsis = _T("...");
3660 const int cchEndEllipsis = 3;
3661 const int cchMidEllipsis = 4;
3662
3663 if(lstrlen(lpstrIn) < cchLen)
3664 {
3665 SecureHelper::strcpy_x(lpstrOut, cchLen, lpstrIn);
3666 return true;
3667 }
3668
3669 lpstrOut[0] = 0;
3670
3671 // check if the separator is a slash or a backslash
3672 TCHAR chSlash = _T('\\');
3673 for(LPTSTR lpstr = (LPTSTR)lpstrIn; *lpstr != 0; lpstr = ::CharNext(lpstr))
3674 {
3675 if((*lpstr == _T('/')) || (*lpstr == _T('\\')))
3676 chSlash = *lpstr;
3677 }
3678
3679 // find the filename portion of the path
3680 LPCTSTR lpstrFileName = lpstrIn;
3681 for(LPCTSTR pPath = lpstrIn; *pPath; pPath = ::CharNext(pPath))
3682 {
3683 if((pPath[0] == _T('\\') || pPath[0] == _T(':') || pPath[0] == _T('/'))
3684 && pPath[1] && pPath[1] != _T('\\') && pPath[1] != _T('/'))
3685 lpstrFileName = pPath + 1;
3686 }
3687 int cchFileName = lstrlen(lpstrFileName);
3688
3689 // handle just the filename without a path
3690 if(lpstrFileName == lpstrIn && cchLen > cchEndEllipsis)
3691 {
3692 bool bRet = (SecureHelper::strncpy_x(lpstrOut, cchLen, lpstrIn, cchLen - cchEndEllipsis - 1) == 0);
3693 if(bRet)
3694 {
3695 #ifndef _UNICODE
3696 if(_IsDBCSTrailByte(lpstrIn, cchLen - cchEndEllipsis))
3697 lpstrOut[cchLen - cchEndEllipsis - 1] = 0;
3698 #endif // _UNICODE
3699 SecureHelper::strcat_x(lpstrOut, cchLen, szEllipsis);
3700 }
3701 return bRet;
3702 }
3703
3704 // handle just ellipsis
3705 if((cchLen < (cchMidEllipsis + cchEndEllipsis)))
3706 {
3707 for(int i = 0; i < cchLen - 1; i++)
3708 lpstrOut[i] = ((i + 1) == cchMidEllipsis) ? chSlash : _T('.');
3709 lpstrOut[cchLen - 1] = 0;
3710 return true;
3711 }
3712
3713 // calc how much we have to copy
3714 int cchToCopy = cchLen - (cchMidEllipsis + cchFileName) - 1;
3715
3716 if(cchToCopy < 0)
3717 cchToCopy = 0;
3718
3719 #ifndef _UNICODE
3720 if(cchToCopy > 0 && _IsDBCSTrailByte(lpstrIn, cchToCopy))
3721 cchToCopy--;
3722 #endif // _UNICODE
3723
3724 bool bRet = (SecureHelper::strncpy_x(lpstrOut, cchLen, lpstrIn, cchToCopy) == 0);
3725 if(!bRet)
3726 return false;
3727
3728 // add ellipsis
3729 SecureHelper::strcat_x(lpstrOut, cchLen, szEllipsis);
3730 TCHAR szSlash[2] = { chSlash, 0 };
3731 SecureHelper::strcat_x(lpstrOut, cchLen, szSlash);
3732
3733 // add filename (and ellipsis, if needed)
3734 if(cchLen > (cchMidEllipsis + cchFileName))
3735 {
3736 SecureHelper::strcat_x(lpstrOut, cchLen, lpstrFileName);
3737 }
3738 else
3739 {
3740 cchToCopy = cchLen - cchMidEllipsis - cchEndEllipsis - 1;
3741 #ifndef _UNICODE
3742 if(cchToCopy > 0 && _IsDBCSTrailByte(lpstrFileName, cchToCopy))
3743 cchToCopy--;
3744 #endif // _UNICODE
3745 bRet = (SecureHelper::strncpy_x(&lpstrOut[cchMidEllipsis], cchLen - cchMidEllipsis, lpstrFileName, cchToCopy) == 0);
3746 if(bRet)
3747 SecureHelper::strcat_x(lpstrOut, cchLen, szEllipsis);
3748 }
3749
3750 return bRet;
3751 }
3752
3753 }; // namespace WTL
3754
3755 #endif // __ATLMISC_H__
+0
-1106
src/third_party/wtl/Include/atlprint.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLPRINT_H__
9 #define __ATLPRINT_H__
10
11 #pragma once
12
13 #ifdef _WIN32_WCE
14 #error atlprint.h is not supported on Windows CE
15 #endif
16
17 #ifndef __ATLAPP_H__
18 #error atlprint.h requires atlapp.h to be included first
19 #endif
20
21 #ifndef __ATLWIN_H__
22 #error atlprint.h requires atlwin.h to be included first
23 #endif
24
25
26 ///////////////////////////////////////////////////////////////////////////////
27 // Classes in this file:
28 //
29 // CPrinterInfo<t_nInfo>
30 // CPrinterT<t_bManaged>
31 // CDevModeT<t_bManaged>
32 // CPrinterDC
33 // CPrintJobInfo
34 // CPrintJob
35 // CPrintPreview
36 // CPrintPreviewWindowImpl<T, TBase, TWinTraits>
37 // CPrintPreviewWindow
38 // CZoomPrintPreviewWindowImpl<T, TBase, TWinTraits>
39 // CZoomPrintPreviewWindow
40
41 namespace WTL
42 {
43
44 ///////////////////////////////////////////////////////////////////////////////
45 // CPrinterInfo - This class wraps all of the PRINTER_INFO_* structures
46 // and provided by ::GetPrinter.
47
48 template <unsigned int t_nInfo>
49 class _printer_info
50 {
51 public:
52 typedef void infotype;
53 };
54
55 template <> class _printer_info<1> { public: typedef PRINTER_INFO_1 infotype; };
56 template <> class _printer_info<2> { public: typedef PRINTER_INFO_2 infotype; };
57 template <> class _printer_info<3> { public: typedef PRINTER_INFO_3 infotype; };
58 template <> class _printer_info<4> { public: typedef PRINTER_INFO_4 infotype; };
59 template <> class _printer_info<5> { public: typedef PRINTER_INFO_5 infotype; };
60 template <> class _printer_info<6> { public: typedef PRINTER_INFO_6 infotype; };
61 template <> class _printer_info<7> { public: typedef PRINTER_INFO_7 infotype; };
62 // these are not in the old (vc6.0) headers
63 #ifdef _ATL_USE_NEW_PRINTER_INFO
64 template <> class _printer_info<8> { public: typedef PRINTER_INFO_8 infotype; };
65 template <> class _printer_info<9> { public: typedef PRINTER_INFO_9 infotype; };
66 #endif // _ATL_USE_NEW_PRINTER_INFO
67
68
69 template <unsigned int t_nInfo>
70 class CPrinterInfo
71 {
72 public:
73 // Data members
74 typename _printer_info<t_nInfo>::infotype* m_pi;
75
76 // Constructor/destructor
77 CPrinterInfo() : m_pi(NULL)
78 { }
79
80 CPrinterInfo(HANDLE hPrinter) : m_pi(NULL)
81 {
82 GetPrinterInfo(hPrinter);
83 }
84
85 ~CPrinterInfo()
86 {
87 Cleanup();
88 }
89
90 // Operations
91 bool GetPrinterInfo(HANDLE hPrinter)
92 {
93 Cleanup();
94 return GetPrinterInfoHelper(hPrinter, (BYTE**)&m_pi, t_nInfo);
95 }
96
97 // Implementation
98 void Cleanup()
99 {
100 delete [] (BYTE*)m_pi;
101 m_pi = NULL;
102 }
103
104 static bool GetPrinterInfoHelper(HANDLE hPrinter, BYTE** pi, int nIndex)
105 {
106 ATLASSERT(pi != NULL);
107 DWORD dw = 0;
108 BYTE* pb = NULL;
109 ::GetPrinter(hPrinter, nIndex, NULL, 0, &dw);
110 if (dw > 0)
111 {
112 ATLTRY(pb = new BYTE[dw]);
113 if (pb != NULL)
114 {
115 memset(pb, 0, dw);
116 DWORD dwNew;
117 if (!::GetPrinter(hPrinter, nIndex, pb, dw, &dwNew))
118 {
119 delete [] pb;
120 pb = NULL;
121 }
122 }
123 }
124 *pi = pb;
125 return (pb != NULL);
126 }
127 };
128
129
130 ///////////////////////////////////////////////////////////////////////////////
131 // CPrinter - Wrapper class for a HANDLE to a printer
132
133 template <bool t_bManaged>
134 class CPrinterT
135 {
136 public:
137 // Data members
138 HANDLE m_hPrinter;
139
140 // Constructor/destructor
141 CPrinterT(HANDLE hPrinter = NULL) : m_hPrinter(hPrinter)
142 { }
143
144 ~CPrinterT()
145 {
146 ClosePrinter();
147 }
148
149 // Operations
150 CPrinterT& operator =(HANDLE hPrinter)
151 {
152 if (hPrinter != m_hPrinter)
153 {
154 ClosePrinter();
155 m_hPrinter = hPrinter;
156 }
157 return *this;
158 }
159
160 bool IsNull() const { return (m_hPrinter == NULL); }
161
162 bool OpenPrinter(HANDLE hDevNames, const DEVMODE* pDevMode = NULL)
163 {
164 bool b = false;
165 DEVNAMES* pdn = (DEVNAMES*)::GlobalLock(hDevNames);
166 if (pdn != NULL)
167 {
168 LPTSTR lpszPrinterName = (LPTSTR)pdn + pdn->wDeviceOffset;
169 b = OpenPrinter(lpszPrinterName, pDevMode);
170 ::GlobalUnlock(hDevNames);
171 }
172 return b;
173 }
174
175 bool OpenPrinter(LPCTSTR lpszPrinterName, const DEVMODE* pDevMode = NULL)
176 {
177 ClosePrinter();
178 PRINTER_DEFAULTS pdefs = { NULL, (DEVMODE*)pDevMode, PRINTER_ACCESS_USE };
179 ::OpenPrinter((LPTSTR) lpszPrinterName, &m_hPrinter, (pDevMode == NULL) ? NULL : &pdefs);
180
181 return (m_hPrinter != NULL);
182 }
183
184 bool OpenPrinter(LPCTSTR lpszPrinterName, PRINTER_DEFAULTS* pprintdefs)
185 {
186 ClosePrinter();
187 ::OpenPrinter((LPTSTR) lpszPrinterName, &m_hPrinter, pprintdefs);
188 return (m_hPrinter != NULL);
189 }
190
191 bool OpenDefaultPrinter(const DEVMODE* pDevMode = NULL)
192 {
193 ClosePrinter();
194 const int cchBuff = 512;
195 TCHAR buffer[cchBuff] = { 0 };
196 ::GetProfileString(_T("windows"), _T("device"), _T(",,,"), buffer, cchBuff);
197 int nLen = lstrlen(buffer);
198 if (nLen != 0)
199 {
200 LPTSTR lpsz = buffer;
201 while (*lpsz)
202 {
203 if (*lpsz == _T(','))
204 {
205 *lpsz = 0;
206 break;
207 }
208 lpsz = CharNext(lpsz);
209 }
210 PRINTER_DEFAULTS pdefs = { NULL, (DEVMODE*)pDevMode, PRINTER_ACCESS_USE };
211 ::OpenPrinter(buffer, &m_hPrinter, (pDevMode == NULL) ? NULL : &pdefs);
212 }
213 return m_hPrinter != NULL;
214 }
215
216 void ClosePrinter()
217 {
218 if (m_hPrinter != NULL)
219 {
220 if (t_bManaged)
221 ::ClosePrinter(m_hPrinter);
222 m_hPrinter = NULL;
223 }
224 }
225
226 bool PrinterProperties(HWND hWnd = NULL)
227 {
228 if (hWnd == NULL)
229 hWnd = ::GetActiveWindow();
230 return !!::PrinterProperties(hWnd, m_hPrinter);
231 }
232
233 HANDLE CopyToHDEVNAMES() const
234 {
235 HANDLE h = NULL;
236 CPrinterInfo<5> pinfon5;
237 CPrinterInfo<2> pinfon2;
238 LPTSTR lpszPrinterName = NULL;
239 // Some printers fail for PRINTER_INFO_5 in some situations
240 if (pinfon5.GetPrinterInfo(m_hPrinter))
241 lpszPrinterName = pinfon5.m_pi->pPrinterName;
242 else if (pinfon2.GetPrinterInfo(m_hPrinter))
243 lpszPrinterName = pinfon2.m_pi->pPrinterName;
244 if (lpszPrinterName != NULL)
245 {
246 int nLen = sizeof(DEVNAMES) + (lstrlen(lpszPrinterName) + 1) * sizeof(TCHAR);
247 h = ::GlobalAlloc(GMEM_MOVEABLE, nLen);
248 BYTE* pv = (BYTE*)::GlobalLock(h);
249 DEVNAMES* pdev = (DEVNAMES*)pv;
250 if (pv != NULL)
251 {
252 memset(pv, 0, nLen);
253 pdev->wDeviceOffset = sizeof(DEVNAMES) / sizeof(TCHAR);
254 pv = pv + sizeof(DEVNAMES); // now points to end
255 SecureHelper::strcpy_x((LPTSTR)pv, lstrlen(lpszPrinterName) + 1, lpszPrinterName);
256 ::GlobalUnlock(h);
257 }
258 }
259 return h;
260 }
261
262 HDC CreatePrinterDC(const DEVMODE* pdm = NULL) const
263 {
264 CPrinterInfo<5> pinfo5;
265 CPrinterInfo<2> pinfo2;
266 HDC hDC = NULL;
267 LPTSTR lpszPrinterName = NULL;
268 // Some printers fail for PRINTER_INFO_5 in some situations
269 if (pinfo5.GetPrinterInfo(m_hPrinter))
270 lpszPrinterName = pinfo5.m_pi->pPrinterName;
271 else if (pinfo2.GetPrinterInfo(m_hPrinter))
272 lpszPrinterName = pinfo2.m_pi->pPrinterName;
273 if (lpszPrinterName != NULL)
274 hDC = ::CreateDC(NULL, lpszPrinterName, NULL, pdm);
275 return hDC;
276 }
277
278 HDC CreatePrinterIC(const DEVMODE* pdm = NULL) const
279 {
280 CPrinterInfo<5> pinfo5;
281 CPrinterInfo<2> pinfo2;
282 HDC hDC = NULL;
283 LPTSTR lpszPrinterName = NULL;
284 // Some printers fail for PRINTER_INFO_5 in some situations
285 if (pinfo5.GetPrinterInfo(m_hPrinter))
286 lpszPrinterName = pinfo5.m_pi->pPrinterName;
287 else if (pinfo2.GetPrinterInfo(m_hPrinter))
288 lpszPrinterName = pinfo2.m_pi->pPrinterName;
289 if (lpszPrinterName != NULL)
290 hDC = ::CreateIC(NULL, lpszPrinterName, NULL, pdm);
291 return hDC;
292 }
293
294 void Attach(HANDLE hPrinter)
295 {
296 ClosePrinter();
297 m_hPrinter = hPrinter;
298 }
299
300 HANDLE Detach()
301 {
302 HANDLE hPrinter = m_hPrinter;
303 m_hPrinter = NULL;
304 return hPrinter;
305 }
306
307 operator HANDLE() const { return m_hPrinter; }
308 };
309
310 typedef CPrinterT<false> CPrinterHandle;
311 typedef CPrinterT<true> CPrinter;
312
313
314 ///////////////////////////////////////////////////////////////////////////////
315 // CDevMode - Wrapper class for DEVMODE
316
317 template <bool t_bManaged>
318 class CDevModeT
319 {
320 public:
321 // Data members
322 HANDLE m_hDevMode;
323 DEVMODE* m_pDevMode;
324
325 // Constructor/destructor
326 CDevModeT(HANDLE hDevMode = NULL) : m_hDevMode(hDevMode)
327 {
328 m_pDevMode = (m_hDevMode != NULL) ? (DEVMODE*)::GlobalLock(m_hDevMode) : NULL;
329 }
330
331 ~CDevModeT()
332 {
333 Cleanup();
334 }
335
336 // Operations
337 CDevModeT<t_bManaged>& operator =(HANDLE hDevMode)
338 {
339 Attach(hDevMode);
340 return *this;
341 }
342
343 void Attach(HANDLE hDevModeNew)
344 {
345 Cleanup();
346 m_hDevMode = hDevModeNew;
347 m_pDevMode = (m_hDevMode != NULL) ? (DEVMODE*)::GlobalLock(m_hDevMode) : NULL;
348 }
349
350 HANDLE Detach()
351 {
352 if (m_hDevMode != NULL)
353 ::GlobalUnlock(m_hDevMode);
354 HANDLE hDevMode = m_hDevMode;
355 m_hDevMode = NULL;
356 return hDevMode;
357 }
358
359 bool IsNull() const { return (m_hDevMode == NULL); }
360
361 bool CopyFromPrinter(HANDLE hPrinter)
362 {
363 CPrinterInfo<2> pinfo;
364 bool b = pinfo.GetPrinterInfo(hPrinter);
365 if (b)
366 b = CopyFromDEVMODE(pinfo.m_pi->pDevMode);
367 return b;
368 }
369
370 bool CopyFromDEVMODE(const DEVMODE* pdm)
371 {
372 if (pdm == NULL)
373 return false;
374 int nSize = pdm->dmSize + pdm->dmDriverExtra;
375 HANDLE h = ::GlobalAlloc(GMEM_MOVEABLE, nSize);
376 if (h != NULL)
377 {
378 void* p = ::GlobalLock(h);
379 SecureHelper::memcpy_x(p, nSize, pdm, nSize);
380 ::GlobalUnlock(h);
381 }
382 Attach(h);
383 return (h != NULL);
384 }
385
386 bool CopyFromHDEVMODE(HANDLE hdm)
387 {
388 bool b = false;
389 if (hdm != NULL)
390 {
391 DEVMODE* pdm = (DEVMODE*)::GlobalLock(hdm);
392 b = CopyFromDEVMODE(pdm);
393 ::GlobalUnlock(hdm);
394 }
395 return b;
396 }
397
398 HANDLE CopyToHDEVMODE()
399 {
400 if ((m_hDevMode == NULL) || (m_pDevMode == NULL))
401 return NULL;
402 int nSize = m_pDevMode->dmSize + m_pDevMode->dmDriverExtra;
403 HANDLE h = ::GlobalAlloc(GMEM_MOVEABLE, nSize);
404 if (h != NULL)
405 {
406 void* p = ::GlobalLock(h);
407 SecureHelper::memcpy_x(p, nSize, m_pDevMode, nSize);
408 ::GlobalUnlock(h);
409 }
410 return h;
411 }
412
413 // If this devmode was for another printer, this will create a new devmode
414 // based on the existing devmode, but retargeted at the new printer
415 bool UpdateForNewPrinter(HANDLE hPrinter)
416 {
417 bool bRet = false;
418 LONG nLen = ::DocumentProperties(NULL, hPrinter, NULL, NULL, NULL, 0);
419 CTempBuffer<DEVMODE, _WTL_STACK_ALLOC_THRESHOLD> buff;
420 DEVMODE* pdm = buff.AllocateBytes(nLen);
421 if(pdm != NULL)
422 {
423 memset(pdm, 0, nLen);
424 LONG l = ::DocumentProperties(NULL, hPrinter, NULL, pdm, m_pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);
425 if (l == IDOK)
426 bRet = CopyFromDEVMODE(pdm);
427 }
428
429 return bRet;
430 }
431
432 bool DocumentProperties(HANDLE hPrinter, HWND hWnd = NULL)
433 {
434 CPrinterInfo<1> pi;
435 pi.GetPrinterInfo(hPrinter);
436 if (hWnd == NULL)
437 hWnd = ::GetActiveWindow();
438
439 bool bRet = false;
440 LONG nLen = ::DocumentProperties(hWnd, hPrinter, pi.m_pi->pName, NULL, NULL, 0);
441 CTempBuffer<DEVMODE, _WTL_STACK_ALLOC_THRESHOLD> buff;
442 DEVMODE* pdm = buff.AllocateBytes(nLen);
443 if(pdm != NULL)
444 {
445 memset(pdm, 0, nLen);
446 LONG l = ::DocumentProperties(hWnd, hPrinter, pi.m_pi->pName, pdm, m_pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER | DM_PROMPT);
447 if (l == IDOK)
448 bRet = CopyFromDEVMODE(pdm);
449 }
450
451 return bRet;
452 }
453
454 operator HANDLE() const { return m_hDevMode; }
455
456 operator DEVMODE*() const { return m_pDevMode; }
457
458 // Implementation
459 void Cleanup()
460 {
461 if (m_hDevMode != NULL)
462 {
463 ::GlobalUnlock(m_hDevMode);
464 if(t_bManaged)
465 ::GlobalFree(m_hDevMode);
466 m_hDevMode = NULL;
467 }
468 }
469 };
470
471 typedef CDevModeT<false> CDevModeHandle;
472 typedef CDevModeT<true> CDevMode;
473
474
475 ///////////////////////////////////////////////////////////////////////////////
476 // CPrinterDC
477
478 class CPrinterDC : public CDC
479 {
480 public:
481 // Constructors/destructor
482 CPrinterDC()
483 {
484 CPrinter printer;
485 printer.OpenDefaultPrinter();
486 Attach(printer.CreatePrinterDC());
487 ATLASSERT(m_hDC != NULL);
488 }
489
490 CPrinterDC(HANDLE hPrinter, const DEVMODE* pdm = NULL)
491 {
492 CPrinterHandle p;
493 p.Attach(hPrinter);
494 Attach(p.CreatePrinterDC(pdm));
495 ATLASSERT(m_hDC != NULL);
496 }
497
498 ~CPrinterDC()
499 {
500 DeleteDC();
501 }
502 };
503
504
505 ///////////////////////////////////////////////////////////////////////////////
506 // CPrintJob - Wraps a set of tasks for a specific printer (StartDoc/EndDoc)
507 // Handles aborting, background printing
508
509 // Defines callbacks used by CPrintJob (not a COM interface)
510 class ATL_NO_VTABLE IPrintJobInfo
511 {
512 public:
513 virtual void BeginPrintJob(HDC hDC) = 0; // allocate handles needed, etc.
514 virtual void EndPrintJob(HDC hDC, bool bAborted) = 0; // free handles, etc.
515 virtual void PrePrintPage(UINT nPage, HDC hDC) = 0;
516 virtual bool PrintPage(UINT nPage, HDC hDC) = 0;
517 virtual void PostPrintPage(UINT nPage, HDC hDC) = 0;
518 // If you want per page devmodes, return the DEVMODE* to use for nPage.
519 // You can optimize by only returning a new DEVMODE* when it is different
520 // from the one for nLastPage, otherwise return NULL.
521 // When nLastPage==0, the current DEVMODE* will be the default passed to
522 // StartPrintJob.
523 // Note: During print preview, nLastPage will always be "0".
524 virtual DEVMODE* GetNewDevModeForPage(UINT nLastPage, UINT nPage) = 0;
525 virtual bool IsValidPage(UINT nPage) = 0;
526 };
527
528 // Provides a default implementatin for IPrintJobInfo
529 // Typically, MI'd into a document or view class
530 class ATL_NO_VTABLE CPrintJobInfo : public IPrintJobInfo
531 {
532 public:
533 virtual void BeginPrintJob(HDC /*hDC*/) // allocate handles needed, etc
534 {
535 }
536
537 virtual void EndPrintJob(HDC /*hDC*/, bool /*bAborted*/) // free handles, etc
538 {
539 }
540
541 virtual void PrePrintPage(UINT /*nPage*/, HDC hDC)
542 {
543 m_nPJState = ::SaveDC(hDC);
544 }
545
546 virtual bool PrintPage(UINT /*nPage*/, HDC /*hDC*/) = 0;
547
548 virtual void PostPrintPage(UINT /*nPage*/, HDC hDC)
549 {
550 RestoreDC(hDC, m_nPJState);
551 }
552
553 virtual DEVMODE* GetNewDevModeForPage(UINT /*nLastPage*/, UINT /*nPage*/)
554 {
555 return NULL;
556 }
557
558 virtual bool IsValidPage(UINT /*nPage*/)
559 {
560 return true;
561 }
562
563 // Implementation - data
564 int m_nPJState;
565 };
566
567
568 class CPrintJob
569 {
570 public:
571 // Data members
572 CPrinterHandle m_printer;
573 IPrintJobInfo* m_pInfo;
574 DEVMODE* m_pDefDevMode;
575 DOCINFO m_docinfo;
576 int m_nJobID;
577 bool m_bCancel;
578 bool m_bComplete;
579 unsigned long m_nStartPage;
580 unsigned long m_nEndPage;
581
582 // Constructor/destructor
583 CPrintJob() : m_nJobID(0), m_bCancel(false), m_bComplete(true)
584 { }
585
586 ~CPrintJob()
587 {
588 ATLASSERT(IsJobComplete()); // premature destruction?
589 }
590
591 // Operations
592 bool IsJobComplete() const
593 {
594 return m_bComplete;
595 }
596
597 bool StartPrintJob(bool bBackground, HANDLE hPrinter, DEVMODE* pDefaultDevMode,
598 IPrintJobInfo* pInfo, LPCTSTR lpszDocName,
599 unsigned long nStartPage, unsigned long nEndPage,
600 bool bPrintToFile = false, LPCTSTR lpstrOutputFile = NULL)
601 {
602 ATLASSERT(m_bComplete); // previous job not done yet?
603 if (pInfo == NULL)
604 return false;
605
606 memset(&m_docinfo, 0, sizeof(m_docinfo));
607 m_docinfo.cbSize = sizeof(m_docinfo);
608 m_docinfo.lpszDocName = lpszDocName;
609 m_pInfo = pInfo;
610 m_nStartPage = nStartPage;
611 m_nEndPage = nEndPage;
612 m_printer.Attach(hPrinter);
613 m_pDefDevMode = pDefaultDevMode;
614 m_bComplete = false;
615
616 if(bPrintToFile)
617 m_docinfo.lpszOutput = (lpstrOutputFile != NULL) ? lpstrOutputFile : _T("FILE:");
618
619 if (!bBackground)
620 {
621 m_bComplete = true;
622 return StartHelper();
623 }
624
625 // Create a thread and return
626 DWORD dwThreadID = 0;
627 #if !defined(_ATL_MIN_CRT) && defined(_MT)
628 HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, (UINT (WINAPI*)(void*))StartProc, this, 0, (UINT*)&dwThreadID);
629 #else
630 HANDLE hThread = ::CreateThread(NULL, 0, StartProc, (void*)this, 0, &dwThreadID);
631 #endif
632 if (hThread == NULL)
633 return false;
634
635 ::CloseHandle(hThread);
636
637 return true;
638 }
639
640 // Implementation
641 static DWORD WINAPI StartProc(void* p)
642 {
643 CPrintJob* pThis = (CPrintJob*)p;
644 pThis->StartHelper();
645 pThis->m_bComplete = true;
646 return 0;
647 }
648
649 bool StartHelper()
650 {
651 CDC dcPrinter;
652 dcPrinter.Attach(m_printer.CreatePrinterDC(m_pDefDevMode));
653 if (dcPrinter.IsNull())
654 return false;
655
656 m_nJobID = ::StartDoc(dcPrinter, &m_docinfo);
657 if (m_nJobID <= 0)
658 return false;
659
660 m_pInfo->BeginPrintJob(dcPrinter);
661
662 // print all the pages now
663 unsigned long nLastPage = 0;
664 for (unsigned long nPage = m_nStartPage; nPage <= m_nEndPage; nPage++)
665 {
666 if (!m_pInfo->IsValidPage(nPage))
667 break;
668 DEVMODE* pdm = m_pInfo->GetNewDevModeForPage(nLastPage, nPage);
669 if (pdm != NULL)
670 dcPrinter.ResetDC(pdm);
671 dcPrinter.StartPage();
672 m_pInfo->PrePrintPage(nPage, dcPrinter);
673 if (!m_pInfo->PrintPage(nPage, dcPrinter))
674 m_bCancel = true;
675 m_pInfo->PostPrintPage(nPage, dcPrinter);
676 dcPrinter.EndPage();
677 if (m_bCancel)
678 break;
679 nLastPage = nPage;
680 }
681
682 m_pInfo->EndPrintJob(dcPrinter, m_bCancel);
683 if (m_bCancel)
684 ::AbortDoc(dcPrinter);
685 else
686 ::EndDoc(dcPrinter);
687 m_nJobID = 0;
688 return true;
689 }
690
691 // Cancels a print job. Can be called asynchronously.
692 void CancelPrintJob()
693 {
694 m_bCancel = true;
695 }
696 };
697
698
699 ///////////////////////////////////////////////////////////////////////////////
700 // CPrintPreview - Adds print preview support to an existing window
701
702 class CPrintPreview
703 {
704 public:
705 // Data members
706 IPrintJobInfo* m_pInfo;
707 CPrinterHandle m_printer;
708 CEnhMetaFile m_meta;
709 DEVMODE* m_pDefDevMode;
710 DEVMODE* m_pCurDevMode;
711 SIZE m_sizeCurPhysOffset;
712
713 // Constructor
714 CPrintPreview() : m_pInfo(NULL), m_pDefDevMode(NULL), m_pCurDevMode(NULL)
715 {
716 m_sizeCurPhysOffset.cx = 0;
717 m_sizeCurPhysOffset.cy = 0;
718 }
719
720 // Operations
721 void SetPrintPreviewInfo(HANDLE hPrinter, DEVMODE* pDefaultDevMode, IPrintJobInfo* pji)
722 {
723 m_printer.Attach(hPrinter);
724 m_pDefDevMode = pDefaultDevMode;
725 m_pInfo = pji;
726 m_nCurPage = 0;
727 m_pCurDevMode = NULL;
728 }
729
730 void SetEnhMetaFile(HENHMETAFILE hEMF)
731 {
732 m_meta = hEMF;
733 }
734
735 void SetPage(int nPage)
736 {
737 if (!m_pInfo->IsValidPage(nPage))
738 return;
739 m_nCurPage = nPage;
740 m_pCurDevMode = m_pInfo->GetNewDevModeForPage(0, nPage);
741 if (m_pCurDevMode == NULL)
742 m_pCurDevMode = m_pDefDevMode;
743 CDC dcPrinter = m_printer.CreatePrinterDC(m_pCurDevMode);
744
745 int iWidth = dcPrinter.GetDeviceCaps(PHYSICALWIDTH);
746 int iHeight = dcPrinter.GetDeviceCaps(PHYSICALHEIGHT);
747 int nLogx = dcPrinter.GetDeviceCaps(LOGPIXELSX);
748 int nLogy = dcPrinter.GetDeviceCaps(LOGPIXELSY);
749
750 RECT rcMM = { 0, 0, ::MulDiv(iWidth, 2540, nLogx), ::MulDiv(iHeight, 2540, nLogy) };
751
752 m_sizeCurPhysOffset.cx = dcPrinter.GetDeviceCaps(PHYSICALOFFSETX);
753 m_sizeCurPhysOffset.cy = dcPrinter.GetDeviceCaps(PHYSICALOFFSETY);
754
755 CEnhMetaFileDC dcMeta(dcPrinter, &rcMM);
756 m_pInfo->PrePrintPage(nPage, dcMeta);
757 m_pInfo->PrintPage(nPage, dcMeta);
758 m_pInfo->PostPrintPage(nPage, dcMeta);
759 m_meta.Attach(dcMeta.Close());
760 }
761
762 void GetPageRect(RECT& rc, LPRECT prc)
763 {
764 int x1 = rc.right-rc.left;
765 int y1 = rc.bottom - rc.top;
766 if ((x1 < 0) || (y1 < 0))
767 return;
768
769 CEnhMetaFileInfo emfinfo(m_meta);
770 ENHMETAHEADER* pmh = emfinfo.GetEnhMetaFileHeader();
771
772 // Compute whether we are OK vertically or horizontally
773 int x2 = pmh->szlDevice.cx;
774 int y2 = pmh->szlDevice.cy;
775 int y1p = MulDiv(x1, y2, x2);
776 int x1p = MulDiv(y1, x2, y2);
777 ATLASSERT((x1p <= x1) || (y1p <= y1));
778 if (x1p <= x1)
779 {
780 prc->left = rc.left + (x1 - x1p) / 2;
781 prc->right = prc->left + x1p;
782 prc->top = rc.top;
783 prc->bottom = rc.bottom;
784 }
785 else
786 {
787 prc->left = rc.left;
788 prc->right = rc.right;
789 prc->top = rc.top + (y1 - y1p) / 2;
790 prc->bottom = prc->top + y1p;
791 }
792 }
793
794 // Painting helpers
795 void DoPaint(CDCHandle dc)
796 {
797 // this one is not used
798 }
799
800 void DoPaint(CDCHandle dc, RECT& rc)
801 {
802 CEnhMetaFileInfo emfinfo(m_meta);
803 ENHMETAHEADER* pmh = emfinfo.GetEnhMetaFileHeader();
804 int nOffsetX = MulDiv(m_sizeCurPhysOffset.cx, rc.right-rc.left, pmh->szlDevice.cx);
805 int nOffsetY = MulDiv(m_sizeCurPhysOffset.cy, rc.bottom-rc.top, pmh->szlDevice.cy);
806
807 dc.OffsetWindowOrg(-nOffsetX, -nOffsetY);
808 dc.PlayMetaFile(m_meta, &rc);
809 }
810
811 // Implementation - data
812 int m_nCurPage;
813 };
814
815
816 ///////////////////////////////////////////////////////////////////////////////
817 // CPrintPreviewWindow - Implements a print preview window
818
819 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
820 class ATL_NO_VTABLE CPrintPreviewWindowImpl : public ATL::CWindowImpl<T, TBase, TWinTraits>, public CPrintPreview
821 {
822 public:
823 DECLARE_WND_CLASS_EX(NULL, CS_VREDRAW | CS_HREDRAW, -1)
824
825 enum { m_cxOffset = 10, m_cyOffset = 10 };
826
827 // Constructor
828 CPrintPreviewWindowImpl() : m_nMaxPage(0), m_nMinPage(0)
829 { }
830
831 // Operations
832 void SetPrintPreviewInfo(HANDLE hPrinter, DEVMODE* pDefaultDevMode,
833 IPrintJobInfo* pji, int nMinPage, int nMaxPage)
834 {
835 CPrintPreview::SetPrintPreviewInfo(hPrinter, pDefaultDevMode, pji);
836 m_nMinPage = nMinPage;
837 m_nMaxPage = nMaxPage;
838 }
839
840 bool NextPage()
841 {
842 if (m_nCurPage == m_nMaxPage)
843 return false;
844 SetPage(m_nCurPage + 1);
845 Invalidate();
846 return true;
847 }
848
849 bool PrevPage()
850 {
851 if (m_nCurPage == m_nMinPage)
852 return false;
853 if (m_nCurPage == 0)
854 return false;
855 SetPage(m_nCurPage - 1);
856 Invalidate();
857 return true;
858 }
859
860 // Message map and handlers
861 BEGIN_MSG_MAP(CPrintPreviewWindowImpl)
862 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
863 MESSAGE_HANDLER(WM_PAINT, OnPaint)
864 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
865 END_MSG_MAP()
866
867 LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
868 {
869 return 1; // no need for the background
870 }
871
872 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
873 {
874 T* pT = static_cast<T*>(this);
875 RECT rc = { 0 };
876
877 if(wParam != NULL)
878 {
879 pT->DoPrePaint((HDC)wParam, rc);
880 pT->DoPaint((HDC)wParam, rc);
881 }
882 else
883 {
884 CPaintDC dc(m_hWnd);
885 pT->DoPrePaint(dc.m_hDC, rc);
886 pT->DoPaint(dc.m_hDC, rc);
887 }
888
889 return 0;
890 }
891
892 // Painting helper
893 void DoPrePaint(CDCHandle dc, RECT& rc)
894 {
895 RECT rcClient = { 0 };
896 GetClientRect(&rcClient);
897 RECT rcArea = rcClient;
898 T* pT = static_cast<T*>(this);
899 pT; // avoid level 4 warning
900 ::InflateRect(&rcArea, -pT->m_cxOffset, -pT->m_cyOffset);
901 if (rcArea.left > rcArea.right)
902 rcArea.right = rcArea.left;
903 if (rcArea.top > rcArea.bottom)
904 rcArea.bottom = rcArea.top;
905 GetPageRect(rcArea, &rc);
906 CRgn rgn1, rgn2;
907 rgn1.CreateRectRgnIndirect(&rc);
908 rgn2.CreateRectRgnIndirect(&rcClient);
909 rgn2.CombineRgn(rgn1, RGN_DIFF);
910 dc.SelectClipRgn(rgn2);
911 dc.FillRect(&rcClient, COLOR_BTNSHADOW);
912 dc.SelectClipRgn(NULL);
913 dc.FillRect(&rc, (HBRUSH)::GetStockObject(WHITE_BRUSH));
914 }
915
916 // Implementation - data
917 int m_nMinPage;
918 int m_nMaxPage;
919 };
920
921
922 class CPrintPreviewWindow : public CPrintPreviewWindowImpl<CPrintPreviewWindow>
923 {
924 public:
925 DECLARE_WND_CLASS_EX(_T("WTL_PrintPreview"), CS_VREDRAW | CS_HREDRAW, -1)
926 };
927
928
929 ///////////////////////////////////////////////////////////////////////////////
930 // CZoomPrintPreviewWindowImpl - Implements print preview window with zooming
931
932 #ifdef __ATLSCRL_H__
933
934 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
935 class ATL_NO_VTABLE CZoomPrintPreviewWindowImpl : public CPrintPreviewWindowImpl< T, TBase, TWinTraits >, public CZoomScrollImpl< T >
936 {
937 public:
938 bool m_bSized;
939
940 CZoomPrintPreviewWindowImpl()
941 {
942 SetScrollExtendedStyle(SCRL_DISABLENOSCROLL);
943 InitZoom();
944 }
945
946 // should be called to reset data members before recreating window
947 void InitZoom()
948 {
949 m_bSized = false;
950 m_nZoomMode = ZOOMMODE_OFF;
951 m_fZoomScaleMin = 1.0;
952 m_fZoomScale = 1.0;
953 }
954
955 BEGIN_MSG_MAP(CZoomPrintPreviewWindowImpl)
956 MESSAGE_HANDLER(WM_SETCURSOR, CZoomScrollImpl< T >::OnSetCursor)
957 MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
958 MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
959 MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
960 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
961 MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel)
962 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
963 MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel)
964 MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange)
965 MESSAGE_HANDLER(WM_LBUTTONDOWN, CZoomScrollImpl< T >::OnLButtonDown)
966 MESSAGE_HANDLER(WM_MOUSEMOVE, CZoomScrollImpl< T >::OnMouseMove)
967 MESSAGE_HANDLER(WM_LBUTTONUP, CZoomScrollImpl< T >::OnLButtonUp)
968 MESSAGE_HANDLER(WM_CAPTURECHANGED, CZoomScrollImpl< T >::OnCaptureChanged)
969 MESSAGE_HANDLER(WM_SIZE, OnSize)
970 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
971 MESSAGE_HANDLER(WM_PAINT, OnPaint)
972 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
973 ALT_MSG_MAP(1)
974 COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
975 COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown)
976 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp)
977 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown)
978 COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
979 COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom)
980 COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft)
981 COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight)
982 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft)
983 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight)
984 COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft)
985 COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight)
986 END_MSG_MAP()
987
988 LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
989 {
990 SIZE sizeClient = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
991 POINT ptOffset = m_ptOffset;
992 SIZE sizeAll = m_sizeAll;
993 SetScrollSize(sizeClient);
994 if(sizeAll.cx > 0)
995 ptOffset.x = ::MulDiv(ptOffset.x, m_sizeAll.cx, sizeAll.cx);
996 if(sizeAll.cy > 0)
997 ptOffset.y = ::MulDiv(ptOffset.y, m_sizeAll.cy, sizeAll.cy);
998 SetScrollOffset(ptOffset);
999 CScrollImpl< T >::OnSize(uMsg, wParam, lParam, bHandled);
1000 if(!m_bSized)
1001 {
1002 m_bSized = true;
1003 T* pT = static_cast<T*>(this);
1004 pT->ShowScrollBar(SB_HORZ, TRUE);
1005 pT->ShowScrollBar(SB_VERT, TRUE);
1006 }
1007 return 0;
1008 }
1009
1010 LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1011 {
1012 return 1;
1013 }
1014
1015 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1016 {
1017 T* pT = static_cast<T*>(this);
1018 RECT rc = { 0 };
1019
1020 if(wParam != NULL)
1021 {
1022 CDCHandle dc = (HDC)wParam;
1023 int nMapModeSav = dc.GetMapMode();
1024 dc.SetMapMode(MM_ANISOTROPIC);
1025 SIZE szWindowExt = { 0, 0 };
1026 dc.SetWindowExt(m_sizeLogAll, &szWindowExt);
1027 SIZE szViewportExt = { 0, 0 };
1028 dc.SetViewportExt(m_sizeAll, &szViewportExt);
1029 POINT ptViewportOrg = { 0, 0 };
1030 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewportOrg);
1031
1032 pT->DoPrePaint(dc, rc);
1033 pT->DoPaint(dc, rc);
1034
1035 dc.SetMapMode(nMapModeSav);
1036 dc.SetWindowExt(szWindowExt);
1037 dc.SetViewportExt(szViewportExt);
1038 dc.SetViewportOrg(ptViewportOrg);
1039 }
1040 else
1041 {
1042 CPaintDC dc(pT->m_hWnd);
1043 pT->PrepareDC(dc.m_hDC);
1044 pT->DoPrePaint(dc.m_hDC, rc);
1045 pT->DoPaint(dc.m_hDC, rc);
1046 }
1047
1048 return 0;
1049 }
1050
1051 // Painting helpers
1052 void DoPaint(CDCHandle dc)
1053 {
1054 // this one is not used
1055 }
1056
1057 void DoPrePaint(CDCHandle dc, RECT& rc)
1058 {
1059 RECT rcClient = { 0 };
1060 GetClientRect(&rcClient);
1061 RECT rcArea = rcClient;
1062 T* pT = static_cast<T*>(this);
1063 pT; // avoid level 4 warning
1064 ::InflateRect(&rcArea, -pT->m_cxOffset, -pT->m_cyOffset);
1065 if (rcArea.left > rcArea.right)
1066 rcArea.right = rcArea.left;
1067 if (rcArea.top > rcArea.bottom)
1068 rcArea.bottom = rcArea.top;
1069 GetPageRect(rcArea, &rc);
1070 HBRUSH hbrOld = dc.SelectBrush(::GetSysColorBrush(COLOR_BTNSHADOW));
1071 dc.PatBlt(rcClient.left, rcClient.top, rc.left - rcClient.left, rcClient.bottom - rcClient.top, PATCOPY);
1072 dc.PatBlt(rc.left, rcClient.top, rc.right - rc.left, rc.top - rcClient.top, PATCOPY);
1073 dc.PatBlt(rc.right, rcClient.top, rcClient.right - rc.right, rcClient.bottom - rcClient.top, PATCOPY);
1074 dc.PatBlt(rc.left, rc.bottom, rc.right - rc.left, rcClient.bottom - rc.bottom, PATCOPY);
1075 dc.SelectBrush((HBRUSH)::GetStockObject(WHITE_BRUSH));
1076 dc.PatBlt(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
1077 dc.SelectBrush(::GetSysColorBrush(COLOR_3DDKSHADOW));
1078 dc.PatBlt(rc.right, rc.top + 4, 4, rc.bottom - rc.top, PATCOPY);
1079 dc.PatBlt(rc.left + 4, rc.bottom, rc.right - rc.left, 4, PATCOPY);
1080 dc.SelectBrush(hbrOld);
1081 }
1082
1083 void DoPaint(CDCHandle dc, RECT& rc)
1084 {
1085 CEnhMetaFileInfo emfinfo(m_meta);
1086 ENHMETAHEADER* pmh = emfinfo.GetEnhMetaFileHeader();
1087 int nOffsetX = MulDiv(m_sizeCurPhysOffset.cx, rc.right-rc.left, pmh->szlDevice.cx);
1088 int nOffsetY = MulDiv(m_sizeCurPhysOffset.cy, rc.bottom-rc.top, pmh->szlDevice.cy);
1089
1090 dc.OffsetWindowOrg(-nOffsetX, -nOffsetY);
1091 dc.PlayMetaFile(m_meta, &rc);
1092 }
1093 };
1094
1095 class CZoomPrintPreviewWindow : public CZoomPrintPreviewWindowImpl<CZoomPrintPreviewWindow>
1096 {
1097 public:
1098 DECLARE_WND_CLASS_EX(_T("WTL_ZoomPrintPreview"), CS_VREDRAW | CS_HREDRAW, -1)
1099 };
1100
1101 #endif // __ATLSCRL_H__
1102
1103 }; // namespace WTL
1104
1105 #endif // __ATLPRINT_H__
+0
-265
src/third_party/wtl/Include/atlres.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLRES_H__
9 #define __ATLRES_H__
10
11 #pragma once
12
13 #if defined(_WIN32_WCE) && !defined(__ATLRESCE_H__)
14 #error Use atlresCE.h instead of atlres.h for Windows CE
15 #endif
16
17
18 #ifdef RC_INVOKED
19 #ifndef _INC_WINDOWS
20
21 #define _INC_WINDOWS
22
23 #ifndef _WIN32_WCE
24 #define VS_VERSION_INFO 1
25
26 #ifdef APSTUDIO_INVOKED
27 #define APSTUDIO_HIDDEN_SYMBOLS // Ignore following symbols
28 #endif // APSTUDIO_INVOKED
29
30 #ifndef WINVER
31 #define WINVER 0x0400 // default to Windows Version 4.0
32 #endif // !WINVER
33
34 #include <winresrc.h>
35
36 // operation messages sent to DLGINIT
37 #define LB_ADDSTRING (WM_USER+1)
38 #define CB_ADDSTRING (WM_USER+3)
39 #endif // !_WIN32_WCE
40
41 #ifdef APSTUDIO_INVOKED
42 #undef APSTUDIO_HIDDEN_SYMBOLS
43 #endif // APSTUDIO_INVOKED
44
45 #ifdef IDC_STATIC
46 #undef IDC_STATIC
47 #endif // IDC_STATIC
48 #define IDC_STATIC (-1)
49
50 #endif // !_INC_WINDOWS
51 #endif // RC_INVOKED
52
53 #ifdef APSTUDIO_INVOKED
54 #define APSTUDIO_HIDDEN_SYMBOLS
55 #endif // APSTUDIO_INVOKED
56
57 ///////////////////////////////////////////////////////////////////////////////
58 // ATL resource types
59
60 #ifndef RC_INVOKED
61 #define RT_DLGINIT MAKEINTRESOURCE(240)
62 #define RT_TOOLBAR MAKEINTRESOURCE(241)
63 #endif // RC_INVOKED
64
65 ///////////////////////////////////////////////////////////////////////////////
66
67 #ifdef APSTUDIO_INVOKED
68 #undef APSTUDIO_HIDDEN_SYMBOLS
69 #endif // APSTUDIO_INVOKED
70
71 ///////////////////////////////////////////////////////////////////////////////
72 // Standard window components
73
74 #define ID_SEPARATOR 0 // special separator value
75 #define ID_DEFAULT_PANE 0 // default status bar pane
76
77 #ifndef RC_INVOKED // code only
78 // standard control bars (IDW = window ID)
79 #define ATL_IDW_TOOLBAR 0xE800 // main Toolbar for window
80 #define ATL_IDW_STATUS_BAR 0xE801 // Status bar window
81 #define ATL_IDW_COMMAND_BAR 0xE802 // Command bar window
82
83 // parts of a frame window
84 #define ATL_IDW_CLIENT 0xE900
85 #define ATL_IDW_PANE_FIRST 0xE900 // first pane (256 max)
86 #define ATL_IDW_PANE_LAST 0xE9FF
87 #define ATL_IDW_HSCROLL_FIRST 0xEA00 // first Horz scrollbar (16 max)
88 #define ATL_IDW_VSCROLL_FIRST 0xEA10 // first Vert scrollbar (16 max)
89
90 #define ATL_IDW_SIZE_BOX 0xEA20 // size box for splitters
91 #define ATL_IDW_PANE_SAVE 0xEA21 // to shift ATL_IDW_PANE_FIRST
92
93 // bands for a rebar
94 #define ATL_IDW_BAND_FIRST 0xEB00
95 #define ATL_IDW_BAND_LAST 0xEBFF
96 #endif // !RC_INVOKED
97
98 ///////////////////////////////////////////////////////////////////////////////
99 // Standard Commands
100
101 // File commands
102 #define ID_FILE_NEW 0xE100
103 #define ID_FILE_OPEN 0xE101
104 #define ID_FILE_CLOSE 0xE102
105 #define ID_FILE_SAVE 0xE103
106 #define ID_FILE_SAVE_AS 0xE104
107 #define ID_FILE_PAGE_SETUP 0xE105
108 #define ID_FILE_PRINT_SETUP 0xE106
109 #define ID_FILE_PRINT 0xE107
110 #define ID_FILE_PRINT_DIRECT 0xE108
111 #define ID_FILE_PRINT_PREVIEW 0xE109
112 #define ID_FILE_UPDATE 0xE10A
113 #define ID_FILE_SAVE_COPY_AS 0xE10B
114 #define ID_FILE_SEND_MAIL 0xE10C
115
116 #define ID_FILE_MRU_FIRST 0xE110
117 #define ID_FILE_MRU_FILE1 0xE110 // range - 16 max
118 #define ID_FILE_MRU_FILE2 0xE111
119 #define ID_FILE_MRU_FILE3 0xE112
120 #define ID_FILE_MRU_FILE4 0xE113
121 #define ID_FILE_MRU_FILE5 0xE114
122 #define ID_FILE_MRU_FILE6 0xE115
123 #define ID_FILE_MRU_FILE7 0xE116
124 #define ID_FILE_MRU_FILE8 0xE117
125 #define ID_FILE_MRU_FILE9 0xE118
126 #define ID_FILE_MRU_FILE10 0xE119
127 #define ID_FILE_MRU_FILE11 0xE11A
128 #define ID_FILE_MRU_FILE12 0xE11B
129 #define ID_FILE_MRU_FILE13 0xE11C
130 #define ID_FILE_MRU_FILE14 0xE11D
131 #define ID_FILE_MRU_FILE15 0xE11E
132 #define ID_FILE_MRU_FILE16 0xE11F
133 #define ID_FILE_MRU_LAST 0xE11F
134
135 // Edit commands
136 #define ID_EDIT_CLEAR 0xE120
137 #define ID_EDIT_CLEAR_ALL 0xE121
138 #define ID_EDIT_COPY 0xE122
139 #define ID_EDIT_CUT 0xE123
140 #define ID_EDIT_FIND 0xE124
141 #define ID_EDIT_PASTE 0xE125
142 #define ID_EDIT_PASTE_LINK 0xE126
143 #define ID_EDIT_PASTE_SPECIAL 0xE127
144 #define ID_EDIT_REPEAT 0xE128
145 #define ID_EDIT_REPLACE 0xE129
146 #define ID_EDIT_SELECT_ALL 0xE12A
147 #define ID_EDIT_UNDO 0xE12B
148 #define ID_EDIT_REDO 0xE12C
149 #define ID_EDIT_DELETE ID_EDIT_CLEAR
150 #define ID_EDIT_FIND_NEXT ID_EDIT_REPEAT
151 #define ID_EDIT_FIND_PREVIOUS 0xE12D
152
153 // Window commands
154 #define ID_WINDOW_NEW 0xE130
155 #define ID_WINDOW_ARRANGE 0xE131
156 #define ID_WINDOW_CASCADE 0xE132
157 #define ID_WINDOW_TILE_HORZ 0xE133
158 #define ID_WINDOW_TILE_VERT 0xE134
159 #define ID_WINDOW_SPLIT 0xE135
160 #ifndef RC_INVOKED // code only
161 #define ATL_IDM_WINDOW_FIRST 0xE130
162 #define ATL_IDM_WINDOW_LAST 0xE13F
163 #define ATL_IDM_FIRST_MDICHILD 0xFF00 // window list starts here
164 #define ATL_IDM_LAST_MDICHILD 0xFFFD
165 #endif // !RC_INVOKED
166 // TabView
167 #define ID_WINDOW_TABFIRST 0xFF00 // = ATL_IDM_FIRST_MDICHILD
168 #define ID_WINDOW_TABLAST 0xFFFD
169 #define ID_WINDOW_SHOWTABLIST 0xFFFE
170
171 // Help and App commands
172 #define ID_APP_ABOUT 0xE140
173 #define ID_APP_EXIT 0xE141
174 #define ID_HELP_INDEX 0xE142
175 #define ID_HELP_FINDER 0xE143
176 #define ID_HELP_USING 0xE144
177 #define ID_CONTEXT_HELP 0xE145 // shift-F1
178 // special commands for processing help
179 #define ID_HELP 0xE146 // first attempt for F1
180 #define ID_DEFAULT_HELP 0xE147 // last attempt
181
182 // Misc
183 #define ID_NEXT_PANE 0xE150
184 #define ID_PREV_PANE 0xE151
185 #define ID_PANE_CLOSE 0xE152
186 #define ID_PANE_NEXT ID_NEXT_PANE
187 #define ID_PANE_PREVIOUS ID_PREV_PANE
188
189 // Format
190 #define ID_FORMAT_FONT 0xE160
191
192 // Scroll
193 #define ID_SCROLL_UP 0xE170
194 #define ID_SCROLL_DOWN 0xE171
195 #define ID_SCROLL_PAGE_UP 0xE172
196 #define ID_SCROLL_PAGE_DOWN 0xE173
197 #define ID_SCROLL_TOP 0xE174
198 #define ID_SCROLL_BOTTOM 0xE175
199 #define ID_SCROLL_LEFT 0xE176
200 #define ID_SCROLL_RIGHT 0xE177
201 #define ID_SCROLL_PAGE_LEFT 0xE178
202 #define ID_SCROLL_PAGE_RIGHT 0xE179
203 #define ID_SCROLL_ALL_LEFT 0xE17A
204 #define ID_SCROLL_ALL_RIGHT 0xE17B
205
206 // OLE commands
207 #define ID_OLE_INSERT_NEW 0xE200
208 #define ID_OLE_EDIT_LINKS 0xE201
209 #define ID_OLE_EDIT_CONVERT 0xE202
210 #define ID_OLE_EDIT_CHANGE_ICON 0xE203
211 #define ID_OLE_EDIT_PROPERTIES 0xE204
212 #define ID_OLE_VERB_FIRST 0xE210 // range - 16 max
213 #ifndef RC_INVOKED // code only
214 #define ID_OLE_VERB_LAST 0xE21F
215 #endif // !RC_INVOKED
216
217 // View commands (same number used as IDW used for toolbar and status bar)
218 #define ID_VIEW_TOOLBAR 0xE800
219 #define ID_VIEW_STATUS_BAR 0xE801
220 #define ID_VIEW_REFRESH 0xE803
221 #define ID_VIEW_RIBBON 0xE804
222
223 ///////////////////////////////////////////////////////////////////////////////
224 // Standard control IDs
225
226 #ifdef IDC_STATIC
227 #undef IDC_STATIC
228 #endif // IDC_STATIC
229 #define IDC_STATIC (-1) // all static controls
230
231 ///////////////////////////////////////////////////////////////////////////////
232 // Standard string error/warnings
233
234 // idle status bar message
235 #define ATL_IDS_IDLEMESSAGE 0xE001
236
237 #ifndef RC_INVOKED // code only
238 #define ATL_IDS_SCFIRST 0xEF00
239 #endif // !RC_INVOKED
240
241 #define ATL_IDS_SCSIZE 0xEF00
242 #define ATL_IDS_SCMOVE 0xEF01
243 #define ATL_IDS_SCMINIMIZE 0xEF02
244 #define ATL_IDS_SCMAXIMIZE 0xEF03
245 #define ATL_IDS_SCNEXTWINDOW 0xEF04
246 #define ATL_IDS_SCPREVWINDOW 0xEF05
247 #define ATL_IDS_SCCLOSE 0xEF06
248 #define ATL_IDS_SCRESTORE 0xEF12
249 #define ATL_IDS_SCTASKLIST 0xEF13
250
251 #define ATL_IDS_MDICHILD 0xEF1F
252 #define ATL_IDS_MRU_FILE 0xEFDA
253
254 ///////////////////////////////////////////////////////////////////////////////
255 // Misc. control IDs
256
257 // Property Sheet control id's (determined with Spy++)
258 #define ID_APPLY_NOW 0x3021
259 #define ID_WIZBACK 0x3023
260 #define ID_WIZNEXT 0x3024
261 #define ID_WIZFINISH 0x3025
262 #define ATL_IDC_TAB_CONTROL 0x3020
263
264 #endif // __ATLRES_H__
+0
-90
src/third_party/wtl/Include/atlresce.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLRESCE_H__
9 #define __ATLRESCE_H__
10
11 #pragma once
12
13 #ifndef _WIN32_WCE
14 #error atlresCE.h is only for Windows CE
15 #endif
16
17
18 #ifdef RC_INVOKED
19 #ifndef _INC_WINDOWS
20
21 #define VS_VERSION_INFO 1
22
23 #ifdef APSTUDIO_INVOKED
24 #define APSTUDIO_HIDDEN_SYMBOLS // Ignore following symbols
25 #endif // APSTUDIO_INVOKED
26
27 #ifndef WINVER
28 #define WINVER 0x0400 // default to Windows Version 4.0
29 #endif // !WINVER
30
31 #if !defined(WCEOLE_ENABLE_DIALOGEX)
32 #define DIALOGEX DIALOG DISCARDABLE
33 #endif
34
35 #include <commctrl.h>
36 #define SHMENUBAR RCDATA
37
38 #if defined(SHELLSDK_MODULES_AYGSHELL)
39 #include <aygshell.h>
40 #else
41 #define NOMENU 0xFFFF
42 #define IDS_SHNEW 1
43 #define IDM_SHAREDNEW 10
44 #define IDM_SHAREDNEWDEFAULT 11
45 #endif
46 #ifndef I_IMAGENONE
47 #define I_IMAGENONE (-2)
48 #endif
49
50 #include <windows.h>
51
52 #endif // !_INC_WINDOWS
53 #endif // RC_INVOKED
54
55 #include "atlres.h"
56
57 #ifdef APSTUDIO_INVOKED
58 #undef APSTUDIO_HIDDEN_SYMBOLS
59 #endif // APSTUDIO_INVOKED
60
61 // Visual Studio dialog editor bug fix
62 #ifndef DS_FIXEDSYS
63 #define DS_FIXEDSYS 0
64 #endif
65
66 #define IDC_INFOSTATIC 0xFFFE // == IDC_STATIC -1
67
68 ///////////////////////////////////////////////////////////////////////////////
69 // Smartphone and PPC 2005 Resource IDs
70
71 // Command and associated string resource IDs
72 #define ID_MENU_OK 0xE790
73 #define ID_MENU_CANCEL 0xE791
74 #define ID_MENU 0xE792
75 #define ID_ACTION 0xE793
76 #define ID_VIEW_FULLSCREEN 0xE802
77
78 // MenuBar resource IDs
79 #define ATL_IDM_MENU_DONE 0xE701
80 #define ATL_IDM_MENU_CANCEL 0xE702
81 #define ATL_IDM_MENU_DONECANCEL 0xE703
82
83 // Default device MenuBar control ID and MenuBar resource ID
84 #define ATL_IDW_MENU_BAR 0xE802
85
86 // SmartPhone spinned controls ID offset for CSpinCtrl
87 #define ATL_IDW_SPIN_ID 9999
88
89 #endif // __ATLRESCE_H__
+0
-3456
src/third_party/wtl/Include/atlribbon.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLRIBBON_H__
9 #define __ATLRIBBON_H__
10
11 #pragma once
12
13 #if (_MSC_VER < 1500)
14 #error atlribbon.h requires Visual C++ 2008 compiler or higher
15 #endif
16
17 #ifndef _UNICODE
18 #error atlribbon.h requires the Unicode character set
19 #endif
20
21 #if !defined(NTDDI_WIN7) || (NTDDI_VERSION < NTDDI_WIN7)
22 #error atlribbon.h requires the Windows 7 SDK or higher
23 #endif
24
25 #ifdef _WIN32_WCE
26 #error atlribbon.h is not supported on Windows CE
27 #endif
28
29 #ifndef __ATLAPP_H__
30 #error atlribbon.h requires atlapp.h to be included first
31 #endif
32
33 #if (_ATL_VER < 0x0700)
34 #include <shlwapi.h>
35 #pragma comment(lib, "shlwapi.lib")
36 #endif
37
38 #include <atlmisc.h> // for RecentDocumentList classes
39 #include <atlframe.h> // for Frame and UpdateUI classes
40 #include <atlctrls.h> // required for atlctrlw.h
41 #include <atlctrlw.h> // for CCommandBarCtrl
42
43 #if !defined(_WTL_USE_CSTRING) && !defined(__ATLSTR_H__)
44 #pragma warning(push)
45 #pragma warning(disable: 4530) // unwind semantics not enabled
46 #include <string>
47 #pragma warning(pop)
48 #endif
49
50 #include <dwmapi.h>
51 #pragma comment(lib, "dwmapi.lib")
52
53 #include <UIRibbon.h>
54 #include <UIRibbonPropertyHelpers.h>
55 #pragma comment(lib, "propsys.lib")
56
57 #include <Richedit.h> // for CHARFORMAT2
58
59
60 ///////////////////////////////////////////////////////////////////////////////
61 // Classes in this file:
62 //
63 // CRibbonUpdateUI : Automatic mapping of ribbon UI elements
64 //
65 // RibbonUI::Text
66 // RibbonUI::CharFormat
67 // RibbonUI::ICtrl
68 // RibbonUI::CtrlImpl
69 // RibbonUI::CommandCtrlImpl
70 // RibbonUI::ItemProperty
71 // RibbonUI::CollectionImplBase
72 // RibbonUI::CollectionImpl
73 // RibbonUI::TextCollectionImpl
74 // RibbonUI::ItemCollectionImpl
75 // RibbonUI::ComboCollectionImpl
76 // RibbonUI::CommandCollectionImpl
77 // RibbonUI::ToolbarCollectionImpl
78 // RibbonUI::SimpleCollectionImpl
79 // RibbonUI::CollectionCtrlImpl
80 // RibbonUI::ToolbarGalleryCtrlImpl
81 // RibbonUI::SimpleCollectionCtrlImpl
82 // RibbonUI::RecentItemsCtrlImpl
83 // RibbonUI::FontCtrlImpl
84 // RibbonUI::ColorCtrlImpl
85 // RibbonUI::SpinnerCtrlImpl
86 //
87 // RibbonUI::CRibbonImpl
88 // CRibbonImpl::CRibbonComboCtrl
89 // CRibbonImpl::CRibbonItemGalleryCtrl
90 // CRibbonImpl::CRibbonCommandGalleryCtrl
91 // CRibbonImpl::CRibbonToolbarGalleryCtrl
92 // CRibbonImpl::CRibbonSimpleComboCtrl
93 // CRibbonImpl::CRibbonSimpleGalleryCtrl
94 // CRibbonImpl::CRibbonRecentItemsCtrl
95 // CRibbonImpl::CRibbonColorCtrl
96 // CRibbonImpl::CRibbonFontCtrl
97 // CRibbonImpl::CRibbonSpinnerCtrl
98 // CRibbonImpl::CRibbonFloatSpinnerCtrl
99 // CRibbonImpl::CRibbonCommandCtrl
100 //
101 // CRibbonFrameWindowImplBase
102 // CRibbonFrameWindowImpl
103 // CRibbonMDIFrameWindowImpl
104 // CRibbonPersist
105 //
106 // Global functions:
107 // RibbonUI::SetPropertyVal()
108 // RibbonUI::GetImage()
109
110
111 // Constants
112
113 #ifndef RIBBONUI_MAX_TEXT
114 #define RIBBONUI_MAX_TEXT 128
115 #endif
116
117 #define TWIPS_PER_POINT 20 // For font size
118
119
120 namespace WTL
121 {
122
123 ///////////////////////////////////////////////////////////////////////////////
124 // CRibbonUpdateUI : Automatic mapping of ribbon UI elements
125
126 template <class T>
127 class CRibbonUpdateUI : public CAutoUpdateUI<T>
128 {
129 public:
130 enum
131 {
132 UPDUI_RIBBON = 0x0080,
133 UPDUI_PERSIST = 0x0020
134 };
135
136 bool IsRibbonElement(const _AtlUpdateUIMap& UIMap)
137 {
138 return (UIMap.m_wType & UPDUI_RIBBON) != 0;
139 }
140
141 bool IsRibbonID(UINT nID)
142 {
143 for(int i = 0; i < m_arrUIMap.GetSize(); i++)
144 {
145 if(m_arrUIMap[i].m_nID == nID)
146 return IsRibbonElement(m_arrUIMap[i]);
147 }
148
149 return false;
150 }
151
152 // Element
153 bool UIAddRibbonElement(UINT nID)
154 {
155 return UIAddElement<UPDUI_RIBBON>(nID);
156 }
157
158 bool UIRemoveRibbonElement(UINT nID)
159 {
160 return UIRemoveElement<UPDUI_RIBBON>(nID);
161 }
162
163 bool UIPersistElement(UINT nID, bool bPersist = true)
164 {
165 return bPersist ?
166 UIAddElement<UPDUI_PERSIST>(nID) :
167 UIRemoveElement<UPDUI_PERSIST>(nID);
168 }
169
170 // methods for Ribbon elements
171 BOOL UISetText(int nID, LPCWSTR sText, BOOL bForceUpdate = FALSE)
172 {
173 T* pT = static_cast<T*>(this);
174 BOOL bRes = CUpdateUIBase::UISetText(nID, sText, bForceUpdate);
175 if (pT->IsRibbonUI() && IsRibbonID(nID))
176 bRes = SUCCEEDED(pT->InvalidateProperty(nID, UI_PKEY_Label));
177 return bRes;
178 }
179
180 BOOL UISetText(int nID, UINT uIdResource, BOOL bForceUpdate = FALSE)
181 {
182 CTempBuffer<WCHAR> sText(RIBBONUI_MAX_TEXT);
183 int nRet = AtlLoadString(uIdResource, sText, RIBBONUI_MAX_TEXT);
184 if(nRet > 0)
185 UISetText(nID, sText, bForceUpdate);
186 return (nRet > 0) ? TRUE : FALSE;
187 }
188
189 LPCTSTR UIGetText(int nID)
190 {
191 T* pT = static_cast<T*>(this);
192 LPCTSTR sUI = CAutoUpdateUI::UIGetText(nID);
193
194 // replace 'tab' by 'space' for RibbonUI elements
195 if (sUI && pT->IsRibbonUI() && IsRibbonID(nID) && wcschr(sUI, L'\t'))
196 {
197 static WCHAR sText[RIBBONUI_MAX_TEXT] = { 0 };
198 wcscpy_s(sText, sUI);
199 WCHAR* pch = wcschr(sText, L'\t');
200 if (pch != NULL)
201 *pch = L' ';
202 return sText;
203 }
204 else
205 {
206 return sUI;
207 }
208 }
209
210 BOOL UIEnable(int nID, BOOL bEnable, BOOL bForceUpdate = FALSE)
211 {
212 T* pT = static_cast<T*>(this);
213 BOOL bRes = CUpdateUIBase::UIEnable(nID, bEnable, bForceUpdate);
214 if (pT->IsRibbonUI() && IsRibbonID(nID))
215 bRes = SUCCEEDED(pT->SetProperty((WORD)nID, UI_PKEY_Enabled, bEnable));
216 return bRes;
217 }
218
219 BOOL UISetCheck(int nID, INT nCheck, BOOL bForceUpdate = FALSE)
220 {
221 if ((nCheck == 0) || (nCheck == 1))
222 return UISetCheck(nID, nCheck != 0, bForceUpdate);
223 else
224 return CUpdateUIBase::UISetCheck(nID, nCheck, bForceUpdate);
225 }
226
227 BOOL UISetCheck(int nID, bool bCheck, BOOL bForceUpdate = FALSE)
228 {
229 T* pT = static_cast<T*>(this);
230 BOOL bRes = CUpdateUIBase::UISetCheck(nID, bCheck, bForceUpdate);
231 if (bRes && pT->IsRibbonUI() && IsRibbonID(nID))
232 bRes = SUCCEEDED(pT->SetProperty((WORD)nID, UI_PKEY_BooleanValue, bCheck));
233 return bRes;
234 }
235 };
236
237
238 ///////////////////////////////////////////////////////////////////////////////
239 // RibbonUI namespace
240 //
241
242 namespace RibbonUI
243 {
244
245 // Minimal string allocation support for various PROPERTYKEY values
246 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
247 typedef _CSTRING_NS::CString Text;
248 #else
249 class Text : public std::wstring
250 {
251 public:
252 Text(std::wstring& s) : std::wstring(s)
253 { }
254 Text(LPCWSTR s) : std::wstring(s)
255 { }
256 Text()
257 { }
258 bool IsEmpty()
259 {
260 return empty();
261 }
262 operator LPCWSTR()
263 {
264 return c_str();
265 }
266 Text& operator =(LPCWSTR s)
267 {
268 return static_cast<Text&>(std::wstring::operator =(s));
269 }
270 };
271 #endif
272
273 // PROPERTYKEY enum and helpers
274 enum k_KEY
275 {
276 // state
277 k_Enabled = 1, k_BooleanValue = 200,
278 // text properties
279 k_LabelDescription = 2, k_Keytip = 3, k_Label = 4, k_TooltipDescription = 5, k_TooltipTitle = 6,
280 // image properties
281 k_LargeImage = 7, k_LargeHighContrastImage = 8, k_SmallImage = 9, k_SmallHighContrastImage = 10,
282 // collection properties
283 k_ItemsSource = 101, k_Categories = 102, k_SelectedItem = 104,
284 // collection item properties
285 k_CommandId = 100, k_CategoryId = 103, k_CommandType = 105, k_ItemImage = 106,
286 // combo control property
287 k_StringValue = 202,
288 // spinner control properties
289 k_DecimalValue = 201, k_MaxValue = 203, k_MinValue, k_Increment, k_DecimalPlaces, k_FormatString, k_RepresentativeString = 208,
290 // font control properties
291 k_FontProperties = 300, k_FontProperties_Family, k_FontProperties_Size, k_FontProperties_Bold, k_FontProperties_Italic = 304,
292 k_FontProperties_Underline = 305, k_FontProperties_Strikethrough, k_FontProperties_VerticalPositioning, k_FontProperties_ForegroundColor = 308,
293 k_FontProperties_BackgroundColor = 309, k_FontProperties_ForegroundColorType, k_FontProperties_BackgroundColorType, k_FontProperties_ChangedProperties = 312,
294 k_FontProperties_DeltaSize = 313,
295 // recent items properties
296 k_RecentItems = 350, k_Pinned = 351,
297 // color control properties
298 k_Color = 400, k_ColorType = 401, k_ColorMode,
299 k_ThemeColorsCategoryLabel = 403, k_StandardColorsCategoryLabel, k_RecentColorsCategoryLabel = 405, k_AutomaticColorLabel = 406,
300 k_NoColorLabel = 407, k_MoreColorsLabel = 408,
301 k_ThemeColors = 409, k_StandardColors = 410, k_ThemeColorsTooltips = 411, k_StandardColorsTooltips = 412,
302 // Ribbon state
303 k_Viewable = 1000, k_Minimized = 1001, k_QuickAccessToolbarDock = 1002, k_ContextAvailable = 1100,
304 // Ribbon UI colors
305 k_GlobalBackgroundColor = 2000, k_GlobalHighlightColor, k_GlobalTextColor = 2002
306 };
307
308 inline k_KEY k_(REFPROPERTYKEY key)
309 {
310 return (k_KEY)key.fmtid.Data1;
311 }
312
313 // PROPERTYKEY value assignment and specializations
314 //
315 template <typename V>
316 HRESULT SetPropertyVal(REFPROPERTYKEY key, V val, PROPVARIANT* ppv)
317 {
318 switch (k_(key))
319 {
320 case k_Enabled:
321 case k_BooleanValue:
322 return InitPropVariantFromBoolean(val, ppv);
323 default:
324 return UIInitPropertyFromUInt32(key, val, ppv);
325 }
326 }
327
328 inline HRESULT SetPropertyVal(REFPROPERTYKEY key, DOUBLE val, PROPVARIANT* ppv)
329 {
330 return SetPropertyVal(key, (LONG)val, ppv);
331 }
332
333 inline HRESULT SetPropertyVal(REFPROPERTYKEY key, IUIImage* val, PROPVARIANT* ppv)
334 {
335 HRESULT hr = UIInitPropertyFromImage(key, val, ppv);
336 ATLVERIFY(val->Release() == 1);
337 return hr;
338 }
339
340 inline HRESULT SetPropertyVal(REFPROPERTYKEY key, IUnknown* val, PROPVARIANT* ppv)
341 {
342 return UIInitPropertyFromInterface(key, val, ppv);
343 }
344
345 inline HRESULT SetPropertyVal(REFPROPERTYKEY key, IPropertyStore* val, PROPVARIANT* ppv)
346 {
347 return UIInitPropertyFromInterface(key, val, ppv);
348 }
349
350 inline HRESULT SetPropertyVal(REFPROPERTYKEY key, SAFEARRAY* val, PROPVARIANT* ppv)
351 {
352 return UIInitPropertyFromIUnknownArray(key, val, ppv);
353 }
354
355 inline HRESULT SetPropertyVal(REFPROPERTYKEY key, DECIMAL* val, PROPVARIANT* ppv)
356 {
357 return UIInitPropertyFromDecimal(key, *val, ppv);
358 }
359
360 inline HRESULT SetPropertyVal(REFPROPERTYKEY key, bool val, PROPVARIANT* ppv)
361 {
362 return UIInitPropertyFromBoolean(key, val, ppv);
363 }
364
365 inline HRESULT SetPropertyVal(REFPROPERTYKEY key, LPCWSTR val, PROPVARIANT* ppv)
366 {
367 return UIInitPropertyFromString(key, val, ppv);
368 }
369
370 // CharFormat helper struct for RibbonUI font control
371 //
372 struct CharFormat : CHARFORMAT2
373 {
374 // Default constructor
375 CharFormat()
376 {
377 cbSize = sizeof(CHARFORMAT2);
378 Reset();
379 }
380
381 // Copy constructor
382 CharFormat(const CharFormat& cf)
383 {
384 ::CopyMemory(this, &cf, sizeof(CHARFORMAT2));
385 }
386
387 // Assign operator
388 CharFormat& operator =(const CharFormat& cf)
389 {
390 ::CopyMemory(this, &cf, sizeof(CHARFORMAT2));
391 return (*this);
392 }
393
394 void Reset()
395 {
396 uValue = dwMask = dwEffects = 0;
397 PropVariantInit(&propvar);
398 }
399
400 void operator <<(IPropertyStore* pStore)
401 {
402 if (pStore == NULL)
403 {
404 ATLASSERT(FALSE);
405 return;
406 }
407
408 static void (CharFormat::*Getk_[])(IPropertyStore*) =
409 {
410 &CharFormat::Getk_Family,
411 &CharFormat::Getk_FontProperties_Size,
412 &CharFormat::Getk_MaskEffect<CFM_BOLD, CFE_BOLD, UI_PKEY_FontProperties_Bold>,
413 &CharFormat::Getk_MaskEffect<CFM_ITALIC, CFE_ITALIC, UI_PKEY_FontProperties_Italic>,
414 &CharFormat::Getk_MaskEffect<CFM_UNDERLINE, CFE_UNDERLINE, UI_PKEY_FontProperties_Underline>,
415 &CharFormat::Getk_MaskEffect<CFM_STRIKEOUT, CFE_STRIKEOUT, UI_PKEY_FontProperties_Strikethrough>,
416 &CharFormat::Getk_VerticalPositioning,
417 &CharFormat::Getk_Color<CFM_COLOR, UI_PKEY_FontProperties_ForegroundColor>,
418 &CharFormat::Getk_Color<CFM_BACKCOLOR, UI_PKEY_FontProperties_BackgroundColor>,
419 &CharFormat::Getk_ColorType<CFM_COLOR, CFE_AUTOCOLOR, UI_SWATCHCOLORTYPE_AUTOMATIC, UI_PKEY_FontProperties_ForegroundColorType>,
420 &CharFormat::Getk_ColorType<CFM_BACKCOLOR, CFE_AUTOBACKCOLOR, UI_SWATCHCOLORTYPE_NOCOLOR, UI_PKEY_FontProperties_BackgroundColorType>,
421 };
422
423 DWORD nProps = 0;
424 Reset();
425
426 ATLVERIFY(SUCCEEDED(pStore->GetCount(&nProps)));
427 for (DWORD iProp = 0; iProp < nProps; iProp++)
428 {
429 PROPERTYKEY key;
430 ATLVERIFY(SUCCEEDED(pStore->GetAt(iProp, &key)));
431 ATLASSERT(k_(key) >= k_FontProperties_Family);
432
433 if (k_(key) <= k_FontProperties_BackgroundColorType)
434 (this->*Getk_[k_(key) - k_FontProperties_Family])(pStore);
435 }
436 }
437
438 void operator >>(IPropertyStore* pStore)
439 {
440 if (pStore == NULL)
441 {
442 ATLASSERT(FALSE);
443 return;
444 }
445
446 PutFace(pStore);
447 PutSize(pStore);
448 PutMaskEffect(CFM_BOLD, CFE_BOLD, UI_PKEY_FontProperties_Bold, pStore);
449 PutMaskEffect(CFM_ITALIC, CFE_ITALIC, UI_PKEY_FontProperties_Italic, pStore);
450 PutMaskEffect(CFM_UNDERLINE, CFE_UNDERLINE, UI_PKEY_FontProperties_Underline, pStore);
451 PutMaskEffect(CFM_STRIKEOUT, CFE_STRIKEOUT, UI_PKEY_FontProperties_Strikethrough, pStore);
452 PutVerticalPos(pStore);
453 PutColor(pStore);
454 PutBackColor(pStore);
455 }
456
457 private:
458 PROPVARIANT propvar;
459 UINT uValue;
460
461 // Getk_ functions
462 void Getk_Family(IPropertyStore* pStore)
463 {
464 if (SUCCEEDED(pStore->GetValue(UI_PKEY_FontProperties_Family, &propvar)))
465 {
466 PropVariantToString(propvar, szFaceName, LF_FACESIZE);
467 if (*szFaceName)
468 dwMask |= CFM_FACE;
469 }
470 }
471
472 void Getk_FontProperties_Size(IPropertyStore* pStore)
473 {
474 if (SUCCEEDED(pStore->GetValue(UI_PKEY_FontProperties_Size, &propvar)))
475 {
476 DECIMAL decSize = { 0 };
477 UIPropertyToDecimal(UI_PKEY_FontProperties_Size, propvar, &decSize);
478 DOUBLE dSize = 0;
479 VarR8FromDec(&decSize, &dSize);
480 if (dSize > 0)
481 {
482 dwMask |= CFM_SIZE;
483 yHeight = (LONG)(dSize * TWIPS_PER_POINT);
484 }
485 }
486 }
487
488 template <DWORD t_dwMask, DWORD t_dwEffects, REFPROPERTYKEY key>
489 void Getk_MaskEffect(IPropertyStore* pStore)
490 {
491 if (SUCCEEDED(pStore->GetValue(key, &propvar)))
492 {
493 UIPropertyToUInt32(key, propvar, &uValue);
494 if ((UI_FONTPROPERTIES)uValue != UI_FONTPROPERTIES_NOTAVAILABLE)
495 {
496 dwMask |= t_dwMask;
497 dwEffects |= ((UI_FONTPROPERTIES) uValue == UI_FONTPROPERTIES_SET) ? t_dwEffects : 0;
498 }
499 }
500 }
501
502 void Getk_VerticalPositioning(IPropertyStore* pStore)
503 {
504 if (SUCCEEDED(pStore->GetValue(UI_PKEY_FontProperties_VerticalPositioning, &propvar)))
505 {
506 UIPropertyToUInt32(UI_PKEY_FontProperties_VerticalPositioning, propvar, &uValue);
507 UI_FONTVERTICALPOSITION uVerticalPosition = (UI_FONTVERTICALPOSITION) uValue;
508 if ((uVerticalPosition != UI_FONTVERTICALPOSITION_NOTAVAILABLE))
509 {
510 dwMask |= (CFM_SUPERSCRIPT | CFM_SUBSCRIPT);
511 if (uVerticalPosition != UI_FONTVERTICALPOSITION_NOTSET)
512 {
513 dwEffects |= (uVerticalPosition == UI_FONTVERTICALPOSITION_SUPERSCRIPT) ? CFE_SUPERSCRIPT : CFE_SUBSCRIPT;
514 }
515 }
516 }
517 }
518
519 template <DWORD t_dwMask, REFPROPERTYKEY key>
520 void Getk_Color(IPropertyStore* pStore)
521 {
522 UINT32 color = 0;
523 if (SUCCEEDED(pStore->GetValue(key, &propvar)))
524 {
525 UIPropertyToUInt32(key, propvar, &color);
526 dwMask |= t_dwMask;
527
528 if (t_dwMask == CFM_COLOR)
529 crTextColor = color;
530 else
531 crBackColor = color;
532 }
533 }
534
535 template <DWORD t_dwMask, DWORD t_dwEffects, UI_SWATCHCOLORTYPE t_type, REFPROPERTYKEY key>
536 void Getk_ColorType(IPropertyStore* pStore)
537 {
538 if (SUCCEEDED(pStore->GetValue(key, &propvar)))
539 {
540 UIPropertyToUInt32(key, propvar, &uValue);
541 if (t_type == (UI_SWATCHCOLORTYPE)uValue)
542 {
543 dwMask |= t_dwMask;
544 dwEffects |= t_dwEffects;
545 }
546 }
547 }
548
549 // Put functions
550 void PutMaskEffect(WORD dwMaskVal, WORD dwEffectVal, REFPROPERTYKEY key, IPropertyStore* pStore)
551 {
552 PROPVARIANT var;
553 UI_FONTPROPERTIES uProp = UI_FONTPROPERTIES_NOTAVAILABLE;
554 if ((dwMask & dwMaskVal) != 0)
555 uProp = dwEffects & dwEffectVal ? UI_FONTPROPERTIES_SET : UI_FONTPROPERTIES_NOTSET;
556 SetPropertyVal(key, uProp, &var);
557 pStore->SetValue(key, var);
558 }
559
560 void PutVerticalPos(IPropertyStore* pStore)
561 {
562 PROPVARIANT var;
563 UI_FONTVERTICALPOSITION uProp = UI_FONTVERTICALPOSITION_NOTAVAILABLE;
564
565 if ((dwMask & CFE_SUBSCRIPT) != 0)
566 {
567 if ((dwMask & CFM_SUBSCRIPT) && (dwEffects & CFE_SUBSCRIPT))
568 uProp = UI_FONTVERTICALPOSITION_SUBSCRIPT;
569 else
570 uProp = UI_FONTVERTICALPOSITION_SUPERSCRIPT;
571 }
572 else if ((dwMask & CFM_OFFSET) != 0)
573 {
574 if (yOffset > 0)
575 uProp = UI_FONTVERTICALPOSITION_SUPERSCRIPT;
576 else if (yOffset < 0)
577 uProp = UI_FONTVERTICALPOSITION_SUBSCRIPT;
578 }
579
580 SetPropertyVal(UI_PKEY_FontProperties_VerticalPositioning, uProp, &var);
581 pStore->SetValue(UI_PKEY_FontProperties_VerticalPositioning, var);
582 }
583
584 void PutFace(IPropertyStore* pStore)
585 {
586 PROPVARIANT var;
587 SetPropertyVal(UI_PKEY_FontProperties_Family,
588 dwMask & CFM_FACE ? szFaceName : L"", &var);
589 pStore->SetValue(UI_PKEY_FontProperties_Family, var);
590 }
591
592 void PutSize(IPropertyStore* pStore)
593 {
594 PROPVARIANT var;
595 DECIMAL decVal;
596
597 if ((dwMask & CFM_SIZE) != 0)
598 VarDecFromR8((DOUBLE)yHeight / TWIPS_PER_POINT, &decVal);
599 else
600 VarDecFromI4(0, &decVal);
601
602 SetPropertyVal(UI_PKEY_FontProperties_Size, &decVal, &var);
603 pStore->SetValue(UI_PKEY_FontProperties_Size, var);
604 }
605
606 void PutColor(IPropertyStore* pStore)
607 {
608 if ((dwMask & CFM_COLOR) != 0)
609 {
610 if ((dwEffects & CFE_AUTOCOLOR) == 0)
611 {
612 SetPropertyVal(UI_PKEY_FontProperties_ForegroundColorType, UI_SWATCHCOLORTYPE_RGB, &propvar);
613 pStore->SetValue(UI_PKEY_FontProperties_ForegroundColorType, propvar);
614
615 SetPropertyVal(UI_PKEY_FontProperties_ForegroundColor, crTextColor, &propvar);
616 pStore->SetValue(UI_PKEY_FontProperties_ForegroundColor, propvar);
617 }
618 else
619 {
620 SetPropertyVal(UI_PKEY_FontProperties_ForegroundColorType, UI_SWATCHCOLORTYPE_AUTOMATIC, &propvar);
621 pStore->SetValue(UI_PKEY_FontProperties_ForegroundColorType, propvar);
622 }
623 }
624 }
625
626 void PutBackColor(IPropertyStore* pStore)
627 {
628 if (((dwMask & CFM_BACKCOLOR) != 0) && ((dwEffects & CFE_AUTOBACKCOLOR) == 0))
629 {
630 SetPropertyVal(UI_PKEY_FontProperties_BackgroundColorType, UI_SWATCHCOLORTYPE_RGB, &propvar);
631 pStore->SetValue(UI_PKEY_FontProperties_BackgroundColorType, propvar);
632
633 SetPropertyVal(UI_PKEY_FontProperties_BackgroundColor, crBackColor, &propvar);
634 pStore->SetValue(UI_PKEY_FontProperties_BackgroundColor, propvar);
635 }
636 else
637 {
638 SetPropertyVal(UI_PKEY_FontProperties_BackgroundColorType, UI_SWATCHCOLORTYPE_NOCOLOR, &propvar);
639 pStore->SetValue(UI_PKEY_FontProperties_BackgroundColorType, propvar);
640 }
641 }
642 };
643
644 // IUIImage helper
645 //
646 inline IUIImage* GetImage(HBITMAP hbm, UI_OWNERSHIP owner)
647 {
648 ATLASSERT(hbm);
649 IUIImage* pIUII = NULL;
650 ATL::CComPtr<IUIImageFromBitmap> pIFB;
651
652 if SUCCEEDED(pIFB.CoCreateInstance(CLSID_UIRibbonImageFromBitmapFactory))
653 ATLVERIFY(SUCCEEDED(pIFB->CreateImage(hbm, owner, &pIUII)));
654
655 return pIUII;
656 }
657
658
659 ///////////////////////////////////////////////////////////////////////////////
660 // Ribbon control classes
661
662 // RibbonUI::ICtrl abstract interface of RibbonUI::CRibbonImpl and all RibbonUI control classes
663 //
664 struct ICtrl
665 {
666 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
667 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
668 IUISimplePropertySet* pCommandExecutionProperties) = 0;
669
670 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
671 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) = 0;
672 };
673
674 // RibbonUI::CtrlImpl base class for all ribbon controls
675 //
676 template <class T, UINT t_ID>
677 class ATL_NO_VTABLE CtrlImpl : public ICtrl
678 {
679 protected:
680 T* m_pWndRibbon;
681
682 public:
683 typedef T WndRibbon;
684
685 CtrlImpl() : m_pWndRibbon(T::pWndRibbon)
686 { }
687
688 WndRibbon& GetWndRibbon()
689 {
690 return *m_pWndRibbon;
691 }
692
693 static WORD GetID()
694 {
695 return t_ID;
696 }
697
698 Text m_sTxt[5];
699
700 // Operations
701 HRESULT Invalidate()
702 {
703 return GetWndRibbon().InvalidateCtrl(GetID());
704 }
705
706 HRESULT Invalidate(REFPROPERTYKEY key, UI_INVALIDATIONS flags = UI_INVALIDATIONS_PROPERTY)
707 {
708 return GetWndRibbon().InvalidateProperty(GetID(), key, flags);
709 }
710
711 HRESULT SetText(REFPROPERTYKEY key, LPCWSTR sTxt, bool bUpdate = false)
712 {
713 ATLASSERT((k_(key) <= k_TooltipTitle) && (k_(key) >= k_LabelDescription));
714
715 m_sTxt[k_(key) - k_LabelDescription] = sTxt;
716
717 return bUpdate ?
718 GetWndRibbon().InvalidateProperty(GetID(), key) :
719 S_OK;
720 }
721
722 // Implementation
723 template <typename V>
724 HRESULT SetProperty(REFPROPERTYKEY key, V val)
725 {
726 return GetWndRibbon().SetProperty(GetID(), key, val);
727 }
728
729 HRESULT OnGetText(REFPROPERTYKEY key, PROPVARIANT* ppv)
730 {
731 ATLASSERT((k_(key) <= k_TooltipTitle) && (k_(key) >= k_LabelDescription));
732
733 const INT iText = k_(key) - k_LabelDescription;
734 if (m_sTxt[iText].IsEmpty())
735 if (LPCWSTR sText = GetWndRibbon().OnRibbonQueryText(GetID(), key))
736 m_sTxt[iText] = sText;
737
738 return !m_sTxt[iText].IsEmpty() ?
739 SetPropertyVal(key, (LPCWSTR)m_sTxt[iText], ppv) :
740 S_OK;
741 }
742
743 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
744 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
745 IUISimplePropertySet* pCommandExecutionProperties)
746 {
747 ATLASSERT(nCmdID == t_ID);
748 return GetWndRibbon().DoExecute(nCmdID, verb, key, ppropvarValue, pCommandExecutionProperties);
749 }
750
751 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
752 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
753 {
754 ATLASSERT(nCmdID == t_ID);
755
756 const INT iMax = k_TooltipTitle - k_LabelDescription;
757 const INT iVal = k_(key) - k_LabelDescription;
758
759 return (iVal <= iMax) && (iVal >= 0) ?
760 OnGetText(key, ppropvarNewValue) :
761 GetWndRibbon().DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
762 }
763 };
764
765 // CommandCtrlImpl base class for most ribbon controls
766 //
767 template <class T, UINT t_ID>
768 class CommandCtrlImpl : public CtrlImpl<T, t_ID>
769 {
770 public:
771 CBitmap m_hbm[4];
772
773 HRESULT SetImage(REFPROPERTYKEY key, HBITMAP hbm, bool bUpdate = false)
774 {
775 ATLASSERT((k_(key) <= k_SmallHighContrastImage) && (k_(key) >= k_LargeImage));
776
777 m_hbm[k_(key) - k_LargeImage].Attach(hbm);
778
779 return bUpdate ?
780 GetWndRibbon().InvalidateProperty(GetID(), key) :
781 S_OK;
782 }
783
784 HRESULT OnGetImage(REFPROPERTYKEY key, PROPVARIANT* ppv)
785 {
786 ATLASSERT((k_(key) <= k_SmallHighContrastImage) && (k_(key) >= k_LargeImage));
787
788 const INT iImage = k_(key) - k_LargeImage;
789
790 if (m_hbm[iImage].IsNull())
791 m_hbm[iImage] = GetWndRibbon().OnRibbonQueryImage(GetID(), key);
792
793 return m_hbm[iImage].IsNull() ?
794 E_NOTIMPL :
795 SetPropertyVal(key, GetImage(m_hbm[iImage], UI_OWNERSHIP_COPY), ppv);
796 }
797
798 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
799 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
800 {
801 ATLASSERT (nCmdID == GetID());
802
803 return (k_(key) <= k_SmallHighContrastImage) && (k_(key) >= k_LargeImage) ?
804 OnGetImage(key, ppropvarNewValue) :
805 CtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
806 }
807 };
808
809
810 ///////////////////////////////////////////////////////////////////////////////
811 // Ribbon collection base classes
812
813 // ItemProperty class: ribbon callback for each item in a collection
814 //
815
816 #pragma warning(push)
817 #pragma warning(disable: 4512) // assignment operator could not be generated
818
819 template <class TCollection>
820 class ItemProperty : public IUISimplePropertySet
821 {
822 public:
823 ItemProperty(UINT i, TCollection* pCollection) : m_Index(i), m_pCollection(pCollection)
824 { }
825
826 const UINT m_Index;
827 TCollection* m_pCollection;
828
829 // IUISimplePropertySet method.
830 STDMETHODIMP GetValue(REFPROPERTYKEY key, PROPVARIANT *value)
831 {
832 return m_pCollection->OnGetItem(m_Index, key, value);
833 }
834
835 // IUnknown methods.
836 STDMETHODIMP_(ULONG) AddRef()
837 {
838 return 1;
839 }
840
841 STDMETHODIMP_(ULONG) Release()
842 {
843 return 1;
844 }
845
846 STDMETHODIMP QueryInterface(REFIID iid, void** ppv)
847 {
848 if ((iid == __uuidof(IUnknown)) || (iid == __uuidof(IUISimplePropertySet)))
849 {
850 *ppv = this;
851 return S_OK;
852 }
853 else
854 {
855 return E_NOINTERFACE;
856 }
857 }
858 };
859
860 #pragma warning(pop)
861
862
863 // CollectionImplBase: base class for all RibbonUI collections
864 //
865 template <class TCollection, size_t t_size>
866 class CollectionImplBase
867 {
868 typedef CollectionImplBase<TCollection, t_size> thisClass;
869
870 public:
871 CollectionImplBase()
872 {
873 for (int i = 0; i < t_size; i++)
874 m_apItems[i] = new ItemProperty<TCollection>(i, static_cast<TCollection*>(this));
875 }
876
877 ~CollectionImplBase()
878 {
879 for (int i = 0; i < t_size; i++)
880 delete m_apItems[i];
881 }
882
883 // Data members
884 ItemProperty<TCollection>* m_apItems[t_size];
885 };
886
887 // CollectionImpl: handles categories and collecton resizing
888 //
889 template <class TCtrl, size_t t_items, size_t t_categories>
890 class CollectionImpl : public CollectionImplBase<CollectionImpl<TCtrl, t_items, t_categories>, t_items + t_categories>
891 {
892 typedef CollectionImpl<TCtrl, t_items, t_categories> thisClass;
893 public:
894 typedef thisClass Collection;
895
896 CollectionImpl() : m_size(t_items)
897 {
898 ::FillMemory(m_auItemCat, sizeof(m_auItemCat), 0xff); // UI_COLLECTION_INVALIDINDEX
899 }
900
901 UINT32 m_auItemCat[t_items];
902 Text m_asCatName[__max(t_categories, 1)];
903 size_t m_size;
904
905 // Operations
906 HRESULT SetItemCategory(UINT uItem, UINT uCat, bool bUpdate = false)
907 {
908 ATLASSERT((uItem < t_items) && (uCat < t_categories));
909
910 m_auItemCat[uItem] = uCat;
911
912 return bUpdate ? InvalidateItems() : S_OK;
913 }
914
915 HRESULT SetCategoryText(UINT uCat, LPCWSTR sText, bool bUpdate = false)
916 {
917 ATLASSERT(uCat < t_categories);
918
919 m_asCatName[uCat] = sText;
920
921 return bUpdate ? InvalidateCategories() : S_OK;
922 }
923
924 HRESULT Resize(size_t size, bool bUpdate = false)
925 {
926 ATLASSERT(size <= t_items);
927
928 m_size = size;
929
930 return bUpdate ? InvalidateItems() : S_OK;
931 }
932
933 // Implementation
934 HRESULT OnGetItem(UINT uIndex, REFPROPERTYKEY key, PROPVARIANT *value)
935 {
936 ATLASSERT(uIndex < t_items + t_categories);
937 TCtrl* pCtrl = static_cast<TCtrl*>(this);
938
939 return uIndex < t_items ?
940 pCtrl->DoGetItem(uIndex, key, value) :
941 pCtrl->DoGetCategory(uIndex - t_items, key, value);
942 }
943
944 HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value)
945 {
946 ATLASSERT(k_(key) == k_CategoryId);
947 UINT32 uCat = UI_COLLECTION_INVALIDINDEX;
948
949 if (t_categories != 0)
950 {
951 if (m_auItemCat[uItem] == UI_COLLECTION_INVALIDINDEX)
952 {
953 TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon();
954 m_auItemCat[uItem] = ribbon.OnRibbonQueryItemCategory(TCtrl::GetID(), uItem);
955 }
956 uCat = m_auItemCat[uItem];
957 }
958
959 return SetPropertyVal(key, uCat, value);
960 }
961
962 HRESULT DoGetCategory(UINT uCat, REFPROPERTYKEY key, PROPVARIANT *value)
963 {
964 HRESULT hr = S_OK;
965
966 switch (k_(key))
967 {
968 case k_Label:
969 if (m_asCatName[uCat].IsEmpty())
970 {
971 TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon();
972 m_asCatName[uCat] = ribbon.OnRibbonQueryCategoryText(TCtrl::GetID(), uCat);
973 }
974 hr = SetPropertyVal(key, (LPCWSTR)m_asCatName[uCat], value);
975 break;
976 case k_CategoryId:
977 hr = SetPropertyVal(key, uCat, value);
978 break;
979 default:
980 ATLASSERT(FALSE);
981 break;
982 }
983
984 return hr;
985 }
986
987 HRESULT InvalidateItems()
988 {
989 return static_cast<TCtrl*>(this)->Invalidate(UI_PKEY_ItemsSource);
990 }
991
992 HRESULT InvalidateCategories()
993 {
994 return static_cast<TCtrl*>(this)->Invalidate(UI_PKEY_Categories);
995 }
996
997 HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
998 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* /*ppropvarNewValue*/)
999 {
1000 ATLASSERT(nCmdID == TCtrl::GetID());
1001 nCmdID; // avoid level 4 warning
1002
1003 HRESULT hr = E_NOTIMPL;
1004 switch (k_(key))
1005 {
1006 case k_ItemsSource:
1007 {
1008 ATL::CComQIPtr<IUICollection> pIUICollection(ppropvarCurrentValue->punkVal);
1009 ATLASSERT(pIUICollection);
1010 hr = pIUICollection->Clear();
1011 for (UINT i = 0; i < m_size; i++)
1012 {
1013 if FAILED(hr = pIUICollection->Add(m_apItems[i]))
1014 break;
1015 }
1016 ATLASSERT(SUCCEEDED(hr));
1017 }
1018 break;
1019 case k_Categories:
1020 if (t_categories != 0)
1021 {
1022 ATL::CComQIPtr<IUICollection> pIUICategory(ppropvarCurrentValue->punkVal);
1023 ATLASSERT(pIUICategory.p);
1024 hr = pIUICategory->Clear();
1025 for (UINT i = t_items; i < (t_items + t_categories); i++)
1026 {
1027 if FAILED(hr = pIUICategory->Add(m_apItems[i]))
1028 break;
1029 }
1030 ATLASSERT(SUCCEEDED(hr));
1031 }
1032 break;
1033 }
1034
1035 return hr;
1036 }
1037 };
1038
1039 // TextCollectionImpl: handles item labels and selection
1040 //
1041 template <class TCtrl, size_t t_items, size_t t_categories = 0>
1042 class TextCollectionImpl : public CollectionImpl<TCtrl, t_items, t_categories>
1043 {
1044 typedef TextCollectionImpl<TCtrl, t_items, t_categories> thisClass;
1045 public:
1046 typedef thisClass TextCollection;
1047
1048 TextCollectionImpl() : m_uSelected(UI_COLLECTION_INVALIDINDEX)
1049 { }
1050
1051 Text m_asText[t_items];
1052 UINT m_uSelected;
1053
1054 // Operations
1055 HRESULT SetItemText(UINT uItem, LPCWSTR sText, bool bUpdate = false)
1056 {
1057 ATLASSERT(uItem < t_items);
1058
1059 m_asText[uItem] = sText;
1060
1061 return bUpdate ? InvalidateItems() : S_OK;
1062 }
1063
1064 UINT GetSelected()
1065 {
1066 return m_uSelected;
1067 }
1068
1069 HRESULT Select(UINT uItem, bool bUpdate = false)
1070 {
1071 ATLASSERT((uItem < t_items) || (uItem == UI_COLLECTION_INVALIDINDEX));
1072
1073 m_uSelected = uItem;
1074
1075 TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon();
1076 return bUpdate ?
1077 ribbon.SetProperty(TCtrl::GetID(), UI_PKEY_SelectedItem, uItem) :
1078 S_OK;
1079 }
1080
1081 // Implementation
1082 HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value)
1083 {
1084 ATLASSERT(uItem < t_items);
1085
1086 if (k_(key) == k_Label)
1087 {
1088 if (m_asText[uItem].IsEmpty())
1089 {
1090 TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon();
1091 m_asText[uItem] = ribbon.OnRibbonQueryItemText(TCtrl::GetID(), uItem);
1092 }
1093 return SetPropertyVal(key, (LPCWSTR)m_asText[uItem], value);
1094 }
1095 else
1096 {
1097 return Collection::DoGetItem(uItem, key, value);
1098 }
1099 }
1100
1101 HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
1102 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
1103 {
1104 ATLASSERT(nCmdID == TCtrl::GetID());
1105
1106 if (k_(key) == k_SelectedItem)
1107 {
1108 TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon();
1109 UINT uSel = UI_COLLECTION_INVALIDINDEX;
1110 if ((m_uSelected == UI_COLLECTION_INVALIDINDEX) &&
1111 ribbon.OnRibbonQuerySelectedItem(TCtrl::GetID(), uSel))
1112 m_uSelected = uSel;
1113
1114 return SetPropertyVal(key, m_uSelected, ppropvarNewValue);
1115 }
1116 else
1117 {
1118 return Collection::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
1119 }
1120 }
1121 };
1122
1123 // ItemCollectionImpl: handles item image
1124 //
1125 template <class TCtrl, size_t t_items, size_t t_categories = 0>
1126 class ItemCollectionImpl : public TextCollectionImpl<TCtrl, t_items, t_categories>
1127 {
1128 typedef ItemCollectionImpl<TCtrl, t_items, t_categories> thisClass;
1129 public:
1130 typedef thisClass ItemCollection;
1131
1132 ItemCollectionImpl()
1133 {
1134 ::ZeroMemory(m_aBitmap, sizeof(m_aBitmap));
1135 }
1136
1137 CBitmap m_aBitmap[t_items];
1138
1139 // Operations
1140 HRESULT SetItemImage(UINT uIndex, HBITMAP hbm, bool bUpdate = false)
1141 {
1142 ATLASSERT(uIndex < t_items);
1143
1144 m_aBitmap[uIndex] = hbm;
1145
1146 return bUpdate ? InvalidateItems() : S_OK;
1147 }
1148
1149 // Implementation
1150 HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value)
1151 {
1152 ATLASSERT(uItem < t_items);
1153
1154 if (k_(key) == k_ItemImage)
1155 {
1156 if (m_aBitmap[uItem].IsNull())
1157 {
1158 TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon();
1159 m_aBitmap[uItem] = ribbon.OnRibbonQueryItemImage(TCtrl::GetID(), uItem);
1160 }
1161 return m_aBitmap[uItem].IsNull() ?
1162 E_NOTIMPL :
1163 SetPropertyVal(key, GetImage(m_aBitmap[uItem], UI_OWNERSHIP_COPY), value);
1164 }
1165 else
1166 {
1167 return TextCollection::DoGetItem(uItem, key, value);
1168 }
1169 }
1170 };
1171
1172 // ComboCollectionImpl: handles combo text
1173 //
1174 template <class TCtrl, size_t t_items, size_t t_categories = 0>
1175 class ComboCollectionImpl : public ItemCollectionImpl<TCtrl, t_items, t_categories>
1176 {
1177 typedef ComboCollectionImpl<TCtrl, t_items, t_categories> thisClass;
1178 public:
1179 typedef thisClass ComboCollection;
1180
1181 // Operations
1182 HRESULT SetComboText(LPCWSTR sText)
1183 {
1184 TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon();
1185 return ribbon.IsRibbonUI() ?
1186 ribbon.SetProperty(TCtrl::GetID(), UI_PKEY_StringValue, sText) :
1187 S_OK;
1188 }
1189
1190 LPCWSTR GetComboText()
1191 {
1192 static WCHAR sCombo[RIBBONUI_MAX_TEXT] = { 0 };
1193 TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon();
1194 PROPVARIANT var;
1195 if (ribbon.IsRibbonUI())
1196 {
1197 HRESULT hr = ribbon.GetIUIFrameworkPtr()->GetUICommandProperty(TCtrl::GetID(), UI_PKEY_StringValue, &var);
1198 hr = PropVariantToString(var, sCombo, RIBBONUI_MAX_TEXT);
1199 return sCombo;
1200 }
1201 return NULL;
1202 }
1203 };
1204
1205 // CommandCollectionImpl: handles RibbonUI command collection controls
1206 //
1207 template <class TCtrl, size_t t_items, size_t t_categories = 0>
1208 class CommandCollectionImpl : public CollectionImpl<TCtrl, t_items, t_categories>
1209 {
1210 typedef CommandCollectionImpl<TCtrl, t_items, t_categories> thisClass;
1211 public:
1212 typedef thisClass CommandCollection;
1213
1214 CommandCollectionImpl()
1215 {
1216 ::ZeroMemory(m_auCmd, sizeof(m_auCmd));
1217 ::ZeroMemory(m_aCmdType, sizeof(m_aCmdType));
1218 }
1219
1220 UINT32 m_auCmd[t_items];
1221 BYTE m_aCmdType[t_items];
1222
1223 // Operations
1224 HRESULT SetItemCommand(UINT uItem, UINT32 uCommandID, bool bUpdate = false)
1225 {
1226 ATLASSERT(uItem < t_items);
1227
1228 if (uCommandID == m_auCmd[uItem])
1229 return S_OK;
1230
1231 TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon();
1232
1233 m_auCmd[uItem] = uCommandID;
1234 if (uCommandID != 0)
1235 ribbon.UIAddRibbonElement(uCommandID);
1236
1237 return bUpdate ? InvalidateItems() : S_OK;
1238 }
1239
1240 HRESULT SetItemCommandType(UINT uItem, UI_COMMANDTYPE type, bool bUpdate = false)
1241 {
1242 ATLASSERT(uItem < t_items);
1243
1244 m_aCmdType[uItem] = (BYTE)type;
1245
1246 return bUpdate ? InvalidateItems() : S_OK;
1247 }
1248
1249 // Implementation
1250 HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value)
1251 {
1252 ATLASSERT(uItem < t_items);
1253 TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon();
1254
1255 HRESULT hr = E_FAIL;
1256 switch (k_(key))
1257 {
1258 case k_CommandId:
1259 if (m_auCmd[uItem] == 0)
1260 SetItemCommand(uItem, ribbon.OnRibbonQueryItemCommand(TCtrl::GetID(), uItem));
1261 hr = SetPropertyVal(key, m_auCmd[uItem], value);
1262 break;
1263 case k_CommandType:
1264 if (m_aCmdType[uItem] == UI_COMMANDTYPE_UNKNOWN)
1265 SetItemCommandType(uItem, ribbon.OnRibbonQueryItemCommandType(TCtrl::GetID(), uItem));
1266 hr = SetPropertyVal(key, UINT32(m_aCmdType[uItem]), value);
1267 break;
1268 case k_CategoryId:
1269 default:
1270 hr = Collection::DoGetItem(uItem, key, value);
1271 break;
1272 }
1273
1274 return hr;
1275 }
1276
1277 HRESULT Select(UINT /*uItem*/, bool /*bUpdate*/ = false)
1278 {
1279 ATLASSERT(FALSE);
1280 return S_OK;
1281 }
1282 };
1283
1284 // SimpleCollectionImpl: collection class for ribbon simple collection controls
1285 //
1286 template <class TCtrl, size_t t_size, UI_COMMANDTYPE t_CommandType = UI_COMMANDTYPE_ACTION>
1287 class SimpleCollectionImpl : public CollectionImplBase<SimpleCollectionImpl<TCtrl, t_size>, t_size>
1288 {
1289 typedef SimpleCollectionImpl<TCtrl, t_size, t_CommandType> thisClass;
1290 public:
1291 typedef CollectionImplBase<thisClass, t_size> CollectionBase;
1292 typedef thisClass SimpleCollection;
1293
1294 // Implementation
1295 HRESULT OnGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value)
1296 {
1297 ATLASSERT(uItem < t_size);
1298 TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon();
1299
1300 HRESULT hr = E_NOTIMPL;
1301 switch (k_(key))
1302 {
1303 case k_ItemImage:
1304 if (HBITMAP hbm = ribbon.DefRibbonQueryItemImage(TCtrl::GetID(), uItem))
1305 hr = SetPropertyVal(key, GetImage(hbm, UI_OWNERSHIP_TRANSFER), value);
1306 break;
1307 case k_Label:
1308 if (LPCWSTR sText = ribbon.DefRibbonQueryItemText(TCtrl::GetID(), uItem))
1309 hr = SetPropertyVal(key, (LPCWSTR)sText, value);
1310 break;
1311 case k_CommandType:
1312 hr = SetPropertyVal(key, t_CommandType, value);
1313 break;
1314 case k_CommandId:
1315 hr = SetPropertyVal(key, ribbon.DefRibbonQueryItemCommand(TCtrl::GetID(), uItem), value);
1316 break;
1317 case k_CategoryId:
1318 hr = SetPropertyVal(key, UI_COLLECTION_INVALIDINDEX, value);
1319 break;
1320 default:
1321 ATLASSERT(FALSE);
1322 break;
1323 }
1324
1325 return hr;
1326 }
1327 };
1328
1329
1330 ///////////////////////////////////////////////////////////////////////////////
1331 // Ribbon collection control classes
1332
1333 // CollectionCtrlImpl: specializable class for ribbon collection controls
1334 //
1335 template <class T, UINT t_ID, class TCollection>
1336 class CollectionCtrlImpl : public CommandCtrlImpl<T, t_ID>, public TCollection
1337 {
1338 typedef CollectionCtrlImpl<T, t_ID, TCollection> thisClass;
1339 public:
1340 typedef CommandCtrlImpl<T, t_ID> CommandCtrl;
1341 typedef TCollection Collection;
1342
1343 // Implementation
1344 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
1345 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
1346 {
1347 ATLASSERT(nCmdID == GetID());
1348 ATLASSERT(ppropvarNewValue);
1349
1350 HRESULT hr = Collection::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
1351 if FAILED(hr)
1352 hr = CommandCtrl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
1353
1354 return hr;
1355 }
1356
1357 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
1358 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
1359 IUISimplePropertySet* /*pCommandExecutionProperties*/)
1360 {
1361 ATLASSERT (nCmdID == GetID());
1362 nCmdID; // avoid level4 warning
1363
1364 if (key == NULL) // gallery button pressed
1365 {
1366 GetWndRibbon().OnRibbonItemSelected(GetID(), UI_EXECUTIONVERB_EXECUTE, UI_COLLECTION_INVALIDINDEX);
1367 return S_OK;
1368 }
1369
1370 ATLASSERT(k_(*key) == k_SelectedItem);
1371 ATLASSERT(ppropvarValue);
1372
1373 HRESULT hr = S_OK;
1374 UINT32 uSel = 0xffff;
1375 hr = UIPropertyToUInt32(*key, *ppropvarValue, &uSel);
1376
1377 if (SUCCEEDED(hr))
1378 {
1379 if (GetWndRibbon().OnRibbonItemSelected(GetID(), verb, uSel))
1380 TCollection::Select(uSel);
1381 }
1382
1383 return hr;
1384 }
1385 };
1386
1387 // ToolbarGalleryCtrlImpl: base class for ribbon toolbar gallery controls
1388 //
1389 template <class T, UINT t_ID, UINT t_idTB, size_t t_size>
1390 class ToolbarGalleryCtrlImpl : public CollectionCtrlImpl<T, t_ID, CommandCollectionImpl<ToolbarGalleryCtrlImpl<T, t_ID, t_idTB, t_size>, t_size>>
1391 {
1392 public:
1393 ToolbarGalleryCtrlImpl()
1394 {
1395 CResource tbres;
1396 ATLVERIFY(tbres.Load(RT_TOOLBAR, t_idTB));
1397 _AtlToolBarData* pData = (_AtlToolBarData*)tbres.Lock();
1398 ATLASSERT(pData);
1399 ATLASSERT(pData->wVersion == 1);
1400
1401 WORD* pItems = pData->items();
1402 INT j = 0;
1403 for (int i = 0; (i < pData->wItemCount) && (j < t_size); i++)
1404 {
1405 if (pItems[i] != 0)
1406 {
1407 m_aCmdType[j] = UI_COMMANDTYPE_ACTION;
1408 m_auCmd[j++] = pItems[i];
1409 }
1410 }
1411
1412 if (j < t_size)
1413 Resize(j);
1414 }
1415
1416 HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value)
1417 {
1418 ATLASSERT(uItem < m_size);
1419 ATLASSERT(m_auCmd[uItem]);
1420
1421 HRESULT hr = E_FAIL;
1422 switch (k_(key))
1423 {
1424 case k_CommandId:
1425 hr = SetPropertyVal(key, m_auCmd[uItem], value);
1426 break;
1427 case k_CommandType:
1428 hr = SetPropertyVal(key, UINT32(m_aCmdType[uItem]), value);
1429 break;
1430 case k_CategoryId:
1431 hr = SetPropertyVal(key, UI_COLLECTION_INVALIDINDEX, value);
1432 break;
1433 default:
1434 ATLASSERT(FALSE);
1435 break;
1436 }
1437
1438 return hr;
1439 }
1440 };
1441
1442
1443 // SimpleCollectionCtrlImpl: base class for simple gallery and listbox controls
1444 //
1445 template <class T, UINT t_ID, size_t t_size, UI_COMMANDTYPE t_CommandType = UI_COMMANDTYPE_ACTION>
1446 class SimpleCollectionCtrlImpl :
1447 public CommandCtrlImpl<T, t_ID>,
1448 public SimpleCollectionImpl<SimpleCollectionCtrlImpl<T, t_ID, t_size, t_CommandType>, t_size, t_CommandType>
1449 {
1450 typedef SimpleCollectionCtrlImpl<T, t_ID, t_size, t_CommandType> thisClass;
1451 public:
1452 typedef thisClass SimpleCollection;
1453
1454 SimpleCollectionCtrlImpl() : m_uSelected(0)
1455 { }
1456
1457 UINT m_uSelected;
1458
1459 HRESULT Select(UINT uItem, bool bUpdate = false)
1460 {
1461 ATLASSERT((uItem < t_size) || (uItem == UI_COLLECTION_INVALIDINDEX));
1462
1463 m_uSelected = uItem;
1464
1465 return bUpdate ?
1466 GetWndRibbon().SetProperty(GetID(), UI_PKEY_SelectedItem, uItem) :
1467 S_OK;
1468 }
1469
1470 // Implementation
1471 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
1472 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
1473 {
1474 ATLASSERT(nCmdID == GetID());
1475 ATLASSERT(ppropvarNewValue != NULL);
1476
1477 HRESULT hr = S_OK;
1478 switch (k_(key))
1479 {
1480 case k_ItemsSource:
1481 {
1482 ATL::CComQIPtr<IUICollection> pIUICollection(ppropvarCurrentValue->punkVal);
1483 ATLASSERT(pIUICollection.p);
1484 hr = pIUICollection->Clear();
1485 for (UINT i = 0; i < t_size; i++)
1486 {
1487 if FAILED(hr = pIUICollection->Add(m_apItems[i]))
1488 break;
1489 }
1490 ATLASSERT(SUCCEEDED(hr));
1491 }
1492 break;
1493 case k_SelectedItem:
1494 hr = SetPropertyVal(UI_PKEY_SelectedItem, m_uSelected, ppropvarNewValue);
1495 break;
1496 default:
1497 hr = CommandCtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
1498 break;
1499 }
1500
1501 return hr;
1502 }
1503
1504 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
1505 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
1506 IUISimplePropertySet* /*pCommandExecutionProperties*/)
1507 {
1508 ATLASSERT (nCmdID == GetID());
1509 nCmdID; // avoid level 4 warning
1510
1511 HRESULT hr = S_OK;
1512 if (key == NULL) // gallery button pressed
1513 {
1514 GetWndRibbon().OnRibbonItemSelected(GetID(), UI_EXECUTIONVERB_EXECUTE, UI_COLLECTION_INVALIDINDEX);
1515 return hr;
1516 }
1517 ATLASSERT(k_(*key) == k_SelectedItem);
1518 ATLASSERT(ppropvarValue);
1519
1520 if SUCCEEDED(hr = UIPropertyToUInt32(*key, *ppropvarValue, &m_uSelected))
1521 GetWndRibbon().OnRibbonItemSelected(GetID(), verb, m_uSelected);
1522
1523 return hr;
1524 }
1525 };
1526
1527 // RecentItemsCtrlImpl
1528 //
1529 template <class T, UINT t_ID, class TDocList = CRecentDocumentList>
1530 class RecentItemsCtrlImpl :
1531 public CtrlImpl<T, t_ID>,
1532 public CollectionImplBase<RecentItemsCtrlImpl<T, t_ID, TDocList>, TDocList::m_nMaxEntries_Max>,
1533 public TDocList
1534 {
1535 typedef RecentItemsCtrlImpl<T, t_ID, TDocList> thisClass;
1536 public:
1537 typedef thisClass RecentItems;
1538
1539 // Implementation
1540 HRESULT OnGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value)
1541 {
1542 ATLASSERT((INT)uItem < GetMaxEntries());
1543
1544 LPCWSTR sPath = m_arrDocs[uItem].szDocName;
1545 HRESULT hr = E_NOTIMPL;
1546 switch (k_(key))
1547 {
1548 case k_Label:
1549 hr = SetPropertyVal(key, GetWndRibbon().OnRibbonQueryRecentItemName(sPath), value);
1550 break;
1551 case k_LabelDescription:
1552 hr = SetPropertyVal(key, sPath, value);
1553 break;
1554 default:
1555 ATLASSERT(FALSE);
1556 break;
1557 }
1558
1559 return hr;
1560 }
1561
1562 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
1563 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
1564 {
1565 ATLASSERT(nCmdID == GetID());
1566 ATLASSERT(ppropvarNewValue);
1567
1568 HRESULT hr = S_OK;
1569 switch (k_(key))
1570 {
1571 case k_RecentItems:
1572 if (SAFEARRAY* psa = SafeArrayCreateVector(VT_UNKNOWN, 0, m_arrDocs.GetSize()))
1573 {
1574 const int iLastIndex = m_arrDocs.GetSize() - 1;
1575 for (LONG i = 0; i <= iLastIndex; i++)
1576 SafeArrayPutElement(psa, &i, m_apItems[iLastIndex - i]); // reverse order
1577
1578 hr = SetPropertyVal(key, psa, ppropvarNewValue);
1579 SafeArrayDestroy(psa);
1580 }
1581 break;
1582 default:
1583 hr = CtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
1584 break;
1585 }
1586
1587 return hr;
1588 }
1589
1590 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
1591 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
1592 IUISimplePropertySet* /*pCommandExecutionProperties*/)
1593 {
1594 ATLASSERT(nCmdID == GetID());
1595 nCmdID; // avoid level 4 warning
1596 ATLASSERT(verb == UI_EXECUTIONVERB_EXECUTE);
1597 verb; // avoid level 4 warning
1598 ATLASSERT((key) && (k_(*key) == k_SelectedItem));
1599 ATLASSERT(ppropvarValue);
1600
1601 UINT32 uSel = 0xffff;
1602 HRESULT hr = UIPropertyToUInt32(*key, *ppropvarValue, &uSel);
1603 if SUCCEEDED(hr)
1604 {
1605 ATLASSERT(uSel < (UINT)GetMaxEntries());
1606 GetWndRibbon().DefCommandExecute(ID_FILE_MRU_FIRST + uSel);
1607 }
1608
1609 return hr;
1610 }
1611 };
1612
1613
1614 ///////////////////////////////////////////////////////////////////////////////
1615 // Ribbon stand-alone control classes
1616
1617 // FontCtrlImpl
1618 //
1619 template <class T, UINT t_ID>
1620 class FontCtrlImpl : public CtrlImpl<T, t_ID>
1621 {
1622 public:
1623
1624 CharFormat m_cf;
1625
1626 // Implementation
1627 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
1628 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
1629 IUISimplePropertySet* pCommandExecutionProperties)
1630 {
1631 ATLASSERT (nCmdID == GetID());
1632 nCmdID; // avoid level 4 warning
1633 ATLASSERT ((key) && (k_(*key) == k_FontProperties));
1634 key; // avoid level 4 warning
1635
1636 HRESULT hr = E_INVALIDARG;
1637 switch (verb)
1638 {
1639 case UI_EXECUTIONVERB_PREVIEW:
1640 case UI_EXECUTIONVERB_EXECUTE:
1641 ATLASSERT(pCommandExecutionProperties);
1642 PROPVARIANT propvar;
1643
1644 if (SUCCEEDED(hr = pCommandExecutionProperties->GetValue(UI_PKEY_FontProperties_ChangedProperties, &propvar)))
1645 m_cf << ATL::CComQIPtr<IPropertyStore>(propvar.punkVal);
1646 break;
1647
1648 case UI_EXECUTIONVERB_CANCELPREVIEW:
1649 ATLASSERT(ppropvarValue);
1650 ATL::CComPtr<IPropertyStore> pStore;
1651
1652 if (SUCCEEDED(hr = UIPropertyToInterface(UI_PKEY_FontProperties, *ppropvarValue, &pStore)))
1653 m_cf << pStore;
1654 break;
1655 }
1656
1657 if (SUCCEEDED(hr))
1658 GetWndRibbon().OnRibbonFontCtrlExecute(GetID(), verb, &m_cf);
1659 else
1660 ATLASSERT(FALSE);
1661
1662 return hr;
1663 }
1664
1665 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
1666 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
1667 {
1668 if ((k_(key) == k_FontProperties) && (GetWndRibbon().OnRibbonQueryFont(t_ID, m_cf)))
1669 {
1670 ATL::CComQIPtr<IPropertyStore> pStore(ppropvarCurrentValue->punkVal);
1671 m_cf >> pStore;
1672 return SetPropertyVal(key, pStore.p, ppropvarNewValue);
1673 }
1674 else
1675 {
1676 return CtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
1677 }
1678 }
1679 };
1680
1681 // ColorCtrlImpl
1682 //
1683 template <class T, UINT t_ID>
1684 class ColorCtrlImpl : public CommandCtrlImpl<T, t_ID>
1685 {
1686 public:
1687 ColorCtrlImpl() : m_colorType(UI_SWATCHCOLORTYPE_NOCOLOR), m_color(0x800080) /*MAGENTA*/
1688 { }
1689
1690 COLORREF m_color;
1691 UINT32 m_colorType; // value in UI_SWATCHCOLORTYPE
1692 Text m_sLabels[6]; // k_MoreColorsLabel to k_ThemeColorsCategoryLabel
1693 ATL::CSimpleArray<COLORREF> m_aColors[2];
1694 ATL::CSimpleArray<LPCWSTR> m_aTooltips[2];
1695
1696 // Operations
1697 HRESULT SetColor(COLORREF color, bool bUpdate = false)
1698 {
1699 if (m_colorType != UI_SWATCHCOLORTYPE_RGB)
1700 SetColorType(UI_SWATCHCOLORTYPE_RGB, bUpdate);
1701 m_color = color;
1702 return bUpdate ? SetProperty(UI_PKEY_Color, color) : S_OK;
1703 }
1704
1705 HRESULT SetColorType(UI_SWATCHCOLORTYPE type, bool bUpdate = false)
1706 {
1707 m_colorType = type;
1708 return bUpdate ? SetProperty(UI_PKEY_ColorType, type) : S_OK;
1709 }
1710
1711 HRESULT SetColorLabel(REFPROPERTYKEY key, LPCWSTR sLabel, bool bUpdate = false)
1712 {
1713 ATLASSERT((k_(key) >= k_ThemeColorsCategoryLabel) && (k_(key) <= k_MoreColorsLabel));
1714 m_sLabels[k_(key) - k_ThemeColorsCategoryLabel] = sLabel;
1715 return bUpdate ? SetProperty(key, sLabel) : S_OK;
1716 }
1717
1718 HRESULT SetColorArray(REFPROPERTYKEY key, COLORREF* pColor, bool bUpdate = false)
1719 {
1720 ATLASSERT((k_(key) == k_ThemeColors) || (k_(key) == k_StandardColors));
1721
1722 const INT ic = k_(key) - k_ThemeColors;
1723 m_aColors[ic].RemoveAll();
1724 while (*pColor != 0x800080) /*MAGENTA*/
1725 m_aColors[ic].Add(*pColor++);
1726
1727 if (bUpdate)
1728 {
1729 PROPVARIANT var;
1730 if SUCCEEDED(InitPropVariantFromUInt32Vector(m_aColors[ic].GetData(), m_aColors[ic].GetSize(), &var))
1731 return SetProperty(key, var);
1732 else
1733 return E_INVALIDARG;
1734 }
1735 else
1736 {
1737 return S_OK;
1738 }
1739 }
1740
1741 HRESULT SetColorTooltips(REFPROPERTYKEY key, LPCWSTR* ppsTT, bool bUpdate = false)
1742 {
1743 ATLASSERT((k_(key) == k_ThemeColorsTooltips) || (k_(key) == k_StandardColorsTooltips));
1744
1745 const INT ic = k_(key) - k_ThemeColorsTooltips;
1746 m_aTooltips[ic].RemoveAll();
1747 while (*ppsTT)
1748 m_aTooltips[ic].Add(*ppsTT++);
1749
1750 if (bUpdate)
1751 {
1752 PROPVARIANT var;
1753 if SUCCEEDED(InitPropVariantFromStringVector(m_aTooltips[ic].GetData(), m_aTooltips[ic].GetSize(), &var))
1754 return SetProperty(key, var);
1755 else
1756 return E_INVALIDARG;
1757 }
1758 else
1759 {
1760 return S_OK;
1761 }
1762 }
1763
1764 // Implementation
1765 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
1766 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
1767 IUISimplePropertySet* pCommandExecutionProperties)
1768 {
1769 ATLASSERT (nCmdID == GetID());
1770 nCmdID; // avoid level 4 warning
1771 ATLASSERT (key && (k_(*key) == k_ColorType));
1772 key; // avoid level 4 warning
1773 ATLASSERT (ppropvarValue);
1774
1775 HRESULT hr = PropVariantToUInt32(*ppropvarValue, &m_colorType);
1776 ATLASSERT(SUCCEEDED(hr));
1777
1778 if (SUCCEEDED(hr) && (m_colorType == UI_SWATCHCOLORTYPE_RGB))
1779 {
1780 ATLASSERT(pCommandExecutionProperties);
1781 PROPVARIANT var;
1782 if SUCCEEDED(hr = pCommandExecutionProperties->GetValue(UI_PKEY_Color, &var))
1783 hr = PropVariantToUInt32(var, &m_color);
1784 }
1785
1786 if SUCCEEDED(hr)
1787 GetWndRibbon().OnRibbonColorCtrlExecute(GetID(), verb, (UI_SWATCHCOLORTYPE)m_colorType/*uType*/, m_color);
1788 else
1789 ATLASSERT(FALSE); // something was wrong
1790
1791 return hr;
1792 }
1793
1794 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
1795 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
1796 {
1797 ATLASSERT (nCmdID == GetID());
1798
1799 HRESULT hr = E_NOTIMPL;
1800
1801 switch (k_(key))
1802 {
1803 case k_ColorType:
1804 hr = SetPropertyVal(key, m_colorType, ppropvarNewValue);
1805 break;
1806 case k_Color:
1807 if (m_color == 0x800080) /*MAGENTA*/
1808 m_color = GetWndRibbon().OnRibbonQueryColor(GetID());
1809 hr = SetPropertyVal(key, m_color, ppropvarNewValue);
1810 break;
1811 case k_ColorMode:
1812 break;
1813 case k_ThemeColorsCategoryLabel:
1814 case k_StandardColorsCategoryLabel:
1815 case k_RecentColorsCategoryLabel:
1816 case k_AutomaticColorLabel:
1817 case k_NoColorLabel:
1818 case k_MoreColorsLabel:
1819 {
1820 const UINT iLabel = k_(key) - k_ThemeColorsCategoryLabel;
1821 if (m_sLabels[iLabel].IsEmpty())
1822 if (LPCWSTR psLabel = GetWndRibbon().OnRibbonQueryColorLabel(GetID(), key))
1823 m_sLabels[iLabel] = psLabel;
1824 if (!m_sLabels[iLabel].IsEmpty())
1825 hr = SetPropertyVal(key, (LPCWSTR)m_sLabels[iLabel], ppropvarNewValue);
1826 }
1827 break;
1828 case k_ThemeColors:
1829 case k_StandardColors:
1830 {
1831 const INT ic = k_(key) - k_ThemeColors;
1832 if (!m_aColors[ic].GetSize())
1833 if (COLORREF* pColor = GetWndRibbon().OnRibbonQueryColorArray(GetID(), key))
1834 SetColorArray(key, pColor);
1835 if (INT iMax = m_aColors[ic].GetSize())
1836 hr = InitPropVariantFromUInt32Vector(m_aColors[ic].GetData(), iMax, ppropvarNewValue);
1837 }
1838 break;
1839 case k_ThemeColorsTooltips:
1840 case k_StandardColorsTooltips:
1841 {
1842 const INT ic = k_(key) - k_ThemeColorsTooltips;
1843 if (m_aTooltips[ic].GetSize() == 0)
1844 if (LPCWSTR* ppsTT = GetWndRibbon().OnRibbonQueryColorTooltips(GetID(), key))
1845 SetColorTooltips(key, ppsTT);
1846 if (INT iMax = m_aTooltips[ic].GetSize())
1847 hr = InitPropVariantFromStringVector(m_aTooltips[ic].GetData(), iMax, ppropvarNewValue);
1848 }
1849 break;
1850 default:
1851 hr = CommandCtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
1852 break;
1853 }
1854
1855 return hr;
1856 }
1857 };
1858
1859 // SpinnerCtrlImpl
1860 //
1861 template <class T, UINT t_ID, typename V = LONG>
1862 class SpinnerCtrlImpl : public CtrlImpl<T, t_ID>
1863 {
1864 public:
1865 SpinnerCtrlImpl()
1866 {
1867 m_Values[0] = m_Values[2] = m_Values[4] = 0;
1868 m_Values[1] = 100;
1869 m_Values[3] = 1;
1870 }
1871
1872 V m_Values[5];
1873 // k_DecimalValue = 201, k_MaxValue = 203, k_MinValue, k_Increment, k_DecimalPlaces
1874
1875 Text m_FormatString;
1876 Text m_RepresentativeString;
1877
1878 // Operations
1879 HRESULT SetDecimalPlaces(V vPlaces, bool bUpdate = false)
1880 {
1881 return SetValue(UI_PKEY_DecimalPlaces, vPlaces, bUpdate);
1882 }
1883
1884 HRESULT SetMin(V vMin, bool bUpdate = false)
1885 {
1886 return SetValue(UI_PKEY_MinValue, vMin, bUpdate);
1887 }
1888
1889 HRESULT SetMax(V vMax, bool bUpdate = false)
1890 {
1891 return SetValue(UI_PKEY_MaxValue, vMax, bUpdate);
1892 }
1893
1894 HRESULT SetVal(V vVal, bool bUpdate = false)
1895 {
1896 return SetValue(UI_PKEY_DecimalValue, vVal, bUpdate);
1897 }
1898
1899 HRESULT SetIncrement(V vIncrement, bool bUpdate = false)
1900 {
1901 return SetValue(UI_PKEY_Increment, vIncrement, bUpdate);
1902 }
1903
1904 HRESULT SetFormatString(LPCWSTR sFormat, bool bUpdate = false)
1905 {
1906 return SetText(UI_PKEY_FormatString, sFormat, bUpdate);
1907 }
1908
1909 HRESULT SetRepresentativeString(LPCWSTR sRepresentative, bool bUpdate = false)
1910 {
1911 return SetText(UI_PKEY_RepresentativeString, sRepresentative, bUpdate);
1912 }
1913
1914 // Implementation
1915 HRESULT SetText(REFPROPERTYKEY key, LPCWSTR sText, bool bUpdate = false)
1916 {
1917 switch (k_(key))
1918 {
1919 case k_FormatString:
1920 m_FormatString = sText;
1921 break;
1922 case k_RepresentativeString:
1923 m_RepresentativeString = sText;
1924 break;
1925 default:
1926 return CtrlImpl::SetText(key, sText, bUpdate);
1927 }
1928
1929 return bUpdate ?
1930 GetWndRibbon().InvalidateProperty(GetID(), key) :
1931 S_OK;
1932 }
1933
1934 HRESULT SetValue(REFPROPERTYKEY key, V val, bool bUpdate = false)
1935 {
1936 ATLASSERT((k_(key) <= k_DecimalPlaces) && (k_(key) >= k_DecimalValue));
1937
1938 const INT iVal = k_(key) == k_DecimalValue ? 0 : k_(key) - k_StringValue;
1939 m_Values[iVal] = val;
1940
1941 if (bUpdate)
1942 {
1943 if(k_(key) == k_DecimalValue)
1944 {
1945 DECIMAL decVal;
1946 InitDecimal(val, &decVal);
1947 return SetProperty(key, &decVal);
1948 }
1949 else
1950 {
1951 return GetWndRibbon().InvalidateProperty(GetID(), key);
1952 }
1953 }
1954 else
1955 {
1956 return S_OK;
1957 }
1958 }
1959
1960 HRESULT QueryValue(REFPROPERTYKEY key, LONG* plVal)
1961 {
1962 return GetWndRibbon().OnRibbonQuerySpinnerValue(GetID(), key, plVal) ? S_OK : S_FALSE;
1963 }
1964
1965 HRESULT QueryValue(REFPROPERTYKEY key, DOUBLE* pdVal)
1966 {
1967 return GetWndRibbon().OnRibbonQueryFloatSpinnerValue(GetID(), key, pdVal) ? S_OK : S_FALSE;
1968 }
1969
1970 HRESULT OnGetValue(REFPROPERTYKEY key, PROPVARIANT* ppv)
1971 {
1972 ATLASSERT((k_(key) <= k_DecimalPlaces) && (k_(key) >= k_DecimalValue));
1973
1974 const INT iVal = k_(key) == k_DecimalValue ? 0 : k_(key) - k_StringValue;
1975
1976 QueryValue(key, m_Values + iVal);
1977
1978 if (k_(key) == k_DecimalPlaces)
1979 {
1980 return SetPropertyVal(key, m_Values[iVal], ppv);
1981 }
1982 else
1983 {
1984 DECIMAL decVal;
1985 InitDecimal(m_Values[iVal], &decVal);
1986 return SetPropertyVal(key, &decVal, ppv);
1987 }
1988 }
1989
1990 HRESULT OnGetText(REFPROPERTYKEY key, Text& sVal, PROPVARIANT* ppv)
1991 {
1992 if (LPCWSTR sNew = GetWndRibbon().OnRibbonQueryText(GetID(), key))
1993 sVal = sNew;
1994 return SetPropertyVal(key, (LPCWSTR)sVal, ppv);
1995 }
1996
1997 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
1998 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
1999 IUISimplePropertySet* /*pCommandExecutionProperties*/)
2000 {
2001 ATLASSERT (nCmdID == GetID());
2002 nCmdID; // avoid level 4 warning
2003 ATLASSERT (key && (k_(*key) == k_DecimalValue));
2004 key; // avoid level 4 warning
2005 ATLASSERT (verb == UI_EXECUTIONVERB_EXECUTE);
2006 verb; // avoid level 4 warning
2007
2008 DECIMAL decVal;
2009
2010 HRESULT hr = UIPropertyToDecimal(UI_PKEY_DecimalValue, *ppropvarValue, &decVal);
2011 hr = InitVal(m_Values[0], &decVal);
2012
2013 GetWndRibbon().OnRibbonSpinnerCtrlExecute(GetID(), &m_Values[0]);
2014
2015 return hr;
2016 }
2017
2018 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
2019 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
2020 {
2021 ATLASSERT (nCmdID == GetID());
2022
2023 HRESULT hr = E_NOTIMPL;
2024 switch (k_(key))
2025 {
2026 case k_DecimalPlaces:
2027 case k_DecimalValue:
2028 case k_Increment:
2029 case k_MaxValue:
2030 case k_MinValue:
2031 hr = OnGetValue(key, ppropvarNewValue);
2032 break;
2033 case k_FormatString:
2034 if (m_FormatString.IsEmpty())
2035 return OnGetText(key, m_FormatString, ppropvarNewValue);
2036 break;
2037 case k_RepresentativeString:
2038 if (m_RepresentativeString.IsEmpty())
2039 return OnGetText(key, m_RepresentativeString, ppropvarNewValue);
2040 break;
2041 default:
2042 hr = CtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
2043 break;
2044 }
2045
2046 return hr;
2047 }
2048
2049 // decimal conversion helpers
2050 static HRESULT InitDecimal(LONG& val, DECIMAL* pDecimal)
2051 {
2052 return ::VarDecFromI4(val, pDecimal);
2053 }
2054
2055 static HRESULT InitDecimal(DOUBLE& val, DECIMAL* pDecimal)
2056 {
2057 return ::VarDecFromR8(val, pDecimal);
2058 }
2059
2060 static HRESULT InitVal(LONG& val, const DECIMAL* pDecimal)
2061 {
2062 return ::VarI4FromDec(pDecimal, &val);
2063 }
2064
2065 static HRESULT InitVal(DOUBLE& val, const DECIMAL* pDecimal)
2066 {
2067 return ::VarR8FromDec(pDecimal, &val);
2068 }
2069 };
2070
2071 // CRibbonImpl Ribbon implementation class
2072 //
2073 template <class T>
2074 class CRibbonImpl :
2075 public CRibbonUpdateUI<T>,
2076 public ICtrl,
2077 public IUIApplication,
2078 public IUICommandHandler
2079 {
2080 typedef CRibbonImpl<T> thisClass;
2081 public:
2082 typedef thisClass Ribbon;
2083 typedef T WndRibbon;
2084
2085 CRibbonImpl() : m_bRibbonUI(false), m_hgRibbonSettings(NULL)
2086 {
2087 #ifdef _DEBUG
2088 m_cRef = 1;
2089 #endif
2090 pWndRibbon = static_cast<T*>(this);
2091 HRESULT hr = ::CoInitialize(NULL);
2092 if(SUCCEEDED(hr))
2093 if (RunTimeHelper::IsRibbonUIAvailable())
2094 hr = m_pIUIFramework.CoCreateInstance(CLSID_UIRibbonFramework);
2095 else
2096 ATLTRACE2(atlTraceUI, 0, _T("Ribbon UI not available\n"));
2097
2098 if FAILED(hr)
2099 ATLTRACE2(atlTraceUI, 0, _T("Ribbon construction failed\n"));
2100
2101 ATLASSERT(SUCCEEDED(hr));
2102 }
2103
2104 ~CRibbonImpl()
2105 {
2106 ::GlobalFree(m_hgRibbonSettings);
2107 m_pIUIFramework.Release();
2108 ::CoUninitialize();
2109 }
2110
2111 ICtrl& GetRibbonCtrl(UINT)
2112 {
2113 return static_cast<ICtrl&>(*this);
2114 }
2115
2116 ATL::CComPtr<IUIFramework> m_pIUIFramework;
2117 HGLOBAL m_hgRibbonSettings;
2118 bool m_bRibbonUI;
2119
2120 bool IsRibbonUI()
2121 {
2122 return m_bRibbonUI;
2123 }
2124
2125 IUIFramework* GetIUIFrameworkPtr()
2126 {
2127 return m_pIUIFramework;
2128 }
2129
2130 template <typename I>
2131 I* GetRibbonViewPtr(UINT32 uID)
2132 {
2133 ATLASSERT(m_pIUIFramework);
2134 ATL::CComPtr<I> pI;
2135 return m_pIUIFramework->GetView(uID, __uuidof(I), (void**) &pI) == S_OK ?
2136 pI :
2137 NULL;
2138 }
2139
2140 IUIRibbon* GetRibbonPtr()
2141 {
2142 return GetRibbonViewPtr<IUIRibbon>(0);
2143 }
2144
2145 IUIContextualUI* GetMenuPtr(UINT32 uID)
2146 {
2147 ATLASSERT(uID);
2148 return GetRibbonViewPtr<IUIContextualUI>(uID);
2149 }
2150
2151 UINT GetRibbonHeight()
2152 {
2153 ATLASSERT(IsRibbonUI());
2154
2155 UINT32 cy = 0;
2156 if (ATL::CComPtr<IUIRibbon> pIUIRibbon = GetRibbonPtr())
2157 pIUIRibbon->GetHeight(&cy);
2158 return cy;
2159 }
2160
2161 HRESULT CreateRibbon(LPCWSTR sResName = L"APPLICATION_RIBBON")
2162 {
2163 T* pT = static_cast<T*>(this);
2164 ATLASSERT(GetIUIFrameworkPtr() && !IsRibbonUI());
2165 ATLASSERT(pT->IsWindow());
2166
2167 HRESULT hr = m_pIUIFramework->Initialize(pT->m_hWnd, this);
2168
2169 if (hr == S_OK)
2170 hr = m_pIUIFramework->LoadUI(ModuleHelper::GetResourceInstance(), sResName);
2171
2172 return hr;
2173 }
2174
2175 HRESULT DestroyRibbon()
2176 {
2177 T* pT = static_cast<T*>(this);
2178 ATLASSERT(GetIUIFrameworkPtr() && IsRibbonUI());
2179 ATLASSERT(pT->IsWindow());
2180
2181 HRESULT hRes = m_pIUIFramework->Destroy();
2182 if (!RunTimeHelper::IsWin7())
2183 pT->SetWindowRgn(NULL, TRUE); // Vista Basic bug workaround
2184 return hRes;
2185 }
2186
2187 // Ribbon persistency
2188 HRESULT operator >>(IStream* pIStream)
2189 {
2190 ATLASSERT(GetIUIFrameworkPtr());
2191 ATLASSERT(pIStream);
2192
2193 HRESULT hr = E_FAIL;
2194 if (ATL::CComPtr<IUIRibbon> pIUIRibbon = GetRibbonPtr())
2195 {
2196 const LARGE_INTEGER li0 = { 0 };
2197 pIStream->Seek(li0, STREAM_SEEK_SET, NULL);
2198 hr = pIUIRibbon->SaveSettingsToStream(pIStream);
2199 pIStream->Commit(STGC_DEFAULT);
2200 }
2201
2202 return hr;
2203 }
2204
2205 HRESULT operator <<(IStream* pIStream)
2206 {
2207 ATLASSERT(GetIUIFrameworkPtr());
2208 ATLASSERT(pIStream);
2209
2210 HRESULT hr = E_FAIL;
2211 if (ATL::CComPtr<IUIRibbon> pIUIRibbon = GetRibbonPtr())
2212 {
2213 const LARGE_INTEGER li0 = { 0 };
2214 pIStream->Seek(li0, STREAM_SEEK_SET, NULL);
2215 hr = pIUIRibbon->LoadSettingsFromStream(pIStream);
2216 }
2217
2218 return hr;
2219 }
2220
2221 void ResetRibbonSettings()
2222 {
2223 if (m_hgRibbonSettings != NULL)
2224 {
2225 ::GlobalFree(m_hgRibbonSettings);
2226 m_hgRibbonSettings = NULL;
2227 }
2228 }
2229
2230 HRESULT SaveRibbonSettings()
2231 {
2232 ATLASSERT(GetIUIFrameworkPtr());
2233 ATLASSERT(static_cast<T*>(this)->IsWindow());
2234
2235 HRESULT hr = E_FAIL;
2236 ATL::CComPtr<IStream> pIStream;
2237
2238 if SUCCEEDED(hr = ::CreateStreamOnHGlobal(m_hgRibbonSettings, FALSE, &pIStream))
2239 hr = *this >> pIStream;
2240
2241 if (SUCCEEDED(hr) && (m_hgRibbonSettings == NULL))
2242 hr = ::GetHGlobalFromStream(pIStream, &m_hgRibbonSettings);
2243
2244 if FAILED(hr)
2245 ResetRibbonSettings();
2246
2247 return hr;
2248 }
2249
2250 HRESULT RestoreRibbonSettings()
2251 {
2252 ATLASSERT(GetIUIFrameworkPtr());
2253 ATLASSERT(m_hgRibbonSettings);
2254 ATLASSERT(static_cast<T*>(this)->IsWindow());
2255
2256 HRESULT hr = E_FAIL;
2257 ATL::CComPtr<IStream> pIStream;
2258
2259 if SUCCEEDED(hr = ::CreateStreamOnHGlobal(m_hgRibbonSettings, FALSE, &pIStream))
2260 hr = *this << pIStream;
2261
2262 if FAILED(hr)
2263 ResetRibbonSettings();
2264
2265 return hr;
2266 }
2267
2268 // QAT dock states
2269 UI_CONTROLDOCK GetQATDock()
2270 {
2271 ATLASSERT(GetIUIFrameworkPtr());
2272 ATLASSERT(IsRibbonUI());
2273
2274 UINT32 uDock = 0;
2275 PROPVARIANT propvar;
2276 ATL::CComQIPtr<IPropertyStore>pIPS(GetRibbonPtr());
2277
2278 if ((pIPS != NULL) && SUCCEEDED(pIPS->GetValue(UI_PKEY_QuickAccessToolbarDock, &propvar)) &&
2279 SUCCEEDED(UIPropertyToUInt32(UI_PKEY_QuickAccessToolbarDock, propvar, &uDock)))
2280 return (UI_CONTROLDOCK)uDock;
2281
2282 ATLASSERT(FALSE); // something was wrong
2283 return (UI_CONTROLDOCK)0;
2284 }
2285
2286 bool SetQATDock(UI_CONTROLDOCK dockState)
2287 {
2288 ATLASSERT(GetIUIFrameworkPtr());
2289 ATLASSERT(IsRibbonUI());
2290
2291 PROPVARIANT propvar;
2292 ATLVERIFY(SUCCEEDED(SetPropertyVal(UI_PKEY_QuickAccessToolbarDock, dockState, &propvar)));
2293
2294 ATL::CComQIPtr<IPropertyStore>pIPS(GetRibbonPtr());
2295 if ((pIPS != NULL) && SUCCEEDED(pIPS->SetValue(UI_PKEY_QuickAccessToolbarDock, propvar)))
2296 {
2297 pIPS->Commit();
2298 return true;
2299 }
2300
2301 ATLASSERT(FALSE); // something was wrong
2302 return false;
2303 }
2304
2305 // Ribbon display states
2306 bool GetRibbonDisplayState(REFPROPERTYKEY key)
2307 {
2308 ATLASSERT(GetIUIFrameworkPtr());
2309 ATLASSERT(IsRibbonUI());
2310 ATLASSERT((k_(key) == k_Viewable) || (k_(key) == k_Minimized));
2311
2312 PROPVARIANT propvar;
2313 ATL::CComQIPtr<IPropertyStore>pIPS(GetRibbonPtr());
2314
2315 if ((pIPS != NULL) && SUCCEEDED(pIPS->GetValue(key, &propvar)))
2316 {
2317 BOOL bState = FALSE;
2318 if SUCCEEDED(UIPropertyToBoolean(key, propvar, &bState))
2319 return (bState != FALSE);
2320 }
2321
2322 ATLASSERT(FALSE); // something was wrong
2323 return false;
2324 }
2325
2326 bool SetRibbonDisplayState(REFPROPERTYKEY key, bool bState = true)
2327 {
2328 ATLASSERT(GetIUIFrameworkPtr());
2329 ATLASSERT(IsRibbonUI());
2330 ATLASSERT((k_(key) == k_Viewable) || (k_(key) == k_Minimized));
2331
2332 PROPVARIANT propvar;
2333 ATLVERIFY(SUCCEEDED(SetPropertyVal(key, bState, &propvar)));
2334
2335 ATL::CComQIPtr<IPropertyStore>pIPS(GetRibbonPtr());
2336
2337 if ((pIPS != NULL) && SUCCEEDED(pIPS->SetValue(key, propvar)))
2338 {
2339 pIPS->Commit();
2340 return true;
2341 }
2342
2343 ATLASSERT(FALSE); // something was wrong
2344 return false;
2345 }
2346
2347 bool IsRibbonMinimized()
2348 {
2349 return GetRibbonDisplayState(UI_PKEY_Minimized);
2350 }
2351
2352 bool MinimizeRibbon(bool bMinimize = true)
2353 {
2354 return SetRibbonDisplayState(UI_PKEY_Minimized, bMinimize);
2355 }
2356
2357 bool IsRibbonHidden()
2358 {
2359 return !GetRibbonDisplayState(UI_PKEY_Viewable);
2360 }
2361
2362 bool HideRibbon(bool bHide = true)
2363 {
2364 return SetRibbonDisplayState(UI_PKEY_Viewable, !bHide);
2365 }
2366
2367 // Ribbon colors
2368 UI_HSBCOLOR GetRibbonColor(REFPROPERTYKEY key)
2369 {
2370 ATLASSERT(GetIUIFrameworkPtr());
2371 ATLASSERT(IsRibbonUI());
2372 ATLASSERT((k_(key) >= k_GlobalBackgroundColor) && (k_(key) <= k_GlobalTextColor));
2373
2374 PROPVARIANT propvar;
2375 ATL::CComQIPtr<IPropertyStore>pIPS(GetIUIFrameworkPtr());
2376
2377 if ((pIPS != NULL) && SUCCEEDED(pIPS->GetValue(key, &propvar)))
2378 {
2379 UINT32 color = 0;
2380 if SUCCEEDED(UIPropertyToUInt32(key, propvar, &color))
2381 return color;
2382 }
2383
2384 ATLASSERT(FALSE); // something was wrong
2385 return 0;
2386 }
2387
2388 bool SetRibbonColor(REFPROPERTYKEY key, UI_HSBCOLOR color)
2389 {
2390 ATLASSERT(GetIUIFrameworkPtr());
2391 ATLASSERT(IsRibbonUI());
2392 ATLASSERT((k_(key) >= k_GlobalBackgroundColor) && (k_(key) <= k_GlobalTextColor));
2393
2394 PROPVARIANT propvar;
2395 ATLVERIFY(SUCCEEDED(SetPropertyVal(key, color, &propvar)));
2396
2397 ATL::CComQIPtr<IPropertyStore>pIPS(GetIUIFrameworkPtr());
2398
2399 if ((pIPS != NULL) && SUCCEEDED(pIPS->SetValue(key, propvar)))
2400 {
2401 pIPS->Commit();
2402 return true;
2403 }
2404
2405 ATLASSERT(FALSE); // something was wrong
2406 return false;
2407 }
2408
2409 // Ribbon modes
2410 HRESULT SetRibbonModes(INT32 iModes)
2411 {
2412 ATLASSERT(IsRibbonUI());
2413 return GetIUIFrameworkPtr()->SetModes(iModes);
2414 }
2415
2416 // Ribbon contextual tab
2417 UI_CONTEXTAVAILABILITY GetRibbonContextAvail(UINT32 uID)
2418 {
2419 ATLASSERT(GetIUIFrameworkPtr());
2420
2421 PROPVARIANT propvar;
2422 if (IsRibbonUI() &&
2423 SUCCEEDED(GetIUIFrameworkPtr()->GetUICommandProperty(uID, UI_PKEY_ContextAvailable, &propvar)))
2424 {
2425 UINT uav;
2426 if (SUCCEEDED(PropVariantToUInt32(propvar, &uav)))
2427 {
2428 CUpdateUIBase::UIEnable(uID, uav != UI_CONTEXTAVAILABILITY_NOTAVAILABLE);
2429 CUpdateUIBase::UISetCheck(uID, uav == UI_CONTEXTAVAILABILITY_ACTIVE);
2430 return (UI_CONTEXTAVAILABILITY)uav;
2431 }
2432 }
2433
2434 return UI_CONTEXTAVAILABILITY_NOTAVAILABLE;
2435 }
2436
2437 HRESULT SetRibbonContextAvail(UINT32 uID, UI_CONTEXTAVAILABILITY cav)
2438 {
2439 CUpdateUIBase::UIEnable(uID, cav != UI_CONTEXTAVAILABILITY_NOTAVAILABLE);
2440 CUpdateUIBase::UISetCheck(uID, cav == UI_CONTEXTAVAILABILITY_ACTIVE);
2441
2442 return SetProperty((WORD)uID, UI_PKEY_ContextAvailable, UINT32(cav));
2443 }
2444
2445 // Ribbon context menu
2446 bool HasRibbonMenu(UINT32 uID)
2447 {
2448 ATL::CComPtr<IUIContextualUI> pI = GetMenuPtr(uID);
2449 return pI != NULL;
2450 }
2451
2452 HRESULT TrackRibbonMenu(UINT32 uID, INT32 x, INT32 y)
2453 {
2454 ATLASSERT(HasRibbonMenu(uID));
2455
2456 return IsRibbonUI() ?
2457 ATL::CComPtr<IUIContextualUI>(GetMenuPtr(uID))->ShowAtLocation(x, y) :
2458 E_FAIL;
2459 }
2460
2461 HRESULT TrackRibbonMenu(UINT32 uID, LPARAM lParam)
2462 {
2463 return TrackRibbonMenu(uID, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
2464 }
2465
2466 // Overrideables
2467 HBITMAP OnRibbonQueryImage(UINT nCmdID, REFPROPERTYKEY /*key*/)
2468 {
2469 return DefRibbonQueryImage(nCmdID);
2470 }
2471
2472 LPCWSTR OnRibbonQueryText(UINT nCmdID, REFPROPERTYKEY key)
2473 {
2474 return DefRibbonQueryText(nCmdID, key);
2475 }
2476
2477 bool OnRibbonQueryState(UINT nCmdID, REFPROPERTYKEY key)
2478 {
2479 return DefRibbonQueryState(nCmdID, key);
2480 }
2481
2482 UI_CONTEXTAVAILABILITY OnRibbonQueryTabAvail(UINT nCmdID)
2483 {
2484 DWORD dwState = UIGetState(nCmdID);
2485 return ((dwState & UPDUI_DISABLED) == UPDUI_DISABLED) ?
2486 UI_CONTEXTAVAILABILITY_NOTAVAILABLE :
2487 (((dwState & UPDUI_CHECKED) == UPDUI_CHECKED) ?
2488 UI_CONTEXTAVAILABILITY_ACTIVE :
2489 UI_CONTEXTAVAILABILITY_AVAILABLE);
2490 }
2491
2492 LPCWSTR OnRibbonQueryComboText(UINT32 /*uCtrlID*/)
2493 {
2494 return NULL;
2495 }
2496
2497 LPCWSTR OnRibbonQueryCategoryText(UINT32 /*uCtrlID*/, UINT32 /*uCat*/)
2498 {
2499 return L"Category";
2500 }
2501
2502 UINT32 OnRibbonQueryItemCategory(UINT32 /*uCtrlID*/, UINT32 /*uItem*/)
2503 {
2504 return 0;
2505 }
2506
2507 LPCWSTR OnRibbonQueryItemText(UINT32 uCtrlID, UINT32 uItem)
2508 {
2509 return DefRibbonQueryItemText(uCtrlID, uItem);
2510 }
2511
2512 bool OnRibbonQuerySelectedItem(UINT32 /*uCtrlID*/, UINT32& /*uSel*/)
2513 {
2514 return false;
2515 }
2516
2517 HBITMAP OnRibbonQueryItemImage(UINT32 uCtrlID, UINT32 uItem)
2518 {
2519 return DefRibbonQueryItemImage(uCtrlID, uItem);
2520 }
2521
2522 UINT32 OnRibbonQueryItemCommand(UINT32 uCtrlID, UINT32 uItem)
2523 {
2524 return DefRibbonQueryItemCommand(uCtrlID, uItem);
2525 }
2526
2527 UI_COMMANDTYPE OnRibbonQueryItemCommandType(UINT32 /*uCtrlID*/, UINT32 /*uItem*/)
2528 {
2529 return UI_COMMANDTYPE_ACTION;
2530 }
2531
2532 LPCWSTR OnRibbonQueryRecentItemName(LPCWSTR sPath)
2533 {
2534 return ::PathFindFileName(sPath);
2535 }
2536
2537 bool OnRibbonQueryFont(UINT /*nId*/, CHARFORMAT2& /*cf*/)
2538 {
2539 return false;
2540 }
2541
2542 bool OnRibbonQuerySpinnerValue(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/, LONG* /*pVal*/)
2543 {
2544 return false;
2545 }
2546
2547 bool OnRibbonQueryFloatSpinnerValue(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/, DOUBLE* /*pVal*/)
2548 {
2549 return false;
2550 }
2551
2552 COLORREF OnRibbonQueryColor(UINT /*nCmdID*/)
2553 {
2554 return 0x800080; /*MAGENTA*/
2555 }
2556
2557 LPCWSTR OnRibbonQueryColorLabel(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/)
2558 {
2559 return NULL;
2560 }
2561
2562 COLORREF* OnRibbonQueryColorArray(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/)
2563 {
2564 return NULL;
2565 }
2566
2567 LPCWSTR* OnRibbonQueryColorTooltips(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/)
2568 {
2569 return NULL;
2570 }
2571
2572 bool OnRibbonItemSelected(UINT32 uCtrlID, UI_EXECUTIONVERB verb, UINT32 uItem)
2573 {
2574 DefCommandExecute(MAKELONG(uCtrlID, verb), uItem);
2575 return true;
2576 }
2577
2578 void OnRibbonColorCtrlExecute(UINT32 uCtrlID, UI_EXECUTIONVERB verb, UI_SWATCHCOLORTYPE uType, COLORREF color)
2579 {
2580 DefRibbonColorCtrlExecute(uCtrlID, verb, uType, color);
2581 }
2582
2583 void OnRibbonFontCtrlExecute(UINT32 uCtrlID, UI_EXECUTIONVERB verb, CHARFORMAT2* pcf)
2584 {
2585 DefCommandExecute(MAKELONG(uCtrlID, verb), (LPARAM)pcf);
2586 }
2587
2588 void OnRibbonSpinnerCtrlExecute(UINT32 uCtrlID, LONG* pVal)
2589 {
2590 DefCommandExecute(uCtrlID, *pVal);
2591 }
2592
2593 void OnRibbonSpinnerCtrlExecute(UINT32 uCtrlID, DOUBLE* pVal)
2594 {
2595 DefCommandExecute(uCtrlID, (LPARAM)pVal);
2596 }
2597
2598 void OnRibbonCommandExecute(UINT32 uCmdID)
2599 {
2600 DefCommandExecute(uCmdID);
2601 }
2602
2603 // Default implementations
2604 HBITMAP DefRibbonQueryImage(UINT nCmdID)
2605 {
2606 return AtlLoadBitmapImage(nCmdID, LR_CREATEDIBSECTION);
2607 }
2608
2609 bool DefRibbonQueryState(UINT nCmdID, REFPROPERTYKEY key)
2610 {
2611 DWORD dwState = UIGetState(nCmdID);
2612 bool bRet = false;
2613 switch (k_(key))
2614 {
2615 case k_BooleanValue:
2616 bRet = (dwState & UPDUI_CHECKED) == UPDUI_CHECKED;
2617 break;
2618 case k_Enabled:
2619 bRet = (dwState & UPDUI_DISABLED) != UPDUI_DISABLED;
2620 break;
2621 default:
2622 ATLASSERT(FALSE);
2623 break;
2624 }
2625
2626 return bRet;
2627 }
2628
2629 LPCTSTR DefRibbonQueryText(UINT nCmdID, REFPROPERTYKEY key)
2630 {
2631 static WCHAR sText[RIBBONUI_MAX_TEXT] = { 0 };
2632
2633 if (k_(key) == k_Label)
2634 return UIGetText(nCmdID);
2635
2636 if (AtlLoadString(nCmdID, sText, RIBBONUI_MAX_TEXT))
2637 {
2638 PWCHAR pTitle = wcschr(sText, L'\n');
2639 switch (k_(key))
2640 {
2641 case k_Keytip:
2642 if (PWCHAR pAmp = wcschr(sText, L'&'))
2643 pTitle = pAmp;
2644 if (pTitle != NULL)
2645 *(pTitle + 2) = NULL; // fall through
2646 case k_TooltipTitle:
2647 return pTitle ? ++pTitle : NULL;
2648 case k_TooltipDescription:
2649 case k_LabelDescription:
2650 if (pTitle != NULL)
2651 *pTitle = NULL;
2652 return sText;
2653 }
2654 }
2655
2656 return NULL;
2657 }
2658
2659 LPCWSTR DefRibbonQueryItemText(UINT32 uCtrlID, UINT32 uItem)
2660 {
2661 return DefRibbonQueryText(uCtrlID + 1 + uItem, UI_PKEY_LabelDescription);
2662 }
2663
2664 HBITMAP DefRibbonQueryItemImage(UINT32 uCtrlID, UINT32 uItem)
2665 {
2666 return DefRibbonQueryImage(uCtrlID + 1 + uItem);
2667 }
2668
2669 UINT32 DefRibbonQueryItemCommand(UINT32 uCtrlID, UINT32 uItem)
2670 {
2671 return uCtrlID + 1 + uItem;
2672 }
2673
2674 void DefRibbonColorCtrlExecute(UINT32 uCtrlID, UI_EXECUTIONVERB verb, UI_SWATCHCOLORTYPE uType, COLORREF color)
2675 {
2676 switch(uType)
2677 {
2678 case UI_SWATCHCOLORTYPE_RGB:
2679 break;
2680 case UI_SWATCHCOLORTYPE_AUTOMATIC:
2681 color = ::GetSysColor(COLOR_WINDOWTEXT);
2682 break;
2683 case UI_SWATCHCOLORTYPE_NOCOLOR:
2684 color = ::GetSysColor(COLOR_WINDOW);
2685 break;
2686 default:
2687 ATLASSERT(FALSE);
2688 break;
2689 }
2690
2691 DefCommandExecute(MAKELONG(uCtrlID, verb), color);
2692 }
2693
2694 void DefCommandExecute(UINT32 uCmd, LPARAM lParam = 0)
2695 {
2696 static_cast<T*>(this)->PostMessage(WM_COMMAND, uCmd, lParam);
2697 }
2698
2699 // Elements setting helpers
2700 HRESULT InvalidateCtrl(UINT32 nID)
2701 {
2702 return IsRibbonUI() ?
2703 GetIUIFrameworkPtr()->InvalidateUICommand(nID, UI_INVALIDATIONS_ALLPROPERTIES, NULL) :
2704 E_FAIL;
2705 }
2706
2707 HRESULT InvalidateProperty(UINT32 nID, REFPROPERTYKEY key, UI_INVALIDATIONS flags = UI_INVALIDATIONS_PROPERTY)
2708 {
2709 return IsRibbonUI() ?
2710 GetIUIFrameworkPtr()->InvalidateUICommand(nID, flags, &key) :
2711 E_FAIL;
2712 }
2713
2714 template <typename V>
2715 HRESULT SetProperty(WORD wID, REFPROPERTYKEY key, V val)
2716 {
2717 if (IsRibbonUI())
2718 {
2719 PROPVARIANT var;
2720 if (SUCCEEDED(RibbonUI::SetPropertyVal(key, val, &var)))
2721 {
2722 return SetProperty(wID, key, var);
2723 }
2724 return E_INVALIDARG;
2725 }
2726 else
2727 {
2728 return E_FAIL;
2729 }
2730 }
2731
2732 template <>
2733 HRESULT SetProperty(WORD nID, REFPROPERTYKEY key, PROPVARIANT var)
2734 {
2735 return IsRibbonUI() ?
2736 GetIUIFrameworkPtr()->SetUICommandProperty(nID, key, var) :
2737 E_FAIL;
2738 }
2739
2740 // Interfaces
2741 // IUIApplication
2742 STDMETHODIMP OnViewChanged(UINT32, UI_VIEWTYPE, IUnknown*, UI_VIEWVERB verb, INT32)
2743 {
2744 switch (verb)
2745 {
2746 case UI_VIEWVERB_CREATE:
2747 m_bRibbonUI = true;
2748 if (m_hgRibbonSettings != NULL)
2749 RestoreRibbonSettings();
2750 break;
2751 case UI_VIEWVERB_SIZE:
2752 static_cast<T*>(this)->UpdateLayout(FALSE);
2753 break;
2754 case UI_VIEWVERB_DESTROY:
2755 SaveRibbonSettings();
2756 m_bRibbonUI = false;
2757 break;
2758 }
2759
2760 return S_OK;
2761 }
2762
2763 STDMETHODIMP OnCreateUICommand(UINT32 nCmdID, UI_COMMANDTYPE typeID, IUICommandHandler** ppCommandHandler)
2764 {
2765 UIAddRibbonElement(nCmdID);
2766 if (typeID == UI_COMMANDTYPE_CONTEXT)
2767 CUpdateUIBase::UIEnable(nCmdID, false);
2768 *ppCommandHandler = this;
2769 return S_OK;
2770 }
2771
2772 STDMETHODIMP OnDestroyUICommand(UINT32 nCmdID, UI_COMMANDTYPE, IUICommandHandler*)
2773 {
2774 UIRemoveRibbonElement(nCmdID);
2775 return S_OK;
2776 }
2777
2778 // IUICommandHandler
2779 STDMETHODIMP Execute(UINT nCmdID,
2780 UI_EXECUTIONVERB verb,
2781 const PROPERTYKEY* key,
2782 const PROPVARIANT* ppropvarValue,
2783 IUISimplePropertySet* pCommandExecutionProperties)
2784 {
2785 T* pT =static_cast<T*>(this);
2786 return pT->GetRibbonCtrl(nCmdID).DoExecute(nCmdID, verb, key, ppropvarValue, pCommandExecutionProperties);
2787 }
2788
2789 STDMETHODIMP UpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
2790 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
2791 {
2792 T* pT =static_cast<T*>(this);
2793 return pT->GetRibbonCtrl(nCmdID).DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
2794 }
2795
2796 #ifdef _DEBUG
2797 // IUnknown methods (heavyweight)
2798 STDMETHODIMP_(ULONG) AddRef()
2799 {
2800 return InterlockedIncrement(&m_cRef);
2801 }
2802
2803 STDMETHODIMP_(ULONG) Release()
2804 {
2805 LONG cRef = InterlockedDecrement(&m_cRef);
2806 if (cRef == 0) // NoOp for breakpoint
2807 {
2808 cRef = 0;
2809 }
2810
2811 return cRef;
2812 }
2813
2814 STDMETHODIMP QueryInterface(REFIID iid, void** ppv)
2815 {
2816 if (ppv == NULL)
2817 {
2818 return E_POINTER;
2819 }
2820 else if ((iid == __uuidof(IUnknown)) ||
2821 (iid == __uuidof(IUICommandHandler)) ||
2822 (iid == __uuidof(IUIApplication)))
2823 {
2824 *ppv = this;
2825 AddRef();
2826 return S_OK;
2827 }
2828 else
2829 {
2830 return E_NOINTERFACE;
2831 }
2832 }
2833
2834 LONG m_cRef;
2835 #else
2836 // IUnknown methods (lightweight)
2837 STDMETHODIMP QueryInterface(REFIID iid, void** ppv)
2838 {
2839 if ((iid == __uuidof(IUnknown)) ||
2840 (iid == __uuidof(IUICommandHandler)) ||
2841 (iid == __uuidof(IUIApplication)))
2842 {
2843 *ppv = this;
2844 return S_OK;
2845 }
2846 return E_NOINTERFACE;
2847 }
2848 ULONG STDMETHODCALLTYPE AddRef()
2849 {
2850 return 1;
2851 }
2852 ULONG STDMETHODCALLTYPE Release()
2853 {
2854 return 1;
2855 }
2856 #endif
2857
2858 // CRibbonImpl ICtrl implementation
2859 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
2860 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
2861 IUISimplePropertySet* /*pCommandExecutionProperties*/)
2862 {
2863 if (key != NULL)
2864 {
2865 if(k_(*key) != k_BooleanValue)
2866 {
2867 ATLTRACE2(atlTraceUI, 0, _T("Control ID %d is not handled\n"), nCmdID);
2868 return E_NOTIMPL;
2869 }
2870 BOOL bChecked = FALSE;
2871 ATLVERIFY(SUCCEEDED(PropVariantToBoolean(*ppropvarValue, &bChecked)));
2872 CUpdateUIBase::UISetCheck(nCmdID, bChecked);
2873 }
2874
2875 ATLASSERT(verb == UI_EXECUTIONVERB_EXECUTE);
2876 verb; // avoid level 4 warning
2877
2878 static_cast<T*>(this)->OnRibbonCommandExecute(nCmdID);
2879
2880 return S_OK;
2881 }
2882
2883 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
2884 const PROPVARIANT* /*ppropvarCurrentValue*/, PROPVARIANT* ppropvarNewValue)
2885 {
2886 T* pT = static_cast<T*>(this);
2887 HRESULT hr = E_NOTIMPL;
2888 switch (k_(key))
2889 {
2890 case k_LargeImage:
2891 case k_LargeHighContrastImage:
2892 case k_SmallImage:
2893 case k_SmallHighContrastImage:
2894 if (HBITMAP hbm = pT->OnRibbonQueryImage(nCmdID, key))
2895 hr = SetPropertyVal(key, GetImage(hbm, UI_OWNERSHIP_TRANSFER), ppropvarNewValue);
2896 break;
2897 case k_Label:
2898 case k_Keytip:
2899 case k_TooltipTitle:
2900 case k_TooltipDescription:
2901 case k_LabelDescription:
2902 if (LPCWSTR sText = pT->OnRibbonQueryText(nCmdID, key))
2903 hr = SetPropertyVal(key, sText, ppropvarNewValue);
2904 break;
2905 case k_BooleanValue:
2906 case k_Enabled:
2907 hr = SetPropertyVal(key, pT->OnRibbonQueryState(nCmdID, key), ppropvarNewValue);
2908 break;
2909 case k_ContextAvailable:
2910 hr = SetPropertyVal(key, pT->OnRibbonQueryTabAvail(nCmdID), ppropvarNewValue);
2911 break;
2912 }
2913
2914 return hr;
2915 }
2916
2917 // CRibbonImpl::CRibbonXXXCtrl specialized classes
2918 //CRibbonComboCtrl
2919 template <UINT t_ID, size_t t_items, size_t t_categories = 0>
2920 class CRibbonComboCtrl : public CollectionCtrlImpl<T, t_ID, ComboCollectionImpl<CRibbonComboCtrl<t_ID, t_items, t_categories>, t_items, t_categories>>
2921 {
2922 public:
2923 CRibbonComboCtrl()
2924 { }
2925 };
2926
2927 // CRibbonItemGalleryCtrl
2928 template <UINT t_ID, size_t t_items, size_t t_categories = 0>
2929 class CRibbonItemGalleryCtrl : public CollectionCtrlImpl<T, t_ID, ItemCollectionImpl<CRibbonItemGalleryCtrl<t_ID, t_items, t_categories>, t_items, t_categories>>
2930 {
2931 public:
2932 CRibbonItemGalleryCtrl()
2933 { }
2934 };
2935
2936 // CRibbonCommandGalleryCtrl
2937 template <UINT t_ID, size_t t_items, size_t t_categories = 0>
2938 class CRibbonCommandGalleryCtrl : public CollectionCtrlImpl<T, t_ID, CommandCollectionImpl<CRibbonCommandGalleryCtrl<t_ID, t_items, t_categories>, t_items, t_categories>>
2939 {
2940 public:
2941 CRibbonCommandGalleryCtrl()
2942 { }
2943 };
2944
2945 // CRibbonToolbarGalleryCtrl
2946 template <UINT t_ID, UINT t_idTB, size_t t_size>
2947 class CRibbonToolbarGalleryCtrl : public ToolbarGalleryCtrlImpl<T, t_ID, t_idTB, t_size>
2948 { };
2949
2950 // CRibbonSimpleComboCtrl
2951 template <UINT t_ID, size_t t_size>
2952 class CRibbonSimpleComboCtrl : public SimpleCollectionCtrlImpl<T, t_ID, t_size>
2953 { };
2954
2955 // CRibbonSimpleGalleryCtrl
2956 template <UINT t_ID, size_t t_size, UI_COMMANDTYPE t_CommandType = UI_COMMANDTYPE_ACTION>
2957 class CRibbonSimpleGalleryCtrl : public SimpleCollectionCtrlImpl<T, t_ID, t_size, t_CommandType>
2958 { };
2959
2960 //CRibbonRecentItemsCtrl
2961 template <UINT t_ID, class TDocList = CRecentDocumentList>
2962 class CRibbonRecentItemsCtrl : public RecentItemsCtrlImpl<T, t_ID, TDocList>
2963 {
2964 public:
2965 CRibbonRecentItemsCtrl()
2966 { }
2967 };
2968
2969 // CRibbonColorCtrl
2970 template <UINT t_ID>
2971 class CRibbonColorCtrl : public ColorCtrlImpl<T, t_ID>
2972 {
2973 public:
2974 CRibbonColorCtrl()
2975 { }
2976 };
2977
2978 //CRibbonFontCtrl
2979 template <UINT t_ID>
2980 class CRibbonFontCtrl : public FontCtrlImpl<T, t_ID>
2981 {
2982 public:
2983 CRibbonFontCtrl()
2984 { }
2985 };
2986
2987 // CRibbonSpinnerCtrl
2988 template <UINT t_ID>
2989 class CRibbonSpinnerCtrl : public SpinnerCtrlImpl<T, t_ID, LONG>
2990 {
2991 public:
2992 CRibbonSpinnerCtrl()
2993 { }
2994 };
2995
2996 // CRibbonFloatSpinnerCtrl
2997 template <UINT t_ID>
2998 class CRibbonFloatSpinnerCtrl : public SpinnerCtrlImpl<T, t_ID, DOUBLE>
2999 {
3000 public:
3001 CRibbonFloatSpinnerCtrl()
3002 {
3003 m_Values[4] = 1; // 1 decimal
3004 }
3005 };
3006
3007 // CRibbonCommandCtrl
3008 template <UINT t_ID>
3009 class CRibbonCommandCtrl : public CommandCtrlImpl<T, t_ID>
3010 {
3011 public:
3012 CRibbonCommandCtrl()
3013 { }
3014 };
3015
3016 // Control classes access to T instance (re-initialized in constructor)
3017 static T* pWndRibbon;
3018 };
3019
3020 template <class T>
3021 __declspec(selectany) T* CRibbonImpl<T>::pWndRibbon;
3022
3023 // Control map element
3024 #pragma warning(push)
3025 #pragma warning(disable: 4510 610 4512) // missing default constructor, can't be instatiated, assignment operator could not be generated
3026 typedef struct
3027 {
3028 UINT uID;
3029 ICtrl& ctrl;
3030 } _ribbonCtrl;
3031 #pragma warning(pop)
3032
3033 }; // namespace RibbonUI
3034
3035
3036 ///////////////////////////////////////////////////////////////////////////////
3037 // RibbonUI Control map
3038
3039 // Control map macros
3040 #define BEGIN_RIBBON_CONTROL_MAP(theClass) \
3041 WTL::RibbonUI::ICtrl& GetRibbonCtrl(UINT id) \
3042 { \
3043 WTL::RibbonUI::_ribbonCtrl _ctrls[] = \
3044 {
3045
3046 #define RIBBON_CONTROL(member) {member.GetID(), static_cast<WTL::RibbonUI::ICtrl&>(member)},
3047
3048 #define END_RIBBON_CONTROL_MAP() \
3049 {0, *this} \
3050 }; \
3051 int i = 0; \
3052 for(; i < _countof(_ctrls) - 1; i++) \
3053 if (_ctrls[i].uID == id) \
3054 break; \
3055 return _ctrls[i].ctrl; \
3056 }
3057
3058 // Control message map macros
3059 #define RIBBON_GALLERY_CONTROL_HANDLER(id, func) \
3060 if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \
3061 { \
3062 bHandled = TRUE; \
3063 lResult = func((UI_EXECUTIONVERB)HIWORD(wParam), LOWORD(wParam), (UINT)lParam, bHandled); \
3064 if(bHandled) \
3065 return TRUE; \
3066 }
3067
3068 #define RIBBON_COMBO_CONTROL_HANDLER(id, func) \
3069 RIBBON_GALLERY_CONTROL_HANDLER(id, func)
3070
3071 #define RIBBON_FONT_CONTROL_HANDLER(id, func) \
3072 if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \
3073 { \
3074 bHandled = TRUE; \
3075 lResult = func((UI_EXECUTIONVERB)HIWORD(wParam), LOWORD(wParam), (CHARFORMAT2*)lParam, bHandled); \
3076 if(bHandled) \
3077 return TRUE; \
3078 }
3079
3080 #define RIBBON_COLOR_CONTROL_HANDLER(id, func) \
3081 if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \
3082 { \
3083 bHandled = TRUE; \
3084 lResult = func((UI_EXECUTIONVERB)HIWORD(wParam), LOWORD(wParam), (COLORREF)lParam, bHandled); \
3085 if(bHandled) \
3086 return TRUE; \
3087 }
3088
3089 #define RIBBON_SPINNER_CONTROL_HANDLER(id, func) \
3090 if(uMsg == WM_COMMAND && id == wParam) \
3091 { \
3092 bHandled = TRUE; \
3093 lResult = func((WORD)wParam, (LONG)lParam, bHandled); \
3094 if(bHandled) \
3095 return TRUE; \
3096 }
3097
3098 #define RIBBON_FLOATSPINNER_CONTROL_HANDLER(id, func) \
3099 if(uMsg == WM_COMMAND && id == wParam) \
3100 { \
3101 bHandled = TRUE; \
3102 lResult = func((WORD)wParam, (DOUBLE*)lParam, bHandled); \
3103 if(bHandled) \
3104 return TRUE; \
3105 }
3106
3107 // Handler prototypes
3108 /*
3109 LRESULT OnRibbonGalleryCtrl(UI_EXECUTIONVERB verb, WORD wID, UINT uSel, BOOL& bHandled);
3110 LRESULT OnRibbonComboCtrl(UI_EXECUTIONVERB verb, WORD wID, UINT uSel, BOOL& bHandled);
3111 LRESULT OnRibbonFontCtrl(UI_EXECUTIONVERB verb, WORD wID, CHARFORMAT2* pcf, BOOL& bHandled);
3112 LRESULT OnRibbonColorCtrl(UI_EXECUTIONVERB verb, WORD wID, COLORREF color, BOOL& bHandled);
3113 LRESULT OnRibbonSpinnerCtrl(WORD wID, LONG lVal, BOOL& bHandled);
3114 LRESULT OnRibbonFloatSpinnerCtrl(WORD wID, DOUBLE* pdVal, BOOL& bHandled);
3115 */
3116
3117
3118 ///////////////////////////////////////////////////////////////////////////////
3119 // Ribbon frame classes
3120
3121 // CRibbonFrameWindowImplBase
3122 //
3123 template <class T, class TFrameImpl>
3124 class ATL_NO_VTABLE CRibbonFrameWindowImplBase : public TFrameImpl, public RibbonUI::CRibbonImpl<T>
3125 {
3126 typedef TFrameImpl baseFrame;
3127 bool m_bUseCommandBarBitmaps;
3128 bool m_bWin7Fix;
3129
3130 public:
3131 // Construction
3132 CRibbonFrameWindowImplBase(bool bUseCommandBarBitmaps = true) :
3133 m_bUseCommandBarBitmaps(bUseCommandBarBitmaps), m_bWin7Fix(false)
3134 {
3135 __if_not_exists(T::m_CmdBar)
3136 {
3137 m_bUseCommandBarBitmaps = false;
3138 }
3139 }
3140
3141 // Win7 Aero fix helpers
3142 void ResetFrame()
3143 {
3144 const MARGINS margins = { 0 };
3145 ::DwmExtendFrameIntoClientArea(m_hWnd, &margins);
3146 }
3147
3148 INT CalcWin7Fix()
3149 {
3150 ResetFrame();
3151 RECT rc = { 0 };
3152 ::AdjustWindowRectEx(&rc, T::GetWndStyle(0), GetMenu() != NULL, T::GetWndExStyle(0));
3153 return -rc.top;
3154 }
3155
3156 bool NeedWin7Fix()
3157 {
3158 BOOL bComp = FALSE;
3159 return m_bWin7Fix && RunTimeHelper::IsWin7() && SUCCEEDED(DwmIsCompositionEnabled(&bComp)) && bComp;
3160 }
3161
3162 // Operations
3163 bool UseCommandBarBitmaps(bool bUse)
3164 {
3165 __if_exists(T::m_CmdBar)
3166 {
3167 return m_bUseCommandBarBitmaps = bUse;
3168 }
3169 __if_not_exists(T::m_CmdBar)
3170 {
3171 bUse; // avoid level 4 warning
3172 return false;
3173 }
3174 }
3175
3176 bool ShowRibbonUI(bool bShow, INT32 imodes = UI_MAKEAPPMODE(0), LPCWSTR sResName = L"APPLICATION_RIBBON")
3177 {
3178 if (!RunTimeHelper::IsRibbonUIAvailable())
3179 return false;
3180
3181 ATLASSERT(GetIUIFrameworkPtr());
3182
3183 if (IsRibbonUI() == bShow)
3184 return bShow;
3185
3186 bool bVisible = (IsWindowVisible() != FALSE);
3187 if(bVisible && !bShow)
3188 SetRedraw(FALSE);
3189
3190 if (bShow && ::IsWindow(m_hWndToolBar))
3191 {
3192 ::ShowWindow(m_hWndToolBar, SW_HIDE);
3193 UpdateLayout();
3194 }
3195
3196 m_bWin7Fix = !bShow;
3197
3198 HRESULT hr = bShow ? CreateRibbon(sResName) : DestroyRibbon();
3199
3200 m_bWin7Fix = SUCCEEDED(hr) && !bShow;
3201
3202 if (SUCCEEDED(hr))
3203 {
3204 if(::IsWindow(m_hWndToolBar) && !bShow)
3205 {
3206 ::ShowWindow(m_hWndToolBar, SW_SHOWNA);
3207 UpdateLayout();
3208 }
3209 else if (bShow)
3210 {
3211 PostMessage(WM_SIZE);
3212 SetRibbonModes(imodes);
3213 }
3214 }
3215
3216 if(bVisible && !bShow)
3217 {
3218 SetRedraw(TRUE);
3219 RedrawWindow(NULL, NULL, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
3220 }
3221
3222 return SUCCEEDED(hr) ? bShow : !bShow;
3223 }
3224
3225 // Overrideables
3226 HBITMAP OnRibbonQueryImage(UINT nCmdID, REFPROPERTYKEY key)
3227 {
3228 if ((key == UI_PKEY_SmallImage) && m_bUseCommandBarBitmaps)
3229 {
3230 if (HBITMAP hbm = GetCommandBarBitmap(nCmdID))
3231 return (HBITMAP)::CopyImage(hbm, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
3232 }
3233
3234 return DefRibbonQueryImage(nCmdID);
3235 }
3236
3237 BEGIN_MSG_MAP(CRibbonFrameWindowImplBase)
3238 if (!IsRibbonUI() && NeedWin7Fix())
3239 {
3240 MESSAGE_HANDLER(WM_SIZING, OnSizing)
3241 MESSAGE_HANDLER(WM_SIZE, OnSize)
3242 MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
3243 MESSAGE_HANDLER(WM_NCCALCSIZE, OnNCCalcSize)
3244 }
3245 CHAIN_MSG_MAP(CRibbonUpdateUI<T>)
3246 CHAIN_MSG_MAP(baseFrame)
3247 END_MSG_MAP()
3248
3249 // Message handlers for Win7 Aero
3250 LRESULT OnSizing(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
3251 {
3252 switch (wParam)
3253 {
3254 case WMSZ_TOP:
3255 case WMSZ_TOPLEFT:
3256 case WMSZ_TOPRIGHT:
3257 SetWindowPos(NULL, (LPRECT)lParam, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
3258 break;
3259 default:
3260 DefWindowProc();
3261 break;
3262 }
3263
3264 return 1; // handled
3265 }
3266
3267 LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
3268 {
3269 if (wParam != SIZE_MINIMIZED)
3270 SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
3271
3272 bHandled = FALSE;
3273 return 1;
3274 }
3275
3276 LRESULT OnActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
3277 {
3278 if(wParam != WA_INACTIVE)
3279 SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
3280
3281 bHandled = FALSE;
3282 return 1;
3283 }
3284
3285 LRESULT OnNCCalcSize(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
3286 {
3287 ATLASSERT(!IsRibbonUI() && NeedWin7Fix());
3288
3289 LRESULT lRet = DefWindowProc();
3290
3291 if(wParam)
3292 {
3293 LPNCCALCSIZE_PARAMS pParams = (LPNCCALCSIZE_PARAMS)lParam;
3294 pParams->rgrc[0].top = pParams->rgrc[1].top + CalcWin7Fix();
3295 }
3296
3297 return lRet;
3298 }
3299
3300 // Overrides
3301 void UpdateLayout(BOOL bResizeBars = TRUE)
3302 {
3303 RECT rect = { 0 };
3304 GetClientRect(&rect);
3305
3306 if (IsRibbonUI() && !IsRibbonHidden())
3307 {
3308 rect.top += GetRibbonHeight();
3309 }
3310 else if (!IsRibbonUI() && NeedWin7Fix())
3311 {
3312 ResetFrame();
3313 }
3314
3315 // position bars and offset their dimensions
3316 UpdateBarsPosition(rect, bResizeBars);
3317
3318 // resize client window
3319 if(m_hWndClient != NULL)
3320 ::SetWindowPos(m_hWndClient, NULL, rect.left, rect.top,
3321 rect.right - rect.left, rect.bottom - rect.top,
3322 SWP_NOZORDER | SWP_NOACTIVATE);
3323 }
3324
3325 // Implementation
3326 HBITMAP GetCommandBarBitmap(UINT nCmdID)
3327 {
3328 __if_exists (T::m_CmdBar)
3329 {
3330 ATLASSERT(RunTimeHelper::IsVista());
3331 T* pT =static_cast<T*>(this);
3332 int nIndex = pT->m_CmdBar.m_arrCommand.Find((WORD&)nCmdID);
3333 return (nIndex == -1) ? NULL : pT->m_CmdBar.m_arrVistaBitmap[nIndex];
3334 }
3335 __if_not_exists (T::m_CmdBar)
3336 {
3337 nCmdID; // avoid level 4 warning
3338 return NULL;
3339 }
3340 }
3341 };
3342
3343 // CRibbonFrameWindowImpl
3344 //
3345 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CFrameWinTraits>
3346 class ATL_NO_VTABLE CRibbonFrameWindowImpl : public CRibbonFrameWindowImplBase<T, CFrameWindowImpl<T, TBase, TWinTraits>>
3347 { };
3348
3349 // CRibbonMDIFrameWindowImpl
3350 //
3351 template <class T, class TBase = CMDIWindow, class TWinTraits = ATL::CFrameWinTraits>
3352 class ATL_NO_VTABLE CRibbonMDIFrameWindowImpl : public CRibbonFrameWindowImplBase<T, CMDIFrameWindowImpl<T, TBase, TWinTraits>>
3353 { };
3354
3355
3356 ///////////////////////////////////////////////////////////////////////////////
3357 // CRibbonPersist helper for RibbonUI persistency
3358
3359 class CRibbonPersist
3360 {
3361 public:
3362 CRibbonPersist(LPCWSTR sAppKey)
3363 {
3364 ATLASSERT(sAppKey && *sAppKey);
3365 m_Key.Create(HKEY_CURRENT_USER, sAppKey);
3366 ATLASSERT(m_Key.m_hKey);
3367 }
3368
3369 CRegKeyEx m_Key;
3370
3371 LONG Save(bool bRibbonUI, HGLOBAL hgSettings = NULL)
3372 {
3373 CRegKeyEx key;
3374 const DWORD dwUI = bRibbonUI;
3375
3376 LONG lRet = key.Create(m_Key, L"Ribbon");
3377 if(lRet != ERROR_SUCCESS)
3378 return lRet;
3379
3380 lRet = key.SetDWORDValue(L"UI", dwUI);
3381 if(lRet != ERROR_SUCCESS)
3382 return lRet;
3383
3384 if (hgSettings != NULL)
3385 {
3386 LPBYTE pVal = (LPBYTE)::GlobalLock(hgSettings);
3387 if (pVal != NULL)
3388 {
3389 lRet = key.SetBinaryValue(L"Settings", pVal, (ULONG)::GlobalSize(hgSettings));
3390 ::GlobalUnlock(hgSettings);
3391 }
3392 else
3393 {
3394 lRet = GetLastError();
3395 }
3396 }
3397
3398 return lRet;
3399 }
3400
3401 LONG Restore(bool& bRibbonUI, HGLOBAL& hgSettings)
3402 {
3403 ATLASSERT(hgSettings == NULL);
3404
3405 CRegKeyEx key;
3406
3407 LONG lRet = key.Open(m_Key, L"Ribbon");
3408 if(lRet != ERROR_SUCCESS)
3409 return lRet;
3410
3411 DWORD dwUI = 0xffff;
3412 lRet = key.QueryDWORDValue(L"UI", dwUI);
3413 if(lRet == ERROR_SUCCESS)
3414 bRibbonUI = dwUI == 1;
3415 else
3416 return lRet;
3417
3418 ULONG ulSize = 0;
3419 lRet = key.QueryBinaryValue(L"Settings", NULL, &ulSize);
3420 if (lRet == ERROR_SUCCESS)
3421 {
3422 ATLASSERT(ulSize != 0);
3423
3424 hgSettings = ::GlobalAlloc(GHND, ulSize);
3425 if (hgSettings != NULL)
3426 {
3427 LPBYTE pData = (LPBYTE)::GlobalLock(hgSettings);
3428 if (pData != NULL)
3429 {
3430 lRet = key.QueryBinaryValue(L"Settings", pData, &ulSize);
3431 }
3432 else
3433 {
3434 lRet = GetLastError();
3435 ::GlobalFree(hgSettings);
3436 hgSettings = NULL;
3437 }
3438 }
3439 else
3440 {
3441 lRet = GetLastError();
3442 }
3443 }
3444 return lRet;
3445 }
3446
3447 LONG Delete()
3448 {
3449 return m_Key.DeleteSubKey(L"Ribbon");
3450 }
3451 };
3452
3453 } // namespace WTL
3454
3455 #endif // __ATLRIBBON_H__
+0
-2166
src/third_party/wtl/Include/atlscrl.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLSCRL_H__
9 #define __ATLSCRL_H__
10
11 #pragma once
12
13 #ifndef __ATLAPP_H__
14 #error atlscrl.h requires atlapp.h to be included first
15 #endif
16
17 #ifndef __ATLWIN_H__
18 #error atlscrl.h requires atlwin.h to be included first
19 #endif
20
21 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE)
22 #include <zmouse.h>
23 #endif
24
25 #ifndef GET_WHEEL_DELTA_WPARAM
26 #define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))
27 #endif
28
29
30 ///////////////////////////////////////////////////////////////////////////////
31 // Classes in this file:
32 //
33 // CScrollImpl<T>
34 // CScrollWindowImpl<T, TBase, TWinTraits>
35 // CMapScrollImpl<T>
36 // CMapScrollWindowImpl<T, TBase, TWinTraits>
37 // CFSBWindowT<TBase>
38 // CZoomScrollImpl<T>
39 // CZoomScrollWindowImpl<T, TBase, TWinTraits>
40 // CScrollContainerImpl<T, TBase, TWinTraits>
41 // CScrollContainer
42
43 namespace WTL
44 {
45
46 ///////////////////////////////////////////////////////////////////////////////
47 // CScrollImpl - Provides scrolling support to any window
48
49 // Scroll extended styles
50 #define SCRL_SCROLLCHILDREN 0x00000001
51 #define SCRL_ERASEBACKGROUND 0x00000002
52 #define SCRL_NOTHUMBTRACKING 0x00000004
53 #if (WINVER >= 0x0500)
54 #define SCRL_SMOOTHSCROLL 0x00000008
55 #endif // (WINVER >= 0x0500)
56 #define SCRL_DISABLENOSCROLLV 0x00000010
57 #define SCRL_DISABLENOSCROLLH 0x00000020
58 #define SCRL_DISABLENOSCROLL (SCRL_DISABLENOSCROLLV | SCRL_DISABLENOSCROLLH)
59
60
61 template <class T>
62 class CScrollImpl
63 {
64 public:
65 enum { uSCROLL_FLAGS = SW_INVALIDATE };
66
67 POINT m_ptOffset;
68 SIZE m_sizeAll;
69 SIZE m_sizeLine;
70 SIZE m_sizePage;
71 SIZE m_sizeClient;
72 int m_zDelta; // current wheel value
73 int m_nWheelLines; // number of lines to scroll on wheel
74 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE)
75 // Note that this message must be forwarded from a top level window
76 UINT m_uMsgMouseWheel; // MSH_MOUSEWHEEL
77 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE)
78 int m_zHDelta; // current horizontal wheel value
79 int m_nHWheelChars; // number of chars to scroll on horizontal wheel
80 UINT m_uScrollFlags;
81 DWORD m_dwExtendedStyle; // scroll specific extended styles
82
83 // Constructor
84 CScrollImpl() : m_zDelta(0), m_nWheelLines(3),
85 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE)
86 m_uMsgMouseWheel(0U),
87 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE)
88 m_zHDelta(0), m_nHWheelChars(3),
89 m_uScrollFlags(0U), m_dwExtendedStyle(0)
90 {
91 m_ptOffset.x = 0;
92 m_ptOffset.y = 0;
93 m_sizeAll.cx = 0;
94 m_sizeAll.cy = 0;
95 m_sizePage.cx = 0;
96 m_sizePage.cy = 0;
97 m_sizeLine.cx = 0;
98 m_sizeLine.cy = 0;
99 m_sizeClient.cx = 0;
100 m_sizeClient.cy = 0;
101
102 SetScrollExtendedStyle(SCRL_SCROLLCHILDREN | SCRL_ERASEBACKGROUND);
103 }
104
105 // Attributes & Operations
106 DWORD GetScrollExtendedStyle() const
107 {
108 return m_dwExtendedStyle;
109 }
110
111 DWORD SetScrollExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
112 {
113 DWORD dwPrevStyle = m_dwExtendedStyle;
114 if(dwMask == 0)
115 m_dwExtendedStyle = dwExtendedStyle;
116 else
117 m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
118 // cache scroll flags
119 T* pT = static_cast<T*>(this);
120 pT; // avoid level 4 warning
121 m_uScrollFlags = pT->uSCROLL_FLAGS | (IsScrollingChildren() ? SW_SCROLLCHILDREN : 0) | (IsErasingBackground() ? SW_ERASE : 0);
122 #if (WINVER >= 0x0500) && !defined(_WIN32_WCE)
123 m_uScrollFlags |= (IsSmoothScroll() ? SW_SMOOTHSCROLL : 0);
124 #endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE)
125 return dwPrevStyle;
126 }
127
128 // offset operations
129 void SetScrollOffset(int x, int y, BOOL bRedraw = TRUE)
130 {
131 T* pT = static_cast<T*>(this);
132 ATLASSERT(::IsWindow(pT->m_hWnd));
133
134 pT->AdjustScrollOffset(x, y);
135
136 int dx = m_ptOffset.x - x;
137 int dy = m_ptOffset.y - y;
138 m_ptOffset.x = x;
139 m_ptOffset.y = y;
140
141 // block: set horizontal scroll bar
142 {
143 SCROLLINFO si = { sizeof(SCROLLINFO) };
144 si.fMask = SIF_POS;
145 if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLH) != 0)
146 si.fMask |= SIF_DISABLENOSCROLL;
147 si.nPos = m_ptOffset.x;
148 pT->SetScrollInfo(SB_HORZ, &si, bRedraw);
149 }
150
151 // block: set vertical scroll bar
152 {
153 SCROLLINFO si = { sizeof(SCROLLINFO) };
154 si.fMask = SIF_POS;
155 if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLV) != 0)
156 si.fMask |= SIF_DISABLENOSCROLL;
157 si.nPos = m_ptOffset.y;
158 pT->SetScrollInfo(SB_VERT, &si, bRedraw);
159 }
160
161 // Move all children if needed
162 if(IsScrollingChildren() && (dx != 0 || dy != 0))
163 {
164 for(HWND hWndChild = ::GetWindow(pT->m_hWnd, GW_CHILD); hWndChild != NULL; hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT))
165 {
166 RECT rect = { 0 };
167 ::GetWindowRect(hWndChild, &rect);
168 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rect, 1);
169 ::SetWindowPos(hWndChild, NULL, rect.left + dx, rect.top + dy, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
170 }
171 }
172
173 if(bRedraw)
174 pT->Invalidate();
175 }
176
177 void SetScrollOffset(POINT ptOffset, BOOL bRedraw = TRUE)
178 {
179 SetScrollOffset(ptOffset.x, ptOffset.y, bRedraw);
180 }
181
182 void GetScrollOffset(POINT& ptOffset) const
183 {
184 ptOffset = m_ptOffset;
185 }
186
187 // size operations
188 void SetScrollSize(int cx, int cy, BOOL bRedraw = TRUE, bool bResetOffset = true)
189 {
190 T* pT = static_cast<T*>(this);
191 ATLASSERT(::IsWindow(pT->m_hWnd));
192
193 m_sizeAll.cx = cx;
194 m_sizeAll.cy = cy;
195
196 int x = 0;
197 int y = 0;
198 if(!bResetOffset)
199 {
200 x = m_ptOffset.x;
201 y = m_ptOffset.y;
202 pT->AdjustScrollOffset(x, y);
203 }
204
205 int dx = m_ptOffset.x - x;
206 int dy = m_ptOffset.y - y;
207 m_ptOffset.x = x;
208 m_ptOffset.y = y;
209
210 // block: set horizontal scroll bar
211 {
212 SCROLLINFO si = { sizeof(SCROLLINFO) };
213 si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
214 if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLH) != 0)
215 si.fMask |= SIF_DISABLENOSCROLL;
216 si.nMin = 0;
217 si.nMax = m_sizeAll.cx - 1;
218 si.nPage = m_sizeClient.cx;
219 si.nPos = m_ptOffset.x;
220 pT->SetScrollInfo(SB_HORZ, &si, bRedraw);
221 }
222
223 // block: set vertical scroll bar
224 {
225 SCROLLINFO si = { sizeof(SCROLLINFO) };
226 si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
227 if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLV) != 0)
228 si.fMask |= SIF_DISABLENOSCROLL;
229 si.nMin = 0;
230 si.nMax = m_sizeAll.cy - 1;
231 si.nPage = m_sizeClient.cy;
232 si.nPos = m_ptOffset.y;
233 pT->SetScrollInfo(SB_VERT, &si, bRedraw);
234 }
235
236 // Move all children if needed
237 if(IsScrollingChildren() && (dx != 0 || dy != 0))
238 {
239 for(HWND hWndChild = ::GetWindow(pT->m_hWnd, GW_CHILD); hWndChild != NULL; hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT))
240 {
241 RECT rect = { 0 };
242 ::GetWindowRect(hWndChild, &rect);
243 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rect, 1);
244 ::SetWindowPos(hWndChild, NULL, rect.left + dx, rect.top + dy, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
245 }
246 }
247
248 SetScrollLine(0, 0);
249 SetScrollPage(0, 0);
250
251 if(bRedraw)
252 pT->Invalidate();
253 }
254
255 void SetScrollSize(SIZE size, BOOL bRedraw = TRUE, bool bResetOffset = true)
256 {
257 SetScrollSize(size.cx, size.cy, bRedraw, bResetOffset);
258 }
259
260 void GetScrollSize(SIZE& sizeWnd) const
261 {
262 sizeWnd = m_sizeAll;
263 }
264
265 // line operations
266 void SetScrollLine(int cxLine, int cyLine)
267 {
268 ATLASSERT(cxLine >= 0 && cyLine >= 0);
269 ATLASSERT(m_sizeAll.cx != 0 && m_sizeAll.cy != 0);
270
271 m_sizeLine.cx = T::CalcLineOrPage(cxLine, m_sizeAll.cx, 100);
272 m_sizeLine.cy = T::CalcLineOrPage(cyLine, m_sizeAll.cy, 100);
273 }
274
275 void SetScrollLine(SIZE sizeLine)
276 {
277 SetScrollLine(sizeLine.cx, sizeLine.cy);
278 }
279
280 void GetScrollLine(SIZE& sizeLine) const
281 {
282 sizeLine = m_sizeLine;
283 }
284
285 // page operations
286 void SetScrollPage(int cxPage, int cyPage)
287 {
288 ATLASSERT(cxPage >= 0 && cyPage >= 0);
289 ATLASSERT(m_sizeAll.cx != 0 && m_sizeAll.cy != 0);
290
291 m_sizePage.cx = T::CalcLineOrPage(cxPage, m_sizeAll.cx, 10);
292 m_sizePage.cy = T::CalcLineOrPage(cyPage, m_sizeAll.cy, 10);
293 }
294
295 void SetScrollPage(SIZE sizePage)
296 {
297 SetScrollPage(sizePage.cx, sizePage.cy);
298 }
299
300 void GetScrollPage(SIZE& sizePage) const
301 {
302 sizePage = m_sizePage;
303 }
304
305 // commands
306 void ScrollLineDown()
307 {
308 T* pT = static_cast<T*>(this);
309 ATLASSERT(::IsWindow(pT->m_hWnd));
310 pT->DoScroll(SB_VERT, SB_LINEDOWN, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
311 }
312
313 void ScrollLineUp()
314 {
315 T* pT = static_cast<T*>(this);
316 ATLASSERT(::IsWindow(pT->m_hWnd));
317 pT->DoScroll(SB_VERT, SB_LINEUP, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
318 }
319
320 void ScrollPageDown()
321 {
322 T* pT = static_cast<T*>(this);
323 ATLASSERT(::IsWindow(pT->m_hWnd));
324 pT->DoScroll(SB_VERT, SB_PAGEDOWN, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
325 }
326
327 void ScrollPageUp()
328 {
329 T* pT = static_cast<T*>(this);
330 ATLASSERT(::IsWindow(pT->m_hWnd));
331 pT->DoScroll(SB_VERT, SB_PAGEUP, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
332 }
333
334 void ScrollTop()
335 {
336 T* pT = static_cast<T*>(this);
337 ATLASSERT(::IsWindow(pT->m_hWnd));
338 pT->DoScroll(SB_VERT, SB_TOP, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
339 }
340
341 void ScrollBottom()
342 {
343 T* pT = static_cast<T*>(this);
344 ATLASSERT(::IsWindow(pT->m_hWnd));
345 pT->DoScroll(SB_VERT, SB_BOTTOM, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
346 }
347
348 void ScrollLineRight()
349 {
350 T* pT = static_cast<T*>(this);
351 ATLASSERT(::IsWindow(pT->m_hWnd));
352 pT->DoScroll(SB_HORZ, SB_LINEDOWN, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
353 }
354
355 void ScrollLineLeft()
356 {
357 T* pT = static_cast<T*>(this);
358 ATLASSERT(::IsWindow(pT->m_hWnd));
359 pT->DoScroll(SB_HORZ, SB_LINEUP, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
360 }
361
362 void ScrollPageRight()
363 {
364 T* pT = static_cast<T*>(this);
365 ATLASSERT(::IsWindow(pT->m_hWnd));
366 pT->DoScroll(SB_HORZ, SB_PAGEDOWN, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
367 }
368
369 void ScrollPageLeft()
370 {
371 T* pT = static_cast<T*>(this);
372 ATLASSERT(::IsWindow(pT->m_hWnd));
373 pT->DoScroll(SB_HORZ, SB_PAGEUP, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
374 }
375
376 void ScrollAllLeft()
377 {
378 T* pT = static_cast<T*>(this);
379 ATLASSERT(::IsWindow(pT->m_hWnd));
380 pT->DoScroll(SB_HORZ, SB_TOP, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
381 }
382
383 void ScrollAllRight()
384 {
385 T* pT = static_cast<T*>(this);
386 ATLASSERT(::IsWindow(pT->m_hWnd));
387 pT->DoScroll(SB_HORZ, SB_BOTTOM, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
388 }
389
390 // scroll to make point/view/window visible
391 void ScrollToView(POINT pt)
392 {
393 T* pT = static_cast<T*>(this);
394 ATLASSERT(::IsWindow(pT->m_hWnd));
395 RECT rect = { pt.x, pt.y, pt.x, pt.y };
396 pT->ScrollToView(rect);
397 }
398
399 void ScrollToView(RECT& rect)
400 {
401 T* pT = static_cast<T*>(this);
402 ATLASSERT(::IsWindow(pT->m_hWnd));
403
404 RECT rcClient = { 0 };
405 pT->GetClientRect(&rcClient);
406
407 int x = m_ptOffset.x;
408 if(rect.left < m_ptOffset.x)
409 x = rect.left;
410 else if(rect.right > (m_ptOffset.x + rcClient.right))
411 x = rect.right - rcClient.right;
412
413 int y = m_ptOffset.y;
414 if(rect.top < m_ptOffset.y)
415 y = rect.top;
416 else if(rect.bottom > (m_ptOffset.y + rcClient.bottom))
417 y = rect.bottom - rcClient.bottom;
418
419 SetScrollOffset(x, y);
420 }
421
422 void ScrollToView(HWND hWnd)
423 {
424 T* pT = static_cast<T*>(this);
425 ATLASSERT(::IsWindow(pT->m_hWnd));
426
427 RECT rect = { 0 };
428 ::GetWindowRect(hWnd, &rect);
429 ::OffsetRect(&rect, m_ptOffset.x, m_ptOffset.y);
430 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rect, 2);
431 ScrollToView(rect);
432 }
433
434 BEGIN_MSG_MAP(CScrollImpl)
435 MESSAGE_HANDLER(WM_CREATE, OnCreate)
436 MESSAGE_HANDLER(WM_VSCROLL, OnVScroll)
437 MESSAGE_HANDLER(WM_HSCROLL, OnHScroll)
438 MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel)
439 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE)
440 MESSAGE_HANDLER(m_uMsgMouseWheel, OnMouseWheel)
441 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE)
442 MESSAGE_HANDLER(WM_MOUSEHWHEEL, OnMouseHWheel)
443 MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
444 MESSAGE_HANDLER(WM_SIZE, OnSize)
445 MESSAGE_HANDLER(WM_PAINT, OnPaint)
446 #ifndef _WIN32_WCE
447 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
448 #endif // !_WIN32_WCE
449 // standard scroll commands
450 ALT_MSG_MAP(1)
451 COMMAND_ID_HANDLER(ID_SCROLL_UP, OnScrollUp)
452 COMMAND_ID_HANDLER(ID_SCROLL_DOWN, OnScrollDown)
453 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, OnScrollPageUp)
454 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, OnScrollPageDown)
455 COMMAND_ID_HANDLER(ID_SCROLL_TOP, OnScrollTop)
456 COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, OnScrollBottom)
457 COMMAND_ID_HANDLER(ID_SCROLL_LEFT, OnScrollLeft)
458 COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, OnScrollRight)
459 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, OnScrollPageLeft)
460 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, OnScrollPageRight)
461 COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, OnScrollAllLeft)
462 COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, OnScrollAllRight)
463 END_MSG_MAP()
464
465 LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
466 {
467 T* pT = static_cast<T*>(this);
468 pT->GetSystemSettings();
469
470 bHandled = FALSE;
471 return 1;
472 }
473
474 LRESULT OnVScroll(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
475 {
476 T* pT = static_cast<T*>(this);
477 ATLASSERT(::IsWindow(pT->m_hWnd));
478 pT->DoScroll(SB_VERT, (int)(short)LOWORD(wParam), (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
479 return 0;
480 }
481
482 LRESULT OnHScroll(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
483 {
484 T* pT = static_cast<T*>(this);
485 ATLASSERT(::IsWindow(pT->m_hWnd));
486 pT->DoScroll(SB_HORZ, (int)(short)LOWORD(wParam), (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
487 return 0;
488 }
489
490 LRESULT OnMouseWheel(UINT uMsg, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
491 {
492 T* pT = static_cast<T*>(this);
493 ATLASSERT(::IsWindow(pT->m_hWnd));
494
495 #if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400) || defined(_WIN32_WCE)
496 uMsg;
497 int zDelta = (int)GET_WHEEL_DELTA_WPARAM(wParam);
498 #else
499 int zDelta = (uMsg == WM_MOUSEWHEEL) ? (int)GET_WHEEL_DELTA_WPARAM(wParam) : (int)wParam;
500 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400) || defined(_WIN32_WCE))
501 int nScrollCode = (m_nWheelLines == WHEEL_PAGESCROLL) ? ((zDelta > 0) ? SB_PAGEUP : SB_PAGEDOWN) : ((zDelta > 0) ? SB_LINEUP : SB_LINEDOWN);
502 m_zDelta += zDelta; // cumulative
503 int zTotal = (m_nWheelLines == WHEEL_PAGESCROLL) ? abs(m_zDelta) : abs(m_zDelta) * m_nWheelLines;
504 if(m_sizeAll.cy > m_sizeClient.cy)
505 {
506 for(int i = 0; i < zTotal; i += WHEEL_DELTA)
507 {
508 pT->DoScroll(SB_VERT, nScrollCode, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
509 pT->UpdateWindow();
510 }
511 }
512 else if(m_sizeAll.cx > m_sizeClient.cx) // can't scroll vertically, scroll horizontally
513 {
514 for(int i = 0; i < zTotal; i += WHEEL_DELTA)
515 {
516 pT->DoScroll(SB_HORZ, nScrollCode, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
517 pT->UpdateWindow();
518 }
519 }
520 m_zDelta %= WHEEL_DELTA;
521
522 return 0;
523 }
524
525 LRESULT OnMouseHWheel(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
526 {
527 T* pT = static_cast<T*>(this);
528 ATLASSERT(::IsWindow(pT->m_hWnd));
529
530 int zDelta = (int)GET_WHEEL_DELTA_WPARAM(wParam);
531 int nScrollCode = (m_nHWheelChars == WHEEL_PAGESCROLL) ? ((zDelta > 0) ? SB_PAGERIGHT : SB_PAGELEFT) : ((zDelta > 0) ? SB_LINERIGHT : SB_LINELEFT);
532 m_zHDelta += zDelta; // cumulative
533 int zTotal = (m_nHWheelChars == WHEEL_PAGESCROLL) ? abs(m_zHDelta) : abs(m_zHDelta) * m_nHWheelChars;
534 if(m_sizeAll.cx > m_sizeClient.cx)
535 {
536 for(int i = 0; i < zTotal; i += WHEEL_DELTA)
537 {
538 pT->DoScroll(SB_HORZ, nScrollCode, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
539 pT->UpdateWindow();
540 }
541 }
542 m_zHDelta %= WHEEL_DELTA;
543
544 return 0;
545 }
546
547 LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
548 {
549 GetSystemSettings();
550 return 0;
551 }
552
553 LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
554 {
555 T* pT = static_cast<T*>(this);
556 ATLASSERT(::IsWindow(pT->m_hWnd));
557
558 pT->DoSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
559
560 bHandled = FALSE;
561 return 1;
562 }
563
564 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
565 {
566 T* pT = static_cast<T*>(this);
567 ATLASSERT(::IsWindow(pT->m_hWnd));
568 if(wParam != NULL)
569 {
570 CDCHandle dc = (HDC)wParam;
571 POINT ptViewportOrg = { 0, 0 };
572 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewportOrg);
573 pT->DoPaint(dc);
574 dc.SetViewportOrg(ptViewportOrg);
575 }
576 else
577 {
578 CPaintDC dc(pT->m_hWnd);
579 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y);
580 pT->DoPaint(dc.m_hDC);
581 }
582 return 0;
583 }
584
585 // scrolling handlers
586 LRESULT OnScrollUp(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
587 {
588 ScrollLineUp();
589 return 0;
590 }
591
592 LRESULT OnScrollDown(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
593 {
594 ScrollLineDown();
595 return 0;
596 }
597
598 LRESULT OnScrollPageUp(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
599 {
600 ScrollPageUp();
601 return 0;
602 }
603
604 LRESULT OnScrollPageDown(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
605 {
606 ScrollPageDown();
607 return 0;
608 }
609
610 LRESULT OnScrollTop(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
611 {
612 ScrollTop();
613 return 0;
614 }
615
616 LRESULT OnScrollBottom(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
617 {
618 ScrollBottom();
619 return 0;
620 }
621
622 LRESULT OnScrollLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
623 {
624 ScrollLineLeft();
625 return 0;
626 }
627
628 LRESULT OnScrollRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
629 {
630 ScrollLineRight();
631 return 0;
632 }
633
634 LRESULT OnScrollPageLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
635 {
636 ScrollPageLeft();
637 return 0;
638 }
639
640 LRESULT OnScrollPageRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
641 {
642 ScrollPageRight();
643 return 0;
644 }
645
646 LRESULT OnScrollAllLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
647 {
648 ScrollAllLeft();
649 return 0;
650 }
651
652 LRESULT OnScrollAllRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
653 {
654 ScrollAllRight();
655 return 0;
656 }
657
658 // Overrideables
659 void DoPaint(CDCHandle /*dc*/)
660 {
661 // must be implemented in a derived class
662 ATLASSERT(FALSE);
663 }
664
665 // Implementation
666 void DoSize(int cx, int cy)
667 {
668 m_sizeClient.cx = cx;
669 m_sizeClient.cy = cy;
670
671 T* pT = static_cast<T*>(this);
672
673 // block: set horizontal scroll bar
674 {
675 SCROLLINFO si = { sizeof(SCROLLINFO) };
676 si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
677 si.nMin = 0;
678 si.nMax = m_sizeAll.cx - 1;
679 if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLH) != 0)
680 si.fMask |= SIF_DISABLENOSCROLL;
681 si.nPage = m_sizeClient.cx;
682 si.nPos = m_ptOffset.x;
683 pT->SetScrollInfo(SB_HORZ, &si, TRUE);
684 }
685
686 // block: set vertical scroll bar
687 {
688 SCROLLINFO si = { sizeof(SCROLLINFO) };
689 si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
690 si.nMin = 0;
691 si.nMax = m_sizeAll.cy - 1;
692 if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLV) != 0)
693 si.fMask |= SIF_DISABLENOSCROLL;
694 si.nPage = m_sizeClient.cy;
695 si.nPos = m_ptOffset.y;
696 pT->SetScrollInfo(SB_VERT, &si, TRUE);
697 }
698
699 int x = m_ptOffset.x;
700 int y = m_ptOffset.y;
701 if(pT->AdjustScrollOffset(x, y))
702 {
703 // Children will be moved in SetScrollOffset, if needed
704 pT->ScrollWindowEx(m_ptOffset.x - x, m_ptOffset.y - y, (m_uScrollFlags & ~SCRL_SCROLLCHILDREN));
705 SetScrollOffset(x, y, FALSE);
706 }
707 }
708
709 void DoScroll(int nType, int nScrollCode, int& cxyOffset, int cxySizeAll, int cxySizePage, int cxySizeLine)
710 {
711 T* pT = static_cast<T*>(this);
712 RECT rect = { 0 };
713 pT->GetClientRect(&rect);
714 int cxyClient = (nType == SB_VERT) ? rect.bottom : rect.right;
715 int cxyMax = cxySizeAll - cxyClient;
716
717 if(cxyMax < 0) // can't scroll, client area is bigger
718 return;
719
720 bool bUpdate = true;
721 int cxyScroll = 0;
722
723 switch(nScrollCode)
724 {
725 case SB_TOP: // top or all left
726 cxyScroll = cxyOffset;
727 cxyOffset = 0;
728 break;
729 case SB_BOTTOM: // bottom or all right
730 cxyScroll = cxyOffset - cxyMax;
731 cxyOffset = cxyMax;
732 break;
733 case SB_LINEUP: // line up or line left
734 if(cxyOffset >= cxySizeLine)
735 {
736 cxyScroll = cxySizeLine;
737 cxyOffset -= cxySizeLine;
738 }
739 else
740 {
741 cxyScroll = cxyOffset;
742 cxyOffset = 0;
743 }
744 break;
745 case SB_LINEDOWN: // line down or line right
746 if(cxyOffset < cxyMax - cxySizeLine)
747 {
748 cxyScroll = -cxySizeLine;
749 cxyOffset += cxySizeLine;
750 }
751 else
752 {
753 cxyScroll = cxyOffset - cxyMax;
754 cxyOffset = cxyMax;
755 }
756 break;
757 case SB_PAGEUP: // page up or page left
758 if(cxyOffset >= cxySizePage)
759 {
760 cxyScroll = cxySizePage;
761 cxyOffset -= cxySizePage;
762 }
763 else
764 {
765 cxyScroll = cxyOffset;
766 cxyOffset = 0;
767 }
768 break;
769 case SB_PAGEDOWN: // page down or page right
770 if(cxyOffset < cxyMax - cxySizePage)
771 {
772 cxyScroll = -cxySizePage;
773 cxyOffset += cxySizePage;
774 }
775 else
776 {
777 cxyScroll = cxyOffset - cxyMax;
778 cxyOffset = cxyMax;
779 }
780 break;
781 case SB_THUMBTRACK:
782 if(IsNoThumbTracking())
783 break;
784 // else fall through
785 case SB_THUMBPOSITION:
786 {
787 SCROLLINFO si = { sizeof(SCROLLINFO), SIF_TRACKPOS };
788 if(pT->GetScrollInfo(nType, &si))
789 {
790 cxyScroll = cxyOffset - si.nTrackPos;
791 cxyOffset = si.nTrackPos;
792 }
793 }
794 break;
795 case SB_ENDSCROLL:
796 default:
797 bUpdate = false;
798 break;
799 }
800
801 if(bUpdate && cxyScroll != 0)
802 {
803 pT->SetScrollPos(nType, cxyOffset, TRUE);
804 if(nType == SB_VERT)
805 pT->ScrollWindowEx(0, cxyScroll, m_uScrollFlags);
806 else
807 pT->ScrollWindowEx(cxyScroll, 0, m_uScrollFlags);
808 }
809 }
810
811 static int CalcLineOrPage(int nVal, int nMax, int nDiv)
812 {
813 if(nVal == 0)
814 {
815 nVal = nMax / nDiv;
816 if(nVal < 1)
817 nVal = 1;
818 }
819 else if(nVal > nMax)
820 {
821 nVal = nMax;
822 }
823
824 return nVal;
825 }
826
827 bool AdjustScrollOffset(int& x, int& y)
828 {
829 int xOld = x;
830 int yOld = y;
831
832 int cxMax = m_sizeAll.cx - m_sizeClient.cx;
833 if(x > cxMax)
834 x = (cxMax >= 0) ? cxMax : 0;
835 else if(x < 0)
836 x = 0;
837
838 int cyMax = m_sizeAll.cy - m_sizeClient.cy;
839 if(y > cyMax)
840 y = (cyMax >= 0) ? cyMax : 0;
841 else if(y < 0)
842 y = 0;
843
844 return (x != xOld || y != yOld);
845 }
846
847 void GetSystemSettings()
848 {
849 #ifndef _WIN32_WCE
850 #ifndef SPI_GETWHEELSCROLLLINES
851 const UINT SPI_GETWHEELSCROLLLINES = 104;
852 #endif // !SPI_GETWHEELSCROLLLINES
853 ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &m_nWheelLines, 0);
854
855 #ifndef SPI_GETWHEELSCROLLCHARS
856 const UINT SPI_GETWHEELSCROLLCHARS = 0x006C;
857 #endif // !SPI_GETWHEELSCROLLCHARS
858 ::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &m_nHWheelChars, 0);
859
860 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
861 if(m_uMsgMouseWheel != 0)
862 m_uMsgMouseWheel = ::RegisterWindowMessage(MSH_MOUSEWHEEL);
863
864 HWND hWndWheel = FindWindow(MSH_WHEELMODULE_CLASS, MSH_WHEELMODULE_TITLE);
865 if(::IsWindow(hWndWheel))
866 {
867 UINT uMsgScrollLines = ::RegisterWindowMessage(MSH_SCROLL_LINES);
868 if(uMsgScrollLines != 0)
869 m_nWheelLines = (int)::SendMessage(hWndWheel, uMsgScrollLines, 0, 0L);
870 }
871 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
872 #endif // !_WIN32_WCE
873 }
874
875 bool IsScrollingChildren() const
876 {
877 return (m_dwExtendedStyle & SCRL_SCROLLCHILDREN) != 0;
878 }
879
880 bool IsErasingBackground() const
881 {
882 return (m_dwExtendedStyle & SCRL_ERASEBACKGROUND) != 0;
883 }
884
885 bool IsNoThumbTracking() const
886 {
887 return (m_dwExtendedStyle & SCRL_NOTHUMBTRACKING) != 0;
888 }
889
890 #if (WINVER >= 0x0500)
891 bool IsSmoothScroll() const
892 {
893 return (m_dwExtendedStyle & SCRL_SMOOTHSCROLL) != 0;
894 }
895 #endif // (WINVER >= 0x0500)
896 };
897
898
899 ///////////////////////////////////////////////////////////////////////////////
900 // CScrollWindowImpl - Implements a scrollable window
901
902 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
903 class ATL_NO_VTABLE CScrollWindowImpl : public ATL::CWindowImpl<T, TBase, TWinTraits>, public CScrollImpl< T >
904 {
905 public:
906 BOOL SubclassWindow(HWND hWnd)
907 {
908 #if (_MSC_VER >= 1300)
909 BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits >::SubclassWindow(hWnd);
910 #else // !(_MSC_VER >= 1300)
911 typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass;
912 BOOL bRet = _baseClass::SubclassWindow(hWnd);
913 #endif // !(_MSC_VER >= 1300)
914 if(bRet != FALSE)
915 {
916 T* pT = static_cast<T*>(this);
917 pT->GetSystemSettings();
918
919 RECT rect = { 0 };
920 GetClientRect(&rect);
921 pT->DoSize(rect.right, rect.bottom);
922 }
923
924 return bRet;
925 }
926
927 BEGIN_MSG_MAP(CScrollWindowImpl)
928 MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
929 MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
930 MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
931 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE)
932 MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel)
933 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE)
934 MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel)
935 MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange)
936 MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
937 MESSAGE_HANDLER(WM_PAINT, CScrollImpl< T >::OnPaint)
938 #ifndef _WIN32_WCE
939 MESSAGE_HANDLER(WM_PRINTCLIENT, CScrollImpl< T >::OnPaint)
940 #endif // !_WIN32_WCE
941 ALT_MSG_MAP(1)
942 COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
943 COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown)
944 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp)
945 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown)
946 COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
947 COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom)
948 COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft)
949 COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight)
950 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft)
951 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight)
952 COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft)
953 COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight)
954 END_MSG_MAP()
955 };
956
957
958 ///////////////////////////////////////////////////////////////////////////////
959 // CMapScrollImpl - Provides mapping and scrolling support to any window
960
961 #ifndef _WIN32_WCE
962
963 template <class T>
964 class CMapScrollImpl : public CScrollImpl< T >
965 {
966 public:
967 int m_nMapMode;
968 RECT m_rectLogAll;
969 SIZE m_sizeLogLine;
970 SIZE m_sizeLogPage;
971
972 // Constructor
973 CMapScrollImpl() : m_nMapMode(MM_TEXT)
974 {
975 ::SetRectEmpty(&m_rectLogAll);
976 m_sizeLogPage.cx = 0;
977 m_sizeLogPage.cy = 0;
978 m_sizeLogLine.cx = 0;
979 m_sizeLogLine.cy = 0;
980 }
981
982 // Attributes & Operations
983 // mapping mode operations
984 void SetScrollMapMode(int nMapMode)
985 {
986 ATLASSERT(nMapMode >= MM_MIN && nMapMode <= MM_MAX_FIXEDSCALE);
987 m_nMapMode = nMapMode;
988 }
989
990 int GetScrollMapMode() const
991 {
992 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
993 return m_nMapMode;
994 }
995
996 // offset operations
997 void SetScrollOffset(int x, int y, BOOL bRedraw = TRUE)
998 {
999 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
1000 POINT ptOff = { x, y };
1001 // block: convert logical to device units
1002 {
1003 CWindowDC dc(NULL);
1004 dc.SetMapMode(m_nMapMode);
1005 dc.LPtoDP(&ptOff);
1006 }
1007 CScrollImpl< T >::SetScrollOffset(ptOff, bRedraw);
1008 }
1009
1010 void SetScrollOffset(POINT ptOffset, BOOL bRedraw = TRUE)
1011 {
1012 SetScrollOffset(ptOffset.x, ptOffset.y, bRedraw);
1013 }
1014
1015 void GetScrollOffset(POINT& ptOffset) const
1016 {
1017 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
1018 ptOffset = m_ptOffset;
1019 // block: convert device to logical units
1020 {
1021 CWindowDC dc(NULL);
1022 dc.SetMapMode(m_nMapMode);
1023 dc.DPtoLP(&ptOffset);
1024 }
1025 }
1026
1027 // size operations
1028 void SetScrollSize(int xMin, int yMin, int xMax, int yMax, BOOL bRedraw = TRUE, bool bResetOffset = true)
1029 {
1030 ATLASSERT(xMax > xMin && yMax > yMin);
1031 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
1032
1033 ::SetRect(&m_rectLogAll, xMin, yMin, xMax, yMax);
1034
1035 SIZE sizeAll = { 0 };
1036 sizeAll.cx = xMax - xMin + 1;
1037 sizeAll.cy = yMax - yMin + 1;
1038 // block: convert logical to device units
1039 {
1040 CWindowDC dc(NULL);
1041 dc.SetMapMode(m_nMapMode);
1042 dc.LPtoDP(&sizeAll);
1043 }
1044 CScrollImpl< T >::SetScrollSize(sizeAll, bRedraw, bResetOffset);
1045 SetScrollLine(0, 0);
1046 SetScrollPage(0, 0);
1047 }
1048
1049 void SetScrollSize(RECT& rcScroll, BOOL bRedraw = TRUE, bool bResetOffset = true)
1050 {
1051 SetScrollSize(rcScroll.left, rcScroll.top, rcScroll.right, rcScroll.bottom, bRedraw, bResetOffset);
1052 }
1053
1054 void SetScrollSize(int cx, int cy, BOOL bRedraw = TRUE, bool bResetOffset = true)
1055 {
1056 SetScrollSize(0, 0, cx, cy, bRedraw, bResetOffset);
1057 }
1058
1059 void SetScrollSize(SIZE size, BOOL bRedraw = TRUE, bool bResetOffset = true)
1060 {
1061 SetScrollSize(0, 0, size.cx, size.cy, bRedraw, bResetOffset);
1062 }
1063
1064 void GetScrollSize(RECT& rcScroll) const
1065 {
1066 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
1067 rcScroll = m_rectLogAll;
1068 }
1069
1070 // line operations
1071 void SetScrollLine(int cxLine, int cyLine)
1072 {
1073 ATLASSERT(cxLine >= 0 && cyLine >= 0);
1074 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
1075
1076 m_sizeLogLine.cx = cxLine;
1077 m_sizeLogLine.cy = cyLine;
1078 SIZE sizeLine = m_sizeLogLine;
1079 // block: convert logical to device units
1080 {
1081 CWindowDC dc(NULL);
1082 dc.SetMapMode(m_nMapMode);
1083 dc.LPtoDP(&sizeLine);
1084 }
1085 CScrollImpl< T >::SetScrollLine(sizeLine);
1086 }
1087
1088 void SetScrollLine(SIZE sizeLine)
1089 {
1090 SetScrollLine(sizeLine.cx, sizeLine.cy);
1091 }
1092
1093 void GetScrollLine(SIZE& sizeLine) const
1094 {
1095 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
1096 sizeLine = m_sizeLogLine;
1097 }
1098
1099 // page operations
1100 void SetScrollPage(int cxPage, int cyPage)
1101 {
1102 ATLASSERT(cxPage >= 0 && cyPage >= 0);
1103 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
1104
1105 m_sizeLogPage.cx = cxPage;
1106 m_sizeLogPage.cy = cyPage;
1107 SIZE sizePage = m_sizeLogPage;
1108 // block: convert logical to device units
1109 {
1110 CWindowDC dc(NULL);
1111 dc.SetMapMode(m_nMapMode);
1112 dc.LPtoDP(&sizePage);
1113 }
1114 CScrollImpl< T >::SetScrollPage(sizePage);
1115 }
1116
1117 void SetScrollPage(SIZE sizePage)
1118 {
1119 SetScrollPage(sizePage.cx, sizePage.cy);
1120 }
1121
1122 void GetScrollPage(SIZE& sizePage) const
1123 {
1124 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
1125 sizePage = m_sizeLogPage;
1126 }
1127
1128 BEGIN_MSG_MAP(CMapScrollImpl)
1129 MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
1130 MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
1131 MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
1132 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
1133 MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel)
1134 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
1135 MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel)
1136 MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange)
1137 MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
1138 MESSAGE_HANDLER(WM_PAINT, OnPaint)
1139 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
1140 ALT_MSG_MAP(1)
1141 COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
1142 COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown)
1143 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp)
1144 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown)
1145 COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
1146 COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom)
1147 COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft)
1148 COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight)
1149 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft)
1150 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight)
1151 COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft)
1152 COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight)
1153 END_MSG_MAP()
1154
1155 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1156 {
1157 T* pT = static_cast<T*>(this);
1158 ATLASSERT(::IsWindow(pT->m_hWnd));
1159 if(wParam != NULL)
1160 {
1161 CDCHandle dc = (HDC)wParam;
1162 int nMapModeSav = dc.GetMapMode();
1163 dc.SetMapMode(m_nMapMode);
1164 POINT ptViewportOrg = { 0, 0 };
1165 if(m_nMapMode == MM_TEXT)
1166 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewportOrg);
1167 else
1168 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y + m_sizeAll.cy, &ptViewportOrg);
1169 POINT ptWindowOrg = { 0, 0 };
1170 dc.SetWindowOrg(m_rectLogAll.left, m_rectLogAll.top, &ptWindowOrg);
1171
1172 pT->DoPaint(dc);
1173
1174 dc.SetMapMode(nMapModeSav);
1175 dc.SetViewportOrg(ptViewportOrg);
1176 dc.SetWindowOrg(ptWindowOrg);
1177 }
1178 else
1179 {
1180 CPaintDC dc(pT->m_hWnd);
1181 dc.SetMapMode(m_nMapMode);
1182 if(m_nMapMode == MM_TEXT)
1183 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y);
1184 else
1185 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y + m_sizeAll.cy);
1186 dc.SetWindowOrg(m_rectLogAll.left, m_rectLogAll.top);
1187 pT->DoPaint(dc.m_hDC);
1188 }
1189 return 0;
1190 }
1191 };
1192
1193 #endif // !_WIN32_WCE
1194
1195
1196 ///////////////////////////////////////////////////////////////////////////////
1197 // CMapScrollWindowImpl - Implements scrolling window with mapping
1198
1199 #ifndef _WIN32_WCE
1200
1201 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
1202 class ATL_NO_VTABLE CMapScrollWindowImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CMapScrollImpl< T >
1203 {
1204 public:
1205 BOOL SubclassWindow(HWND hWnd)
1206 {
1207 #if (_MSC_VER >= 1300)
1208 BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits >::SubclassWindow(hWnd);
1209 #else // !(_MSC_VER >= 1300)
1210 typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass;
1211 BOOL bRet = _baseClass::SubclassWindow(hWnd);
1212 #endif // !(_MSC_VER >= 1300)
1213 if(bRet != FALSE)
1214 {
1215 T* pT = static_cast<T*>(this);
1216 pT->GetSystemSettings();
1217
1218 RECT rect = { 0 };
1219 GetClientRect(&rect);
1220 pT->DoSize(rect.right, rect.bottom);
1221 }
1222
1223 return bRet;
1224 }
1225
1226 BEGIN_MSG_MAP(CMapScrollWindowImpl)
1227 MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
1228 MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
1229 MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
1230 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
1231 MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel)
1232 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
1233 MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel)
1234 MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange)
1235 MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
1236 MESSAGE_HANDLER(WM_PAINT, CMapScrollImpl< T >::OnPaint)
1237 MESSAGE_HANDLER(WM_PRINTCLIENT, CMapScrollImpl< T >::OnPaint)
1238 ALT_MSG_MAP(1)
1239 COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
1240 COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown)
1241 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp)
1242 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown)
1243 COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
1244 COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom)
1245 COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft)
1246 COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight)
1247 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft)
1248 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight)
1249 COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft)
1250 COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight)
1251 END_MSG_MAP()
1252 };
1253
1254 #endif // !_WIN32_WCE
1255
1256
1257 ///////////////////////////////////////////////////////////////////////////////
1258 // CFSBWindow - Use as a base instead of CWindow to get flat scroll bar support
1259
1260 #if defined(__ATLCTRLS_H__) && (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
1261
1262 template <class TBase = ATL::CWindow>
1263 class CFSBWindowT : public TBase, public CFlatScrollBarImpl<CFSBWindowT< TBase > >
1264 {
1265 public:
1266 // Constructors
1267 CFSBWindowT(HWND hWnd = NULL) : TBase(hWnd)
1268 { }
1269
1270 CFSBWindowT< TBase >& operator =(HWND hWnd)
1271 {
1272 m_hWnd = hWnd;
1273 return *this;
1274 }
1275
1276 // CWindow overrides that use flat scroll bar API
1277 // (only those methods that are used by scroll window classes)
1278 int SetScrollPos(int nBar, int nPos, BOOL bRedraw = TRUE)
1279 {
1280 ATLASSERT(::IsWindow(m_hWnd));
1281 return FlatSB_SetScrollPos(nBar, nPos, bRedraw);
1282 }
1283
1284 BOOL GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo)
1285 {
1286 ATLASSERT(::IsWindow(m_hWnd));
1287 return FlatSB_GetScrollInfo(nBar, lpScrollInfo);
1288 }
1289
1290 BOOL SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE)
1291 {
1292 ATLASSERT(::IsWindow(m_hWnd));
1293 return FlatSB_SetScrollInfo(nBar, lpScrollInfo, bRedraw);
1294 }
1295 };
1296
1297 typedef CFSBWindowT<ATL::CWindow> CFSBWindow;
1298
1299 #endif // defined(__ATLCTRLS_H__) && (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
1300
1301
1302 ///////////////////////////////////////////////////////////////////////////////
1303 // CZoomScrollImpl - Provides zooming and scrolling support to any window
1304
1305 #ifndef _WIN32_WCE
1306
1307 // The zoom modes that can be set with the SetZoomMode method
1308 enum
1309 {
1310 ZOOMMODE_OFF,
1311 ZOOMMODE_IN, // If left mouse button is clicked or dragged, zoom in on point clicked or rectangle dragged.
1312 ZOOMMODE_OUT // If left mouse button clicked, zoom out on point clicked.
1313 };
1314
1315 // Notification to parent that zoom scale changed as a result of user mouse action.
1316 #define ZSN_ZOOMCHANGED (NM_FIRST - 50)
1317
1318 template <class T>
1319 class CZoomScrollImpl : public CScrollImpl< T >
1320 {
1321 public:
1322 enum { m_cxyMinZoomRect = 12 }; // min rect size to zoom in on rect.
1323
1324 struct _ChildPlacement
1325 {
1326 HWND hWnd;
1327 int x;
1328 int y;
1329 int cx;
1330 int cy;
1331
1332 bool operator ==(const _ChildPlacement& cp) const { return (memcmp(this, &cp, sizeof(_ChildPlacement)) == 0); }
1333 };
1334
1335 // Data members
1336 SIZE m_sizeLogAll;
1337 SIZE m_sizeLogLine;
1338 SIZE m_sizeLogPage;
1339 float m_fZoomScale;
1340 float m_fZoomScaleMin;
1341 float m_fZoomScaleMax;
1342 float m_fZoomDelta; // Used in ZOOMMODE_IN and ZOOMMODE_OUT on left-button click.
1343 int m_nZoomMode;
1344 RECT m_rcTrack;
1345 bool m_bTracking;
1346
1347 bool m_bZoomChildren;
1348 ATL::CSimpleArray<_ChildPlacement> m_arrChildren;
1349
1350 // Constructor
1351 CZoomScrollImpl(): m_fZoomScale(1.0f), m_fZoomScaleMin(0.1f), m_fZoomScaleMax(100.0f), m_fZoomDelta(0.5f),
1352 m_nZoomMode(ZOOMMODE_OFF), m_bTracking(false), m_bZoomChildren(false)
1353 {
1354 m_sizeLogAll.cx = 0;
1355 m_sizeLogAll.cy = 0;
1356 m_sizeLogPage.cx = 0;
1357 m_sizeLogPage.cy = 0;
1358 m_sizeLogLine.cx = 0;
1359 m_sizeLogLine.cy = 0;
1360 ::SetRectEmpty(&m_rcTrack);
1361 }
1362
1363 // Attributes & Operations
1364 // size operations
1365 void SetScrollSize(int cxLog, int cyLog, BOOL bRedraw = TRUE, bool bResetOffset = true)
1366 {
1367 ATLASSERT(cxLog >= 0 && cyLog >= 0);
1368
1369 // Set up the defaults
1370 if((cxLog == 0) && (cyLog == 0))
1371 {
1372 cxLog = 1;
1373 cyLog = 1;
1374 }
1375
1376 m_sizeLogAll.cx = cxLog;
1377 m_sizeLogAll.cy = cyLog;
1378 SIZE sizeAll = { 0 };
1379 sizeAll.cx = (int)((float)m_sizeLogAll.cx * m_fZoomScale);
1380 sizeAll.cy = (int)((float)m_sizeLogAll.cy * m_fZoomScale);
1381
1382 CScrollImpl< T >::SetScrollSize(sizeAll, bRedraw, bResetOffset);
1383 }
1384
1385 void SetScrollSize(SIZE sizeLog, BOOL bRedraw = TRUE, bool bResetOffset = true)
1386 {
1387 SetScrollSize(sizeLog.cx, sizeLog.cy, bRedraw, bResetOffset);
1388 }
1389
1390 void GetScrollSize(SIZE& sizeLog) const
1391 {
1392 sizeLog = m_sizeLogAll;
1393 }
1394
1395 // line operations
1396 void SetScrollLine(int cxLogLine, int cyLogLine)
1397 {
1398 ATLASSERT(cxLogLine >= 0 && cyLogLine >= 0);
1399
1400 m_sizeLogLine.cx = cxLogLine;
1401 m_sizeLogLine.cy = cyLogLine;
1402
1403 SIZE sizeLine = { 0 };
1404 sizeLine.cx = (int)((float)m_sizeLogLine.cx * m_fZoomScale);
1405 sizeLine.cy = (int)((float)m_sizeLogLine.cy * m_fZoomScale);
1406 CScrollImpl< T >::SetScrollLine(sizeLine);
1407 }
1408
1409 void SetScrollLine(SIZE sizeLogLine)
1410 {
1411 SetScrollLine(sizeLogLine.cx, sizeLogLine.cy);
1412 }
1413
1414 void GetScrollLine(SIZE& sizeLogLine) const
1415 {
1416 sizeLogLine = m_sizeLogLine;
1417 }
1418
1419 // page operations
1420 void SetScrollPage(int cxLogPage, int cyLogPage)
1421 {
1422 ATLASSERT((cxLogPage >= 0) && (cyLogPage >= 0));
1423
1424 m_sizeLogPage.cx = cxLogPage;
1425 m_sizeLogPage.cy = cyLogPage;
1426
1427 SIZE sizePage = { 0 };
1428 sizePage.cx = (int)((float)m_sizeLogPage.cx * m_fZoomScale);
1429 sizePage.cy = (int)((float)m_sizeLogPage.cy * m_fZoomScale);
1430
1431 CScrollImpl< T >::SetScrollPage(sizePage);
1432 }
1433
1434 void SetScrollPage(SIZE sizeLogPage)
1435 {
1436 SetScrollPage(sizeLogPage.cx, sizeLogPage.cy);
1437 }
1438
1439 void GetScrollPage(SIZE& sizeLogPage) const
1440 {
1441 sizeLogPage = m_sizeLogPage;
1442 }
1443
1444 void SetZoomScale(float fZoomScale)
1445 {
1446 ATLASSERT(fZoomScale > 0.0f);
1447 if(fZoomScale <= 0.0f)
1448 return;
1449
1450 m_fZoomScale = fZoomScale;
1451 if(m_fZoomScale < m_fZoomScaleMin)
1452 m_fZoomScale = m_fZoomScaleMin;
1453 else if(m_fZoomScale > m_fZoomScaleMax)
1454 m_fZoomScale = m_fZoomScaleMax;
1455 }
1456
1457 float GetZoomScale() const
1458 {
1459 return m_fZoomScale;
1460 }
1461
1462 void SetZoomScaleMin(float fZoomScaleMin)
1463 {
1464 ATLASSERT(fZoomScaleMin > 0.0f);
1465 ATLASSERT(fZoomScaleMin <= m_fZoomScaleMax);
1466
1467 m_fZoomScaleMin = fZoomScaleMin;
1468 }
1469
1470 float GetZoomScaleMin() const
1471 {
1472 return m_fZoomScaleMin;
1473 }
1474
1475 void SetZoomScaleMax(float fZoomScaleMax)
1476 {
1477 ATLASSERT(fZoomScaleMax > 0.0f);
1478 ATLASSERT(m_fZoomScaleMin <= fZoomScaleMax);
1479
1480 m_fZoomScaleMax = fZoomScaleMax;
1481 }
1482
1483 float GetZoomScaleMax() const
1484 {
1485 return m_fZoomScaleMax;
1486 }
1487
1488 void SetZoomDelta(float fZoomDelta)
1489 {
1490 ATLASSERT(fZoomDelta >= 0.0f);
1491
1492 if(fZoomDelta >= 0.0f)
1493 m_fZoomDelta = fZoomDelta;
1494 }
1495
1496 float GetZoomDelta() const
1497 {
1498 return m_fZoomDelta;
1499 }
1500
1501 void SetZoomMode(int nZoomMode)
1502 {
1503 m_nZoomMode = nZoomMode;
1504 }
1505
1506 int GetZoomMode() const
1507 {
1508 return m_nZoomMode;
1509 }
1510
1511 void SetZoomChildren(bool bEnable = true)
1512 {
1513 T* pT = static_cast<T*>(this);
1514 ATLASSERT(::IsWindow(pT->m_hWnd));
1515
1516 m_bZoomChildren = bEnable;
1517
1518 m_arrChildren.RemoveAll();
1519 if(m_bZoomChildren)
1520 {
1521 for(HWND hWndChild = ::GetWindow(pT->m_hWnd, GW_CHILD); hWndChild != NULL; hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT))
1522 {
1523 RECT rect = { 0 };
1524 ::GetWindowRect(hWndChild, &rect);
1525 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rect, 2);
1526
1527 _ChildPlacement cp = { 0 };
1528 cp.hWnd = hWndChild;
1529 cp.x = rect.left;
1530 cp.y = rect.top;
1531 cp.cx = rect.right - rect.left;
1532 cp.cy = rect.bottom - rect.top;
1533 m_arrChildren.Add(cp);
1534 }
1535 }
1536 }
1537
1538 bool GetZoomChildren() const
1539 {
1540 return m_bZoomChildren;
1541 }
1542
1543 void Zoom(int x, int y, float fZoomScale)
1544 {
1545 if(fZoomScale <= 0.0f)
1546 return;
1547
1548 if(fZoomScale < m_fZoomScaleMin)
1549 fZoomScale = m_fZoomScaleMin;
1550 else if(fZoomScale > m_fZoomScaleMax)
1551 fZoomScale = m_fZoomScaleMax;
1552
1553 T* pT = static_cast<T*>(this);
1554 POINT pt = { x, y };
1555 if(!pT->PtInDevRect(pt))
1556 return;
1557
1558 pT->ViewDPtoLP(&pt);
1559 pT->Zoom(fZoomScale, false);
1560 pT->CenterOnLogicalPoint(pt);
1561 }
1562
1563 void Zoom(POINT pt, float fZoomScale)
1564 {
1565 T* pT = static_cast<T*>(this);
1566 pT->Zoom(pt.x, pt.y, fZoomScale);
1567 }
1568
1569 void Zoom(RECT& rc)
1570 {
1571 T* pT = static_cast<T*>(this);
1572 RECT rcZoom = rc;
1573 pT->NormalizeRect(rcZoom);
1574 SIZE size = { rcZoom.right - rcZoom.left, rcZoom.bottom - rcZoom.top };
1575 POINT pt = { rcZoom.left + size.cx / 2, rcZoom.top + size.cy / 2 };
1576 if(size.cx < m_cxyMinZoomRect || size.cy < m_cxyMinZoomRect)
1577 {
1578 pT->Zoom(pt, m_fZoomScale + m_fZoomDelta);
1579 return;
1580 }
1581
1582 ATLASSERT((size.cx > 0) && (size.cy > 0));
1583
1584 float fScaleH = (float)(m_sizeClient.cx + 1) / (float)size.cx;
1585 float fScaleV = (float)(m_sizeClient.cy + 1) / (float)size.cy;
1586 float fZoomScale = __min(fScaleH, fScaleV) * m_fZoomScale;
1587 pT->Zoom(pt, fZoomScale);
1588 }
1589
1590 void Zoom(float fZoomScale, bool bCenter = true)
1591 {
1592 if(fZoomScale <= 0.0f)
1593 return;
1594
1595 if(fZoomScale < m_fZoomScaleMin)
1596 fZoomScale = m_fZoomScaleMin;
1597 else if(fZoomScale > m_fZoomScaleMax)
1598 fZoomScale = m_fZoomScaleMax;
1599
1600 T* pT = static_cast<T*>(this);
1601 POINT pt = { 0 };
1602 if(bCenter)
1603 {
1604 RECT rcClient = { 0 };
1605 ::GetClientRect(pT->m_hWnd, &rcClient);
1606 pt.x = rcClient.right / 2;
1607 pt.y = rcClient.bottom / 2;
1608 pT->ViewDPtoLP(&pt);
1609 }
1610
1611 // Modify the Viewport extent
1612 SIZE sizeAll = { 0 };
1613 sizeAll.cx = (int)((float)m_sizeLogAll.cx * fZoomScale);
1614 sizeAll.cy = (int)((float)m_sizeLogAll.cy * fZoomScale);
1615
1616 // Update scroll bars and window
1617 CScrollImpl< T >::SetScrollSize(sizeAll);
1618
1619 // Zoom all children if needed
1620 if(m_bZoomChildren && (m_fZoomScale != fZoomScale))
1621 {
1622 for(int i = 0; i < m_arrChildren.GetSize(); i++)
1623 {
1624 ATLASSERT(::IsWindow(m_arrChildren[i].hWnd));
1625
1626 ::SetWindowPos(m_arrChildren[i].hWnd, NULL,
1627 (int)((float)m_arrChildren[i].x * fZoomScale + 0.5f),
1628 (int)((float)m_arrChildren[i].y * fZoomScale + 0.5f),
1629 (int)((float)m_arrChildren[i].cx * fZoomScale + 0.5f),
1630 (int)((float)m_arrChildren[i].cy * fZoomScale + 0.5f),
1631 SWP_NOZORDER | SWP_NOACTIVATE);
1632 }
1633 }
1634
1635 // Set new zoom scale
1636 m_fZoomScale = fZoomScale;
1637
1638 if(bCenter)
1639 pT->CenterOnLogicalPoint(pt);
1640 }
1641
1642 // Helper functions
1643 void PrepareDC(CDCHandle dc)
1644 {
1645 ATLASSERT(m_sizeAll.cx >= 0 && m_sizeAll.cy >= 0);
1646 dc.SetMapMode(MM_ANISOTROPIC);
1647 dc.SetWindowExt(m_sizeLogAll);
1648 dc.SetViewportExt(m_sizeAll);
1649 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y);
1650 }
1651
1652 void ViewDPtoLP(LPPOINT lpPoints, int nCount = 1)
1653 {
1654 ATLASSERT(lpPoints);
1655 T* pT = static_cast<T*>(this);
1656 ATLASSERT(::IsWindow(pT->m_hWnd));
1657
1658 CWindowDC dc(pT->m_hWnd);
1659 pT->PrepareDC(dc.m_hDC);
1660 dc.DPtoLP(lpPoints, nCount);
1661 }
1662
1663 void ViewLPtoDP(LPPOINT lpPoints, int nCount = 1)
1664 {
1665 ATLASSERT(lpPoints);
1666 T* pT = static_cast<T*>(this);
1667 ATLASSERT(::IsWindow(pT->m_hWnd));
1668
1669 CWindowDC dc(pT->m_hWnd);
1670 pT->PrepareDC(dc.m_hDC);
1671 dc.LPtoDP(lpPoints, nCount);
1672 }
1673
1674 void ClientToDevice(POINT &pt)
1675 {
1676 pt.x += m_ptOffset.x;
1677 pt.y += m_ptOffset.y;
1678 }
1679
1680 void DeviceToClient(POINT &pt)
1681 {
1682 pt.x -= m_ptOffset.x;
1683 pt.y -= m_ptOffset.y;
1684 }
1685
1686 void CenterOnPoint(POINT pt)
1687 {
1688 T* pT = static_cast<T*>(this);
1689 RECT rect = { 0 };
1690 pT->GetClientRect(&rect);
1691
1692 int xOfs = pt.x - (rect.right / 2) + m_ptOffset.x;
1693 if(xOfs < 0)
1694 {
1695 xOfs = 0;
1696 }
1697 else
1698 {
1699 int xMax = __max((int)(m_sizeAll.cx - rect.right), 0);
1700 if(xOfs > xMax)
1701 xOfs = xMax;
1702 }
1703
1704 int yOfs = pt.y - (rect.bottom / 2) + m_ptOffset.y;
1705 if(yOfs < 0)
1706 {
1707 yOfs = 0;
1708 }
1709 else
1710 {
1711 int yMax = __max((int)(m_sizeAll.cy - rect.bottom), 0);
1712 if(yOfs > yMax)
1713 yOfs = yMax;
1714 }
1715
1716 CScrollImpl< T >::SetScrollOffset(xOfs, yOfs);
1717 }
1718
1719 void CenterOnLogicalPoint(POINT ptLog)
1720 {
1721 T* pT = static_cast<T*>(this);
1722 pT->ViewLPtoDP(&ptLog);
1723 pT->DeviceToClient(ptLog);
1724 pT->CenterOnPoint(ptLog);
1725 }
1726
1727 BOOL PtInDevRect(POINT pt)
1728 {
1729 RECT rc = { 0, 0, m_sizeAll.cx, m_sizeAll.cy };
1730 ::OffsetRect(&rc, -m_ptOffset.x, -m_ptOffset.y);
1731 return ::PtInRect(&rc, pt);
1732 }
1733
1734 void NormalizeRect(RECT& rc)
1735 {
1736 if(rc.left > rc.right)
1737 {
1738 int r = rc.right;
1739 rc.right = rc.left;
1740 rc.left = r;
1741 }
1742
1743 if(rc.top > rc.bottom)
1744 {
1745 int b = rc.bottom;
1746 rc.bottom = rc.top;
1747 rc.top = b;
1748 }
1749 }
1750
1751 void DrawTrackRect()
1752 {
1753 T* pT = static_cast<T*>(this);
1754 const SIZE sizeLines = { 2, 2 };
1755 RECT rc = m_rcTrack;
1756 pT->NormalizeRect(rc);
1757 if(!::IsRectEmpty(&rc))
1758 {
1759 ::MapWindowPoints(pT->m_hWnd, NULL, (LPPOINT)&rc, 2);
1760 CWindowDC dc(NULL);
1761 dc.DrawDragRect(&rc, sizeLines, NULL, sizeLines);
1762 }
1763 }
1764
1765 void NotifyParentZoomChanged()
1766 {
1767 T* pT = static_cast<T*>(this);
1768 int nId = pT->GetDlgCtrlID();
1769 NMHDR nmhdr = { pT->m_hWnd, (UINT_PTR)nId, ZSN_ZOOMCHANGED };
1770 ::SendMessage(pT->GetParent(), WM_NOTIFY, (WPARAM)nId, (LPARAM)&nmhdr);
1771 }
1772
1773 BEGIN_MSG_MAP(CZoomScrollImpl)
1774 MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor)
1775 MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
1776 MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
1777 MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
1778 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
1779 MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel)
1780 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
1781 MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel)
1782 MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange)
1783 MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
1784 MESSAGE_HANDLER(WM_PAINT, OnPaint)
1785 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
1786 MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
1787 MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
1788 MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
1789 MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged)
1790 ALT_MSG_MAP(1)
1791 COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
1792 COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown)
1793 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp)
1794 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown)
1795 COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
1796 COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom)
1797 COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft)
1798 COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight)
1799 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft)
1800 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight)
1801 COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft)
1802 COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight)
1803 END_MSG_MAP()
1804
1805 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1806 {
1807 T* pT = static_cast<T*>(this);
1808 ATLASSERT(::IsWindow(pT->m_hWnd));
1809 ATLASSERT((m_sizeLogAll.cx >= 0) && (m_sizeLogAll.cy >= 0));
1810 ATLASSERT((m_sizeAll.cx >= 0) && (m_sizeAll.cy >= 0));
1811
1812 if(wParam != NULL)
1813 {
1814 CDCHandle dc = (HDC)wParam;
1815 int nMapModeSav = dc.GetMapMode();
1816 dc.SetMapMode(MM_ANISOTROPIC);
1817 SIZE szWindowExt = { 0, 0 };
1818 dc.SetWindowExt(m_sizeLogAll, &szWindowExt);
1819 SIZE szViewportExt = { 0, 0 };
1820 dc.SetViewportExt(m_sizeAll, &szViewportExt);
1821 POINT ptViewportOrg = { 0, 0 };
1822 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewportOrg);
1823
1824 pT->DoPaint(dc);
1825
1826 dc.SetMapMode(nMapModeSav);
1827 dc.SetWindowExt(szWindowExt);
1828 dc.SetViewportExt(szViewportExt);
1829 dc.SetViewportOrg(ptViewportOrg);
1830 }
1831 else
1832 {
1833 CPaintDC dc(pT->m_hWnd);
1834 pT->PrepareDC(dc.m_hDC);
1835 pT->DoPaint(dc.m_hDC);
1836 }
1837
1838 return 0;
1839 }
1840
1841 LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
1842 {
1843 if(m_nZoomMode == ZOOMMODE_IN && !m_bTracking)
1844 {
1845 T* pT = static_cast<T*>(this);
1846 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
1847 if(pT->PtInDevRect(pt))
1848 {
1849 pT->SetCapture();
1850 m_bTracking = true;
1851 ::SetRect(&m_rcTrack, pt.x, pt.y, pt.x, pt.y);
1852 }
1853 }
1854
1855 bHandled = FALSE;
1856 return 0;
1857 }
1858
1859 LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
1860 {
1861 if(m_bTracking)
1862 {
1863 T* pT = static_cast<T*>(this);
1864 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
1865 if(pT->PtInDevRect(pt))
1866 {
1867 pT->DrawTrackRect();
1868 m_rcTrack.right = pt.x;
1869 m_rcTrack.bottom = pt.y;
1870 pT->DrawTrackRect();
1871 }
1872 }
1873
1874 bHandled = FALSE;
1875 return 0;
1876 }
1877
1878 LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
1879 {
1880 ::ReleaseCapture();
1881 if(m_nZoomMode == ZOOMMODE_OUT)
1882 {
1883 T* pT = static_cast<T*>(this);
1884 pT->Zoom(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), m_fZoomScale - m_fZoomDelta);
1885 pT->NotifyParentZoomChanged();
1886 }
1887
1888 bHandled = FALSE;
1889 return 0;
1890 }
1891
1892 LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
1893 {
1894 if(m_bTracking)
1895 {
1896 m_bTracking = false;
1897 T* pT = static_cast<T*>(this);
1898 pT->DrawTrackRect();
1899 pT->Zoom(m_rcTrack);
1900 pT->NotifyParentZoomChanged();
1901 ::SetRectEmpty(&m_rcTrack);
1902 }
1903
1904 bHandled = FALSE;
1905 return 0;
1906 }
1907
1908 LRESULT OnSetCursor(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1909 {
1910 if(LOWORD(lParam) == HTCLIENT && m_nZoomMode != ZOOMMODE_OFF)
1911 {
1912 T* pT = static_cast<T*>(this);
1913 if((HWND)wParam == pT->m_hWnd)
1914 {
1915 DWORD dwPos = ::GetMessagePos();
1916 POINT pt = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos) };
1917 pT->ScreenToClient(&pt);
1918 if(pT->PtInDevRect(pt))
1919 {
1920 ::SetCursor(::LoadCursor(NULL, IDC_CROSS));
1921 return 1;
1922 }
1923 }
1924 }
1925
1926 bHandled = FALSE;
1927 return 0;
1928 }
1929 };
1930
1931 ///////////////////////////////////////////////////////////////////////////////
1932 // CZoomScrollWindowImpl - Implements scrolling window with zooming
1933
1934 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
1935 class ATL_NO_VTABLE CZoomScrollWindowImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CZoomScrollImpl< T >
1936 {
1937 public:
1938 BOOL SubclassWindow(HWND hWnd)
1939 {
1940 #if (_MSC_VER >= 1300)
1941 BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits >::SubclassWindow(hWnd);
1942 #else // !(_MSC_VER >= 1300)
1943 typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass;
1944 BOOL bRet = _baseClass::SubclassWindow(hWnd);
1945 #endif // !(_MSC_VER >= 1300)
1946 if(bRet != FALSE)
1947 {
1948 T* pT = static_cast<T*>(this);
1949 pT->GetSystemSettings();
1950
1951 RECT rect = { 0 };
1952 GetClientRect(&rect);
1953 pT->DoSize(rect.right, rect.bottom);
1954 }
1955
1956 return bRet;
1957 }
1958
1959 BEGIN_MSG_MAP(CZoomScrollWindowImpl)
1960 MESSAGE_HANDLER(WM_SETCURSOR, CZoomScrollImpl< T >::OnSetCursor)
1961 MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
1962 MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
1963 MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
1964 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
1965 MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel)
1966 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
1967 MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel)
1968 MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange)
1969 MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
1970 MESSAGE_HANDLER(WM_PAINT, CZoomScrollImpl< T >::OnPaint)
1971 MESSAGE_HANDLER(WM_PRINTCLIENT, CZoomScrollImpl< T >::OnPaint)
1972 MESSAGE_HANDLER(WM_LBUTTONDOWN, CZoomScrollImpl< T >::OnLButtonDown)
1973 MESSAGE_HANDLER(WM_MOUSEMOVE, CZoomScrollImpl< T >::OnMouseMove)
1974 MESSAGE_HANDLER(WM_LBUTTONUP, CZoomScrollImpl< T >::OnLButtonUp)
1975 MESSAGE_HANDLER(WM_CAPTURECHANGED, CZoomScrollImpl< T >::OnCaptureChanged)
1976 ALT_MSG_MAP(1)
1977 COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
1978 COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown)
1979 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp)
1980 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown)
1981 COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
1982 COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom)
1983 COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft)
1984 COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight)
1985 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft)
1986 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight)
1987 COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft)
1988 COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight)
1989 END_MSG_MAP()
1990 };
1991
1992 #endif // !_WIN32_WCE
1993
1994
1995 ///////////////////////////////////////////////////////////////////////////////
1996 // CScrollContainer
1997
1998 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
1999 class ATL_NO_VTABLE CScrollContainerImpl : public CScrollWindowImpl< T, TBase, TWinTraits >
2000 {
2001 public:
2002 DECLARE_WND_CLASS_EX(NULL, 0, -1)
2003
2004 typedef CScrollWindowImpl< T, TBase, TWinTraits > _baseClass;
2005
2006 // Data members
2007 ATL::CWindow m_wndClient;
2008 bool m_bAutoSizeClient;
2009 bool m_bDrawEdgeIfEmpty;
2010
2011 // Constructor
2012 CScrollContainerImpl() : m_bAutoSizeClient(true), m_bDrawEdgeIfEmpty(false)
2013 {
2014 // Set CScrollWindowImpl extended style
2015 SetScrollExtendedStyle(SCRL_SCROLLCHILDREN);
2016 }
2017
2018 // Attributes
2019 HWND GetClient() const
2020 {
2021 return m_wndClient;
2022 }
2023
2024 HWND SetClient(HWND hWndClient, bool bClientSizeAsMin = true)
2025 {
2026 ATLASSERT(::IsWindow(m_hWnd));
2027
2028 HWND hWndOldClient = m_wndClient;
2029 m_wndClient = hWndClient;
2030
2031 SetRedraw(FALSE);
2032 SetScrollSize(1, 1, FALSE);
2033
2034 if(m_wndClient.m_hWnd != NULL)
2035 {
2036 m_wndClient.SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
2037
2038 if(bClientSizeAsMin)
2039 {
2040 RECT rect = { 0 };
2041 m_wndClient.GetWindowRect(&rect);
2042 if((rect.right - rect.left) > 0 && (rect.bottom - rect.top) > 0)
2043 SetScrollSize(rect.right - rect.left, rect.bottom - rect.top, FALSE);
2044 }
2045
2046 T* pT = static_cast<T*>(this);
2047 pT->UpdateLayout();
2048 }
2049
2050 SetRedraw(TRUE);
2051 RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN);
2052
2053 return hWndOldClient;
2054 }
2055
2056 // Message map and handlers
2057 BEGIN_MSG_MAP(CScrollContainerImpl)
2058 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
2059 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
2060 CHAIN_MSG_MAP(_baseClass)
2061 FORWARD_NOTIFICATIONS()
2062 ALT_MSG_MAP(1)
2063 CHAIN_MSG_MAP_ALT(_baseClass, 1)
2064 END_MSG_MAP()
2065
2066 LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
2067 {
2068 if(m_wndClient.m_hWnd != NULL)
2069 m_wndClient.SetFocus();
2070
2071 return 0;
2072 }
2073
2074 LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
2075 {
2076 return 1; // no background needed
2077 }
2078
2079 // Overrides for CScrollWindowImpl
2080 void DoSize(int cx, int cy)
2081 {
2082 _baseClass::DoSize(cx, cy);
2083
2084 T* pT = static_cast<T*>(this);
2085 pT->UpdateLayout();
2086 }
2087
2088 void DoPaint(CDCHandle dc)
2089 {
2090 if(!m_bAutoSizeClient || m_wndClient.m_hWnd == NULL)
2091 {
2092 T* pT = static_cast<T*>(this);
2093 RECT rect = { 0 };
2094 pT->GetContainerRect(rect);
2095
2096 if(m_bDrawEdgeIfEmpty && m_wndClient.m_hWnd == NULL)
2097 dc.DrawEdge(&rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
2098
2099 dc.FillRect(&rect, COLOR_APPWORKSPACE);
2100 }
2101 }
2102
2103 void ScrollToView(POINT pt)
2104 {
2105 CScrollWindowImpl< T, TBase, TWinTraits >::ScrollToView(pt);
2106 }
2107
2108 void ScrollToView(RECT& rect)
2109 {
2110 CScrollWindowImpl< T, TBase, TWinTraits >::ScrollToView(rect);
2111 }
2112
2113 void ScrollToView(HWND hWnd) // client window coordinates
2114 {
2115 T* pT = static_cast<T*>(this);
2116 pT; // avoid level 4 warning
2117 ATLASSERT(::IsWindow(pT->m_hWnd));
2118 ATLASSERT(m_wndClient.IsWindow());
2119
2120 RECT rect = { 0 };
2121 ::GetWindowRect(hWnd, &rect);
2122 ::MapWindowPoints(NULL, m_wndClient.m_hWnd, (LPPOINT)&rect, 2);
2123 ScrollToView(rect);
2124 }
2125
2126 // Implementation - overrideable methods
2127 void UpdateLayout()
2128 {
2129 ATLASSERT(::IsWindow(m_hWnd));
2130
2131 if(m_bAutoSizeClient && m_wndClient.m_hWnd != NULL)
2132 {
2133 T* pT = static_cast<T*>(this);
2134 RECT rect = { 0 };
2135 pT->GetContainerRect(rect);
2136
2137 m_wndClient.SetWindowPos(NULL, &rect, SWP_NOZORDER | SWP_NOMOVE);
2138 }
2139 else
2140 {
2141 Invalidate();
2142 }
2143 }
2144
2145 void GetContainerRect(RECT& rect)
2146 {
2147 GetClientRect(&rect);
2148
2149 if(rect.right < m_sizeAll.cx)
2150 rect.right = m_sizeAll.cx;
2151
2152 if(rect.bottom < m_sizeAll.cy)
2153 rect.bottom = m_sizeAll.cy;
2154 }
2155 };
2156
2157 class CScrollContainer : public CScrollContainerImpl<CScrollContainer>
2158 {
2159 public:
2160 DECLARE_WND_CLASS_EX(_T("WTL_ScrollContainer"), 0, -1)
2161 };
2162
2163 }; // namespace WTL
2164
2165 #endif // __ATLSCRL_H__
+0
-1130
src/third_party/wtl/Include/atlsplit.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLSPLIT_H__
9 #define __ATLSPLIT_H__
10
11 #pragma once
12
13 #ifndef __ATLAPP_H__
14 #error atlsplit.h requires atlapp.h to be included first
15 #endif
16
17 #ifndef __ATLWIN_H__
18 #error atlsplit.h requires atlwin.h to be included first
19 #endif
20
21
22 ///////////////////////////////////////////////////////////////////////////////
23 // Classes in this file:
24 //
25 // CSplitterImpl<T>
26 // CSplitterWindowImpl<T, TBase, TWinTraits>
27 // CSplitterWindowT<t_bVertical> - CSplitterWindow, CHorSplitterWindow
28
29
30 namespace WTL
31 {
32
33 ///////////////////////////////////////////////////////////////////////////////
34 // CSplitterImpl - Provides splitter support to any window
35
36 // Splitter panes constants
37 #define SPLIT_PANE_LEFT 0
38 #define SPLIT_PANE_RIGHT 1
39 #define SPLIT_PANE_TOP SPLIT_PANE_LEFT
40 #define SPLIT_PANE_BOTTOM SPLIT_PANE_RIGHT
41 #define SPLIT_PANE_NONE -1
42
43 // Splitter extended styles
44 #define SPLIT_PROPORTIONAL 0x00000001
45 #define SPLIT_NONINTERACTIVE 0x00000002
46 #define SPLIT_RIGHTALIGNED 0x00000004
47 #define SPLIT_BOTTOMALIGNED SPLIT_RIGHTALIGNED
48 #define SPLIT_GRADIENTBAR 0x00000008
49 #define SPLIT_FIXEDBARSIZE 0x00000010
50
51 // Note: SPLIT_PROPORTIONAL and SPLIT_RIGHTALIGNED/SPLIT_BOTTOMALIGNED are
52 // mutually exclusive. If both are set, splitter defaults to SPLIT_PROPORTIONAL.
53 // SPLIT_GRADIENTBAR doesn't work with _ATL_NO_MSIMG
54
55
56 template <class T>
57 class CSplitterImpl
58 {
59 public:
60 enum { m_nPanesCount = 2, m_nPropMax = 10000, m_cxyStep = 10 };
61
62 bool m_bVertical;
63 HWND m_hWndPane[m_nPanesCount];
64 RECT m_rcSplitter;
65 int m_xySplitterPos; // splitter bar position
66 int m_xySplitterPosNew; // internal - new position while moving
67 HWND m_hWndFocusSave;
68 int m_nDefActivePane;
69 int m_cxySplitBar; // splitter bar width/height
70 HCURSOR m_hCursor;
71 int m_cxyMin; // minimum pane size
72 int m_cxyBarEdge; // splitter bar edge
73 bool m_bFullDrag;
74 int m_cxyDragOffset; // internal
75 int m_nProportionalPos;
76 bool m_bUpdateProportionalPos;
77 DWORD m_dwExtendedStyle; // splitter specific extended styles
78 int m_nSinglePane; // single pane mode
79 int m_xySplitterDefPos; // default position
80 bool m_bProportionalDefPos; // porportinal def pos
81
82 // Constructor
83 CSplitterImpl(bool bVertical = true) :
84 m_bVertical(bVertical), m_xySplitterPos(-1), m_xySplitterPosNew(-1), m_hWndFocusSave(NULL),
85 m_nDefActivePane(SPLIT_PANE_NONE), m_cxySplitBar(4), m_hCursor(NULL), m_cxyMin(0), m_cxyBarEdge(0),
86 m_bFullDrag(true), m_cxyDragOffset(0), m_nProportionalPos(0), m_bUpdateProportionalPos(true),
87 m_dwExtendedStyle(SPLIT_PROPORTIONAL), m_nSinglePane(SPLIT_PANE_NONE),
88 m_xySplitterDefPos(-1), m_bProportionalDefPos(false)
89 {
90 m_hWndPane[SPLIT_PANE_LEFT] = NULL;
91 m_hWndPane[SPLIT_PANE_RIGHT] = NULL;
92
93 ::SetRectEmpty(&m_rcSplitter);
94 }
95
96 // Attributes
97 void SetSplitterRect(LPRECT lpRect = NULL, bool bUpdate = true)
98 {
99 if(lpRect == NULL)
100 {
101 T* pT = static_cast<T*>(this);
102 pT->GetClientRect(&m_rcSplitter);
103 }
104 else
105 {
106 m_rcSplitter = *lpRect;
107 }
108
109 if(IsProportional())
110 UpdateProportionalPos();
111 else if(IsRightAligned())
112 UpdateRightAlignPos();
113
114 if(bUpdate)
115 UpdateSplitterLayout();
116 }
117
118 void GetSplitterRect(LPRECT lpRect) const
119 {
120 ATLASSERT(lpRect != NULL);
121 *lpRect = m_rcSplitter;
122 }
123
124 bool SetSplitterPos(int xyPos = -1, bool bUpdate = true)
125 {
126 if(xyPos == -1) // -1 == default position
127 {
128 if(m_bProportionalDefPos)
129 {
130 ATLASSERT((m_xySplitterDefPos >= 0) && (m_xySplitterDefPos <= m_nPropMax));
131
132 if(m_bVertical)
133 xyPos = ::MulDiv(m_xySplitterDefPos, m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge, m_nPropMax);
134 else
135 xyPos = ::MulDiv(m_xySplitterDefPos, m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge, m_nPropMax);
136 }
137 else if(m_xySplitterDefPos != -1)
138 {
139 xyPos = m_xySplitterDefPos;
140 }
141 else // not set, use middle position
142 {
143 if(m_bVertical)
144 xyPos = (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) / 2;
145 else
146 xyPos = (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge) / 2;
147 }
148 }
149
150 // Adjust if out of valid range
151 int cxyMax = 0;
152 if(m_bVertical)
153 cxyMax = m_rcSplitter.right - m_rcSplitter.left;
154 else
155 cxyMax = m_rcSplitter.bottom - m_rcSplitter.top;
156
157 if(xyPos < m_cxyMin + m_cxyBarEdge)
158 xyPos = m_cxyMin;
159 else if(xyPos > (cxyMax - m_cxySplitBar - m_cxyBarEdge - m_cxyMin))
160 xyPos = cxyMax - m_cxySplitBar - m_cxyBarEdge - m_cxyMin;
161
162 // Set new position and update if requested
163 bool bRet = (m_xySplitterPos != xyPos);
164 m_xySplitterPos = xyPos;
165
166 if(m_bUpdateProportionalPos)
167 {
168 if(IsProportional())
169 StoreProportionalPos();
170 else if(IsRightAligned())
171 StoreRightAlignPos();
172 }
173 else
174 {
175 m_bUpdateProportionalPos = true;
176 }
177
178 if(bUpdate && bRet)
179 UpdateSplitterLayout();
180
181 return bRet;
182 }
183
184 int GetSplitterPos() const
185 {
186 return m_xySplitterPos;
187 }
188
189 void SetSplitterPosPct(int nPct, bool bUpdate = true)
190 {
191 ATLASSERT((nPct >= 0) && (nPct <= 100));
192
193 m_nProportionalPos = ::MulDiv(nPct, m_nPropMax, 100);
194 UpdateProportionalPos();
195
196 if(bUpdate)
197 UpdateSplitterLayout();
198 }
199
200 int GetSplitterPosPct() const
201 {
202 int cxyTotal = m_bVertical ? (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge);
203 return ((cxyTotal > 0) && (m_xySplitterPos >= 0)) ? (::MulDiv(m_xySplitterPos, m_nPropMax, cxyTotal) / 100) : -1;
204 }
205
206 bool SetSinglePaneMode(int nPane = SPLIT_PANE_NONE)
207 {
208 ATLASSERT((nPane == SPLIT_PANE_LEFT) || (nPane == SPLIT_PANE_RIGHT) || (nPane == SPLIT_PANE_NONE));
209 if(!((nPane == SPLIT_PANE_LEFT) || (nPane == SPLIT_PANE_RIGHT) || (nPane == SPLIT_PANE_NONE)))
210 return false;
211
212 if(nPane != SPLIT_PANE_NONE)
213 {
214 if(::IsWindowVisible(m_hWndPane[nPane]) == FALSE)
215 ::ShowWindow(m_hWndPane[nPane], SW_SHOW);
216 int nOtherPane = (nPane == SPLIT_PANE_LEFT) ? SPLIT_PANE_RIGHT : SPLIT_PANE_LEFT;
217 ::ShowWindow(m_hWndPane[nOtherPane], SW_HIDE);
218 if(m_nDefActivePane != nPane)
219 m_nDefActivePane = nPane;
220 }
221 else if(m_nSinglePane != SPLIT_PANE_NONE)
222 {
223 int nOtherPane = (m_nSinglePane == SPLIT_PANE_LEFT) ? SPLIT_PANE_RIGHT : SPLIT_PANE_LEFT;
224 ::ShowWindow(m_hWndPane[nOtherPane], SW_SHOW);
225 }
226
227 m_nSinglePane = nPane;
228 UpdateSplitterLayout();
229
230 return true;
231 }
232
233 int GetSinglePaneMode() const
234 {
235 return m_nSinglePane;
236 }
237
238 DWORD GetSplitterExtendedStyle() const
239 {
240 return m_dwExtendedStyle;
241 }
242
243 DWORD SetSplitterExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
244 {
245 DWORD dwPrevStyle = m_dwExtendedStyle;
246 if(dwMask == 0)
247 m_dwExtendedStyle = dwExtendedStyle;
248 else
249 m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
250
251 #ifdef _DEBUG
252 if(IsProportional() && IsRightAligned())
253 ATLTRACE2(atlTraceUI, 0, _T("CSplitterImpl::SetSplitterExtendedStyle - SPLIT_PROPORTIONAL and SPLIT_RIGHTALIGNED are mutually exclusive, defaulting to SPLIT_PROPORTIONAL.\n"));
254 #endif // _DEBUG
255
256 return dwPrevStyle;
257 }
258
259 void SetSplitterDefaultPos(int xyPos = -1)
260 {
261 m_xySplitterDefPos = xyPos;
262 m_bProportionalDefPos = false;
263 }
264
265 void SetSplitterDefaultPosPct(int nPct)
266 {
267 ATLASSERT((nPct >= 0) && (nPct <= 100));
268
269 m_xySplitterDefPos = ::MulDiv(nPct, m_nPropMax, 100);
270 m_bProportionalDefPos = true;
271 }
272
273 // Splitter operations
274 void SetSplitterPanes(HWND hWndLeftTop, HWND hWndRightBottom, bool bUpdate = true)
275 {
276 m_hWndPane[SPLIT_PANE_LEFT] = hWndLeftTop;
277 m_hWndPane[SPLIT_PANE_RIGHT] = hWndRightBottom;
278 ATLASSERT((m_hWndPane[SPLIT_PANE_LEFT] == NULL) || (m_hWndPane[SPLIT_PANE_RIGHT] == NULL) || (m_hWndPane[SPLIT_PANE_LEFT] != m_hWndPane[SPLIT_PANE_RIGHT]));
279 if(bUpdate)
280 UpdateSplitterLayout();
281 }
282
283 bool SetSplitterPane(int nPane, HWND hWnd, bool bUpdate = true)
284 {
285 ATLASSERT((nPane == SPLIT_PANE_LEFT) || (nPane == SPLIT_PANE_RIGHT));
286 if((nPane != SPLIT_PANE_LEFT) && (nPane != SPLIT_PANE_RIGHT))
287 return false;
288
289 m_hWndPane[nPane] = hWnd;
290 ATLASSERT((m_hWndPane[SPLIT_PANE_LEFT] == NULL) || (m_hWndPane[SPLIT_PANE_RIGHT] == NULL) || (m_hWndPane[SPLIT_PANE_LEFT] != m_hWndPane[SPLIT_PANE_RIGHT]));
291 if(bUpdate)
292 UpdateSplitterLayout();
293
294 return true;
295 }
296
297 HWND GetSplitterPane(int nPane) const
298 {
299 ATLASSERT((nPane == SPLIT_PANE_LEFT) || (nPane == SPLIT_PANE_RIGHT));
300 if((nPane != SPLIT_PANE_LEFT) && (nPane != SPLIT_PANE_RIGHT))
301 return NULL;
302
303 return m_hWndPane[nPane];
304 }
305
306 bool SetActivePane(int nPane)
307 {
308 ATLASSERT((nPane == SPLIT_PANE_LEFT) || (nPane == SPLIT_PANE_RIGHT));
309 if((nPane != SPLIT_PANE_LEFT) && (nPane != SPLIT_PANE_RIGHT))
310 return false;
311 if((m_nSinglePane != SPLIT_PANE_NONE) && (nPane != m_nSinglePane))
312 return false;
313
314 ::SetFocus(m_hWndPane[nPane]);
315 m_nDefActivePane = nPane;
316
317 return true;
318 }
319
320 int GetActivePane() const
321 {
322 int nRet = SPLIT_PANE_NONE;
323 HWND hWndFocus = ::GetFocus();
324 if(hWndFocus != NULL)
325 {
326 for(int nPane = 0; nPane < m_nPanesCount; nPane++)
327 {
328 if((hWndFocus == m_hWndPane[nPane]) || (::IsChild(m_hWndPane[nPane], hWndFocus) != FALSE))
329 {
330 nRet = nPane;
331 break;
332 }
333 }
334 }
335
336 return nRet;
337 }
338
339 bool ActivateNextPane(bool bNext = true)
340 {
341 int nPane = m_nSinglePane;
342 if(nPane == SPLIT_PANE_NONE)
343 {
344 switch(GetActivePane())
345 {
346 case SPLIT_PANE_LEFT:
347 nPane = SPLIT_PANE_RIGHT;
348 break;
349 case SPLIT_PANE_RIGHT:
350 nPane = SPLIT_PANE_LEFT;
351 break;
352 default:
353 nPane = bNext ? SPLIT_PANE_LEFT : SPLIT_PANE_RIGHT;
354 break;
355 }
356 }
357
358 return SetActivePane(nPane);
359 }
360
361 bool SetDefaultActivePane(int nPane)
362 {
363 ATLASSERT((nPane == SPLIT_PANE_LEFT) || (nPane == SPLIT_PANE_RIGHT));
364 if((nPane != SPLIT_PANE_LEFT) && (nPane != SPLIT_PANE_RIGHT))
365 return false;
366
367 m_nDefActivePane = nPane;
368
369 return true;
370 }
371
372 bool SetDefaultActivePane(HWND hWnd)
373 {
374 for(int nPane = 0; nPane < m_nPanesCount; nPane++)
375 {
376 if(hWnd == m_hWndPane[nPane])
377 {
378 m_nDefActivePane = nPane;
379 return true;
380 }
381 }
382
383 return false; // not found
384 }
385
386 int GetDefaultActivePane() const
387 {
388 return m_nDefActivePane;
389 }
390
391 void DrawSplitter(CDCHandle dc)
392 {
393 ATLASSERT(dc.m_hDC != NULL);
394 if((m_nSinglePane == SPLIT_PANE_NONE) && (m_xySplitterPos == -1))
395 return;
396
397 T* pT = static_cast<T*>(this);
398 if(m_nSinglePane == SPLIT_PANE_NONE)
399 {
400 pT->DrawSplitterBar(dc);
401
402 for(int nPane = 0; nPane < m_nPanesCount; nPane++)
403 {
404 if(m_hWndPane[nPane] == NULL)
405 pT->DrawSplitterPane(dc, nPane);
406 }
407 }
408 else
409 {
410 if(m_hWndPane[m_nSinglePane] == NULL)
411 pT->DrawSplitterPane(dc, m_nSinglePane);
412 }
413 }
414
415 // call to initiate moving splitter bar with keyboard
416 void MoveSplitterBar()
417 {
418 T* pT = static_cast<T*>(this);
419
420 int x = 0;
421 int y = 0;
422 if(m_bVertical)
423 {
424 x = m_xySplitterPos + (m_cxySplitBar / 2) + m_cxyBarEdge;
425 y = (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge) / 2;
426 }
427 else
428 {
429 x = (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) / 2;
430 y = m_xySplitterPos + (m_cxySplitBar / 2) + m_cxyBarEdge;
431 }
432
433 POINT pt = { x, y };
434 pT->ClientToScreen(&pt);
435 ::SetCursorPos(pt.x, pt.y);
436
437 m_xySplitterPosNew = m_xySplitterPos;
438 pT->SetCapture();
439 m_hWndFocusSave = pT->SetFocus();
440 ::SetCursor(m_hCursor);
441 if(!m_bFullDrag)
442 DrawGhostBar();
443 if(m_bVertical)
444 m_cxyDragOffset = x - m_rcSplitter.left - m_xySplitterPos;
445 else
446 m_cxyDragOffset = y - m_rcSplitter.top - m_xySplitterPos;
447 }
448
449 void SetOrientation(bool bVertical, bool bUpdate = true)
450 {
451 if(m_bVertical != bVertical)
452 {
453 m_bVertical = bVertical;
454
455 m_hCursor = ::LoadCursor(NULL, m_bVertical ? IDC_SIZEWE : IDC_SIZENS);
456
457 T* pT = static_cast<T*>(this);
458 pT->GetSystemSettings(false);
459
460 if(m_bVertical)
461 m_xySplitterPos = ::MulDiv(m_xySplitterPos, m_rcSplitter.right - m_rcSplitter.left, m_rcSplitter.bottom - m_rcSplitter.top);
462 else
463 m_xySplitterPos = ::MulDiv(m_xySplitterPos, m_rcSplitter.bottom - m_rcSplitter.top, m_rcSplitter.right - m_rcSplitter.left);
464 }
465
466 if(bUpdate)
467 UpdateSplitterLayout();
468 }
469
470 // Overrideables
471 void DrawSplitterBar(CDCHandle dc)
472 {
473 RECT rect = { 0 };
474 if(GetSplitterBarRect(&rect))
475 {
476 dc.FillRect(&rect, COLOR_3DFACE);
477
478 #if (!defined(_WIN32_WCE) && !defined(_ATL_NO_MSIMG)) || (_WIN32_WCE >= 420)
479 if((m_dwExtendedStyle & SPLIT_GRADIENTBAR) != 0)
480 {
481 RECT rect2 = rect;
482 if(m_bVertical)
483 rect2.left = (rect.left + rect.right) / 2 - 1;
484 else
485 rect2.top = (rect.top + rect.bottom) / 2 - 1;
486
487 dc.GradientFillRect(rect2, ::GetSysColor(COLOR_3DFACE), ::GetSysColor(COLOR_3DSHADOW), m_bVertical);
488 }
489 #endif // (!defined(_WIN32_WCE) && !defined(_ATL_NO_MSIMG)) || (_WIN32_WCE >= 420)
490
491 // draw 3D edge if needed
492 T* pT = static_cast<T*>(this);
493 if((pT->GetExStyle() & WS_EX_CLIENTEDGE) != 0)
494 dc.DrawEdge(&rect, EDGE_RAISED, m_bVertical ? (BF_LEFT | BF_RIGHT) : (BF_TOP | BF_BOTTOM));
495 }
496 }
497
498 // called only if pane is empty
499 void DrawSplitterPane(CDCHandle dc, int nPane)
500 {
501 RECT rect = { 0 };
502 if(GetSplitterPaneRect(nPane, &rect))
503 {
504 T* pT = static_cast<T*>(this);
505 if((pT->GetExStyle() & WS_EX_CLIENTEDGE) == 0)
506 dc.DrawEdge(&rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
507 dc.FillRect(&rect, COLOR_APPWORKSPACE);
508 }
509 }
510
511 // Message map and handlers
512 BEGIN_MSG_MAP(CSplitterImpl)
513 MESSAGE_HANDLER(WM_CREATE, OnCreate)
514 MESSAGE_HANDLER(WM_PAINT, OnPaint)
515 #ifndef _WIN32_WCE
516 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
517 #endif // !_WIN32_WCE
518 if(IsInteractive())
519 {
520 MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor)
521 MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
522 MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
523 MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
524 MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDoubleClick)
525 MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged)
526 MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
527 }
528 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
529 #ifndef _WIN32_WCE
530 MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate)
531 #endif // !_WIN32_WCE
532 MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
533 END_MSG_MAP()
534
535 LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
536 {
537 T* pT = static_cast<T*>(this);
538 pT->Init();
539
540 bHandled = FALSE;
541 return 1;
542 }
543
544 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
545 {
546 T* pT = static_cast<T*>(this);
547
548 // try setting position if not set
549 if((m_nSinglePane == SPLIT_PANE_NONE) && (m_xySplitterPos == -1))
550 pT->SetSplitterPos();
551
552 // do painting
553 if(wParam != NULL)
554 {
555 pT->DrawSplitter((HDC)wParam);
556 }
557 else
558 {
559 CPaintDC dc(pT->m_hWnd);
560 pT->DrawSplitter(dc.m_hDC);
561 }
562
563 return 0;
564 }
565
566 LRESULT OnSetCursor(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
567 {
568 T* pT = static_cast<T*>(this);
569 if(((HWND)wParam == pT->m_hWnd) && (LOWORD(lParam) == HTCLIENT))
570 {
571 DWORD dwPos = ::GetMessagePos();
572 POINT ptPos = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos) };
573 pT->ScreenToClient(&ptPos);
574 if(IsOverSplitterBar(ptPos.x, ptPos.y))
575 return 1;
576 }
577
578 bHandled = FALSE;
579 return 0;
580 }
581
582 LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
583 {
584 T* pT = static_cast<T*>(this);
585 int xPos = GET_X_LPARAM(lParam);
586 int yPos = GET_Y_LPARAM(lParam);
587 if(::GetCapture() == pT->m_hWnd)
588 {
589 int xyNewSplitPos = 0;
590 if(m_bVertical)
591 xyNewSplitPos = xPos - m_rcSplitter.left - m_cxyDragOffset;
592 else
593 xyNewSplitPos = yPos - m_rcSplitter.top - m_cxyDragOffset;
594
595 if(xyNewSplitPos == -1) // avoid -1, that means default position
596 xyNewSplitPos = -2;
597
598 if(m_xySplitterPos != xyNewSplitPos)
599 {
600 if(m_bFullDrag)
601 {
602 if(pT->SetSplitterPos(xyNewSplitPos, true))
603 pT->UpdateWindow();
604 }
605 else
606 {
607 DrawGhostBar();
608 pT->SetSplitterPos(xyNewSplitPos, false);
609 DrawGhostBar();
610 }
611 }
612 }
613 else // not dragging, just set cursor
614 {
615 if(IsOverSplitterBar(xPos, yPos))
616 ::SetCursor(m_hCursor);
617 bHandled = FALSE;
618 }
619
620 return 0;
621 }
622
623 LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
624 {
625 T* pT = static_cast<T*>(this);
626 int xPos = GET_X_LPARAM(lParam);
627 int yPos = GET_Y_LPARAM(lParam);
628 if((::GetCapture() != pT->m_hWnd) && IsOverSplitterBar(xPos, yPos))
629 {
630 m_xySplitterPosNew = m_xySplitterPos;
631 pT->SetCapture();
632 m_hWndFocusSave = pT->SetFocus();
633 ::SetCursor(m_hCursor);
634 if(!m_bFullDrag)
635 DrawGhostBar();
636 if(m_bVertical)
637 m_cxyDragOffset = xPos - m_rcSplitter.left - m_xySplitterPos;
638 else
639 m_cxyDragOffset = yPos - m_rcSplitter.top - m_xySplitterPos;
640 }
641 else if((::GetCapture() == pT->m_hWnd) && !IsOverSplitterBar(xPos, yPos))
642 {
643 ::ReleaseCapture();
644 }
645
646 bHandled = FALSE;
647 return 1;
648 }
649
650 LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
651 {
652 T* pT = static_cast<T*>(this);
653 if(::GetCapture() == pT->m_hWnd)
654 {
655 m_xySplitterPosNew = m_xySplitterPos;
656 ::ReleaseCapture();
657 }
658
659 bHandled = FALSE;
660 return 1;
661 }
662
663 LRESULT OnLButtonDoubleClick(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
664 {
665 T* pT = static_cast<T*>(this);
666 pT->SetSplitterPos(); // default
667
668 return 0;
669 }
670
671 LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
672 {
673 if(!m_bFullDrag)
674 DrawGhostBar();
675
676 if((m_xySplitterPosNew != -1) && (!m_bFullDrag || (m_xySplitterPos != m_xySplitterPosNew)))
677 {
678 m_xySplitterPos = m_xySplitterPosNew;
679 m_xySplitterPosNew = -1;
680 UpdateSplitterLayout();
681 T* pT = static_cast<T*>(this);
682 pT->UpdateWindow();
683 }
684
685 if(m_hWndFocusSave != NULL)
686 ::SetFocus(m_hWndFocusSave);
687
688 return 0;
689 }
690
691 LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
692 {
693 T* pT = static_cast<T*>(this);
694 if(::GetCapture() == pT->m_hWnd)
695 {
696 switch(wParam)
697 {
698 case VK_RETURN:
699 m_xySplitterPosNew = m_xySplitterPos;
700 case VK_ESCAPE:
701 ::ReleaseCapture();
702 break;
703 case VK_LEFT:
704 case VK_RIGHT:
705 if(m_bVertical)
706 {
707 POINT pt = { 0, 0 };
708 ::GetCursorPos(&pt);
709 int xyPos = m_xySplitterPos + ((wParam == VK_LEFT) ? -pT->m_cxyStep : pT->m_cxyStep);
710 int cxyMax = m_rcSplitter.right - m_rcSplitter.left;
711 if(xyPos < (m_cxyMin + m_cxyBarEdge))
712 xyPos = m_cxyMin;
713 else if(xyPos > (cxyMax - m_cxySplitBar - m_cxyBarEdge - m_cxyMin))
714 xyPos = cxyMax - m_cxySplitBar - m_cxyBarEdge - m_cxyMin;
715 pt.x += xyPos - m_xySplitterPos;
716 ::SetCursorPos(pt.x, pt.y);
717 }
718 break;
719 case VK_UP:
720 case VK_DOWN:
721 if(!m_bVertical)
722 {
723 POINT pt = { 0, 0 };
724 ::GetCursorPos(&pt);
725 int xyPos = m_xySplitterPos + ((wParam == VK_UP) ? -pT->m_cxyStep : pT->m_cxyStep);
726 int cxyMax = m_rcSplitter.bottom - m_rcSplitter.top;
727 if(xyPos < (m_cxyMin + m_cxyBarEdge))
728 xyPos = m_cxyMin;
729 else if(xyPos > (cxyMax - m_cxySplitBar - m_cxyBarEdge - m_cxyMin))
730 xyPos = cxyMax - m_cxySplitBar - m_cxyBarEdge - m_cxyMin;
731 pt.y += xyPos - m_xySplitterPos;
732 ::SetCursorPos(pt.x, pt.y);
733 }
734 break;
735 default:
736 break;
737 }
738 }
739 else
740 {
741 bHandled = FALSE;
742 }
743
744 return 0;
745 }
746
747 LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM, BOOL& bHandled)
748 {
749 T* pT = static_cast<T*>(this);
750 if(::GetCapture() != pT->m_hWnd)
751 {
752 if(m_nSinglePane == SPLIT_PANE_NONE)
753 {
754 if((m_nDefActivePane == SPLIT_PANE_LEFT) || (m_nDefActivePane == SPLIT_PANE_RIGHT))
755 ::SetFocus(m_hWndPane[m_nDefActivePane]);
756 }
757 else
758 {
759 ::SetFocus(m_hWndPane[m_nSinglePane]);
760 }
761 }
762
763 bHandled = FALSE;
764 return 1;
765 }
766
767 #ifndef _WIN32_WCE
768 LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
769 {
770 T* pT = static_cast<T*>(this);
771 LRESULT lRet = pT->DefWindowProc(uMsg, wParam, lParam);
772 if((lRet == MA_ACTIVATE) || (lRet == MA_ACTIVATEANDEAT))
773 {
774 DWORD dwPos = ::GetMessagePos();
775 POINT pt = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos) };
776 pT->ScreenToClient(&pt);
777 RECT rcPane = { 0 };
778 for(int nPane = 0; nPane < m_nPanesCount; nPane++)
779 {
780 if(GetSplitterPaneRect(nPane, &rcPane) && (::PtInRect(&rcPane, pt) != FALSE))
781 {
782 m_nDefActivePane = nPane;
783 break;
784 }
785 }
786 }
787
788 return lRet;
789 }
790 #endif // !_WIN32_WCE
791
792 LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
793 {
794 T* pT = static_cast<T*>(this);
795 pT->GetSystemSettings(true);
796
797 return 0;
798 }
799
800 // Implementation - internal helpers
801 void Init()
802 {
803 m_hCursor = ::LoadCursor(NULL, m_bVertical ? IDC_SIZEWE : IDC_SIZENS);
804
805 T* pT = static_cast<T*>(this);
806 pT->GetSystemSettings(false);
807 }
808
809 void UpdateSplitterLayout()
810 {
811 if((m_nSinglePane == SPLIT_PANE_NONE) && (m_xySplitterPos == -1))
812 return;
813
814 T* pT = static_cast<T*>(this);
815 RECT rect = { 0 };
816 if(m_nSinglePane == SPLIT_PANE_NONE)
817 {
818 if(GetSplitterBarRect(&rect))
819 pT->InvalidateRect(&rect);
820
821 for(int nPane = 0; nPane < m_nPanesCount; nPane++)
822 {
823 if(GetSplitterPaneRect(nPane, &rect))
824 {
825 if(m_hWndPane[nPane] != NULL)
826 ::SetWindowPos(m_hWndPane[nPane], NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER);
827 else
828 pT->InvalidateRect(&rect);
829 }
830 }
831 }
832 else
833 {
834 if(GetSplitterPaneRect(m_nSinglePane, &rect))
835 {
836 if(m_hWndPane[m_nSinglePane] != NULL)
837 ::SetWindowPos(m_hWndPane[m_nSinglePane], NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER);
838 else
839 pT->InvalidateRect(&rect);
840 }
841 }
842 }
843
844 bool GetSplitterBarRect(LPRECT lpRect) const
845 {
846 ATLASSERT(lpRect != NULL);
847 if((m_nSinglePane != SPLIT_PANE_NONE) || (m_xySplitterPos == -1))
848 return false;
849
850 if(m_bVertical)
851 {
852 lpRect->left = m_rcSplitter.left + m_xySplitterPos;
853 lpRect->top = m_rcSplitter.top;
854 lpRect->right = m_rcSplitter.left + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge;
855 lpRect->bottom = m_rcSplitter.bottom;
856 }
857 else
858 {
859 lpRect->left = m_rcSplitter.left;
860 lpRect->top = m_rcSplitter.top + m_xySplitterPos;
861 lpRect->right = m_rcSplitter.right;
862 lpRect->bottom = m_rcSplitter.top + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge;
863 }
864
865 return true;
866 }
867
868 bool GetSplitterPaneRect(int nPane, LPRECT lpRect) const
869 {
870 ATLASSERT((nPane == SPLIT_PANE_LEFT) || (nPane == SPLIT_PANE_RIGHT));
871 ATLASSERT(lpRect != NULL);
872 bool bRet = true;
873 if(m_nSinglePane != SPLIT_PANE_NONE)
874 {
875 if(nPane == m_nSinglePane)
876 *lpRect = m_rcSplitter;
877 else
878 bRet = false;
879 }
880 else if(nPane == SPLIT_PANE_LEFT)
881 {
882 if(m_bVertical)
883 {
884 lpRect->left = m_rcSplitter.left;
885 lpRect->top = m_rcSplitter.top;
886 lpRect->right = m_rcSplitter.left + m_xySplitterPos;
887 lpRect->bottom = m_rcSplitter.bottom;
888 }
889 else
890 {
891 lpRect->left = m_rcSplitter.left;
892 lpRect->top = m_rcSplitter.top;
893 lpRect->right = m_rcSplitter.right;
894 lpRect->bottom = m_rcSplitter.top + m_xySplitterPos;
895 }
896 }
897 else if(nPane == SPLIT_PANE_RIGHT)
898 {
899 if(m_bVertical)
900 {
901 lpRect->left = m_rcSplitter.left + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge;
902 lpRect->top = m_rcSplitter.top;
903 lpRect->right = m_rcSplitter.right;
904 lpRect->bottom = m_rcSplitter.bottom;
905 }
906 else
907 {
908 lpRect->left = m_rcSplitter.left;
909 lpRect->top = m_rcSplitter.top + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge;
910 lpRect->right = m_rcSplitter.right;
911 lpRect->bottom = m_rcSplitter.bottom;
912 }
913 }
914 else
915 {
916 bRet = false;
917 }
918
919 return bRet;
920 }
921
922 bool IsOverSplitterRect(int x, int y) const
923 {
924 // -1 == don't check
925 return ((x == -1 || (x >= m_rcSplitter.left && x <= m_rcSplitter.right)) &&
926 (y == -1 || (y >= m_rcSplitter.top && y <= m_rcSplitter.bottom)));
927 }
928
929 bool IsOverSplitterBar(int x, int y) const
930 {
931 if(m_nSinglePane != SPLIT_PANE_NONE)
932 return false;
933 if((m_xySplitterPos == -1) || !IsOverSplitterRect(x, y))
934 return false;
935 int xy = m_bVertical ? x : y;
936 int xyOff = m_bVertical ? m_rcSplitter.left : m_rcSplitter.top;
937
938 return ((xy >= (xyOff + m_xySplitterPos)) && (xy < xyOff + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge));
939 }
940
941 void DrawGhostBar()
942 {
943 RECT rect = { 0 };
944 if(GetSplitterBarRect(&rect))
945 {
946 // convert client to window coordinates
947 T* pT = static_cast<T*>(this);
948 RECT rcWnd = { 0 };
949 pT->GetWindowRect(&rcWnd);
950 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rcWnd, 2);
951 ::OffsetRect(&rect, -rcWnd.left, -rcWnd.top);
952
953 // invert the brush pattern (looks just like frame window sizing)
954 CWindowDC dc(pT->m_hWnd);
955 CBrush brush = CDCHandle::GetHalftoneBrush();
956 if(brush.m_hBrush != NULL)
957 {
958 CBrushHandle brushOld = dc.SelectBrush(brush);
959 dc.PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT);
960 dc.SelectBrush(brushOld);
961 }
962 }
963 }
964
965 void GetSystemSettings(bool bUpdate)
966 {
967 if((m_dwExtendedStyle & SPLIT_FIXEDBARSIZE) == 0)
968 {
969 #ifndef _WIN32_WCE
970 m_cxySplitBar = ::GetSystemMetrics(m_bVertical ? SM_CXSIZEFRAME : SM_CYSIZEFRAME);
971 #else // CE specific
972 m_cxySplitBar = 2 * ::GetSystemMetrics(m_bVertical ? SM_CXEDGE : SM_CYEDGE);
973 #endif // _WIN32_WCE
974 }
975
976 T* pT = static_cast<T*>(this);
977 if((pT->GetExStyle() & WS_EX_CLIENTEDGE) != 0)
978 {
979 m_cxyBarEdge = 2 * ::GetSystemMetrics(m_bVertical ? SM_CXEDGE : SM_CYEDGE);
980 m_cxyMin = 0;
981 }
982 else
983 {
984 m_cxyBarEdge = 0;
985 m_cxyMin = 2 * ::GetSystemMetrics(m_bVertical ? SM_CXEDGE : SM_CYEDGE);
986 }
987
988 #ifndef _WIN32_WCE
989 ::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &m_bFullDrag, 0);
990 #endif // !_WIN32_WCE
991
992 if(bUpdate)
993 UpdateSplitterLayout();
994 }
995
996 bool IsProportional() const
997 {
998 return ((m_dwExtendedStyle & SPLIT_PROPORTIONAL) != 0);
999 }
1000
1001 void StoreProportionalPos()
1002 {
1003 int cxyTotal = m_bVertical ? (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge);
1004 if(cxyTotal > 0)
1005 m_nProportionalPos = ::MulDiv(m_xySplitterPos, m_nPropMax, cxyTotal);
1006 else
1007 m_nProportionalPos = 0;
1008 ATLTRACE2(atlTraceUI, 0, _T("CSplitterImpl::StoreProportionalPos - %i\n"), m_nProportionalPos);
1009 }
1010
1011 void UpdateProportionalPos()
1012 {
1013 int cxyTotal = m_bVertical ? (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge);
1014 if(cxyTotal > 0)
1015 {
1016 int xyNewPos = ::MulDiv(m_nProportionalPos, cxyTotal, m_nPropMax);
1017 m_bUpdateProportionalPos = false;
1018 T* pT = static_cast<T*>(this);
1019 pT->SetSplitterPos(xyNewPos, false);
1020 }
1021 }
1022
1023 bool IsRightAligned() const
1024 {
1025 return ((m_dwExtendedStyle & SPLIT_RIGHTALIGNED) != 0);
1026 }
1027
1028 void StoreRightAlignPos()
1029 {
1030 int cxyTotal = m_bVertical ? (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge);
1031 if(cxyTotal > 0)
1032 m_nProportionalPos = cxyTotal - m_xySplitterPos;
1033 else
1034 m_nProportionalPos = 0;
1035 ATLTRACE2(atlTraceUI, 0, _T("CSplitterImpl::StoreRightAlignPos - %i\n"), m_nProportionalPos);
1036 }
1037
1038 void UpdateRightAlignPos()
1039 {
1040 int cxyTotal = m_bVertical ? (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge);
1041 if(cxyTotal > 0)
1042 {
1043 m_bUpdateProportionalPos = false;
1044 T* pT = static_cast<T*>(this);
1045 pT->SetSplitterPos(cxyTotal - m_nProportionalPos, false);
1046 }
1047 }
1048
1049 bool IsInteractive() const
1050 {
1051 return ((m_dwExtendedStyle & SPLIT_NONINTERACTIVE) == 0);
1052 }
1053 };
1054
1055
1056 ///////////////////////////////////////////////////////////////////////////////
1057 // CSplitterWindowImpl - Implements a splitter window
1058
1059 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
1060 class ATL_NO_VTABLE CSplitterWindowImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CSplitterImpl< T >
1061 {
1062 public:
1063 DECLARE_WND_CLASS_EX(NULL, CS_DBLCLKS, COLOR_WINDOW)
1064
1065 CSplitterWindowImpl(bool bVertical = true) : CSplitterImpl< T >(bVertical)
1066 { }
1067
1068 BOOL SubclassWindow(HWND hWnd)
1069 {
1070 #if (_MSC_VER >= 1300)
1071 BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits >::SubclassWindow(hWnd);
1072 #else // !(_MSC_VER >= 1300)
1073 typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass;
1074 BOOL bRet = _baseClass::SubclassWindow(hWnd);
1075 #endif // !(_MSC_VER >= 1300)
1076 if(bRet != FALSE)
1077 {
1078 T* pT = static_cast<T*>(this);
1079 pT->Init();
1080
1081 SetSplitterRect();
1082 }
1083
1084 return bRet;
1085 }
1086
1087 BEGIN_MSG_MAP(CSplitterWindowImpl)
1088 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
1089 MESSAGE_HANDLER(WM_SIZE, OnSize)
1090 CHAIN_MSG_MAP(CSplitterImpl< T >)
1091 FORWARD_NOTIFICATIONS()
1092 END_MSG_MAP()
1093
1094 LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1095 {
1096 // handled, no background painting needed
1097 return 1;
1098 }
1099
1100 LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
1101 {
1102 if(wParam != SIZE_MINIMIZED)
1103 SetSplitterRect();
1104
1105 bHandled = FALSE;
1106 return 1;
1107 }
1108 };
1109
1110
1111 ///////////////////////////////////////////////////////////////////////////////
1112 // CSplitterWindow/CHorSplitterWindow - Implements splitter windows to be used as is
1113
1114 template <bool t_bVertical = true>
1115 class CSplitterWindowT : public CSplitterWindowImpl<CSplitterWindowT<t_bVertical> >
1116 {
1117 public:
1118 DECLARE_WND_CLASS_EX(_T("WTL_SplitterWindow"), CS_DBLCLKS, COLOR_WINDOW)
1119
1120 CSplitterWindowT() : CSplitterWindowImpl<CSplitterWindowT<t_bVertical> >(t_bVertical)
1121 { }
1122 };
1123
1124 typedef CSplitterWindowT<true> CSplitterWindow;
1125 typedef CSplitterWindowT<false> CHorSplitterWindow;
1126
1127 }; // namespace WTL
1128
1129 #endif // __ATLSPLIT_H__
+0
-1257
src/third_party/wtl/Include/atltheme.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLTHEME_H__
9 #define __ATLTHEME_H__
10
11 #pragma once
12
13 #ifdef _WIN32_WCE
14 #error atltheme.h is not supported on Windows CE
15 #endif
16
17 #ifndef __ATLAPP_H__
18 #error atltheme.h requires atlapp.h to be included first
19 #endif
20
21 #ifndef __ATLWIN_H__
22 #error atltheme.h requires atlwin.h to be included first
23 #endif
24
25 #if (_WIN32_WINNT < 0x0501)
26 #error atltheme.h requires _WIN32_WINNT >= 0x0501
27 #endif // (_WIN32_WINNT < 0x0501)
28
29 #if defined(_WTL_USE_VSSYM32) || (defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN))
30 #include <vssym32.h>
31 #else
32 #ifndef TMSCHEMA_H
33 #include <tmschema.h>
34 #endif
35 #endif
36
37 #include <uxtheme.h>
38 #pragma comment(lib, "uxtheme.lib")
39
40 // Note: To create an application that also runs on older versions of Windows,
41 // use delay load of uxtheme.dll and ensure that no calls to the Theme API are
42 // made if theming is not supported. It is enough to check if m_hTheme is NULL.
43 // Example:
44 // if(m_hTheme != NULL)
45 // {
46 // DrawThemeBackground(dc, BP_PUSHBUTTON, PBS_NORMAL, &rect, NULL);
47 // DrawThemeText(dc, BP_PUSHBUTTON, PBS_NORMAL, L"Button", -1, DT_SINGLELINE | DT_CENTER | DT_VCENTER, 0, &rect);
48 // }
49 // else
50 // {
51 // dc.DrawFrameControl(&rect, DFC_BUTTON, DFCS_BUTTONPUSH);
52 // dc.DrawText(_T("Button"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
53 // }
54 //
55 // Delay load is NOT AUTOMATIC for VC++ 7, you have to link to delayimp.lib,
56 // and add uxtheme.dll in the Linker.Input.Delay Loaded DLLs section of the
57 // project properties.
58 #if (_MSC_VER < 1300) && !defined(_WTL_NO_THEME_DELAYLOAD)
59 #pragma comment(lib, "delayimp.lib")
60 #pragma comment(linker, "/delayload:uxtheme.dll")
61 #endif // (_MSC_VER < 1300) && !defined(_WTL_NO_THEME_DELAYLOAD)
62
63 // Hack: Signatures in uxtheme.h changed - the only way to check which variant of uxtheme.h
64 // is included is to check for presence of new defines MAX_THEMECOLOR and MAX_THEMESIZE
65 // Note: In WinSDK 7.0 (and higher) they are defined with #if (_WIN32_WINNT >= 0x0600),
66 // so you have to compile with _WTL_NEW_UXTHEME defined for _WIN32_WINNT < 0x0600
67 #ifndef _WTL_NEW_UXTHEME
68 #if defined(MAX_THEMECOLOR) && defined(MAX_THEMESIZE)
69 #define _WTL_NEW_UXTHEME
70 #endif // defined(MAX_THEMECOLOR) && defined(MAX_THEMESIZE)
71 #endif // _WTL_NEW_UXTHEME
72
73
74 ///////////////////////////////////////////////////////////////////////////////
75 // Classes in this file:
76 //
77 // CTheme
78 // CThemeImpl<T, TBase>
79 //
80 // CBufferedPaint
81 // CBufferedPaintImpl<T>
82 // CBufferedPaintWindowImpl<T, TBase, TWinTraits>
83 // CBufferedAnimation
84 // CBufferedAnimationImpl<T, TState>
85 // CBufferedAnimationWindowImpl<T, TState, TBase, TWinTraits>
86 //
87 // Global functions:
88 // AtlDrawThemeClientEdge()
89
90
91 namespace WTL
92 {
93
94 ///////////////////////////////////////////////////////////////////////////////
95 // CTheme - wrapper for theme handle
96
97 class CTheme
98 {
99 public:
100 // Data members
101 HTHEME m_hTheme;
102 static int m_nIsThemingSupported;
103
104 // Constructor
105 CTheme(HTHEME hTheme = NULL) : m_hTheme(hTheme)
106 {
107 IsThemingSupported();
108 }
109
110 // Operators and helpers
111 bool IsThemeNull() const
112 {
113 return (m_hTheme == NULL);
114 }
115
116 CTheme& operator =(HTHEME hTheme)
117 {
118 m_hTheme = hTheme;
119 return *this;
120 }
121
122 operator HTHEME() const
123 {
124 return m_hTheme;
125 }
126
127 void Attach(HTHEME hTheme)
128 {
129 m_hTheme = hTheme;
130 }
131
132 HTHEME Detach()
133 {
134 HTHEME hTheme = m_hTheme;
135 m_hTheme = NULL;
136 return hTheme;
137 }
138
139 // Theme support helper
140 static bool IsThemingSupported()
141 {
142 if(m_nIsThemingSupported == -1)
143 {
144 CStaticDataInitCriticalSectionLock lock;
145 if(FAILED(lock.Lock()))
146 {
147 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CTheme::IsThemingSupported.\n"));
148 ATLASSERT(FALSE);
149 return false;
150 }
151
152 if(m_nIsThemingSupported == -1)
153 {
154 HMODULE hThemeDLL = ::LoadLibrary(_T("uxtheme.dll"));
155 m_nIsThemingSupported = (hThemeDLL != NULL) ? 1 : 0;
156 if(hThemeDLL != NULL)
157 ::FreeLibrary(hThemeDLL);
158 }
159
160 lock.Unlock();
161 }
162
163 ATLASSERT(m_nIsThemingSupported != -1);
164 return (m_nIsThemingSupported == 1);
165 }
166
167 // Operations and theme properties
168 HTHEME OpenThemeData(HWND hWnd, LPCWSTR pszClassList)
169 {
170 if(!IsThemingSupported())
171 return NULL;
172
173 ATLASSERT(m_hTheme == NULL);
174 m_hTheme = ::OpenThemeData(hWnd, pszClassList);
175 return m_hTheme;
176 }
177
178 HRESULT CloseThemeData()
179 {
180 HRESULT hRet = S_FALSE;
181 if(m_hTheme != NULL)
182 {
183 hRet = ::CloseThemeData(m_hTheme);
184 if(SUCCEEDED(hRet))
185 m_hTheme = NULL;
186 }
187 return hRet;
188 }
189
190 HRESULT DrawThemeBackground(HDC hDC, int nPartID, int nStateID, LPCRECT pRect, LPCRECT pClipRect = NULL)
191 {
192 ATLASSERT(m_hTheme != NULL);
193 return ::DrawThemeBackground(m_hTheme, hDC, nPartID, nStateID, pRect, pClipRect);
194 }
195
196 // Missing in original uxtheme.h
197 #ifdef DTBG_CLIPRECT
198 HRESULT DrawThemeBackgroundEx(HDC hDC, int nPartID, int nStateID, LPCRECT pRect, const DTBGOPTS* pOptions = NULL)
199 {
200 ATLASSERT(m_hTheme != NULL);
201 return ::DrawThemeBackgroundEx(m_hTheme, hDC, nPartID, nStateID, pRect, pOptions);
202 }
203 #endif // DTBG_CLIPRECT
204
205 HRESULT DrawThemeText(HDC hDC, int nPartID, int nStateID, LPCWSTR pszText, int nCharCount, DWORD dwTextFlags, DWORD dwTextFlags2, LPCRECT pRect)
206 {
207 ATLASSERT(m_hTheme != NULL);
208 return ::DrawThemeText(m_hTheme, hDC, nPartID, nStateID, pszText, nCharCount, dwTextFlags, dwTextFlags2, pRect);
209 }
210
211 HRESULT GetThemeBackgroundContentRect(HDC hDC, int nPartID, int nStateID, LPCRECT pBoundingRect, LPRECT pContentRect) const
212 {
213 ATLASSERT(m_hTheme != NULL);
214 return ::GetThemeBackgroundContentRect(m_hTheme, hDC, nPartID, nStateID, pBoundingRect, pContentRect);
215 }
216
217 HRESULT GetThemeBackgroundExtent(HDC hDC, int nPartID, int nStateID, LPCRECT pContentRect, LPRECT pExtentRect) const
218 {
219 ATLASSERT(m_hTheme != NULL);
220 return ::GetThemeBackgroundExtent(m_hTheme, hDC, nPartID, nStateID, pContentRect, pExtentRect);
221 }
222
223 HRESULT GetThemePartSize(HDC hDC, int nPartID, int nStateID, LPCRECT pRect, enum THEMESIZE eSize, LPSIZE pSize) const
224 {
225 ATLASSERT(m_hTheme != NULL);
226 #ifdef _WTL_NEW_UXTHEME
227 return ::GetThemePartSize(m_hTheme, hDC, nPartID, nStateID, pRect, eSize, pSize);
228 #else // !_WTL_NEW_UXTHEME
229 // Note: The cast to LPRECT is because uxtheme.h incorrectly uses it instead of LPCRECT
230 return ::GetThemePartSize(m_hTheme, hDC, nPartID, nStateID, (LPRECT)pRect, eSize, pSize);
231 #endif // !_WTL_NEW_UXTHEME
232 }
233
234 HRESULT GetThemeTextExtent(HDC hDC, int nPartID, int nStateID, LPCWSTR pszText, int nCharCount, DWORD dwTextFlags, LPCRECT pBoundingRect, LPRECT pExtentRect) const
235 {
236 ATLASSERT(m_hTheme != NULL);
237 return ::GetThemeTextExtent(m_hTheme, hDC, nPartID, nStateID, pszText, nCharCount, dwTextFlags, pBoundingRect, pExtentRect);
238 }
239
240 HRESULT GetThemeTextMetrics(HDC hDC, int nPartID, int nStateID, PTEXTMETRICW pTextMetric) const
241 {
242 ATLASSERT(m_hTheme != NULL);
243 #ifdef _WTL_NEW_UXTHEME
244 return ::GetThemeTextMetrics(m_hTheme, hDC, nPartID, nStateID, pTextMetric);
245 #else // !_WTL_NEW_UXTHEME
246 // Note: The cast to PTEXTMETRIC is because uxtheme.h incorrectly uses it instead of PTEXTMETRICW
247 return ::GetThemeTextMetrics(m_hTheme, hDC, nPartID, nStateID, (PTEXTMETRIC)pTextMetric);
248 #endif // !_WTL_NEW_UXTHEME
249 }
250
251 HRESULT GetThemeBackgroundRegion(HDC hDC, int nPartID, int nStateID, LPCRECT pRect, HRGN* pRegion) const
252 {
253 ATLASSERT(m_hTheme != NULL);
254 return ::GetThemeBackgroundRegion(m_hTheme, hDC, nPartID, nStateID, pRect, pRegion);
255 }
256
257 HRESULT HitTestThemeBackground(HDC hDC, int nPartID, int nStateID, DWORD dwOptions, LPCRECT pRect, HRGN hrgn, POINT ptTest, WORD* pwHitTestCode) const
258 {
259 ATLASSERT(m_hTheme != NULL);
260 return ::HitTestThemeBackground(m_hTheme, hDC, nPartID, nStateID, dwOptions, pRect, hrgn, ptTest, pwHitTestCode);
261 }
262
263 HRESULT DrawThemeEdge(HDC hDC, int nPartID, int nStateID, LPCRECT pDestRect, UINT uEdge, UINT uFlags, LPRECT pContentRect = NULL)
264 {
265 ATLASSERT(m_hTheme != NULL);
266 return ::DrawThemeEdge(m_hTheme, hDC, nPartID, nStateID, pDestRect, uEdge, uFlags, pContentRect);
267 }
268
269 HRESULT DrawThemeIcon(HDC hDC, int nPartID, int nStateID, LPCRECT pRect, HIMAGELIST himl, int nImageIndex)
270 {
271 ATLASSERT(m_hTheme != NULL);
272 return ::DrawThemeIcon(m_hTheme, hDC, nPartID, nStateID, pRect, himl, nImageIndex);
273 }
274
275 BOOL IsThemePartDefined(int nPartID, int nStateID) const
276 {
277 ATLASSERT(m_hTheme != NULL);
278 return ::IsThemePartDefined(m_hTheme, nPartID, nStateID);
279 }
280
281 BOOL IsThemeBackgroundPartiallyTransparent(int nPartID, int nStateID) const
282 {
283 ATLASSERT(m_hTheme != NULL);
284 return ::IsThemeBackgroundPartiallyTransparent(m_hTheme, nPartID, nStateID);
285 }
286
287 HRESULT GetThemeColor(int nPartID, int nStateID, int nPropID, COLORREF* pColor) const
288 {
289 ATLASSERT(m_hTheme != NULL);
290 return ::GetThemeColor(m_hTheme, nPartID, nStateID, nPropID, pColor);
291 }
292
293 HRESULT GetThemeMetric(HDC hDC, int nPartID, int nStateID, int nPropID, int* pnVal) const
294 {
295 ATLASSERT(m_hTheme != NULL);
296 return ::GetThemeMetric(m_hTheme, hDC, nPartID, nStateID, nPropID, pnVal);
297 }
298
299 HRESULT GetThemeString(int nPartID, int nStateID, int nPropID, LPWSTR pszBuff, int cchMaxBuffChars) const
300 {
301 ATLASSERT(m_hTheme != NULL);
302 return ::GetThemeString(m_hTheme, nPartID, nStateID, nPropID, pszBuff, cchMaxBuffChars);
303 }
304
305 HRESULT GetThemeBool(int nPartID, int nStateID, int nPropID, BOOL* pfVal) const
306 {
307 ATLASSERT(m_hTheme != NULL);
308 return ::GetThemeBool(m_hTheme, nPartID, nStateID, nPropID, pfVal);
309 }
310
311 HRESULT GetThemeInt(int nPartID, int nStateID, int nPropID, int* pnVal) const
312 {
313 ATLASSERT(m_hTheme != NULL);
314 return ::GetThemeInt(m_hTheme, nPartID, nStateID, nPropID, pnVal);
315 }
316
317 HRESULT GetThemeEnumValue(int nPartID, int nStateID, int nPropID, int* pnVal) const
318 {
319 ATLASSERT(m_hTheme != NULL);
320 return ::GetThemeEnumValue(m_hTheme, nPartID, nStateID, nPropID, pnVal);
321 }
322
323 HRESULT GetThemePosition(int nPartID, int nStateID, int nPropID, LPPOINT pPoint) const
324 {
325 ATLASSERT(m_hTheme != NULL);
326 return ::GetThemePosition(m_hTheme, nPartID, nStateID, nPropID, pPoint);
327 }
328
329 // deprecated
330 HRESULT GetThemeFont(int nPartID, HDC hDC, int nStateID, int nPropID, LOGFONTW* pFont) const
331 {
332 ATLASSERT(m_hTheme != NULL);
333 #ifdef _WTL_NEW_UXTHEME
334 return ::GetThemeFont(m_hTheme, hDC, nPartID, nStateID, nPropID, pFont);
335 #else // !_WTL_NEW_UXTHEME
336 // Note: The cast to LOGFONT* is because uxtheme.h incorrectly uses it instead of LOGFONTW*
337 return ::GetThemeFont(m_hTheme, hDC, nPartID, nStateID, nPropID, (LOGFONT*)pFont);
338 #endif // !_WTL_NEW_UXTHEME
339 }
340
341 HRESULT GetThemeFont(HDC hDC, int nPartID, int nStateID, int nPropID, LOGFONTW* pFont) const
342 {
343 ATLASSERT(m_hTheme != NULL);
344 #ifdef _WTL_NEW_UXTHEME
345 return ::GetThemeFont(m_hTheme, hDC, nPartID, nStateID, nPropID, pFont);
346 #else // !_WTL_NEW_UXTHEME
347 // Note: The cast to LOGFONT* is because uxtheme.h incorrectly uses it instead of LOGFONTW*
348 return ::GetThemeFont(m_hTheme, hDC, nPartID, nStateID, nPropID, (LOGFONT*)pFont);
349 #endif // !_WTL_NEW_UXTHEME
350 }
351
352 HRESULT GetThemeRect(int nPartID, int nStateID, int nPropID, LPRECT pRect) const
353 {
354 ATLASSERT(m_hTheme != NULL);
355 return ::GetThemeRect(m_hTheme, nPartID, nStateID, nPropID, pRect);
356 }
357
358 HRESULT GetThemeMargins(HDC hDC, int nPartID, int nStateID, int nPropID, LPRECT pRect, PMARGINS pMargins) const
359 {
360 ATLASSERT(m_hTheme != NULL);
361 return ::GetThemeMargins(m_hTheme, hDC, nPartID, nStateID, nPropID, pRect, pMargins);
362 }
363
364 HRESULT GetThemeIntList(int nPartID, int nStateID, int nPropID, INTLIST* pIntList) const
365 {
366 ATLASSERT(m_hTheme != NULL);
367 return ::GetThemeIntList(m_hTheme, nPartID, nStateID, nPropID, pIntList);
368 }
369
370 HRESULT GetThemePropertyOrigin(int nPartID, int nStateID, int nPropID, enum PROPERTYORIGIN* pOrigin) const
371 {
372 ATLASSERT(m_hTheme != NULL);
373 return ::GetThemePropertyOrigin(m_hTheme, nPartID, nStateID, nPropID, pOrigin);
374 }
375
376 HRESULT GetThemeFilename(int nPartID, int nStateID, int nPropID, LPWSTR pszThemeFileName, int cchMaxBuffChars) const
377 {
378 ATLASSERT(m_hTheme != NULL);
379 return ::GetThemeFilename(m_hTheme, nPartID, nStateID, nPropID, pszThemeFileName, cchMaxBuffChars);
380 }
381
382 COLORREF GetThemeSysColor(int nColorID) const
383 {
384 ATLASSERT(m_hTheme != NULL);
385 return ::GetThemeSysColor(m_hTheme, nColorID);
386 }
387
388 HBRUSH GetThemeSysColorBrush(int nColorID) const
389 {
390 ATLASSERT(m_hTheme != NULL);
391 return ::GetThemeSysColorBrush(m_hTheme, nColorID);
392 }
393
394 int GetThemeSysSize(int nSizeID) const
395 {
396 ATLASSERT(m_hTheme != NULL);
397 return ::GetThemeSysSize(m_hTheme, nSizeID);
398 }
399
400 BOOL GetThemeSysBool(int nBoolID) const
401 {
402 ATLASSERT(m_hTheme != NULL);
403 return ::GetThemeSysBool(m_hTheme, nBoolID);
404 }
405
406 HRESULT GetThemeSysFont(int nFontID, LOGFONTW* plf) const
407 {
408 ATLASSERT(m_hTheme != NULL);
409 #ifdef _WTL_NEW_UXTHEME
410 return ::GetThemeSysFont(m_hTheme, nFontID, plf);
411 #else // !_WTL_NEW_UXTHEME
412 // Note: The cast to LOGFONT* is because uxtheme.h incorrectly uses it instead of LOGFONTW*
413 return ::GetThemeSysFont(m_hTheme, nFontID, (LOGFONT*)plf);
414 #endif // !_WTL_NEW_UXTHEME
415 }
416
417 HRESULT GetThemeSysString(int nStringID, LPWSTR pszStringBuff, int cchMaxStringChars) const
418 {
419 ATLASSERT(m_hTheme != NULL);
420 return ::GetThemeSysString(m_hTheme, nStringID, pszStringBuff, cchMaxStringChars);
421 }
422
423 HRESULT GetThemeSysInt(int nIntID, int* pnValue) const
424 {
425 ATLASSERT(m_hTheme != NULL);
426 return ::GetThemeSysInt(m_hTheme, nIntID, pnValue);
427 }
428
429 #ifdef _WTL_NEW_UXTHEME
430 HTHEME OpenThemeDataEx(HWND hWnd, LPCWSTR pszClassList, DWORD dwFlags)
431 {
432 if(!IsThemingSupported())
433 return NULL;
434
435 ATLASSERT(m_hTheme == NULL);
436 m_hTheme = ::OpenThemeDataEx(hWnd, pszClassList, dwFlags);
437 return m_hTheme;
438 }
439
440 #if (_WIN32_WINNT >= 0x0600)
441 HRESULT DrawThemeTextEx(HDC hDC, int nPartID, int nStateID, LPCWSTR pszText, int cchText, DWORD dwTextFlags, LPRECT lpRect, const DTTOPTS* pOptions)
442 {
443 ATLASSERT(m_hTheme != NULL);
444 return ::DrawThemeTextEx(m_hTheme, hDC, nPartID, nStateID, pszText, cchText, dwTextFlags, lpRect, pOptions);
445 }
446
447 HRESULT GetThemeTransitionDuration(int nPartID, int nFromStateID, int nToStateID, int nPropID, DWORD& dwDuration)
448 {
449 ATLASSERT(m_hTheme != NULL);
450 return ::GetThemeTransitionDuration(m_hTheme, nPartID, nFromStateID, nToStateID, nPropID, &dwDuration);
451 }
452 #endif // (_WIN32_WINNT >= 0x0600)
453 #endif // _WTL_NEW_UXTHEME
454
455 #if (_WIN32_WINNT >= 0x0600)
456 HRESULT GetThemeBitmap(int nPartID, int nStateID, int nPropID, ULONG uFlags, HBITMAP& hBitmap)
457 {
458 ATLASSERT(m_hTheme != NULL);
459 return ::GetThemeBitmap(m_hTheme, nPartID, nStateID, nPropID, uFlags, &hBitmap);
460 }
461
462 HRESULT GetThemeStream(int nPartID, int nStateID, int nPropID, VOID** ppvStream, DWORD* pcbStream, HINSTANCE hInstance)
463 {
464 ATLASSERT(m_hTheme != NULL);
465 return ::GetThemeStream(m_hTheme, nPartID, nStateID, nPropID, ppvStream, pcbStream, hInstance);
466 }
467 #endif // (_WIN32_WINNT >= 0x0600)
468
469 #if (_WIN32_WINNT >= 0x0602)
470 HRESULT GetThemeAnimationProperty(int iStoryboardId, int iTargetId, TA_PROPERTY eProperty, VOID* pvProperty, DWORD cbSize, DWORD* pcbSizeOut)
471 {
472 ATLASSERT(m_hTheme != NULL);
473 return ::GetThemeAnimationProperty(m_hTheme, iStoryboardId, iTargetId, eProperty, pvProperty, cbSize, pcbSizeOut);
474 }
475
476 HRESULT GetThemeAnimationTransform(int iStoryboardId, int iTargetId, DWORD dwTransformIndex, TA_TRANSFORM* pTransform, DWORD cbSize, DWORD* pcbSizeOut)
477 {
478 ATLASSERT(m_hTheme != NULL);
479 return ::GetThemeAnimationTransform(m_hTheme, iStoryboardId, iTargetId, dwTransformIndex, pTransform, cbSize, pcbSizeOut);
480 }
481
482 HRESULT GetThemeTimingFunction(int iTimingFunctionId, TA_TIMINGFUNCTION* pTimingFunction, DWORD cbSize, DWORD* pcbSizeOut)
483 {
484 ATLASSERT(m_hTheme != NULL);
485 return ::GetThemeTimingFunction(m_hTheme, iTimingFunctionId, pTimingFunction, cbSize, pcbSizeOut);
486 }
487 #endif // (_WIN32_WINNT >= 0x0602)
488 };
489
490 __declspec(selectany) int CTheme::m_nIsThemingSupported = -1;
491
492
493 ///////////////////////////////////////////////////////////////////////////////
494 // CThemeImpl - theme support implementation
495
496 // Derive from this class to implement window with theme support.
497 // Example:
498 // class CMyThemeWindow : public CWindowImpl<CMyThemeWindow>, public CThemeImpl<CMyThemeWindow>
499 // {
500 // ...
501 // BEGIN_MSG_MAP(CMyThemeWindow)
502 // CHAIN_MSG_MAP(CThemeImpl<CMyThemeWindow>)
503 // ...
504 // END_MSG_MAP()
505 // ...
506 // };
507 //
508 // If you set theme class list, the class will automaticaly open/close/reopen theme data.
509
510
511 // Helper for drawing theme client edge
512 inline bool AtlDrawThemeClientEdge(HTHEME hTheme, HWND hWnd, HRGN hRgnUpdate = NULL, HBRUSH hBrush = NULL, int nPartID = 0, int nStateID = 0)
513 {
514 ATLASSERT(hTheme != NULL);
515 ATLASSERT(::IsWindow(hWnd));
516
517 CWindowDC dc(hWnd);
518 if(dc.IsNull())
519 return false;
520
521 // Get border size
522 int cxBorder = ::GetSystemMetrics(SM_CXBORDER);
523 int cyBorder = ::GetSystemMetrics(SM_CYBORDER);
524 if(SUCCEEDED(::GetThemeInt(hTheme, nPartID, nStateID, TMT_SIZINGBORDERWIDTH, &cxBorder)))
525 cyBorder = cxBorder;
526
527 RECT rect = { 0 };
528 ::GetWindowRect(hWnd, &rect);
529
530 // Remove the client edge from the update region
531 int cxEdge = ::GetSystemMetrics(SM_CXEDGE);
532 int cyEdge = ::GetSystemMetrics(SM_CYEDGE);
533 ::InflateRect(&rect, -cxEdge, -cyEdge);
534 CRgn rgn;
535 rgn.CreateRectRgnIndirect(&rect);
536 if(rgn.IsNull())
537 return false;
538
539 if(hRgnUpdate != NULL)
540 rgn.CombineRgn(hRgnUpdate, rgn, RGN_AND);
541
542 ::OffsetRect(&rect, -rect.left, -rect.top);
543
544 ::OffsetRect(&rect, cxEdge, cyEdge);
545 dc.ExcludeClipRect(&rect);
546 ::InflateRect(&rect, cxEdge, cyEdge);
547
548 ::DrawThemeBackground(hTheme, dc, nPartID, nStateID, &rect, NULL);
549
550 // Use background brush too, since theme border might not cover everything
551 if((cxBorder < cxEdge) && (cyBorder < cyEdge))
552 {
553 if(hBrush == NULL)
554 // need conditional code because types don't match in winuser.h
555 #ifdef _WIN64
556 hBrush = (HBRUSH)::GetClassLongPtr(hWnd, GCLP_HBRBACKGROUND);
557 #else
558 hBrush = (HBRUSH)UlongToPtr(::GetClassLongPtr(hWnd, GCLP_HBRBACKGROUND));
559 #endif
560
561 ::InflateRect(&rect, cxBorder - cxEdge, cyBorder - cyEdge);
562 dc.FillRect(&rect, hBrush);
563 }
564
565 ::DefWindowProc(hWnd, WM_NCPAINT, (WPARAM)rgn.m_hRgn, 0L);
566
567 return true;
568 }
569
570
571 // Theme extended styles
572 #define THEME_EX_3DCLIENTEDGE 0x00000001
573 #define THEME_EX_THEMECLIENTEDGE 0x00000002
574
575 template <class T, class TBase = CTheme>
576 class CThemeImpl : public TBase
577 {
578 public:
579 // Data members
580 LPWSTR m_lpstrThemeClassList;
581 DWORD m_dwExtendedStyle; // theme specific extended styles
582
583 // Constructor & destructor
584 CThemeImpl() : m_lpstrThemeClassList(NULL), m_dwExtendedStyle(0)
585 { }
586
587 ~CThemeImpl()
588 {
589 delete [] m_lpstrThemeClassList;
590 }
591
592 // Attributes
593 bool SetThemeClassList(LPCWSTR lpstrThemeClassList)
594 {
595 if(m_lpstrThemeClassList != NULL)
596 {
597 delete [] m_lpstrThemeClassList;
598 m_lpstrThemeClassList = NULL;
599 }
600
601 if(lpstrThemeClassList == NULL)
602 return true;
603
604 int cchLen = lstrlenW(lpstrThemeClassList) + 1;
605 ATLTRY(m_lpstrThemeClassList = new WCHAR[cchLen]);
606 if(m_lpstrThemeClassList == NULL)
607 return false;
608
609 SecureHelper::strcpyW_x(m_lpstrThemeClassList, cchLen, lpstrThemeClassList);
610
611 return true;
612 }
613
614 bool GetThemeClassList(LPWSTR lpstrThemeClassList, int cchListBuffer) const
615 {
616 int cchLen = lstrlenW(m_lpstrThemeClassList) + 1;
617 if(cchListBuffer < cchLen)
618 return false;
619
620 SecureHelper::strcpyW_x(lpstrThemeClassList, cchListBuffer, m_lpstrThemeClassList);
621
622 return true;
623 }
624
625 LPCWSTR GetThemeClassList() const
626 {
627 return m_lpstrThemeClassList;
628 }
629
630 DWORD SetThemeExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
631 {
632 DWORD dwPrevStyle = m_dwExtendedStyle;
633 if(dwMask == 0)
634 m_dwExtendedStyle = dwExtendedStyle;
635 else
636 m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
637
638 return dwPrevStyle;
639 }
640
641 DWORD GetThemeExtendedStyle() const
642 {
643 return m_dwExtendedStyle;
644 }
645
646 // Operations
647 HTHEME OpenThemeData()
648 {
649 T* pT = static_cast<T*>(this);
650 ATLASSERT(::IsWindow(pT->m_hWnd));
651 ATLASSERT(m_lpstrThemeClassList != NULL);
652 if(m_lpstrThemeClassList == NULL)
653 return NULL;
654 CloseThemeData();
655
656 return TBase::OpenThemeData(pT->m_hWnd, m_lpstrThemeClassList);
657 }
658
659 HTHEME OpenThemeData(LPCWSTR pszClassList)
660 {
661 if(!SetThemeClassList(pszClassList))
662 return NULL;
663
664 return OpenThemeData();
665 }
666
667 HRESULT SetWindowTheme(LPCWSTR pszSubAppName, LPCWSTR pszSubIDList)
668 {
669 if(!IsThemingSupported())
670 return S_FALSE;
671
672 T* pT = static_cast<T*>(this);
673 ATLASSERT(::IsWindow(pT->m_hWnd));
674 return ::SetWindowTheme(pT->m_hWnd, pszSubAppName, pszSubIDList);
675 }
676
677 HTHEME GetWindowTheme() const
678 {
679 if(!IsThemingSupported())
680 return NULL;
681
682 const T* pT = static_cast<const T*>(this);
683 ATLASSERT(::IsWindow(pT->m_hWnd));
684 return ::GetWindowTheme(pT->m_hWnd);
685 }
686
687 HRESULT EnableThemeDialogTexture(DWORD dwFlags)
688 {
689 if(!IsThemingSupported())
690 return S_FALSE;
691
692 T* pT = static_cast<T*>(this);
693 ATLASSERT(::IsWindow(pT->m_hWnd));
694 return ::EnableThemeDialogTexture(pT->m_hWnd, dwFlags);
695 }
696
697 BOOL IsThemeDialogTextureEnabled() const
698 {
699 if(!IsThemingSupported())
700 return FALSE;
701
702 const T* pT = static_cast<const T*>(this);
703 ATLASSERT(::IsWindow(pT->m_hWnd));
704 return ::IsThemeDialogTextureEnabled(pT->m_hWnd);
705 }
706
707 HRESULT DrawThemeParentBackground(HDC hDC, const RECT* pRect = NULL)
708 {
709 if(!IsThemingSupported())
710 return S_FALSE;
711
712 T* pT = static_cast<T*>(this);
713 ATLASSERT(::IsWindow(pT->m_hWnd));
714 #ifdef _WTL_NEW_UXTHEME
715 return ::DrawThemeParentBackground(pT->m_hWnd, hDC, pRect);
716 #else
717 return ::DrawThemeParentBackground(pT->m_hWnd, hDC, (RECT*)pRect);
718 #endif
719 }
720
721 #if defined(_WTL_NEW_UXTHEME) && (_WIN32_WINNT >= 0x0600)
722 HRESULT SetWindowThemeAttribute(WINDOWTHEMEATTRIBUTETYPE type, PVOID pvAttribute, DWORD cbAttribute)
723 {
724 if(!IsThemingSupported())
725 return S_FALSE;
726
727 T* pT = static_cast<T*>(this);
728 ATLASSERT(::IsWindow(pT->m_hWnd));
729 return ::SetWindowThemeAttribute(pT->m_hWnd, type, pvAttribute, cbAttribute);
730 }
731
732 HRESULT SetWindowThemeNonClientAttributes(DWORD dwAttributes, DWORD dwMask)
733 {
734 if(!IsThemingSupported())
735 return S_FALSE;
736
737 T* pT = static_cast<T*>(this);
738 ATLASSERT(::IsWindow(pT->m_hWnd));
739 WTA_OPTIONS opt = { dwAttributes, dwMask };
740 return ::SetWindowThemeAttribute(pT->m_hWnd, WTA_NONCLIENT, (PVOID)&opt, sizeof(opt));
741 }
742
743 HRESULT DrawThemeParentBackgroundEx(HDC hDC, DWORD dwFlags, const RECT* lpRect = NULL)
744 {
745 if(!IsThemingSupported())
746 return S_FALSE;
747
748 T* pT = static_cast<T*>(this);
749 ATLASSERT(::IsWindow(pT->m_hWnd));
750 return ::DrawThemeParentBackgroundEx(pT->m_hWnd, hDC, dwFlags, lpRect);
751 }
752 #endif // defined(_WTL_NEW_UXTHEME) && (_WIN32_WINNT >= 0x0600)
753
754 // Message map and handlers
755 // Note: If you handle any of these messages in your derived class,
756 // it is better to put CHAIN_MSG_MAP at the start of your message map.
757 BEGIN_MSG_MAP(CThemeImpl)
758 MESSAGE_HANDLER(WM_CREATE, OnCreate)
759 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
760 MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged)
761 MESSAGE_HANDLER(WM_NCPAINT, OnNcPaint)
762 END_MSG_MAP()
763
764 LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
765 {
766 if(m_lpstrThemeClassList != NULL)
767 OpenThemeData();
768
769 bHandled = FALSE;
770 return 1;
771 }
772
773 LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
774 {
775 CloseThemeData();
776
777 bHandled = FALSE;
778 return 1;
779 }
780
781 LRESULT OnThemeChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
782 {
783 CloseThemeData();
784 if(m_lpstrThemeClassList != NULL)
785 OpenThemeData();
786
787 bHandled = FALSE;
788 return 1;
789 }
790
791 LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
792 {
793 T* pT = static_cast<T*>(this);
794 ATLASSERT(::IsWindow(pT->m_hWnd));
795 LRESULT lRet = 0;
796 bHandled = FALSE;
797 if(IsThemingSupported() && ((pT->GetExStyle() & WS_EX_CLIENTEDGE) != 0))
798 {
799 if((m_dwExtendedStyle & THEME_EX_3DCLIENTEDGE) != 0)
800 {
801 lRet = ::DefWindowProc(pT->m_hWnd, uMsg, wParam, lParam);
802 bHandled = TRUE;
803 }
804 else if((m_hTheme != NULL) && ((m_dwExtendedStyle & THEME_EX_THEMECLIENTEDGE) != 0))
805 {
806 HRGN hRgn = (wParam != 1) ? (HRGN)wParam : NULL;
807 if(pT->DrawThemeClientEdge(hRgn))
808 bHandled = TRUE;
809 }
810 }
811
812 return lRet;
813 }
814
815 // Drawing helper
816 bool DrawThemeClientEdge(HRGN hRgnUpdate)
817 {
818 T* pT = static_cast<T*>(this);
819 return AtlDrawThemeClientEdge(m_hTheme, pT->m_hWnd, hRgnUpdate, NULL, 0, 0);
820 }
821 };
822
823 ///////////////////////////////////////////////////////////////////////////////
824 // Buffered Paint and Animation
825
826 #if defined(_WTL_NEW_UXTHEME) && (_WIN32_WINNT >= 0x0600)
827
828 ///////////////////////////////////////////////////////////////////////////////
829 // CBufferedPaintBase - Buffered Paint support for othe classes
830
831 class CBufferedPaintBase
832 {
833 public:
834 static int m_nIsBufferedPaintSupported;
835
836 CBufferedPaintBase()
837 {
838 if(IsBufferedPaintSupported())
839 ATLVERIFY(SUCCEEDED(::BufferedPaintInit()));
840 }
841
842 ~CBufferedPaintBase()
843 {
844 if(IsBufferedPaintSupported())
845 ATLVERIFY(SUCCEEDED(::BufferedPaintUnInit()));
846 }
847
848 static bool IsBufferedPaintSupported()
849 {
850 if(m_nIsBufferedPaintSupported == -1)
851 {
852 CStaticDataInitCriticalSectionLock lock;
853 if(FAILED(lock.Lock()))
854 {
855 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CBufferedPaintBase::IsBufferedPaintSupported.\n"));
856 ATLASSERT(FALSE);
857 return false;
858 }
859
860 if(m_nIsBufferedPaintSupported == -1)
861 m_nIsBufferedPaintSupported = RunTimeHelper::IsVista() ? 1 : 0;
862
863 lock.Unlock();
864 }
865
866 ATLASSERT(m_nIsBufferedPaintSupported != -1);
867 return (m_nIsBufferedPaintSupported == 1);
868 }
869 };
870
871 __declspec(selectany) int CBufferedPaintBase::m_nIsBufferedPaintSupported = -1;
872
873
874 ///////////////////////////////////////////////////////////////////////////////
875 // CBufferedPaint - support for buffered paint functions
876
877 class CBufferedPaint
878 {
879 public:
880 HPAINTBUFFER m_hPaintBuffer;
881
882 CBufferedPaint() : m_hPaintBuffer(NULL)
883 { }
884
885 ~CBufferedPaint()
886 {
887 ATLVERIFY(SUCCEEDED(End()));
888 }
889
890 bool IsNull() const
891 {
892 return (m_hPaintBuffer == NULL);
893 }
894
895 HPAINTBUFFER Begin(HDC hdcTarget, const RECT* prcTarget, BP_BUFFERFORMAT dwFormat, BP_PAINTPARAMS* pPaintParams, HDC* phdcPaint)
896 {
897 ATLASSERT(m_hPaintBuffer == NULL);
898 m_hPaintBuffer = ::BeginBufferedPaint(hdcTarget, prcTarget, dwFormat, pPaintParams, phdcPaint);
899 return m_hPaintBuffer;
900 }
901
902 HRESULT End(BOOL bUpdate = TRUE)
903 {
904 HRESULT hRet = S_FALSE;
905 if(m_hPaintBuffer != NULL)
906 {
907 hRet = ::EndBufferedPaint(m_hPaintBuffer, bUpdate);
908 m_hPaintBuffer = NULL;
909 }
910 return hRet;
911 }
912
913 HRESULT GetTargetRect(LPRECT pRect) const
914 {
915 ATLASSERT(m_hPaintBuffer != NULL);
916 return ::GetBufferedPaintTargetRect(m_hPaintBuffer, pRect);
917 }
918
919 HDC GetTargetDC() const
920 {
921 ATLASSERT(m_hPaintBuffer != NULL);
922 return ::GetBufferedPaintTargetDC(m_hPaintBuffer);
923 }
924
925 HDC GetPaintDC() const
926 {
927 ATLASSERT(m_hPaintBuffer != NULL);
928 return ::GetBufferedPaintDC(m_hPaintBuffer);
929 }
930
931 HRESULT GetBits(RGBQUAD** ppbBuffer, int* pcxRow) const
932 {
933 ATLASSERT(m_hPaintBuffer != NULL);
934 return ::GetBufferedPaintBits(m_hPaintBuffer, ppbBuffer, pcxRow);
935 }
936
937 HRESULT Clear(const RECT* pRect = NULL)
938 {
939 ATLASSERT(m_hPaintBuffer != NULL);
940 return ::BufferedPaintClear(m_hPaintBuffer, pRect);
941 }
942
943 HRESULT SetAlpha(BYTE alpha, const RECT* pRect = NULL)
944 {
945 ATLASSERT(m_hPaintBuffer != NULL);
946 return ::BufferedPaintSetAlpha(m_hPaintBuffer, pRect, alpha);
947 }
948
949 HRESULT MakeOpaque(const RECT* pRect = NULL)
950 {
951 ATLASSERT(m_hPaintBuffer != NULL);
952 return ::BufferedPaintSetAlpha(m_hPaintBuffer, pRect, 255);
953 }
954 };
955
956
957 ///////////////////////////////////////////////////////////////////////////////
958 // CBufferedPaintImpl - provides buffered paint for any window
959
960 template <class T>
961 class ATL_NO_VTABLE CBufferedPaintImpl : public CBufferedPaintBase
962 {
963 public:
964 CBufferedPaint m_BufferedPaint;
965 BP_BUFFERFORMAT m_dwFormat;
966 BP_PAINTPARAMS m_PaintParams;
967
968 CBufferedPaintImpl() : m_dwFormat(BPBF_TOPDOWNDIB)
969 {
970 memset(&m_PaintParams, 0, sizeof(BP_PAINTPARAMS));
971 m_PaintParams.cbSize = sizeof(BP_PAINTPARAMS);
972 }
973
974 // Message map and handlers
975 BEGIN_MSG_MAP(CBufferedPaintImpl)
976 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
977 MESSAGE_HANDLER(WM_PAINT, OnPaint)
978 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
979 END_MSG_MAP()
980
981 LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
982 {
983 return 1; // no background needed
984 }
985
986 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
987 {
988 T* pT = static_cast<T*>(this);
989 if(wParam != NULL)
990 {
991 RECT rect = { 0 };
992 pT->GetClientRect(&rect);
993 pT->DoPaint((HDC)wParam, rect);
994 }
995 else
996 {
997 CPaintDC dc(pT->m_hWnd);
998 pT->DoBufferedPaint(dc.m_hDC, dc.m_ps.rcPaint);
999 }
1000
1001 return 0;
1002 }
1003
1004 // Overrideables
1005 void DoBufferedPaint(CDCHandle dc, RECT& rect)
1006 {
1007 HDC hDCPaint = NULL;
1008 if(IsBufferedPaintSupported())
1009 m_BufferedPaint.Begin(dc, &rect, m_dwFormat, &m_PaintParams, &hDCPaint);
1010
1011 T* pT = static_cast<T*>(this);
1012 if(hDCPaint != NULL)
1013 pT->DoPaint(hDCPaint, rect);
1014 else
1015 pT->DoPaint(dc.m_hDC, rect);
1016
1017 if(IsBufferedPaintSupported())
1018 m_BufferedPaint.End();
1019 }
1020
1021 void DoPaint(CDCHandle /*dc*/, RECT& /*rect*/)
1022 {
1023 // must be implemented in a derived class
1024 ATLASSERT(FALSE);
1025 }
1026 };
1027
1028
1029 ///////////////////////////////////////////////////////////////////////////////
1030 // CBufferedPaintWindowImpl - implements a window that uses buffered paint
1031
1032 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
1033 class ATL_NO_VTABLE CBufferedPaintWindowImpl :
1034 public ATL::CWindowImpl<T, TBase, TWinTraits>,
1035 public CBufferedPaintImpl< T >
1036 {
1037 public:
1038 BEGIN_MSG_MAP(CBufferedPaintWindowImpl)
1039 CHAIN_MSG_MAP(CBufferedPaintImpl< T >)
1040 END_MSG_MAP()
1041 };
1042
1043
1044 ///////////////////////////////////////////////////////////////////////////////
1045 // CBufferedAnimation - support for buffered animation
1046
1047 class CBufferedAnimation
1048 {
1049 public:
1050 HANIMATIONBUFFER m_hAnimationBuffer;
1051
1052 CBufferedAnimation() : m_hAnimationBuffer(NULL)
1053 { }
1054
1055 ~CBufferedAnimation()
1056 {
1057 ATLVERIFY(SUCCEEDED(End()));
1058 }
1059
1060 bool IsNull() const
1061 {
1062 return (m_hAnimationBuffer == NULL);
1063 }
1064
1065 HANIMATIONBUFFER Begin(HWND hWnd, HDC hDCTarget, const RECT* pRectTarget, BP_BUFFERFORMAT dwFormat, BP_PAINTPARAMS* pPaintParams, BP_ANIMATIONPARAMS* pAnimationParams, HDC* phdcFrom, HDC* phdcTo)
1066 {
1067 ATLASSERT(m_hAnimationBuffer == NULL);
1068 m_hAnimationBuffer = ::BeginBufferedAnimation(hWnd, hDCTarget, pRectTarget, dwFormat, pPaintParams, pAnimationParams, phdcFrom, phdcTo);
1069 return m_hAnimationBuffer;
1070 }
1071
1072 HRESULT End(BOOL bUpdate = TRUE)
1073 {
1074 HRESULT hRet = S_FALSE;
1075 if(m_hAnimationBuffer != NULL)
1076 {
1077 hRet = ::EndBufferedAnimation(m_hAnimationBuffer, bUpdate);
1078 m_hAnimationBuffer = NULL;
1079 }
1080 return hRet;
1081 }
1082
1083 static bool IsRendering(HWND hWnd, HDC hDC)
1084 {
1085 return (::BufferedPaintRenderAnimation(hWnd, hDC) != FALSE);
1086 }
1087
1088 static HRESULT StopAllAnimations(HWND hWnd)
1089 {
1090 return ::BufferedPaintStopAllAnimations(hWnd);
1091 }
1092 };
1093
1094
1095 ///////////////////////////////////////////////////////////////////////////////
1096 // CBufferedAnimationImpl - provides buffered animation support for any window
1097
1098 // Note: You can either use m_State and m_NewState to store the state information
1099 // for the animation change, or map your state to those data members. DoPaint()
1100 // should only rely on the state information that is passed to it.
1101
1102 template <class T, class TState = DWORD_PTR>
1103 class ATL_NO_VTABLE CBufferedAnimationImpl : public CBufferedPaintBase
1104 {
1105 public:
1106 BP_BUFFERFORMAT m_dwFormat;
1107 BP_PAINTPARAMS m_PaintParams;
1108 BP_ANIMATIONPARAMS m_AnimationParams;
1109
1110 TState m_State;
1111 TState m_NewState;
1112
1113 CBufferedAnimationImpl(TState InitialState) : m_dwFormat(BPBF_TOPDOWNDIB)
1114 {
1115 memset(&m_PaintParams, 0, sizeof(BP_PAINTPARAMS));
1116 m_PaintParams.cbSize = sizeof(BP_PAINTPARAMS);
1117
1118 memset(&m_AnimationParams, 0, sizeof(BP_ANIMATIONPARAMS));
1119 m_AnimationParams.cbSize = sizeof(BP_ANIMATIONPARAMS);
1120 m_AnimationParams.style = BPAS_LINEAR;
1121 m_AnimationParams.dwDuration = 500;
1122
1123 T* pT = static_cast<T*>(this);
1124 pT->SetState(InitialState);
1125 pT->SetNewState(InitialState);
1126 }
1127
1128 DWORD GetDuration() const
1129 {
1130 return m_AnimationParams.dwDuration;
1131 }
1132
1133 void SetDuration(DWORD dwDuration)
1134 {
1135 m_AnimationParams.dwDuration = dwDuration;
1136 }
1137
1138 void DoAnimation(TState NewState, const RECT* pRect = NULL)
1139 {
1140 T* pT = static_cast<T*>(this);
1141 pT->SetNewState(NewState);
1142
1143 pT->InvalidateRect(pRect, FALSE);
1144 pT->UpdateWindow();
1145
1146 pT->SetState(NewState);
1147 }
1148
1149 // Message map and handlers
1150 BEGIN_MSG_MAP(CBufferedAnimationImpl)
1151 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
1152 MESSAGE_HANDLER(WM_PAINT, OnPaint)
1153 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
1154 END_MSG_MAP()
1155
1156 LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1157 {
1158 return 1; // no background needed
1159 }
1160
1161 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1162 {
1163 T* pT = static_cast<T*>(this);
1164 if(wParam != NULL)
1165 {
1166 RECT rect = { 0 };
1167 pT->GetClientRect(&rect);
1168 pT->DoPaint((HDC)wParam, rect, m_NewState);
1169 }
1170 else
1171 {
1172 CPaintDC dc(pT->m_hWnd);
1173 pT->DoAnimationPaint(dc.m_hDC, dc.m_ps.rcPaint);
1174 }
1175
1176 return 0;
1177 }
1178
1179 // Overrideables
1180 void SetState(TState State)
1181 {
1182 m_State = State;
1183 }
1184
1185 void SetNewState(TState State)
1186 {
1187 m_NewState = State;
1188 }
1189
1190 bool AreStatesEqual() const
1191 {
1192 return (m_State == m_NewState);
1193 }
1194
1195 void DoAnimationPaint(CDCHandle dc, RECT& rect)
1196 {
1197 T* pT = static_cast<T*>(this);
1198 if(IsBufferedPaintSupported() && CBufferedAnimation::IsRendering(pT->m_hWnd, dc))
1199 return;
1200
1201 DWORD dwDurationSave = m_AnimationParams.dwDuration;
1202 if(pT->AreStatesEqual())
1203 m_AnimationParams.dwDuration = 0;
1204
1205 HDC hdcFrom = NULL, hdcTo = NULL;
1206 CBufferedAnimation ba;
1207 if(IsBufferedPaintSupported())
1208 ba.Begin(pT->m_hWnd, dc, &rect, m_dwFormat, &m_PaintParams, &m_AnimationParams, &hdcFrom, &hdcTo);
1209
1210 if(!ba.IsNull())
1211 {
1212 if(hdcFrom != NULL)
1213 pT->DoPaint(hdcFrom, rect, m_State);
1214
1215 if (hdcTo != NULL)
1216 pT->DoPaint(hdcTo, rect, m_NewState);
1217 }
1218 else
1219 {
1220 pT->DoPaint(dc.m_hDC, rect, m_NewState);
1221 }
1222
1223 m_AnimationParams.dwDuration = dwDurationSave;
1224 }
1225
1226 void DoPaint(CDCHandle /*dc*/, RECT& /*rect*/, TState /*State*/)
1227 {
1228 // must be implemented in a derived class
1229 ATLASSERT(FALSE);
1230 }
1231 };
1232
1233
1234 ///////////////////////////////////////////////////////////////////////////////
1235 // CBufferedAnimationWindowImpl - implements a window that uses buffered animation
1236
1237 template <class T, class TState = DWORD_PTR, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
1238 class ATL_NO_VTABLE CBufferedAnimationWindowImpl :
1239 public ATL::CWindowImpl<T, TBase, TWinTraits>,
1240 public CBufferedAnimationImpl< T, TState >
1241 {
1242 public:
1243 CBufferedAnimationWindowImpl(TState InitialState) : CBufferedAnimationImpl< T, TState >(InitialState)
1244 { }
1245
1246 typedef CBufferedAnimationImpl< T, TState > _baseBufferedAnimation;
1247 BEGIN_MSG_MAP(CBufferedAnimationWindowImpl)
1248 CHAIN_MSG_MAP(_baseBufferedAnimation)
1249 END_MSG_MAP()
1250 };
1251
1252 #endif // defined(_WTL_NEW_UXTHEME) && (_WIN32_WINNT >= 0x0600)
1253
1254 }; // namespace WTL
1255
1256 #endif // __ATLTHEME_H__
+0
-1387
src/third_party/wtl/Include/atluser.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLUSER_H__
9 #define __ATLUSER_H__
10
11 #pragma once
12
13 #ifndef __ATLAPP_H__
14 #error atluser.h requires atlapp.h to be included first
15 #endif
16
17
18 ///////////////////////////////////////////////////////////////////////////////
19 // Classes in this file:
20 //
21 // CMenuItemInfo
22 // CMenuT<t_bManaged>
23 // CAcceleratorT<t_bManaged>
24 // CIconT<t_bManaged>
25 // CCursorT<t_bManaged>
26 // CResource
27 //
28 // Global functions:
29 // AtlMessageBox()
30 //
31 // AtlLoadAccelerators()
32 // AtlLoadMenu()
33 // AtlLoadBitmap()
34 // AtlLoadSysBitmap()
35 // AtlLoadCursor()
36 // AtlLoadSysCursor()
37 // AtlLoadIcon()
38 // AtlLoadSysIcon()
39 // AtlLoadBitmapImage()
40 // AtlLoadCursorImage()
41 // AtlLoadIconImage()
42 // AtlLoadSysBitmapImage()
43 // AtlLoadSysCursorImage()
44 // AtlLoadSysIconImage()
45 // AtlLoadString()
46
47
48 namespace WTL
49 {
50
51 ///////////////////////////////////////////////////////////////////////////////
52 // AtlMessageBox - accepts both memory and resource based strings
53
54 inline int AtlMessageBox(HWND hWndOwner, ATL::_U_STRINGorID message, ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uType = MB_OK | MB_ICONINFORMATION)
55 {
56 ATLASSERT(hWndOwner == NULL || ::IsWindow(hWndOwner));
57
58 LPTSTR lpstrMessage = NULL;
59 if(IS_INTRESOURCE(message.m_lpstr))
60 {
61 for(int nLen = 256; ; nLen *= 2)
62 {
63 ATLTRY(lpstrMessage = new TCHAR[nLen]);
64 if(lpstrMessage == NULL)
65 {
66 ATLASSERT(FALSE);
67 return 0;
68 }
69 int nRes = ::LoadString(ModuleHelper::GetResourceInstance(), LOWORD(message.m_lpstr), lpstrMessage, nLen);
70 if(nRes < nLen - 1)
71 break;
72 delete [] lpstrMessage;
73 lpstrMessage = NULL;
74 }
75
76 message.m_lpstr = lpstrMessage;
77 }
78
79 LPTSTR lpstrTitle = NULL;
80 if(IS_INTRESOURCE(title.m_lpstr) && LOWORD(title.m_lpstr) != 0)
81 {
82 for(int nLen = 256; ; nLen *= 2)
83 {
84 ATLTRY(lpstrTitle = new TCHAR[nLen]);
85 if(lpstrTitle == NULL)
86 {
87 ATLASSERT(FALSE);
88 return 0;
89 }
90 int nRes = ::LoadString(ModuleHelper::GetResourceInstance(), LOWORD(title.m_lpstr), lpstrTitle, nLen);
91 if(nRes < nLen - 1)
92 break;
93 delete [] lpstrTitle;
94 lpstrTitle = NULL;
95 }
96
97 title.m_lpstr = lpstrTitle;
98 }
99
100 int nRet = ::MessageBox(hWndOwner, message.m_lpstr, title.m_lpstr, uType);
101
102 delete [] lpstrMessage;
103 delete [] lpstrTitle;
104
105 return nRet;
106 }
107
108
109 ///////////////////////////////////////////////////////////////////////////////
110 // CMenu
111
112 #if (WINVER >= 0x0500)
113 #ifndef MII_SIZEOF_STRUCT
114 #define MII_SIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member))
115 #endif
116 #define MENUITEMINFO_SIZE_VERSION_400A MII_SIZEOF_STRUCT(MENUITEMINFOA, cch)
117 #define MENUITEMINFO_SIZE_VERSION_400W MII_SIZEOF_STRUCT(MENUITEMINFOW, cch)
118 #ifdef UNICODE
119 #define MENUITEMINFO_SIZE_VERSION_400 MENUITEMINFO_SIZE_VERSION_400W
120 #else
121 #define MENUITEMINFO_SIZE_VERSION_400 MENUITEMINFO_SIZE_VERSION_400A
122 #endif // !UNICODE
123 #endif // (WINVER >= 0x0500)
124
125 class CMenuItemInfo : public MENUITEMINFO
126 {
127 public:
128 CMenuItemInfo()
129 {
130 memset(this, 0, sizeof(MENUITEMINFO));
131 cbSize = sizeof(MENUITEMINFO);
132 #if (WINVER >= 0x0500)
133 // adjust struct size if running on older version of Windows
134 if(AtlIsOldWindows())
135 {
136 ATLASSERT(cbSize > MENUITEMINFO_SIZE_VERSION_400); // must be
137 cbSize = MENUITEMINFO_SIZE_VERSION_400;
138 }
139 #endif // (WINVER >= 0x0500)
140 }
141 };
142
143
144 // forward declarations
145 template <bool t_bManaged> class CMenuT;
146 typedef CMenuT<false> CMenuHandle;
147 typedef CMenuT<true> CMenu;
148
149
150 template <bool t_bManaged>
151 class CMenuT
152 {
153 public:
154 // Data members
155 HMENU m_hMenu;
156
157 // Constructor/destructor/operators
158 CMenuT(HMENU hMenu = NULL) : m_hMenu(hMenu)
159 { }
160
161 ~CMenuT()
162 {
163 if(t_bManaged && m_hMenu != NULL)
164 DestroyMenu();
165 }
166
167 CMenuT<t_bManaged>& operator =(HMENU hMenu)
168 {
169 Attach(hMenu);
170 return *this;
171 }
172
173 void Attach(HMENU hMenuNew)
174 {
175 ATLASSERT(::IsMenu(hMenuNew));
176 if(t_bManaged && m_hMenu != NULL && m_hMenu != hMenuNew)
177 ::DestroyMenu(m_hMenu);
178 m_hMenu = hMenuNew;
179 }
180
181 HMENU Detach()
182 {
183 HMENU hMenu = m_hMenu;
184 m_hMenu = NULL;
185 return hMenu;
186 }
187
188 operator HMENU() const { return m_hMenu; }
189
190 bool IsNull() const { return (m_hMenu == NULL); }
191
192 BOOL IsMenu() const
193 {
194 return ::IsMenu(m_hMenu);
195 }
196
197 // Create/destroy methods
198 BOOL CreateMenu()
199 {
200 ATLASSERT(m_hMenu == NULL);
201 m_hMenu = ::CreateMenu();
202 return (m_hMenu != NULL) ? TRUE : FALSE;
203 }
204
205 BOOL CreatePopupMenu()
206 {
207 ATLASSERT(m_hMenu == NULL);
208 m_hMenu = ::CreatePopupMenu();
209 return (m_hMenu != NULL) ? TRUE : FALSE;
210 }
211
212 BOOL LoadMenu(ATL::_U_STRINGorID menu)
213 {
214 ATLASSERT(m_hMenu == NULL);
215 m_hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), menu.m_lpstr);
216 return (m_hMenu != NULL) ? TRUE : FALSE;
217 }
218
219 #ifndef _WIN32_WCE
220 BOOL LoadMenuIndirect(const void* lpMenuTemplate)
221 {
222 ATLASSERT(m_hMenu == NULL);
223 m_hMenu = ::LoadMenuIndirect(lpMenuTemplate);
224 return (m_hMenu != NULL) ? TRUE : FALSE;
225 }
226 #endif // !_WIN32_WCE
227
228 BOOL DestroyMenu()
229 {
230 if (m_hMenu == NULL)
231 return FALSE;
232 BOOL bRet = ::DestroyMenu(m_hMenu);
233 if(bRet)
234 m_hMenu = NULL;
235 return bRet;
236 }
237
238 // Menu Operations
239 BOOL DeleteMenu(UINT nPosition, UINT nFlags)
240 {
241 ATLASSERT(::IsMenu(m_hMenu));
242 return ::DeleteMenu(m_hMenu, nPosition, nFlags);
243 }
244
245 BOOL TrackPopupMenu(UINT nFlags, int x, int y, HWND hWnd, LPCRECT lpRect = NULL)
246 {
247 ATLASSERT(::IsMenu(m_hMenu));
248 #ifndef _WIN32_WCE
249 #if (WINVER >= 0x0500)
250 x = _FixTrackMenuPopupX(x, y);
251 #endif // !(WINVER >= 0x0500)
252 return ::TrackPopupMenu(m_hMenu, nFlags, x, y, 0, hWnd, lpRect);
253 #else // CE specific
254 lpRect;
255 return ::TrackPopupMenuEx(m_hMenu, nFlags, x, y, hWnd, NULL);
256 #endif // _WIN32_WCE
257 }
258
259 BOOL TrackPopupMenuEx(UINT uFlags, int x, int y, HWND hWnd, LPTPMPARAMS lptpm = NULL)
260 {
261 ATLASSERT(::IsMenu(m_hMenu));
262 #if (WINVER >= 0x0500) && !defined(_WIN32_WCE)
263 x = _FixTrackMenuPopupX(x, y);
264 #endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE)
265 return ::TrackPopupMenuEx(m_hMenu, uFlags, x, y, hWnd, lptpm);
266 }
267
268 #if (WINVER >= 0x0500) && !defined(_WIN32_WCE)
269 // helper that fixes popup menu X position when it's off-screen
270 static int _FixTrackMenuPopupX(int x, int y)
271 {
272 POINT pt = { x, y };
273 HMONITOR hMonitor = ::MonitorFromPoint(pt, MONITOR_DEFAULTTONULL);
274 if(hMonitor == NULL)
275 {
276 HMONITOR hMonitorNear = ::MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
277 if(hMonitorNear != NULL)
278 {
279 MONITORINFO mi = { sizeof(MONITORINFO) };
280 if(::GetMonitorInfo(hMonitorNear, &mi) != FALSE)
281 {
282 if(x < mi.rcWork.left)
283 x = mi.rcWork.left;
284 else if(x > mi.rcWork.right)
285 x = mi.rcWork.right;
286 }
287 }
288 }
289
290 return x;
291 }
292
293 BOOL GetMenuInfo(LPMENUINFO lpMenuInfo) const
294 {
295 ATLASSERT(::IsMenu(m_hMenu));
296 return ::GetMenuInfo(m_hMenu, lpMenuInfo);
297 }
298
299 BOOL SetMenuInfo(LPCMENUINFO lpMenuInfo)
300 {
301 ATLASSERT(::IsMenu(m_hMenu));
302 return ::SetMenuInfo(m_hMenu, lpMenuInfo);
303 }
304 #endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE)
305
306 // Menu Item Operations
307 BOOL AppendMenu(UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL)
308 {
309 ATLASSERT(::IsMenu(m_hMenu));
310 return ::AppendMenu(m_hMenu, nFlags, nIDNewItem, lpszNewItem);
311 }
312
313 BOOL AppendMenu(UINT nFlags, HMENU hSubMenu, LPCTSTR lpszNewItem)
314 {
315 ATLASSERT(::IsMenu(m_hMenu));
316 ATLASSERT(::IsMenu(hSubMenu));
317 return ::AppendMenu(m_hMenu, nFlags | MF_POPUP, (UINT_PTR)hSubMenu, lpszNewItem);
318 }
319
320 #ifndef _WIN32_WCE
321 BOOL AppendMenu(UINT nFlags, UINT_PTR nIDNewItem, HBITMAP hBmp)
322 {
323 ATLASSERT(::IsMenu(m_hMenu));
324 return ::AppendMenu(m_hMenu, nFlags | MF_BITMAP, nIDNewItem, (LPCTSTR)hBmp);
325 }
326
327 BOOL AppendMenu(UINT nFlags, HMENU hSubMenu, HBITMAP hBmp)
328 {
329 ATLASSERT(::IsMenu(m_hMenu));
330 ATLASSERT(::IsMenu(hSubMenu));
331 return ::AppendMenu(m_hMenu, nFlags | (MF_BITMAP | MF_POPUP), (UINT_PTR)hSubMenu, (LPCTSTR)hBmp);
332 }
333 #endif // !_WIN32_WCE
334
335 UINT CheckMenuItem(UINT nIDCheckItem, UINT nCheck)
336 {
337 ATLASSERT(::IsMenu(m_hMenu));
338 return (UINT)::CheckMenuItem(m_hMenu, nIDCheckItem, nCheck);
339 }
340
341 UINT EnableMenuItem(UINT nIDEnableItem, UINT nEnable)
342 {
343 ATLASSERT(::IsMenu(m_hMenu));
344 return ::EnableMenuItem(m_hMenu, nIDEnableItem, nEnable);
345 }
346
347 #ifndef _WIN32_WCE
348 BOOL HiliteMenuItem(HWND hWnd, UINT uIDHiliteItem, UINT uHilite)
349 {
350 ATLASSERT(::IsMenu(m_hMenu));
351 return ::HiliteMenuItem(hWnd, m_hMenu, uIDHiliteItem, uHilite);
352 }
353
354 int GetMenuItemCount() const
355 {
356 ATLASSERT(::IsMenu(m_hMenu));
357 return ::GetMenuItemCount(m_hMenu);
358 }
359
360 UINT GetMenuItemID(int nPos) const
361 {
362 ATLASSERT(::IsMenu(m_hMenu));
363 return ::GetMenuItemID(m_hMenu, nPos);
364 }
365
366 UINT GetMenuState(UINT nID, UINT nFlags) const
367 {
368 ATLASSERT(::IsMenu(m_hMenu));
369 return ::GetMenuState(m_hMenu, nID, nFlags);
370 }
371
372 int GetMenuString(UINT nIDItem, LPTSTR lpString, int nMaxCount, UINT nFlags) const
373 {
374 ATLASSERT(::IsMenu(m_hMenu));
375 return ::GetMenuString(m_hMenu, nIDItem, lpString, nMaxCount, nFlags);
376 }
377
378 int GetMenuStringLen(UINT nIDItem, UINT nFlags) const
379 {
380 ATLASSERT(::IsMenu(m_hMenu));
381 return ::GetMenuString(m_hMenu, nIDItem, NULL, 0, nFlags);
382 }
383
384 #ifndef _ATL_NO_COM
385 BOOL GetMenuString(UINT nIDItem, BSTR& bstrText, UINT nFlags) const
386 {
387 USES_CONVERSION;
388 ATLASSERT(::IsMenu(m_hMenu));
389 ATLASSERT(bstrText == NULL);
390
391 int nLen = GetMenuStringLen(nIDItem, nFlags);
392 if(nLen == 0)
393 {
394 bstrText = ::SysAllocString(OLESTR(""));
395 return (bstrText != NULL) ? TRUE : FALSE;
396 }
397
398 nLen++; // increment to include terminating NULL char
399 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
400 LPTSTR lpszText = buff.Allocate(nLen);
401 if(lpszText == NULL)
402 return FALSE;
403
404 if(!GetMenuString(nIDItem, lpszText, nLen, nFlags))
405 return FALSE;
406
407 bstrText = ::SysAllocString(T2OLE(lpszText));
408 return (bstrText != NULL) ? TRUE : FALSE;
409 }
410 #endif // !_ATL_NO_COM
411
412 #elif (_ATL_VER >= 0x0800)
413 int GetMenuItemCount() const
414 {
415 ATLASSERT(::IsMenu(m_hMenu));
416 return ATL::GetMenuItemCount(m_hMenu);
417 }
418
419 UINT GetMenuItemID(int nPos) const
420 {
421 ATLASSERT(::IsMenu(m_hMenu));
422 return ATL::GetMenuItemID(m_hMenu, nPos);
423 }
424
425 UINT GetMenuState(UINT nID, UINT nFlags) const
426 {
427 ATLASSERT(::IsMenu(m_hMenu));
428 return ATL::GetMenuState(m_hMenu, nID, nFlags);
429 }
430
431 int GetMenuString(UINT nIDItem, LPTSTR lpString, int nMaxCount, UINT nFlags) const
432 {
433 ATLASSERT(::IsMenu(m_hMenu));
434 return ATL::GetMenuString(m_hMenu, nIDItem, lpString, nMaxCount, nFlags);
435 }
436
437 int GetMenuStringLen(UINT nIDItem, UINT nFlags) const
438 {
439 ATLASSERT(::IsMenu(m_hMenu));
440 return ATL::GetMenuString(m_hMenu, nIDItem, NULL, 0, nFlags);
441 }
442 #endif // (_ATL_VER >= 0x0800)
443
444 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
445 int GetMenuString(UINT nIDItem, _CSTRING_NS::CString& strText, UINT nFlags) const
446 {
447 ATLASSERT(::IsMenu(m_hMenu));
448
449 int nLen = GetMenuStringLen(nIDItem, nFlags);
450 if(nLen == 0)
451 return 0;
452
453 nLen++; // increment to include terminating NULL char
454 LPTSTR lpstr = strText.GetBufferSetLength(nLen);
455 if(lpstr == NULL)
456 return 0;
457 int nRet = GetMenuString(nIDItem, lpstr, nLen, nFlags);
458 strText.ReleaseBuffer();
459 return nRet;
460 }
461 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
462
463 CMenuHandle GetSubMenu(int nPos) const
464 {
465 ATLASSERT(::IsMenu(m_hMenu));
466 return CMenuHandle(::GetSubMenu(m_hMenu, nPos));
467 }
468
469 BOOL InsertMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL)
470 {
471 ATLASSERT(::IsMenu(m_hMenu));
472 return ::InsertMenu(m_hMenu, nPosition, nFlags, nIDNewItem, lpszNewItem);
473 }
474
475 BOOL InsertMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, LPCTSTR lpszNewItem)
476 {
477 ATLASSERT(::IsMenu(m_hMenu));
478 ATLASSERT(::IsMenu(hSubMenu));
479 return ::InsertMenu(m_hMenu, nPosition, nFlags | MF_POPUP, (UINT_PTR)hSubMenu, lpszNewItem);
480 }
481
482 #ifndef _WIN32_WCE
483 BOOL InsertMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem, HBITMAP hBmp)
484 {
485 ATLASSERT(::IsMenu(m_hMenu));
486 return ::InsertMenu(m_hMenu, nPosition, nFlags | MF_BITMAP, nIDNewItem, (LPCTSTR)hBmp);
487 }
488
489 BOOL InsertMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, HBITMAP hBmp)
490 {
491 ATLASSERT(::IsMenu(m_hMenu));
492 ATLASSERT(::IsMenu(hSubMenu));
493 return ::InsertMenu(m_hMenu, nPosition, nFlags | (MF_BITMAP | MF_POPUP), (UINT_PTR)hSubMenu, (LPCTSTR)hBmp);
494 }
495
496 BOOL ModifyMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL)
497 {
498 ATLASSERT(::IsMenu(m_hMenu));
499 return ::ModifyMenu(m_hMenu, nPosition, nFlags, nIDNewItem, lpszNewItem);
500 }
501
502 BOOL ModifyMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, LPCTSTR lpszNewItem)
503 {
504 ATLASSERT(::IsMenu(m_hMenu));
505 ATLASSERT(::IsMenu(hSubMenu));
506 return ::ModifyMenu(m_hMenu, nPosition, nFlags | MF_POPUP, (UINT_PTR)hSubMenu, lpszNewItem);
507 }
508
509 BOOL ModifyMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem, HBITMAP hBmp)
510 {
511 ATLASSERT(::IsMenu(m_hMenu));
512 return ::ModifyMenu(m_hMenu, nPosition, nFlags | MF_BITMAP, nIDNewItem, (LPCTSTR)hBmp);
513 }
514
515 BOOL ModifyMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, HBITMAP hBmp)
516 {
517 ATLASSERT(::IsMenu(m_hMenu));
518 ATLASSERT(::IsMenu(hSubMenu));
519 return ::ModifyMenu(m_hMenu, nPosition, nFlags | (MF_BITMAP | MF_POPUP), (UINT_PTR)hSubMenu, (LPCTSTR)hBmp);
520 }
521 #endif // !_WIN32_WCE
522
523 BOOL RemoveMenu(UINT nPosition, UINT nFlags)
524 {
525 ATLASSERT(::IsMenu(m_hMenu));
526 return ::RemoveMenu(m_hMenu, nPosition, nFlags);
527 }
528
529 #ifndef _WIN32_WCE
530 BOOL SetMenuItemBitmaps(UINT nPosition, UINT nFlags, HBITMAP hBmpUnchecked, HBITMAP hBmpChecked)
531 {
532 ATLASSERT(::IsMenu(m_hMenu));
533 return ::SetMenuItemBitmaps(m_hMenu, nPosition, nFlags, hBmpUnchecked, hBmpChecked);
534 }
535 #endif // !_WIN32_WCE
536
537 BOOL CheckMenuRadioItem(UINT nIDFirst, UINT nIDLast, UINT nIDItem, UINT nFlags)
538 {
539 ATLASSERT(::IsMenu(m_hMenu));
540 return ::CheckMenuRadioItem(m_hMenu, nIDFirst, nIDLast, nIDItem, nFlags);
541 }
542
543 BOOL GetMenuItemInfo(UINT uItem, BOOL bByPosition, LPMENUITEMINFO lpmii) const
544 {
545 ATLASSERT(::IsMenu(m_hMenu));
546 return (BOOL)::GetMenuItemInfo(m_hMenu, uItem, bByPosition, lpmii);
547 }
548
549 BOOL SetMenuItemInfo(UINT uItem, BOOL bByPosition, LPMENUITEMINFO lpmii)
550 {
551 ATLASSERT(::IsMenu(m_hMenu));
552 return (BOOL)::SetMenuItemInfo(m_hMenu, uItem, bByPosition, lpmii);
553 }
554
555 #ifndef _WIN32_WCE
556 BOOL InsertMenuItem(UINT uItem, BOOL bByPosition, LPMENUITEMINFO lpmii)
557 {
558 ATLASSERT(::IsMenu(m_hMenu));
559 return (BOOL)::InsertMenuItem(m_hMenu, uItem, bByPosition, lpmii);
560 }
561
562 UINT GetMenuDefaultItem(BOOL bByPosition = FALSE, UINT uFlags = 0U) const
563 {
564 ATLASSERT(::IsMenu(m_hMenu));
565 return ::GetMenuDefaultItem(m_hMenu, (UINT)bByPosition, uFlags);
566 }
567
568 BOOL SetMenuDefaultItem(UINT uItem = (UINT)-1, BOOL bByPosition = FALSE)
569 {
570 ATLASSERT(::IsMenu(m_hMenu));
571 return ::SetMenuDefaultItem(m_hMenu, uItem, (UINT)bByPosition);
572 }
573
574 BOOL GetMenuItemRect(HWND hWnd, UINT uItem, LPRECT lprcItem) const
575 {
576 ATLASSERT(::IsMenu(m_hMenu));
577 return ::GetMenuItemRect(hWnd, m_hMenu, uItem, lprcItem);
578 }
579
580 int MenuItemFromPoint(HWND hWnd, POINT point) const
581 {
582 ATLASSERT(::IsMenu(m_hMenu));
583 return ::MenuItemFromPoint(hWnd, m_hMenu, point);
584 }
585
586 // Context Help Functions
587 BOOL SetMenuContextHelpId(DWORD dwContextHelpId)
588 {
589 ATLASSERT(::IsMenu(m_hMenu));
590 return ::SetMenuContextHelpId(m_hMenu, dwContextHelpId);
591 }
592
593 DWORD GetMenuContextHelpId() const
594 {
595 ATLASSERT(::IsMenu(m_hMenu));
596 return ::GetMenuContextHelpId(m_hMenu);
597 }
598 #endif // !_WIN32_WCE
599 };
600
601
602 ///////////////////////////////////////////////////////////////////////////////
603 // CAccelerator
604
605 template <bool t_bManaged>
606 class CAcceleratorT
607 {
608 public:
609 HACCEL m_hAccel;
610
611 // Constructor/destructor/operators
612 CAcceleratorT(HACCEL hAccel = NULL) : m_hAccel(hAccel)
613 { }
614
615 ~CAcceleratorT()
616 {
617 if(t_bManaged && m_hAccel != NULL)
618 ::DestroyAcceleratorTable(m_hAccel);
619 }
620
621 CAcceleratorT<t_bManaged>& operator =(HACCEL hAccel)
622 {
623 Attach(hAccel);
624 return *this;
625 }
626
627 void Attach(HACCEL hAccel)
628 {
629 if(t_bManaged && m_hAccel != NULL)
630 ::DestroyAcceleratorTable(m_hAccel);
631 m_hAccel = hAccel;
632 }
633
634 HACCEL Detach()
635 {
636 HACCEL hAccel = m_hAccel;
637 m_hAccel = NULL;
638 return hAccel;
639 }
640
641 operator HACCEL() const { return m_hAccel; }
642
643 bool IsNull() const { return m_hAccel == NULL; }
644
645 // Create/destroy methods
646 HACCEL LoadAccelerators(ATL::_U_STRINGorID accel)
647 {
648 ATLASSERT(m_hAccel == NULL);
649 m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), accel.m_lpstr);
650 return m_hAccel;
651 }
652
653 HACCEL CreateAcceleratorTable(LPACCEL pAccel, int cEntries)
654 {
655 ATLASSERT(m_hAccel == NULL);
656 ATLASSERT(pAccel != NULL);
657 m_hAccel = ::CreateAcceleratorTable(pAccel, cEntries);
658 return m_hAccel;
659 }
660
661 void DestroyObject()
662 {
663 if(m_hAccel != NULL)
664 {
665 ::DestroyAcceleratorTable(m_hAccel);
666 m_hAccel = NULL;
667 }
668 }
669
670 // Operations
671 #ifndef _WIN32_WCE
672 int CopyAcceleratorTable(LPACCEL lpAccelDst, int cEntries)
673 {
674 ATLASSERT(m_hAccel != NULL);
675 ATLASSERT(lpAccelDst != NULL);
676 return ::CopyAcceleratorTable(m_hAccel, lpAccelDst, cEntries);
677 }
678
679 int GetEntriesCount() const
680 {
681 ATLASSERT(m_hAccel != NULL);
682 return ::CopyAcceleratorTable(m_hAccel, NULL, 0);
683 }
684 #endif // !_WIN32_WCE
685
686 BOOL TranslateAccelerator(HWND hWnd, LPMSG pMsg)
687 {
688 ATLASSERT(m_hAccel != NULL);
689 ATLASSERT(::IsWindow(hWnd));
690 ATLASSERT(pMsg != NULL);
691 return ::TranslateAccelerator(hWnd, m_hAccel, pMsg);
692 }
693 };
694
695 typedef CAcceleratorT<false> CAcceleratorHandle;
696 typedef CAcceleratorT<true> CAccelerator;
697
698
699 ///////////////////////////////////////////////////////////////////////////////
700 // CIcon
701
702 template <bool t_bManaged>
703 class CIconT
704 {
705 public:
706 HICON m_hIcon;
707
708 // Constructor/destructor/operators
709 CIconT(HICON hIcon = NULL) : m_hIcon(hIcon)
710 { }
711
712 ~CIconT()
713 {
714 if(t_bManaged && m_hIcon != NULL)
715 ::DestroyIcon(m_hIcon);
716 }
717
718 CIconT<t_bManaged>& operator =(HICON hIcon)
719 {
720 Attach(hIcon);
721 return *this;
722 }
723
724 void Attach(HICON hIcon)
725 {
726 if(t_bManaged && m_hIcon != NULL)
727 ::DestroyIcon(m_hIcon);
728 m_hIcon = hIcon;
729 }
730
731 HICON Detach()
732 {
733 HICON hIcon = m_hIcon;
734 m_hIcon = NULL;
735 return hIcon;
736 }
737
738 operator HICON() const { return m_hIcon; }
739
740 bool IsNull() const { return m_hIcon == NULL; }
741
742 // Create/destroy methods
743 HICON LoadIcon(ATL::_U_STRINGorID icon)
744 {
745 ATLASSERT(m_hIcon == NULL);
746 m_hIcon = ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr);
747 return m_hIcon;
748 }
749
750 HICON LoadIcon(ATL::_U_STRINGorID icon, int cxDesired, int cyDesired, UINT fuLoad = 0)
751 {
752 ATLASSERT(m_hIcon == NULL);
753 m_hIcon = (HICON) ::LoadImage(ModuleHelper::GetResourceInstance(), icon.m_lpstr, IMAGE_ICON, cxDesired, cyDesired, fuLoad);
754 return m_hIcon;
755 }
756
757 #ifndef _WIN32_WCE
758 HICON LoadOEMIcon(LPCTSTR lpstrIconName)
759 {
760 ATLASSERT(m_hIcon == NULL);
761 ATLASSERT(IsOEMIcon(lpstrIconName));
762 m_hIcon = ::LoadIcon(NULL, lpstrIconName);
763 return m_hIcon;
764 }
765
766 HICON CreateIcon(int nWidth, int nHeight, BYTE cPlanes, BYTE cBitsPixel, CONST BYTE* lpbANDbits, CONST BYTE *lpbXORbits)
767 {
768 ATLASSERT(m_hIcon == NULL);
769 ATLASSERT(lpbANDbits != NULL);
770 ATLASSERT(lpbXORbits != NULL);
771 m_hIcon = ::CreateIcon(ModuleHelper::GetResourceInstance(), nWidth, nHeight, cPlanes, cBitsPixel, lpbANDbits, lpbXORbits);
772 return m_hIcon;
773 }
774
775 HICON CreateIconFromResource(PBYTE pBits, DWORD dwResSize, DWORD dwVersion = 0x00030000)
776 {
777 ATLASSERT(m_hIcon == NULL);
778 ATLASSERT(pBits != NULL);
779 m_hIcon = ::CreateIconFromResource(pBits, dwResSize, TRUE, dwVersion);
780 return m_hIcon;
781 }
782
783 HICON CreateIconFromResourceEx(PBYTE pbBits, DWORD cbBits, DWORD dwVersion = 0x00030000, int cxDesired = 0, int cyDesired = 0, UINT uFlags = LR_DEFAULTCOLOR)
784 {
785 ATLASSERT(m_hIcon == NULL);
786 ATLASSERT(pbBits != NULL);
787 ATLASSERT(cbBits > 0);
788 m_hIcon = ::CreateIconFromResourceEx(pbBits, cbBits, TRUE, dwVersion, cxDesired, cyDesired, uFlags);
789 return m_hIcon;
790 }
791 #endif // !_WIN32_WCE
792
793 HICON CreateIconIndirect(PICONINFO pIconInfo)
794 {
795 ATLASSERT(m_hIcon == NULL);
796 ATLASSERT(pIconInfo != NULL);
797 m_hIcon = ::CreateIconIndirect(pIconInfo);
798 return m_hIcon;
799 }
800
801 #ifndef _WIN32_WCE
802 HICON ExtractIcon(LPCTSTR lpszExeFileName, UINT nIconIndex)
803 {
804 ATLASSERT(m_hIcon == NULL);
805 ATLASSERT(lpszExeFileName != NULL);
806 m_hIcon = ::ExtractIcon(ModuleHelper::GetModuleInstance(), lpszExeFileName, nIconIndex);
807 return m_hIcon;
808 }
809
810 HICON ExtractAssociatedIcon(HINSTANCE hInst, LPTSTR lpIconPath, LPWORD lpiIcon)
811 {
812 ATLASSERT(m_hIcon == NULL);
813 ATLASSERT(lpIconPath != NULL);
814 ATLASSERT(lpiIcon != NULL);
815 m_hIcon = ::ExtractAssociatedIcon(hInst, lpIconPath, lpiIcon);
816 return m_hIcon;
817 }
818 #endif // !_WIN32_WCE
819
820 BOOL DestroyIcon()
821 {
822 ATLASSERT(m_hIcon != NULL);
823 BOOL bRet = ::DestroyIcon(m_hIcon);
824 if(bRet != FALSE)
825 m_hIcon = NULL;
826 return bRet;
827 }
828
829 // Operations
830 #ifndef _WIN32_WCE
831 HICON CopyIcon()
832 {
833 ATLASSERT(m_hIcon != NULL);
834 return ::CopyIcon(m_hIcon);
835 }
836
837 HICON DuplicateIcon()
838 {
839 ATLASSERT(m_hIcon != NULL);
840 return ::DuplicateIcon(NULL, m_hIcon);
841 }
842 #endif // !_WIN32_WCE
843
844 BOOL DrawIcon(HDC hDC, int x, int y)
845 {
846 ATLASSERT(m_hIcon != NULL);
847 #ifndef _WIN32_WCE
848 return ::DrawIcon(hDC, x, y, m_hIcon);
849 #else // CE specific
850 return ::DrawIconEx(hDC, x, y, m_hIcon, 0, 0, 0, NULL, DI_NORMAL);
851 #endif // _WIN32_WCE
852 }
853
854 BOOL DrawIcon(HDC hDC, POINT pt)
855 {
856 ATLASSERT(m_hIcon != NULL);
857 #ifndef _WIN32_WCE
858 return ::DrawIcon(hDC, pt.x, pt.y, m_hIcon);
859 #else // CE specific
860 return ::DrawIconEx(hDC, pt.x, pt.y, m_hIcon, 0, 0, 0, NULL, DI_NORMAL);
861 #endif // _WIN32_WCE
862 }
863
864 BOOL DrawIconEx(HDC hDC, int x, int y, int cxWidth, int cyWidth, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL)
865 {
866 ATLASSERT(m_hIcon != NULL);
867 return ::DrawIconEx(hDC, x, y, m_hIcon, cxWidth, cyWidth, uStepIfAniCur, hbrFlickerFreeDraw, uFlags);
868 }
869
870 BOOL DrawIconEx(HDC hDC, POINT pt, SIZE size, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL)
871 {
872 ATLASSERT(m_hIcon != NULL);
873 return ::DrawIconEx(hDC, pt.x, pt.y, m_hIcon, size.cx, size.cy, uStepIfAniCur, hbrFlickerFreeDraw, uFlags);
874 }
875
876 #ifndef _WIN32_WCE
877 BOOL GetIconInfo(PICONINFO pIconInfo) const
878 {
879 ATLASSERT(m_hIcon != NULL);
880 ATLASSERT(pIconInfo != NULL);
881 return ::GetIconInfo(m_hIcon, pIconInfo);
882 }
883
884 #if (_WIN32_WINNT >= 0x0600)
885 BOOL GetIconInfoEx(PICONINFOEX pIconInfo) const
886 {
887 ATLASSERT(m_hIcon != NULL);
888 ATLASSERT(pIconInfo != NULL);
889 return ::GetIconInfoEx(m_hIcon, pIconInfo);
890 }
891 #endif // (_WIN32_WINNT >= 0x0600)
892
893 #if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
894 HRESULT LoadIconMetric(ATL::_U_STRINGorID icon, int lims)
895 {
896 ATLASSERT(m_hIcon == NULL);
897 USES_CONVERSION;
898 return ::LoadIconMetric(ModuleHelper::GetResourceInstance(), T2CW(icon.m_lpstr), lims, &m_hIcon);
899 }
900
901 HRESULT LoadIconWithScaleDown(ATL::_U_STRINGorID icon, int cx, int cy)
902 {
903 ATLASSERT(m_hIcon == NULL);
904 USES_CONVERSION;
905 return ::LoadIconWithScaleDown(ModuleHelper::GetResourceInstance(), T2CW(icon.m_lpstr), cx, cy, &m_hIcon);
906 }
907
908 HRESULT LoadOEMIconMetric(LPCTSTR lpstrIconName, int lims)
909 {
910 ATLASSERT(m_hIcon == NULL);
911 ATLASSERT(IsOEMIcon(lpstrIconName));
912 return ::LoadIconMetric(NULL, (LPCWSTR)lpstrIconName, lims, &m_hIcon);
913 }
914
915 HRESULT LoadOEMIconWithScaleDown(LPCTSTR lpstrIconName, int cx, int cy)
916 {
917 ATLASSERT(m_hIcon == NULL);
918 ATLASSERT(IsOEMIcon(lpstrIconName));
919 USES_CONVERSION;
920 return ::LoadIconWithScaleDown(NULL, (LPCWSTR)lpstrIconName, cx, cy, &m_hIcon);
921 }
922 #endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
923 #endif // !_WIN32_WCE
924
925 // Helper
926 #ifndef _WIN32_WCE
927 static bool IsOEMIcon(LPCTSTR lpstrIconName)
928 {
929 #if (WINVER >= 0x0600)
930 return (lpstrIconName == IDI_APPLICATION || lpstrIconName == IDI_ASTERISK || lpstrIconName == IDI_EXCLAMATION ||
931 lpstrIconName == IDI_HAND || lpstrIconName == IDI_QUESTION || lpstrIconName == IDI_WINLOGO ||
932 lpstrIconName == IDI_SHIELD);
933 #else // !(WINVER >= 0x0600)
934 return (lpstrIconName == IDI_APPLICATION || lpstrIconName == IDI_ASTERISK || lpstrIconName == IDI_EXCLAMATION ||
935 lpstrIconName == IDI_HAND || lpstrIconName == IDI_QUESTION || lpstrIconName == IDI_WINLOGO);
936 #endif // !(WINVER >= 0x0600)
937 }
938 #endif // !_WIN32_WCE
939 };
940
941 typedef CIconT<false> CIconHandle;
942 typedef CIconT<true> CIcon;
943
944
945 ///////////////////////////////////////////////////////////////////////////////
946 // CCursor
947
948 // protect template member from a winuser.h macro
949 #ifdef CopyCursor
950 #undef CopyCursor
951 #endif
952
953 template <bool t_bManaged>
954 class CCursorT
955 {
956 public:
957 HCURSOR m_hCursor;
958
959 // Constructor/destructor/operators
960 CCursorT(HCURSOR hCursor = NULL) : m_hCursor(hCursor)
961 { }
962
963 ~CCursorT()
964 {
965 if(t_bManaged && m_hCursor != NULL)
966 DestroyCursor();
967 }
968
969 CCursorT<t_bManaged>& operator =(HCURSOR hCursor)
970 {
971 Attach(hCursor);
972 return *this;
973 }
974
975 void Attach(HCURSOR hCursor)
976 {
977 if(t_bManaged && m_hCursor != NULL)
978 DestroyCursor();
979 m_hCursor = hCursor;
980 }
981
982 HCURSOR Detach()
983 {
984 HCURSOR hCursor = m_hCursor;
985 m_hCursor = NULL;
986 return hCursor;
987 }
988
989 operator HCURSOR() const { return m_hCursor; }
990
991 bool IsNull() const { return m_hCursor == NULL; }
992
993 // Create/destroy methods
994 HCURSOR LoadCursor(ATL::_U_STRINGorID cursor)
995 {
996 ATLASSERT(m_hCursor == NULL);
997 m_hCursor = ::LoadCursor(ModuleHelper::GetResourceInstance(), cursor.m_lpstr);
998 return m_hCursor;
999 }
1000
1001 HCURSOR LoadSysCursor(LPCTSTR lpstrCursorName)
1002 {
1003 ATLASSERT(m_hCursor == NULL);
1004 #if (WINVER >= 0x0500)
1005 ATLASSERT(lpstrCursorName == IDC_ARROW || lpstrCursorName == IDC_IBEAM || lpstrCursorName == IDC_WAIT ||
1006 lpstrCursorName == IDC_CROSS || lpstrCursorName == IDC_UPARROW || lpstrCursorName == IDC_SIZE ||
1007 lpstrCursorName == IDC_ICON || lpstrCursorName == IDC_SIZENWSE || lpstrCursorName == IDC_SIZENESW ||
1008 lpstrCursorName == IDC_SIZEWE || lpstrCursorName == IDC_SIZENS || lpstrCursorName == IDC_SIZEALL ||
1009 lpstrCursorName == IDC_NO || lpstrCursorName == IDC_APPSTARTING || lpstrCursorName == IDC_HELP ||
1010 lpstrCursorName == IDC_HAND);
1011 #else // !(WINVER >= 0x0500)
1012 ATLASSERT(lpstrCursorName == IDC_ARROW || lpstrCursorName == IDC_IBEAM || lpstrCursorName == IDC_WAIT ||
1013 lpstrCursorName == IDC_CROSS || lpstrCursorName == IDC_UPARROW || lpstrCursorName == IDC_SIZE ||
1014 lpstrCursorName == IDC_ICON || lpstrCursorName == IDC_SIZENWSE || lpstrCursorName == IDC_SIZENESW ||
1015 lpstrCursorName == IDC_SIZEWE || lpstrCursorName == IDC_SIZENS || lpstrCursorName == IDC_SIZEALL ||
1016 lpstrCursorName == IDC_NO || lpstrCursorName == IDC_APPSTARTING || lpstrCursorName == IDC_HELP);
1017 #endif // !(WINVER >= 0x0500)
1018 m_hCursor = ::LoadCursor(NULL, lpstrCursorName);
1019 return m_hCursor;
1020 }
1021
1022 // deprecated
1023 HCURSOR LoadOEMCursor(LPCTSTR lpstrCursorName)
1024 {
1025 return LoadSysCursor(lpstrCursorName);
1026 }
1027
1028 HCURSOR LoadCursor(ATL::_U_STRINGorID cursor, int cxDesired, int cyDesired, UINT fuLoad = 0)
1029 {
1030 ATLASSERT(m_hCursor == NULL);
1031 m_hCursor = (HCURSOR) ::LoadImage(ModuleHelper::GetResourceInstance(), cursor.m_lpstr, IMAGE_CURSOR, cxDesired, cyDesired, fuLoad);
1032 return m_hCursor;
1033 }
1034
1035 #ifndef _WIN32_WCE
1036 HCURSOR LoadCursorFromFile(LPCTSTR pstrFilename)
1037 {
1038 ATLASSERT(m_hCursor == NULL);
1039 ATLASSERT(pstrFilename != NULL);
1040 m_hCursor = ::LoadCursorFromFile(pstrFilename);
1041 return m_hCursor;
1042 }
1043 #endif // !_WIN32_WCE
1044
1045 #if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)))
1046 HCURSOR CreateCursor(int xHotSpot, int yHotSpot, int nWidth, int nHeight, CONST VOID *pvANDPlane, CONST VOID *pvXORPlane)
1047 {
1048 ATLASSERT(m_hCursor == NULL);
1049 m_hCursor = ::CreateCursor(ModuleHelper::GetResourceInstance(), xHotSpot, yHotSpot, nWidth, nHeight, pvANDPlane, pvXORPlane);
1050 return m_hCursor;
1051 }
1052 #endif // !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)))
1053
1054 #ifndef _WIN32_WCE
1055 HCURSOR CreateCursorFromResource(PBYTE pBits, DWORD dwResSize, DWORD dwVersion = 0x00030000)
1056 {
1057 ATLASSERT(m_hCursor == NULL);
1058 ATLASSERT(pBits != NULL);
1059 m_hCursor = (HCURSOR)::CreateIconFromResource(pBits, dwResSize, FALSE, dwVersion);
1060 return m_hCursor;
1061 }
1062
1063 HCURSOR CreateCursorFromResourceEx(PBYTE pbBits, DWORD cbBits, DWORD dwVersion = 0x00030000, int cxDesired = 0, int cyDesired = 0, UINT uFlags = LR_DEFAULTCOLOR)
1064 {
1065 ATLASSERT(m_hCursor == NULL);
1066 ATLASSERT(pbBits != NULL);
1067 ATLASSERT(cbBits > 0);
1068 m_hCursor = (HCURSOR)::CreateIconFromResourceEx(pbBits, cbBits, FALSE, dwVersion, cxDesired, cyDesired, uFlags);
1069 return m_hCursor;
1070 }
1071 #endif // !_WIN32_WCE
1072
1073 BOOL DestroyCursor()
1074 {
1075 ATLASSERT(m_hCursor != NULL);
1076 #if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)))
1077 BOOL bRet = ::DestroyCursor(m_hCursor);
1078 if(bRet != FALSE)
1079 m_hCursor = NULL;
1080 return bRet;
1081 #else // !(!defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))))
1082 ATLTRACE2(atlTraceUI, 0, _T("Warning: This version of Windows CE does not have ::DestroyCursor()\n"));
1083 return FALSE;
1084 #endif // !(!defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))))
1085 }
1086
1087 // Operations
1088 #ifndef _WIN32_WCE
1089 HCURSOR CopyCursor()
1090 {
1091 ATLASSERT(m_hCursor != NULL);
1092 return (HCURSOR)::CopyIcon((HICON)m_hCursor);
1093 }
1094 #endif // !_WIN32_WCE
1095
1096 #if (WINVER >= 0x0500) && !defined(_WIN32_WCE)
1097 BOOL GetCursorInfo(LPCURSORINFO pCursorInfo)
1098 {
1099 ATLASSERT(m_hCursor != NULL);
1100 ATLASSERT(pCursorInfo != NULL);
1101 return ::GetCursorInfo(pCursorInfo);
1102 }
1103 #endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE)
1104 };
1105
1106 typedef CCursorT<false> CCursorHandle;
1107 typedef CCursorT<true> CCursor;
1108
1109
1110 ///////////////////////////////////////////////////////////////////////////////
1111 // CResource - Wraps a generic Windows resource.
1112 // Use it with custom resource types other than the
1113 // standard RT_CURSOR, RT_BITMAP, etc.
1114
1115 class CResource
1116 {
1117 public:
1118 HGLOBAL m_hGlobal;
1119 HRSRC m_hResource;
1120
1121 // Constructor/destructor
1122 CResource() : m_hGlobal(NULL), m_hResource(NULL)
1123 { }
1124
1125 ~CResource()
1126 {
1127 Release();
1128 }
1129
1130 // Load methods
1131 bool Load(ATL::_U_STRINGorID Type, ATL::_U_STRINGorID ID)
1132 {
1133 ATLASSERT(m_hResource == NULL);
1134 ATLASSERT(m_hGlobal == NULL);
1135
1136 m_hResource = ::FindResource(ModuleHelper::GetResourceInstance(), ID.m_lpstr, Type.m_lpstr);
1137 if(m_hResource == NULL)
1138 return false;
1139
1140 m_hGlobal = ::LoadResource(ModuleHelper::GetResourceInstance(), m_hResource);
1141 if(m_hGlobal == NULL)
1142 {
1143 m_hResource = NULL;
1144 return false;
1145 }
1146
1147 return true;
1148 }
1149
1150 #ifndef _WIN32_WCE
1151 bool LoadEx(ATL::_U_STRINGorID ID, ATL::_U_STRINGorID Type, WORD wLanguage)
1152 {
1153 ATLASSERT(m_hResource == NULL);
1154 ATLASSERT(m_hGlobal == NULL);
1155
1156 m_hResource = ::FindResourceEx(ModuleHelper::GetResourceInstance(), Type.m_lpstr, ID.m_lpstr, wLanguage);
1157 if(m_hResource == NULL)
1158 return false;
1159
1160 m_hGlobal = ::LoadResource(ModuleHelper::GetResourceInstance(), m_hResource);
1161 if(m_hGlobal == NULL)
1162 {
1163 m_hResource = NULL;
1164 return false;
1165 }
1166
1167 return true;
1168 }
1169 #endif // !_WIN32_WCE
1170
1171 // Misc. operations
1172 DWORD GetSize() const
1173 {
1174 ATLASSERT(m_hResource != NULL);
1175 return ::SizeofResource(ModuleHelper::GetResourceInstance(), m_hResource);
1176 }
1177
1178 LPVOID Lock()
1179 {
1180 ATLASSERT(m_hResource != NULL);
1181 ATLASSERT(m_hGlobal != NULL);
1182 LPVOID pVoid = ::LockResource(m_hGlobal);
1183 ATLASSERT(pVoid != NULL);
1184 return pVoid;
1185 }
1186
1187 void Release()
1188 {
1189 if(m_hGlobal != NULL)
1190 {
1191 FreeResource(m_hGlobal);
1192 m_hGlobal = NULL;
1193 m_hResource = NULL;
1194 }
1195 }
1196 };
1197
1198
1199 ///////////////////////////////////////////////////////////////////////////////
1200 // Toolbar resource descriptor
1201
1202 struct _AtlToolBarData
1203 {
1204 WORD wVersion;
1205 WORD wWidth;
1206 WORD wHeight;
1207 WORD wItemCount;
1208
1209 WORD* items()
1210 { return (WORD*)(this+1); }
1211 };
1212
1213
1214 ///////////////////////////////////////////////////////////////////////////////
1215 // Global functions for loading resources
1216
1217 inline HACCEL AtlLoadAccelerators(ATL::_U_STRINGorID table)
1218 {
1219 return ::LoadAccelerators(ModuleHelper::GetResourceInstance(), table.m_lpstr);
1220 }
1221
1222 inline HMENU AtlLoadMenu(ATL::_U_STRINGorID menu)
1223 {
1224 return ::LoadMenu(ModuleHelper::GetResourceInstance(), menu.m_lpstr);
1225 }
1226
1227 inline HBITMAP AtlLoadBitmap(ATL::_U_STRINGorID bitmap)
1228 {
1229 return ::LoadBitmap(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr);
1230 }
1231
1232 #ifdef OEMRESOURCE
1233 inline HBITMAP AtlLoadSysBitmap(ATL::_U_STRINGorID bitmap)
1234 {
1235 #ifdef _DEBUG
1236 WORD wID = LOWORD(bitmap.m_lpstr);
1237 ATLASSERT(wID >= 32734 && wID <= 32767);
1238 #endif // _DEBUG
1239 return ::LoadBitmap(NULL, bitmap.m_lpstr);
1240 }
1241 #endif // OEMRESOURCE
1242
1243 inline HCURSOR AtlLoadCursor(ATL::_U_STRINGorID cursor)
1244 {
1245 return ::LoadCursor(ModuleHelper::GetResourceInstance(), cursor.m_lpstr);
1246 }
1247
1248 inline HCURSOR AtlLoadSysCursor(LPCTSTR lpCursorName)
1249 {
1250 #if (WINVER >= 0x0500)
1251 ATLASSERT(lpCursorName == IDC_ARROW || lpCursorName == IDC_IBEAM || lpCursorName == IDC_WAIT ||
1252 lpCursorName == IDC_CROSS || lpCursorName == IDC_UPARROW || lpCursorName == IDC_SIZE ||
1253 lpCursorName == IDC_ICON || lpCursorName == IDC_SIZENWSE || lpCursorName == IDC_SIZENESW ||
1254 lpCursorName == IDC_SIZEWE || lpCursorName == IDC_SIZENS || lpCursorName == IDC_SIZEALL ||
1255 lpCursorName == IDC_NO || lpCursorName == IDC_APPSTARTING || lpCursorName == IDC_HELP ||
1256 lpCursorName == IDC_HAND);
1257 #else // !(WINVER >= 0x0500)
1258 ATLASSERT(lpCursorName == IDC_ARROW || lpCursorName == IDC_IBEAM || lpCursorName == IDC_WAIT ||
1259 lpCursorName == IDC_CROSS || lpCursorName == IDC_UPARROW || lpCursorName == IDC_SIZE ||
1260 lpCursorName == IDC_ICON || lpCursorName == IDC_SIZENWSE || lpCursorName == IDC_SIZENESW ||
1261 lpCursorName == IDC_SIZEWE || lpCursorName == IDC_SIZENS || lpCursorName == IDC_SIZEALL ||
1262 lpCursorName == IDC_NO || lpCursorName == IDC_APPSTARTING || lpCursorName == IDC_HELP);
1263 #endif // !(WINVER >= 0x0500)
1264 return ::LoadCursor(NULL, lpCursorName);
1265 }
1266
1267 inline HICON AtlLoadIcon(ATL::_U_STRINGorID icon)
1268 {
1269 return ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr);
1270 }
1271
1272 #ifndef _WIN32_WCE
1273 inline HICON AtlLoadSysIcon(LPCTSTR lpIconName)
1274 {
1275 #if (WINVER >= 0x0600)
1276 ATLASSERT(lpIconName == IDI_APPLICATION || lpIconName == IDI_ASTERISK || lpIconName == IDI_EXCLAMATION ||
1277 lpIconName == IDI_HAND || lpIconName == IDI_QUESTION || lpIconName == IDI_WINLOGO ||
1278 lpIconName == IDI_SHIELD);
1279 #else // !(WINVER >= 0x0600)
1280 ATLASSERT(lpIconName == IDI_APPLICATION || lpIconName == IDI_ASTERISK || lpIconName == IDI_EXCLAMATION ||
1281 lpIconName == IDI_HAND || lpIconName == IDI_QUESTION || lpIconName == IDI_WINLOGO);
1282 #endif // !(WINVER >= 0x0600)
1283 return ::LoadIcon(NULL, lpIconName);
1284 }
1285 #endif // !_WIN32_WCE
1286
1287 inline HBITMAP AtlLoadBitmapImage(ATL::_U_STRINGorID bitmap, UINT fuLoad = LR_DEFAULTCOLOR)
1288 {
1289 return (HBITMAP)::LoadImage(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr, IMAGE_BITMAP, 0, 0, fuLoad);
1290 }
1291
1292 inline HCURSOR AtlLoadCursorImage(ATL::_U_STRINGorID cursor, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0)
1293 {
1294 return (HCURSOR)::LoadImage(ModuleHelper::GetResourceInstance(), cursor.m_lpstr, IMAGE_CURSOR, cxDesired, cyDesired, fuLoad);
1295 }
1296
1297 inline HICON AtlLoadIconImage(ATL::_U_STRINGorID icon, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0)
1298 {
1299 return (HICON)::LoadImage(ModuleHelper::GetResourceInstance(), icon.m_lpstr, IMAGE_ICON, cxDesired, cyDesired, fuLoad);
1300 }
1301
1302 #ifdef OEMRESOURCE
1303 inline HBITMAP AtlLoadSysBitmapImage(WORD wBitmapID, UINT fuLoad = LR_DEFAULTCOLOR)
1304 {
1305 ATLASSERT(wBitmapID >= 32734 && wBitmapID <= 32767);
1306 ATLASSERT((fuLoad & LR_LOADFROMFILE) == 0); // this one doesn't load from a file
1307 return (HBITMAP)::LoadImage(NULL, MAKEINTRESOURCE(wBitmapID), IMAGE_BITMAP, 0, 0, fuLoad);
1308 }
1309 #endif // OEMRESOURCE
1310
1311 inline HCURSOR AtlLoadSysCursorImage(ATL::_U_STRINGorID cursor, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0)
1312 {
1313 #ifdef _DEBUG
1314 WORD wID = LOWORD(cursor.m_lpstr);
1315 ATLASSERT((wID >= 32512 && wID <= 32516) || (wID >= 32640 && wID <= 32648) || (wID == 32650) || (wID == 32651));
1316 ATLASSERT((fuLoad & LR_LOADFROMFILE) == 0); // this one doesn't load from a file
1317 #endif // _DEBUG
1318 return (HCURSOR)::LoadImage(NULL, cursor.m_lpstr, IMAGE_CURSOR, cxDesired, cyDesired, fuLoad);
1319 }
1320
1321 inline HICON AtlLoadSysIconImage(ATL::_U_STRINGorID icon, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0)
1322 {
1323 #ifdef _DEBUG
1324 WORD wID = LOWORD(icon.m_lpstr);
1325 ATLASSERT(wID >= 32512 && wID <= 32517);
1326 ATLASSERT((fuLoad & LR_LOADFROMFILE) == 0); // this one doesn't load from a file
1327 #endif // _DEBUG
1328 return (HICON)::LoadImage(NULL, icon.m_lpstr, IMAGE_ICON, cxDesired, cyDesired, fuLoad);
1329 }
1330
1331 #if (_ATL_VER < 0x0700)
1332 inline int AtlLoadString(UINT uID, LPTSTR lpBuffer, int nBufferMax)
1333 {
1334 return ::LoadString(ModuleHelper::GetResourceInstance(), uID, lpBuffer, nBufferMax);
1335 }
1336 #else
1337
1338 using ATL::AtlLoadString;
1339
1340 #endif // (_ATL_VER < 0x0700)
1341
1342 #ifdef _WIN32_WCE // CE only direct access to the resource
1343 inline LPCTSTR AtlLoadString(UINT uID)
1344 {
1345 LPCTSTR s = (LPCTSTR)::LoadString(ModuleHelper::GetResourceInstance(), uID, NULL, 0);
1346 #ifdef DEBUG // Check for null-termination
1347 if(s != NULL)
1348 // Note: RC -n <file.rc> compiles null-terminated resource strings
1349 ATLASSERT(s[*((WORD*)s -1) - 1] == L'\0');
1350 #endif
1351 return s;
1352 }
1353 #endif // _WIN32_WCE
1354
1355 inline bool AtlLoadString(UINT uID, BSTR& bstrText)
1356 {
1357 USES_CONVERSION;
1358 ATLASSERT(bstrText == NULL);
1359
1360 LPTSTR lpstrText = NULL;
1361 int nRes = 0;
1362 for(int nLen = 256; ; nLen *= 2)
1363 {
1364 ATLTRY(lpstrText = new TCHAR[nLen]);
1365 if(lpstrText == NULL)
1366 break;
1367 nRes = ::LoadString(ModuleHelper::GetResourceInstance(), uID, lpstrText, nLen);
1368 if(nRes < nLen - 1)
1369 break;
1370 delete [] lpstrText;
1371 lpstrText = NULL;
1372 }
1373
1374 if(lpstrText != NULL)
1375 {
1376 if(nRes != 0)
1377 bstrText = ::SysAllocString(T2OLE(lpstrText));
1378 delete [] lpstrText;
1379 }
1380
1381 return (bstrText != NULL) ? true : false;
1382 }
1383
1384 }; // namespace WTL
1385
1386 #endif // __ATLUSER_H__
+0
-2981
src/third_party/wtl/Include/atlwince.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLWINCE_H__
9 #define __ATLWINCE_H__
10
11 #pragma once
12
13 #ifndef __ATLAPP_H__
14 #error atlwince.h requires atlapp.h to be included first
15 #endif
16
17 #ifndef __ATLWIN_H__
18 #error atlwince.h requires atlwin.h to be included first
19 #endif
20
21 #ifndef _WIN32_WCE
22 #error atlwince.h compiles under Windows CE only
23 #endif
24
25 #if (_WIN32_WCE < 300)
26 #error atlwince.h requires Windows CE 3.0 or higher.
27 #endif
28
29 #if defined(WIN32_PLATFORM_WFSP) && _MSC_VER < 1400 // EVC compiling SmartPhone code
30 #if (WIN32_PLATFORM_WFSP < 200)
31 #error atlwince.h requires Smartphone 2003 or higher
32 #endif
33 #endif // WIN32_PLATFORM_WFSP
34
35 #if defined(WIN32_PLATFORM_PSPC) && _MSC_VER < 1400 // EVC compiling Pocket PC code
36 #if (WIN32_PLATFORM_PSPC < 310)
37 #error atlwince.h requires Pocket PC 2002 or higher
38 #endif
39 #endif // WIN32_PLATFORM_PSPC
40
41 #if !defined(_AYGSHELL_H_) && !defined(__AYGSHELL_H__)
42 #error atlwince.h requires aygshell.h to be included first
43 #else
44 #if defined(WIN32_PLATFORM_WFSP) && !defined(_TPCSHELL_H_)
45 #error SmartPhone dialog classes require tpcshell.h to be included first
46 #endif
47 #endif
48
49 #if (_MSC_VER >= 1400) // VS2005
50 #include <DeviceResolutionAware.h>
51 #define _WTL_CE_DRA
52 #endif // (_MSC_VER >= 1400)
53
54 #if !defined(_WTL_CE_NO_DIALOGS) && !defined(__ATLFRAME_H__)
55 #error Orientation aware dialog classes require atlframe.h to be included first
56 #endif
57
58 #if !defined(_WTL_CE_NO_APPWINDOW) && !defined(__ATLFRAME_H__)
59 #error Application window class require atlframe.h to be included first
60 #endif
61
62 #if !defined(_WTL_CE_NO_ZOOMSCROLL) && !defined(__ATLSCRL_H__)
63 #error ZoomScroll implementation requires atlscrl.h to be included first
64 #endif
65
66 #if !defined(_WTL_CE_NO_ZOOMSCROLL)
67 #if !(defined(__ATLTYPES_H__) || (defined(__ATLMISC_H__) && !defined(_WTL_NO_WTYPES)))
68 #error ZoomScroll requires _WTL_NO_WTYPES not to be defined and either atlmisc.h or atltypes.h to be included first
69 #endif // !(defined(__ATLTYPES_H__) || (defined(__ATLMISC_H__) && !defined(_WTL_NO_WTYPES)))
70 #endif // !defined(_WTL_CE_NO_ZOOMSCROLL)
71
72 #if !defined(WIN32_PLATFORM_WFSP) && !defined(WIN32_PLATFORM_PSPC)
73 #define _WTL_CE_NO_CONTROLS
74 #endif // !defined(WIN32_PLATFORM_WFSP) && !defined(WIN32_PLATFORM_PSPC)
75
76 #ifndef _WTL_CE_NO_CONTROLS
77 #ifndef __ATLCTRLS_H__
78 #error The PPC/SmartPhone controls classes require atlctrls.h to be included first
79 #endif
80
81 #include <htmlctrl.h>
82 #pragma comment(lib, "htmlview.lib")
83
84 #include <voicectl.h>
85 #pragma comment(lib, "voicectl.lib")
86
87 #ifdef WIN32_PLATFORM_PSPC
88 #include <richink.h>
89 #pragma comment(lib, "richink.lib")
90
91 #include <inkx.h>
92 #pragma comment(lib, "inkx.lib")
93
94 #include <doclist.h>
95 #pragma comment(lib, "doclist.lib")
96 #endif
97 #endif
98
99
100 ///////////////////////////////////////////////////////////////////////////////
101 // Classes in this file:
102 //
103 // CStdDialogBase<T, t_shidiFlags, t_bModal> : Standard PPC/SmartPhone dialog base class
104 // CStdDialogImplBase - Base implementation of standard dialog
105 // CStdDialogImpl<T, t_shidiFlags, t_bModal> : Standard dialog implementation
106 // CStdIndirectDialogImpl - implementation of standard indirect PPC/SmartPhone dialog
107 // CStdAxDialogImpl<T, t_shidiFlags, t_bModal> : Standard AxDialog implementation
108 // CStdSimpleDialog<t_wDlgTemplateID, t_shidiFlags> : Standard simple dialog
109 // CStdDialogResizeImplBase - Base implementation of orientation resizing standard dialog
110 // CStdDialogResizeImpl<T, t_shidiFlags, t_bModal> : Orientation resizing standard dialog implementation
111 // CStdAxDialogResizeImpl - implementation of orientation resizing standard AxDialog
112 // CStdSimpleDialogResizeImpl<T, t_wDlgTemplateID, t_shidiFlags> : Standard resizing simple dialog implementation
113 // CStdOrientedDialogBase - Oriented PPC standard dialog base class
114 // CStdOrientedDialogImplBase - Oriented PPC standard dialog base implementation
115 // CStdOrientedDialogImpl<T, t_shidiFlags, t_bModal> : Oriented PPC standard dialog implementation
116 // CStdAxOrientedDialogImpl - Oriented PPC standard AxDialog implementation
117 // CStdSimpleOrientedDialog<t_wDlgTemplateID, t_wDlgLandscapeID, t_shidiFlags> : Standard simple orientable dialog
118 //
119 // CAppInfoBase : Helper for application state save/restore to registry
120 // CAppInfoT<T> : CAppInfoBase constructed from a CAppWindow<T>
121 // CAppWindowBase<T> : Base class for PPC/SmartPhone well-behaved application window or dialog
122 // CAppWindow<T> : PPC/SmartPhone well-behaved application window class
123 // CAppDialog<T> : PPC/SmartPhone well-behaved application dialog class
124 // CAppStdDialogImplBase - Base implementation of standard application dialogs
125 // CAppStdDialogImpl<T, t_shidiFlags, t_bModal> : Implementation of standard application dialog
126 // CAppStdDialogResizeImpl - implementation of orientation resizing standard application dialog
127 // CAppStdAxDialogImpl - Implementation of standard application AxDialog
128 // CAppStdAxDialogResizeImpl - implementation of orientation resizing standard application AxDialog
129 // CAppStdOrientedDialogImpl - implementation of oriented PPC standard application dialog
130 // CAppStdAxOrientedDialogImpl - implementation of oriented PPC standard application AxDialog
131 //
132 // CFullScreenFrame<T, t_bHasSip> : Full screen frame class
133 //
134 // CZoomScrollImpl<T> : WinCE zooming implementation
135 //
136 // CBottomTabViewImpl<T, TBase, TWinTraits> - CBottomTabView
137 // CHtmlCtrlT<TBase> - CHtmlCtrl
138 // CRichInkCtrlT<TBase> - CRichInkCtrl
139 // CInkXCtrlT<TBase> - CInkXCtrl
140 // CVoiceRecorderCtrlT<TBase> - CVoiceRecorderCtrl
141 // CDocListCtrlT<TBase> - CDocListCtrl
142 // CCapEditT<TBase> - CCapEdit
143 // CTTStaticT<TBase> - CTTStatic
144 // CTTButtonT<TBase> - CTTButton
145 //
146 // CSpinCtrlT<TBase> - CSpinCtrl : SmartPhone specific UpDown control
147 // CSpinned<TBase, t_bExpandOnly> : SmartPhone association of control and Spin
148 // CSpinListBox : SmartPhone spinned ListBox control
149 // CExpandListBox : SmartPhone expandable ListBox control
150 // CExpandEdit : SmartPhone expandable Edit control
151 // CExpandCapEdit : SmartPhone expandable CapEdit control
152 //
153 // Global functions:
154 // AtlCreateMenuBar()
155 // AtlCreateEmptyMenuBar()
156 // AtlIsEditFocus()
157 // AtlActivateBackKey()
158
159 namespace WTL
160 {
161
162 ///////////////////////////////////////////////////////////////////////////////
163 // MenuBar creation functions for property sheets and dialogs
164 // Frame windows use CreateSimpleCEMenuBar
165
166 inline HWND AtlCreateMenuBar(SHMENUBARINFO& mbi)
167 {
168 ATLASSERT(::IsWindow(mbi.hwndParent));
169 ATLVERIFY(::SHCreateMenuBar(&mbi) != FALSE);
170 return mbi.hwndMB;
171 };
172
173 inline HWND AtlCreateMenuBar(HWND hWnd, UINT nToolBarId = ATL_IDW_TOOLBAR, DWORD dwFlags = 0, int nBmpId = 0, int cBmpImages = 0, COLORREF clrBk = 0)
174 {
175 SHMENUBARINFO mbi = { sizeof(mbi), hWnd, dwFlags, nToolBarId, ModuleHelper::GetResourceInstance(), nBmpId, cBmpImages, 0, clrBk };
176 return AtlCreateMenuBar(mbi);
177 }
178
179 inline HWND AtlCreateEmptyMenuBar(HWND hWnd, bool bSip = true)
180 {
181 SHMENUBARINFO embi = { sizeof(SHMENUBARINFO), hWnd, SHCMBF_EMPTYBAR };
182 if (!bSip)
183 embi.dwFlags |= SHCMBF_HIDESIPBUTTON;
184
185 return AtlCreateMenuBar(embi);
186 }
187
188 ///////////////////////////////////////////////////////////////////////////////
189 // Helper functions for SmartPhone back key handling
190
191 inline bool AtlIsEditFocus()
192 {
193 ATL::CWindow wCtrl = GetFocus();
194 if (wCtrl.IsWindow())
195 {
196 TCHAR szClassName[8] = {0};
197 ATLVERIFY(::GetClassName(wCtrl.m_hWnd, szClassName, 8));
198 return !_tcscmp(szClassName, _T("Edit")) || !_tcscmp(szClassName, WC_CAPEDIT);
199 }
200 return false;
201 }
202
203 #if defined WIN32_PLATFORM_WFSP
204 inline void AtlActivateBackKey(HWND hMenuBar)
205 {
206 ATLASSERT(::IsWindow(hMenuBar));
207 ::SendMessage(hMenuBar, SHCMBM_OVERRIDEKEY, VK_TBACK,
208 MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, SHMBOF_NODEFAULT | SHMBOF_NOTIFY));
209 }
210 #endif // WIN32_PLATFORM_WFSP
211
212 // --- Standard PPC/SmartPhone dialogs ---
213
214 #ifndef _WTL_CE_NO_DIALOGS
215
216 ///////////////////////////////////////////////////////////////////////////////
217 // CStdDialogBase - base class for standard PPC/SmartPhone dialogs
218
219 #define WTL_STD_SHIDIF SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN
220 #define WTL_SP_SHIDIF SHIDIF_SIZEDLGFULLSCREEN
221
222 // Title setting macros
223 #define WTL_DLG_TITLEHEIGHT(iHeight) static const int GetTitleHeight(){return iHeight;}
224 #define WTL_DLG_NOTITLE WTL_DLG_TITLEHEIGHT(0)
225
226 ///////////////////////////////////////////////////////////////////////////////
227 // CStdDialogBase - Base class for standard PPC/SmartPhone dialog
228
229 template <class T, UINT t_shidiFlags, bool t_bModal = true>
230 class CStdDialogBase
231 {
232 public:
233 #ifdef WIN32_PLATFORM_PSPC
234 // Pocket PC only Dialog title handling
235 const int nTitleHeight;
236
237 CStdDialogBase() : nTitleHeight(T::GetTitleHeight())
238 { }
239
240 // Overloads
241 BOOL GetClientRect(LPRECT lpRect)
242 {
243 T* pT = static_cast<T*>(this);
244 ATLASSERT(pT->IsWindow());
245 BOOL bRes = ::GetClientRect(pT->m_hWnd, lpRect);
246 if (nTitleHeight)
247 lpRect->top += nTitleHeight + 1;
248 return bRes;
249 }
250
251 BOOL SetWindowText(LPCTSTR lpszString)
252 {
253 T* pT = static_cast<T*>(this);
254 ATLASSERT(pT->IsWindow());
255 BOOL bRes = ::SetWindowText(pT->m_hWnd, lpszString);
256 if (nTitleHeight != 0)
257 pT->DoPaintTitle();
258 return bRes;
259 }
260
261 // Overrideables
262 static const int GetTitleHeight()
263 {
264 #ifdef _WTL_CE_DRA
265 return DRA::SCALEY(24);
266 #else // !_WTL_CE_DRA
267 CWindowDC dc(NULL);
268 return dc.GetDeviceCaps(LOGPIXELSY) >> 2; // LOGPIXELSY * 24 / 96,
269 #endif // !_WTL_CE_DRA
270 }
271
272 // Title painting
273 bool DoPaintTitle()
274 {
275 T* pT = static_cast<T*>(this);
276 ATLASSERT(pT->IsWindow());
277 TCHAR sTitle[48] = { 0 };
278
279 // Preparation
280 CPaintDC dc(pT->m_hWnd);
281 CFont fontTitle = AtlCreateBoldFont();
282 CFontHandle fontOld = dc.SelectFont(fontTitle);
283 dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHT));
284 int nLen = pT->GetWindowText(sTitle, 48);
285 int nWidth = dc.GetDeviceCaps(HORZRES);
286
287 // Display title text
288 RECT rTitle = { 0, 0, nWidth, nTitleHeight };
289 dc.FillRect(&rTitle, COLOR_3DHIGHLIGHT);
290 #ifdef _WTL_CE_DRA
291 rTitle.left = DRA::SCALEX(8);
292 #else // !_WTL_CE_DRA
293 rTitle.left = nTitleHeight / 3; // 8 == 24 / 3
294 #endif // !_WTL_CE_DRA
295 dc.DrawText(sTitle, nLen, &rTitle, DT_VCENTER | DT_SINGLELINE);
296 dc.SelectFont(fontOld);
297
298 // Draw bottom line, 2 pixels thick if HI_RES_AWARE
299 CPenHandle penOld = dc.SelectStockPen(BLACK_PEN);
300 POINT line[4] = {{0, nTitleHeight}, {nWidth, nTitleHeight}, {0, nTitleHeight - 1}, {nWidth, nTitleHeight - 1}};
301
302 #ifdef _WTL_CE_DRA
303 int nSeg = DRA::SCALEY(1);
304 #else // !_WTL_CE_DRA
305 int nSeg = nTitleHeight / 24;
306 #endif // !_WTL_CE_DRA
307
308 dc.Polyline(line, nSeg <= 2 ? nSeg * 2 : 4);
309 dc.SelectPen(penOld);
310
311 return false;
312 }
313
314 // Title preparation: move the dialog controls down to make room for title
315 void DialogTitleInit()
316 {
317 T* pT = static_cast<T*>(this);
318 ATLASSERT(pT->IsWindow());
319
320 ATL::CWindow wCtl = pT->GetWindow(GW_CHILD);
321 while (wCtl.IsWindow())
322 {
323 RECT rCtl = { 0 };
324 wCtl.GetWindowRect(&rCtl);
325 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rCtl, 2);
326 ::OffsetRect(&rCtl, 0, nTitleHeight);
327 wCtl.MoveWindow(&rCtl, FALSE);
328 wCtl = wCtl.GetWindow(GW_HWNDNEXT);
329 }
330 }
331
332 // SIP management
333 void DoSipInfo()
334 {
335 T* pT = static_cast<T*>(this);
336 ATLASSERT(pT->IsWindow());
337
338 SIPINFO si = {sizeof(SIPINFO)};
339 SipGetInfo(&si);
340 if ((si.fdwFlags & SIPF_ON) ^ SIPF_ON)
341 si.rcVisibleDesktop.bottom = si.rcSipRect.bottom;
342 pT->MoveWindow(&si.rcVisibleDesktop, FALSE);
343 }
344
345 // Title painting handler
346 LRESULT OnPaintTitle(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
347 {
348 T* pT = static_cast<T*>(this);
349 return bHandled = nTitleHeight ? pT->DoPaintTitle() : FALSE;
350 }
351
352 // SIP handler
353 LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
354 {
355 T* pT = static_cast<T*>(this);
356 if (wParam == SPI_SETSIPINFO)
357 {
358 pT->DoSipInfo();
359 return TRUE;
360 }
361 return bHandled = FALSE;
362 }
363
364 #elif defined WIN32_PLATFORM_WFSP
365 // SmartPhone VK_TBACK key standard management
366 LRESULT OnHotKey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
367 {
368 T* pT = static_cast<T*>(this);
369 const UINT uModif = (UINT)LOWORD(lParam);
370 const UINT uVirtKey = (UINT)HIWORD(lParam);
371
372 if(uVirtKey == VK_TBACK)
373 if (AtlIsEditFocus())
374 ::SHSendBackToFocusWindow(uMsg, wParam, lParam);
375 else if (uModif & MOD_KEYUP)
376 pT->StdCloseDialog(IDCANCEL);
377 return 1;
378 }
379
380 // SmartPhone MenuBar and VK_TBACK key initialization
381 void StdSPInit()
382 {
383 T* pT = static_cast<T*>(this);
384 HWND hMenuBar = ::SHFindMenuBar(pT->m_hWnd);
385
386 if (!hMenuBar && (t_shidiFlags & SHIDIF_DONEBUTTON))
387 hMenuBar = CreateMenuBar(ATL_IDM_MENU_DONE);
388
389 if(hMenuBar != NULL)
390 AtlActivateBackKey(hMenuBar);
391 }
392
393 void SetStaticBold()
394 {
395 T* pT = static_cast<T*>(this);
396 ATLASSERT(pT->IsWindow());
397
398 CFontHandle fontBold = AtlCreateBoldFont(pT->GetFont());
399
400 ATL::CWindow wCtl = pT->GetWindow(GW_CHILD);
401
402 while (wCtl.IsWindow())
403 {
404 if ((short int)wCtl.GetDlgCtrlID() == IDC_STATIC)
405 wCtl.SetFont(fontBold);
406 wCtl = wCtl.GetWindow(GW_HWNDNEXT);
407 }
408 }
409 #endif // WIN32_PLATFORM_WFSP
410
411 // Platform dependant initialization
412 void StdPlatformInit()
413 {
414 T* pT = static_cast<T*>(this);
415 #ifdef WIN32_PLATFORM_PSPC // Pocket PC title initialization
416 if (nTitleHeight != 0)
417 pT->DialogTitleInit();
418 #elif defined(WIN32_PLATFORM_WFSP)
419 pT->StdSPInit();
420 SetStaticBold();
421 #endif // WIN32_PLATFORM_WFSP
422 }
423
424 // Menu bar creation
425 HWND CreateMenuBar(UINT uiMB = T::IDD, int nBmpImages = 0)
426 {
427 T* pT = static_cast<T*>(this);
428 return AtlCreateMenuBar(pT->m_hWnd, uiMB, 0, nBmpImages ? uiMB : 0, nBmpImages);
429 }
430
431 // Dialog closing
432 void StdCloseDialog(WORD wID)
433 {
434 T* pT = static_cast<T*>(this);
435 if (t_bModal)
436 ::EndDialog(pT->m_hWnd, wID);
437 else
438 pT->DestroyWindow();
439 }
440
441 // Shell dialog layout initialization
442 void StdShidInit()
443 {
444 T* pT = static_cast<T*>(this);
445 SHINITDLGINFO shidi = { SHIDIM_FLAGS, pT->m_hWnd, t_shidiFlags };
446 ::SHInitDialog(&shidi);
447 }
448
449 // IDC_INFOSTATIC background setting
450 LRESULT OnColorStatic(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
451 {
452 if (::GetDlgCtrlID((HWND)lParam) == IDC_INFOSTATIC)
453 {
454 ::SetBkMode((HDC)wParam, TRANSPARENT);
455 return (LRESULT)::GetSysColorBrush(COLOR_INFOBK);
456 }
457 return bHandled = FALSE;
458 }
459
460 // Menu dialog ending
461 LRESULT OnMenuClose(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
462 {
463 T* pT = static_cast<T*>(this);
464 pT->StdCloseDialog((WORD)(wID - ID_MENU_OK + IDOK));
465 return 0;
466 }
467
468 // Standard dialog ending: may be used with any command
469 LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
470 {
471 T* pT = static_cast<T*>(this);
472 pT->StdCloseDialog(wID);
473 return 0;
474 }
475 };
476
477
478 ///////////////////////////////////////////////////////////////////////////////
479 // CStdDialogImplBase - Base implementation of standard PPC/SmartPhone dialog
480
481 template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true, class TBase = ATL::CDialogImpl< T > >
482 class ATL_NO_VTABLE CStdDialogImplBase :
483 public TBase,
484 public CStdDialogBase<T, t_shidiFlags, t_bModal>
485 {
486 public:
487 #ifdef WIN32_PLATFORM_PSPC
488 BOOL GetClientRect(LPRECT lpRect)
489 {
490 return CStdDialogBase<T, t_shidiFlags, t_bModal>::GetClientRect(lpRect);
491 }
492
493 BOOL SetWindowText(LPCTSTR lpszString)
494 {
495 return CStdDialogBase<T, t_shidiFlags, t_bModal>::SetWindowText(lpszString);
496 }
497 #endif
498
499 BEGIN_MSG_MAP(CStdDialogImplBase)
500 #ifdef WIN32_PLATFORM_PSPC // Pocket PC title and SIP
501 MESSAGE_HANDLER(WM_PAINT, OnPaintTitle)
502 MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
503 #elif defined(WIN32_PLATFORM_WFSP) // SmartPhone VK_TBACK key
504 MESSAGE_HANDLER(WM_HOTKEY, OnHotKey)
505 #endif
506 MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic)
507 MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
508 COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, OnCloseCmd)
509 COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose)
510 END_MSG_MAP()
511
512 LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
513 {
514 T* pT = static_cast<T*>(this);
515 ATLASSERT(t_bModal == pT->m_bModal);
516 pT->StdPlatformInit();
517 pT->StdShidInit();
518 return bHandled = FALSE;
519 }
520 };
521
522 ///////////////////////////////////////////////////////////////////////////////
523 // CStdDialogImpl - implementation of standard PPC/SmartPhone dialog
524
525 template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true >
526 class ATL_NO_VTABLE CStdDialogImpl : public CStdDialogImplBase< T, t_shidiFlags, t_bModal>
527 {};
528
529 ///////////////////////////////////////////////////////////////////////////////
530 // CStdIndirectDialogImpl - implementation of standard indirect PPC/SmartPhone dialog
531
532 #if defined __ATLDLGS_H__
533
534 template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true>
535 class ATL_NO_VTABLE CStdIndirectDialogImpl :
536 public CIndirectDialogImpl< T, CMemDlgTemplate, CStdDialogImpl<T, t_shidiFlags, t_bModal> >
537 {
538 public:
539 typedef CIndirectDialogImpl< T, CMemDlgTemplate, CStdDialogImpl<T, t_shidiFlags, t_bModal> > _baseClass;
540 typedef CStdDialogImpl<T, t_shidiFlags, t_bModal> _baseStd;
541
542 void CheckStyle()
543 {
544 // Mobile devices don't support DLGTEMPLATEEX
545 ATLASSERT(!m_Template.IsTemplateEx());
546
547 // Standard dialogs need only DS_CENTER
548 DWORD &dwStyle = m_Template.GetTemplatePtr()->style;
549 if (dwStyle & DS_CENTER)
550 if(t_bModal)
551 {
552 ATLASSERT((dwStyle & WS_CHILD) != WS_CHILD);
553 dwStyle |= WS_POPUP;
554 }
555 else
556 {
557 if((dwStyle & WS_CHILD) != WS_CHILD)
558 dwStyle |= WS_POPUP;
559 }
560 }
561
562 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow(), LPARAM dwInitParam = NULL)
563 {
564 ATLASSERT(t_bModal);
565
566 if (!m_Template.IsValid())
567 CreateTemplate();
568
569 CheckStyle();
570
571 return _baseClass::DoModal(hWndParent, dwInitParam);
572 }
573
574 HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL)
575 {
576 ATLASSERT(!t_bModal);
577
578 if (!m_Template.IsValid())
579 CreateTemplate();
580
581 CheckStyle();
582
583 return _baseClass::Create(hWndParent, dwInitParam);
584 }
585
586 BEGIN_MSG_MAP(CStdIndirectDialogImpl)
587 CHAIN_MSG_MAP(_baseStd)
588 END_MSG_MAP()
589
590 };
591
592 #endif // defined __ATLDLGS_H__
593
594 #ifndef _ATL_NO_HOSTING
595
596 ///////////////////////////////////////////////////////////////////////////////
597 // CStdAxDialogImpl - implementation of standard PPC/SmartPhone AxDialog
598
599 template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true >
600 class ATL_NO_VTABLE CStdAxDialogImpl : public CStdDialogImplBase< T, t_shidiFlags, t_bModal, ATL::CAxDialogImpl< T > >
601 {};
602 #endif // _ATL_NO_HOSTING
603
604 ///////////////////////////////////////////////////////////////////////////////
605 // CStdSimpleDialog - standard PPC/SmartPhone simple dialog with SHIDIF_xxx flags
606
607 template <WORD t_wDlgTemplateID, UINT t_shidiFlags = WTL_STD_SHIDIF>
608 class CStdSimpleDialog :
609 public ATL::CSimpleDialog<t_wDlgTemplateID, FALSE>,
610 public CStdDialogBase<CStdSimpleDialog<t_wDlgTemplateID, t_shidiFlags>, t_shidiFlags>
611 {
612 public:
613 typedef CStdDialogBase<CStdSimpleDialog<t_wDlgTemplateID, t_shidiFlags>, t_shidiFlags> baseClass;
614
615 #ifdef WIN32_PLATFORM_PSPC
616 BOOL GetClientRect(LPRECT lpRect)
617 {
618 return baseClass::GetClientRect(lpRect);
619 }
620
621 BOOL SetWindowText(LPCTSTR lpszString)
622 {
623 return baseClass::SetWindowText(lpszString);
624 }
625 #endif
626
627 BEGIN_MSG_MAP(CStdSimpleDialog)
628 #ifdef WIN32_PLATFORM_PSPC // Pocket PC title and SIP
629 MESSAGE_HANDLER(WM_PAINT, OnPaintTitle)
630 MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
631 #elif defined(WIN32_PLATFORM_WFSP) // SmartPhone VK_TBACK key
632 MESSAGE_HANDLER(WM_HOTKEY, OnHotKey)
633 #endif
634 MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic)
635 MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
636 COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose)
637 COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, baseClass::OnCloseCmd)
638 END_MSG_MAP()
639
640 LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
641 {
642 StdPlatformInit();
643 StdShidInit();
644 return bHandled = FALSE;
645 }
646 };
647
648 ///////////////////////////////////////////////////////////////////////////////
649 // CStdDialogResizeImplBase - Base implementation of orientation resizing standard PPC/SmartPhone dialog
650
651 template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true, class TBase = ATL::CDialogImpl<T> >
652 class ATL_NO_VTABLE CStdDialogResizeImplBase :
653 public CStdDialogImplBase< T, t_shidiFlags, t_bModal, TBase>,
654 public CDialogResize<T>
655 {
656 public:
657 // Note: BEGIN_DLGRESIZE_MAP is required in the derived class.
658
659 BEGIN_MSG_MAP(CStdResizeDialogImplBase)
660 #ifdef WIN32_PLATFORM_PSPC // Pocket PC title
661 MESSAGE_HANDLER(WM_PAINT, OnPaintTitle)
662 #elif defined(WIN32_PLATFORM_WFSP) // SmartPhone VK_TBACK key
663 MESSAGE_HANDLER(WM_HOTKEY, OnHotKey)
664 #endif
665 MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic)
666 MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
667 COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, OnCloseCmd)
668 COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose)
669 CHAIN_MSG_MAP(CDialogResize< T >)
670 END_MSG_MAP()
671
672 LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
673 {
674 T* pT = static_cast<T*>(this);
675 ATLASSERT(t_bModal == pT->m_bModal);
676 pT->StdPlatformInit();
677 pT->DlgResize_Init(FALSE);
678 pT->StdShidInit();
679 return bHandled = FALSE;
680 }
681 };
682
683 ///////////////////////////////////////////////////////////////////////////////
684 // CStdDialogResizeImpl - implementation of orientation resizing standard PPC/SmartPhone dialog
685
686 template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true >
687 class ATL_NO_VTABLE CStdDialogResizeImpl : public CStdDialogResizeImplBase< T, t_shidiFlags, t_bModal>
688 {};
689
690 #ifndef _ATL_NO_HOSTING
691
692 ///////////////////////////////////////////////////////////////////////////////
693 // CStdAxDialogResizeImpl - implementation of orientation resizing standard PPC/SmartPhone AxDialog
694
695 template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true >
696 class ATL_NO_VTABLE CStdAxDialogResizeImpl : public CStdDialogResizeImplBase< T, t_shidiFlags, t_bModal, ATL::CAxDialogImpl<T> >
697 {};
698 #endif // _ATL_NO_HOSTING
699
700 ///////////////////////////////////////////////////////////////////////////////
701 // CStdSimpleDialogResizeImpl - implementation of standard resizing simple dialog with SHIDIF_xxx flags
702
703 // Usage:
704 // class CMyDlg : public CStdSimpleDialogResize<CMyDlg,
705 // IDD_MYDLG, SHIDIF_DONEBUTTON | SHIDIF_FULLSCREENNOMENUBAR>
706 // {
707 // public:
708 // BEGIN_DLGRESIZE_MAP(CMyDlg)
709 // ...
710 // END_DLGRESIZE_MAP()
711 // };
712
713 template <class T, WORD t_wDlgTemplateID, UINT t_shidiFlags = WTL_STD_SHIDIF>
714 class ATL_NO_VTABLE CStdSimpleDialogResizeImpl :
715 public CStdSimpleDialog<t_wDlgTemplateID, t_shidiFlags>,
716 public CDialogResize< T >
717 {
718 public:
719 typedef CStdSimpleDialog<t_wDlgTemplateID, t_shidiFlags>::baseClass baseClass;
720
721 BEGIN_MSG_MAP(CStdSimpleDialogResizeImpl)
722 #ifdef WIN32_PLATFORM_PSPC // Pocket PC title
723 MESSAGE_HANDLER(WM_PAINT, OnPaintTitle)
724 #elif defined(WIN32_PLATFORM_WFSP) // SmartPhone VK_TBACK key
725 MESSAGE_HANDLER(WM_HOTKEY, OnHotKey)
726 #endif
727 MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic)
728 MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
729 COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, baseClass::OnCloseCmd)
730 COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose)
731 CHAIN_MSG_MAP(CDialogResize< T >)
732 END_MSG_MAP()
733
734 LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
735 {
736 T* pT = static_cast<T*>(this);
737 pT->StdPlatformInit();
738 pT->DlgResize_Init(FALSE);
739 pT->StdShidInit();
740 return bHandled = FALSE;
741 }
742 };
743
744 #if defined(_WTL_CE_DRA) && defined(WIN32_PLATFORM_PSPC)
745
746 ///////////////////////////////////////////////////////////////////////////////
747 // CStdOrientedDialogBase - Oriented PPC standard dialog base class
748
749 template <class T>
750 class CStdOrientedDialogBase
751 {
752 public:
753 // Operation
754 BOOL SetOrientation(DRA::DisplayMode mode)
755 {
756 T* pT = static_cast<T*>(this);
757 ATLASSERT(pT->IsWindow());
758 ATLASSERT(mode == DRA::GetDisplayMode());
759
760 // Derived dialog must enumerate TWO dialog templates with the same control ids and types ie:
761 // enum { IDD = IDD_MYDLG, IDD_LANDSCAPE = IDD_MYDLG_L };
762 UINT iResource = (mode == DRA::Landscape)? T::IDD_LANDSCAPE : T::IDD;
763
764 BOOL bRes = DRA::RelayoutDialog(ModuleHelper::GetResourceInstance(), pT->m_hWnd, MAKEINTRESOURCE(iResource));
765 pT->OnOrientation(mode);
766 return bRes;
767 }
768
769 // Override
770 void OnOrientation(DRA::DisplayMode /*mode*/)
771 {}
772
773 // Message handlers
774 LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
775 {
776 T* pT = static_cast<T*>(this);
777 ATLASSERT(pT->IsWindow());
778 if (wParam == SETTINGCHANGE_RESET)
779 {
780 pT->SetOrientation(DRA::GetDisplayMode());
781 pT->StdPlatformInit();
782 pT->StdShidInit();
783 }
784 else if (wParam == SPI_SETSIPINFO)
785 {
786 pT->DoSipInfo();
787 return TRUE;
788 }
789 return bHandled = FALSE;
790 }
791 };
792
793 ///////////////////////////////////////////////////////////////////////////////
794 // CStdOrientedDialogImplBase - Oriented PPC standard dialog base implementation
795
796 template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true, class TBase = ATL::CDialogImpl<T> >
797 class ATL_NO_VTABLE CStdOrientedDialogImplBase :
798 public CStdDialogImplBase< T, t_shidiFlags, t_bModal, TBase>,
799 public CStdOrientedDialogBase<T>
800 {
801 public:
802 BEGIN_MSG_MAP(CStdOrientedDialogImpl)
803 MESSAGE_HANDLER(WM_PAINT, OnPaintTitle)
804 MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic)
805 MESSAGE_HANDLER(WM_SETTINGCHANGE, CStdOrientedDialogBase<T>::OnSettingChange)
806 MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
807 COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, OnCloseCmd)
808 COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose)
809 END_MSG_MAP()
810
811 LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
812 {
813 T* pT = static_cast<T*>(this);
814 #ifdef _DEBUG
815 ATLASSERT(t_bModal == pT->m_bModal);
816 #endif
817 if (DRA::GetDisplayMode() == DRA::Landscape)
818 pT->SetOrientation(DRA::Landscape);
819 pT->StdPlatformInit();
820 pT->StdShidInit();
821 return bHandled = FALSE;
822 }
823 };
824
825 ///////////////////////////////////////////////////////////////////////////////
826 // CStdOrientedDialogImpl - Oriented PPC standard dialog implementation
827
828 template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true >
829 class ATL_NO_VTABLE CStdOrientedDialogImpl : public CStdOrientedDialogImplBase< T, t_shidiFlags, t_bModal>
830 {};
831
832 #ifndef _ATL_NO_HOSTING
833 ///////////////////////////////////////////////////////////////////////////////
834 // CStdAxOrientedDialogImpl - Oriented PPC standard AxDialog implementation
835
836 template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true >
837 class ATL_NO_VTABLE CStdAxOrientedDialogImpl : public CStdOrientedDialogImplBase< T, t_shidiFlags, t_bModal, ATL::CAxDialogImpl<T> >
838 {};
839 #endif // _ATL_NO_HOSTING
840
841 ///////////////////////////////////////////////////////////////////////////////
842 // CStdSimpleOrientedDialog - Standard simple orientable dialog
843
844 template <WORD t_wDlgTemplateID, WORD t_wDlgLandscapeID, UINT t_shidiFlags = WTL_STD_SHIDIF>
845 class CStdSimpleOrientedDialog :
846 public CStdSimpleDialog<t_wDlgTemplateID, t_shidiFlags>,
847 public CStdOrientedDialogBase<CStdSimpleOrientedDialog<t_wDlgTemplateID, t_wDlgLandscapeID, t_shidiFlags> >
848 {
849 public:
850 typedef CStdSimpleDialog<t_wDlgTemplateID, t_shidiFlags>::baseClass baseClass;
851 typedef CStdOrientedDialogBase<CStdSimpleOrientedDialog<t_wDlgTemplateID, t_wDlgLandscapeID, t_shidiFlags> > baseOriented;
852
853 enum {IDD = t_wDlgTemplateID, IDD_LANDSCAPE = t_wDlgLandscapeID};
854
855 BEGIN_MSG_MAP(CStdSimpleDialog)
856 MESSAGE_HANDLER(WM_PAINT, OnPaintTitle)
857 MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic)
858 MESSAGE_HANDLER(WM_SETTINGCHANGE, baseOriented::OnSettingChange)
859 MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
860 COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, baseClass::OnCloseCmd)
861 COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose)
862 END_MSG_MAP()
863
864 LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
865 {
866 if (DRA::GetDisplayMode() == DRA::Landscape)
867 SetOrientation(DRA::Landscape);
868 StdPlatformInit();
869 StdShidInit();
870 return bHandled = FALSE;
871 }
872 };
873
874 #endif // _WTL_CE_DRA
875
876
877 #endif // _WTL_CE_NO_DIALOGS
878
879
880 // --- PPC/SmartPhone application window and helpers ---
881
882 #ifndef _WTL_CE_NO_APPWINDOW
883
884 ///////////////////////////////////////////////////////////////////////////////
885 // CAppInfoBase - Helper for application state save/restore to registry
886
887 class CAppInfoBase
888 {
889 public:
890 CRegKeyEx m_Key;
891
892 CAppInfoBase(ATL::_U_STRINGorID sAppKey)
893 {
894 m_Key.Create(HKEY_CURRENT_USER, sAppKey.m_lpstr);
895 ATLASSERT(m_Key.m_hKey);
896 }
897
898 template <class V>
899 LONG Save(V& val, ATL::_U_STRINGorID sName)
900 {
901 return m_Key.SetBinaryValue(sName.m_lpstr, &val, sizeof(V));
902 }
903
904 template <class V>
905 LONG Save(int nb, V& val0, ATL::_U_STRINGorID sName)
906 {
907 return m_Key.SetBinaryValue(sName.m_lpstr, &val0, nb * sizeof(V));
908 }
909
910 template <class V>
911 LONG Restore(V& val, ATL::_U_STRINGorID sName)
912 {
913 ULONG bufSize = sizeof(V);
914 return m_Key.QueryBinaryValue(sName.m_lpstr, &val, &bufSize);
915 }
916
917 template <class V>
918 LONG Restore(int nb, V& val0, ATL::_U_STRINGorID sName)
919 {
920 ULONG bufSize = nb * sizeof(V);
921 return m_Key.QueryBinaryValue(sName.m_lpstr, &val0, &bufSize);
922 }
923
924 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
925 LONG Save(_CSTRING_NS::CString& sval, ATL::_U_STRINGorID sName)
926 {
927 return m_Key.SetStringValue(sName.m_lpstr, sval);
928 }
929
930 LONG Restore(_CSTRING_NS::CString& sval, ATL::_U_STRINGorID sName)
931 {
932 DWORD size = MAX_PATH;
933 LONG res = m_Key.QueryStringValue(sName.m_lpstr, sval.GetBuffer(size), &size);
934 sval.ReleaseBuffer();
935 return res;
936 }
937 #else
938 #pragma message("Warning: CAppInfoBase compiles without CString support. Do not use CString in Save or Restore.")
939 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
940
941 LONG Save(LPCTSTR sval, ATL::_U_STRINGorID sName)
942 {
943 return m_Key.SetStringValue(sName.m_lpstr, sval);
944 }
945
946 LONG Restore(LPTSTR sval, ATL::_U_STRINGorID sName, DWORD *plength)
947 {
948 return m_Key.QueryStringValue(sName.m_lpstr, sval, plength);
949 }
950
951 LONG Delete(ATL::_U_STRINGorID sName)
952 {
953 return m_Key.DeleteValue(sName.m_lpstr);
954 }
955 };
956
957
958 ///////////////////////////////////////////////////////////////////////////////
959 // CAppInfoT - CAppInfoBase constructed from a class with T::GetAppKey()
960
961 // Macro for declaring AppKey
962 #define DECLARE_APPKEY(uAppKey) \
963 static LPCTSTR GetAppKey() \
964 { \
965 static LPCTSTR sAppKey = ATL::_U_STRINGorID(uAppKey).m_lpstr; \
966 return sAppKey; \
967 }
968
969 template <class T>
970 class CAppInfoT : public CAppInfoBase
971 {
972 public:
973 CAppInfoT() : CAppInfoBase(T::GetAppKey()){}
974 };
975
976
977 ///////////////////////////////////////////////////////////////////////////////
978 // CAppWindowBase - Base class for PPC/SmartPhone "well-behaved" application window or dialog
979
980 // Macros for declaring frame WNDCLASS and AppKey
981 #define DECLARE_APP_FRAME_CLASS(WndClassName, uCommonResourceID, uAppKey) \
982 DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) \
983 DECLARE_APPKEY(uAppKey)
984
985 #define DECLARE_APP_FRAME_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd, uAppKey) \
986 DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd) \
987 DECLARE_APPKEY(uAppKey)
988
989 template <class T>
990 class CAppWindowBase
991 {
992 public:
993 typedef class CAppInfoT< T > CAppInfo;
994
995 #ifndef WIN32_PLATFORM_WFSP
996 SHACTIVATEINFO m_sai; // NoOp on SmartPhones
997 #endif // WIN32_PLATFORM_WFSP
998
999 bool m_bHibernate;
1000
1001 CAppWindowBase< T >() : m_bHibernate(false)
1002 {
1003 #ifndef WIN32_PLATFORM_WFSP
1004 SHACTIVATEINFO sai = { sizeof(SHACTIVATEINFO) };
1005 m_sai = sai;
1006 #endif // WIN32_PLATFORM_WFSP
1007 };
1008
1009 // Same as WTL 7.1 AppWizard generated ActivatePreviousInstance + SendMessage WM_COPYDATA
1010 static HRESULT ActivatePreviousInstance(HINSTANCE hInstance, LPCTSTR lpstrCmdLine, bool bDialog)
1011 {
1012 // requires T does DECLARE_APP_FRAME_CLASS, DECLARE_APP_FRAME_CLASS_EX or DECLARE_APP_DLG_CLASS
1013 CFrameWndClassInfo& classInfo = T::GetWndClassInfo();
1014
1015 ATLVERIFY(::LoadString(hInstance, classInfo.m_uCommonResourceID, classInfo.m_szAutoName, sizeof(classInfo.m_szAutoName)/sizeof(classInfo.m_szAutoName[0])) != 0);
1016
1017 classInfo.m_wc.lpszClassName = classInfo.m_szAutoName;
1018
1019 const TCHAR* pszClass = classInfo.m_wc.lpszClassName;
1020
1021 if(NULL == pszClass || '\0' == *pszClass)
1022 {
1023 return E_FAIL;
1024 }
1025
1026 const DWORD dRetryInterval = 100;
1027 const int iMaxRetries = 25;
1028
1029 for(int i = 0; i < iMaxRetries; ++i)
1030 {
1031 HANDLE hMutex = CreateMutex(NULL, FALSE, pszClass);
1032
1033 DWORD dw = GetLastError();
1034
1035 if(NULL == hMutex)
1036 {
1037 HRESULT hr;
1038
1039 switch(dw)
1040 {
1041 case ERROR_INVALID_HANDLE:
1042 // A non-mutext object with this name already exists.
1043 hr = E_INVALIDARG;
1044 break;
1045 default:
1046 // This should never happen...
1047 hr = E_FAIL;
1048 }
1049
1050 return hr;
1051 }
1052
1053 // If the mutex already exists, then there should be another instance running
1054 if(dw == ERROR_ALREADY_EXISTS)
1055 {
1056 CloseHandle(hMutex);
1057
1058 HWND hwnd = NULL;
1059 if (bDialog)
1060 hwnd = FindWindow(NULL, pszClass);
1061 else
1062 hwnd = FindWindow(pszClass, NULL);
1063
1064 if(hwnd == NULL)
1065 {
1066 Sleep(dRetryInterval);
1067 continue;
1068 }
1069 else
1070 {
1071 // Transmit our params to previous instance
1072 if (lpstrCmdLine && *lpstrCmdLine)
1073 {
1074 COPYDATASTRUCT cd = { NULL, sizeof(TCHAR) * (wcslen(lpstrCmdLine) + 1), (PVOID)lpstrCmdLine };
1075 ::SendMessage(hwnd, WM_COPYDATA, NULL, (LPARAM)&cd);
1076 }
1077 // Set the previous instance as the foreground window
1078 if(0 != SetForegroundWindow(reinterpret_cast<HWND>(reinterpret_cast<ULONG>(hwnd) | 0x1)))
1079 return S_FALSE;
1080 }
1081 }
1082 else
1083 {
1084 return S_OK;
1085 }
1086 }
1087 return S_OK;
1088 }
1089
1090 // Operations overriden in derived class
1091 bool AppHibernate(bool /*bHibernate*/)
1092 {
1093 return false;
1094 }
1095
1096 bool AppNewInstance(LPCTSTR /*lpstrCmdLine*/)
1097 {
1098 return false;
1099 }
1100
1101 void AppSave()
1102 {
1103 }
1104
1105 #ifdef WIN32_PLATFORM_WFSP
1106 void AppBackKey()
1107 {
1108 ::SHNavigateBack();
1109 }
1110 #endif
1111
1112 // Message map and handlers
1113 BEGIN_MSG_MAP(CAppWindowBase)
1114 MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
1115 #ifdef WIN32_PLATFORM_WFSP
1116 MESSAGE_HANDLER(WM_HOTKEY, OnHotKey)
1117 #else
1118 MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
1119 #endif // WIN32_PLATFORM_WFSP
1120 MESSAGE_HANDLER(WM_HIBERNATE, OnHibernate)
1121 MESSAGE_HANDLER(WM_COPYDATA, OnNewInstance)
1122 MESSAGE_HANDLER(WM_CLOSE, OnClose)
1123 END_MSG_MAP()
1124
1125 LRESULT OnActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1126 {
1127 T* pT = static_cast<T*>(this);
1128 if (m_bHibernate)
1129 m_bHibernate = pT->AppHibernate(false);
1130 #ifndef WIN32_PLATFORM_WFSP
1131 ::SHHandleWMActivate(pT->m_hWnd, wParam, lParam, &m_sai, 0);
1132 #else
1133 wParam;
1134 lParam;
1135 #endif // WIN32_PLATFORM_WFSP
1136 return bHandled = FALSE;
1137 }
1138
1139 #ifdef WIN32_PLATFORM_WFSP
1140 // SmartPhone VK_TBACK key standard management
1141 LRESULT OnHotKey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
1142 {
1143 T* pT = static_cast<T*>(this);
1144 const UINT uModif = (UINT)LOWORD(lParam);
1145 const UINT uVirtKey = (UINT)HIWORD(lParam);
1146 if(uVirtKey == VK_TBACK)
1147 if (AtlIsEditFocus())
1148 ::SHSendBackToFocusWindow(uMsg, wParam, lParam);
1149 else if (uModif & MOD_KEYUP)
1150 pT->AppBackKey();
1151 return 1;
1152 }
1153
1154 #else // !WIN32_PLATFORM_WFSP
1155 // PPC SIP handling
1156 LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1157 {
1158 T* pT = static_cast<T*>(this);
1159 bHandled = FALSE;
1160 return ::SHHandleWMSettingChange(pT->m_hWnd, wParam, lParam, &m_sai);
1161 }
1162 #endif // !WIN32_PLATFORM_WFSP
1163
1164 LRESULT OnHibernate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1165 {
1166 T* pT = static_cast<T*>(this);
1167 return m_bHibernate = pT->AppHibernate(true);
1168 }
1169
1170 LRESULT OnNewInstance(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
1171 {
1172 T* pT = static_cast<T*>(this);
1173 PCOPYDATASTRUCT pcds = (PCOPYDATASTRUCT)lParam;
1174 return pT->AppNewInstance((LPCTSTR)pcds->lpData);
1175 }
1176
1177 LRESULT OnClose(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
1178 {
1179 T* pT = static_cast<T*>(this);
1180 pT->AppSave();
1181 bHandled = FALSE;
1182 return 1;
1183 }
1184 };
1185
1186
1187 ///////////////////////////////////////////////////////////////////////////////
1188 // CAppWindow - PPC/SmartPhone "well-behaved" application window class
1189
1190 template <class T>
1191 class CAppWindow : public CAppWindowBase< T >
1192 {
1193 public:
1194 // Same as WTL 7.1 AppWizard generated Run + lpstrCmdLine in CreateEx
1195 static int AppRun(LPTSTR lpstrCmdLine = NULL, int nCmdShow = SW_SHOWNORMAL)
1196 {
1197 CMessageLoop theLoop;
1198 _Module.AddMessageLoop(&theLoop);
1199
1200 T wndMain;
1201
1202 if(wndMain.CreateEx(NULL, NULL, 0, 0, lpstrCmdLine) == NULL)
1203 {
1204 ATLTRACE2(atlTraceUI, 0, _T("Main window creation failed!\n"));
1205 return 0;
1206 }
1207
1208 wndMain.ShowWindow(nCmdShow);
1209
1210 int nRet = theLoop.Run();
1211
1212 _Module.RemoveMessageLoop();
1213 return nRet;
1214 }
1215
1216 static HRESULT ActivatePreviousInstance(HINSTANCE hInstance, LPCTSTR lpstrCmdLine)
1217 {
1218 return CAppWindowBase< T >::ActivatePreviousInstance(hInstance, lpstrCmdLine, false);
1219 }
1220 };
1221
1222
1223 #ifndef _WTL_CE_NO_DIALOGS
1224
1225 ///////////////////////////////////////////////////////////////////////////////
1226 // CAppDialog - PPC/SmartPhone "well-behaved" dialog application class
1227
1228 // Macro for declaring dialog WNDCLASS and AppKey
1229 #define DECLARE_APP_DLG_CLASS(WndClassName, uCommonResourceID, uAppKey) \
1230 static WTL::CFrameWndClassInfo& GetWndClassInfo() \
1231 { \
1232 static WTL::CFrameWndClassInfo wc = \
1233 { \
1234 { 0, (WNDPROC)StartDialogProc, \
1235 0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndClassName }, \
1236 NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \
1237 }; \
1238 return wc; \
1239 }; \
1240 DECLARE_APPKEY(uAppKey)
1241
1242 template <class T>
1243 class CAppDialog : public CAppWindowBase< T >
1244 {
1245 public:
1246 static int AppRun(LPTSTR lpstrCmdLine = NULL, int nCmdShow = SW_SHOWNORMAL)
1247 {
1248 CMessageLoop theLoop;
1249 _Module.AddMessageLoop(&theLoop);
1250
1251 T dlgMain;
1252
1253 if(dlgMain.Create(NULL, (LPARAM)lpstrCmdLine) == NULL)
1254 {
1255 ATLTRACE2(atlTraceUI, 0, _T("Main dialog creation failed!\n"));
1256 return 0;
1257 }
1258
1259 dlgMain.ShowWindow(nCmdShow);
1260
1261 int nRet = theLoop.Run();
1262
1263 _Module.RemoveMessageLoop();
1264 return nRet;
1265 }
1266
1267 static HRESULT ActivatePreviousInstance(HINSTANCE hInstance, LPCTSTR lpstrCmdLine)
1268 {
1269 return CAppWindowBase< T >::ActivatePreviousInstance(hInstance, lpstrCmdLine, true);
1270 };
1271 };
1272
1273 // PPC/SmartPhone standard application dialogs
1274
1275 #ifdef WIN32_PLATFORM_WFSP
1276 #define WTL_APP_SHIDIF WTL_SP_SHIDIF
1277 #else
1278 #define WTL_APP_SHIDIF WTL_STD_SHIDIF
1279 #endif
1280
1281 ///////////////////////////////////////////////////////////////////////////////
1282 // CAppStdDialogImplBase - Base implementation of standard application dialogs
1283
1284 template <class T, class TImplBase, UINT t_shidiFlags = WTL_APP_SHIDIF, bool t_bModal = false>
1285 class ATL_NO_VTABLE CAppStdDialogImplBase :
1286 public TImplBase,
1287 public CAppDialog< T >
1288 {
1289 public:
1290 WTL_DLG_NOTITLE;
1291
1292 void StdCloseDialog(int nVal)
1293 {
1294 T* pT = static_cast<T*>(this);
1295 if (nVal != IDCANCEL)
1296 pT->AppSave();
1297 if (t_bModal == false)
1298 {
1299 pT->DestroyWindow();
1300 ::PostQuitMessage(nVal);
1301 }
1302 else
1303 ::EndDialog(pT->m_hWnd, nVal);
1304 }
1305
1306 BEGIN_MSG_MAP(CAppStdDialogImplBase)
1307 MESSAGE_HANDLER(WM_CLOSE, OnSystemClose)
1308 CHAIN_MSG_MAP(TImplBase)
1309 CHAIN_MSG_MAP(CAppDialog< T >)
1310 END_MSG_MAP()
1311
1312 LRESULT OnSystemClose(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1313 {
1314 T* pT = static_cast<T*>(this);
1315 pT->StdCloseDialog(IDCANCEL);
1316 return 0;
1317 }
1318 };
1319
1320 ///////////////////////////////////////////////////////////////////////////////
1321 // CAppStdDialogImpl - Implementation of standard application dialog
1322
1323 template <class T, UINT t_shidiFlags = WTL_APP_SHIDIF, bool t_bModal = false>
1324 class ATL_NO_VTABLE CAppStdDialogImpl :
1325 public CAppStdDialogImplBase<T, CStdDialogImpl<T, t_shidiFlags, t_bModal>, t_shidiFlags, t_bModal>
1326 {};
1327
1328 ///////////////////////////////////////////////////////////////////////////////
1329 // CAppStdDialogResizeImpl - implementation of orientation resizing standard application dialog
1330
1331 template <class T, UINT t_shidiFlags = WTL_APP_SHIDIF, bool t_bModal = false>
1332 class ATL_NO_VTABLE CAppStdDialogResizeImpl :
1333 public CAppStdDialogImplBase<T, CStdDialogResizeImpl<T, t_shidiFlags, t_bModal>, t_shidiFlags, t_bModal>
1334 {};
1335
1336 #ifndef _ATL_NO_HOSTING
1337 ///////////////////////////////////////////////////////////////////////////////
1338 // CAppStdAxDialogImpl - Implementation of standard application AxDialog
1339
1340 template <class T, UINT t_shidiFlags = WTL_APP_SHIDIF, bool t_bModal = false>
1341 class ATL_NO_VTABLE CAppStdAxDialogImpl :
1342 public CAppStdDialogImplBase<T, CStdAxDialogImpl<T, t_shidiFlags, t_bModal>, t_shidiFlags, t_bModal>
1343 {};
1344
1345 ///////////////////////////////////////////////////////////////////////////////
1346 // CAppStdAxDialogResizeImpl - implementation of orientation resizing standard application AxDialog
1347
1348 template <class T, UINT t_shidiFlags = WTL_APP_SHIDIF, bool t_bModal = false>
1349 class ATL_NO_VTABLE CAppStdAxDialogResizeImpl :
1350 public CAppStdDialogImplBase<T, CStdAxDialogResizeImpl<T, t_shidiFlags, t_bModal>, t_shidiFlags, t_bModal>
1351 {};
1352 #endif // _ATL_NO_HOSTING
1353
1354 #if defined(_WTL_CE_DRA) && defined(WIN32_PLATFORM_PSPC)
1355 ///////////////////////////////////////////////////////////////////////////////
1356 // CAppStdOrientedDialogImpl - implementation of oriented PPC standard application dialog
1357
1358 template <class T, UINT t_shidiFlags = WTL_APP_SHIDIF, bool t_bModal = false>
1359 class ATL_NO_VTABLE CAppStdOrientedDialogImpl :
1360 public CAppStdDialogImplBase<T, CStdOrientedDialogImpl<T, t_shidiFlags, t_bModal>, t_shidiFlags, t_bModal>
1361 {};
1362
1363 #ifndef _ATL_NO_HOSTING
1364 ///////////////////////////////////////////////////////////////////////////////
1365 // CAppStdAxOrientedDialogImpl - implementation of oriented PPC standard application AxDialog
1366
1367 template <class T, UINT t_shidiFlags = WTL_APP_SHIDIF, bool t_bModal = false>
1368 class ATL_NO_VTABLE CAppStdAxOrientedDialogImpl :
1369 public CAppStdDialogImplBase<T, CStdAxOrientedDialogImpl<T, t_shidiFlags, t_bModal>, t_shidiFlags, t_bModal>
1370 {};
1371 #endif // _ATL_NO_HOSTING
1372
1373 #endif // defined(_WTL_CE_DRA) && defined(WIN32_PLATFORM_PSPC)
1374
1375 #endif // _WTL_CE_NO_DIALOGS
1376
1377 #endif // _WTL_CE_NO_APPWINDOW
1378
1379
1380 // --- Full screen support ---
1381
1382 #ifndef _WTL_CE_NO_FULLSCREEN
1383
1384 ///////////////////////////////////////////////////////////////////////////////
1385 // CFullScreenFrame - full screen frame implementation
1386
1387 template <class T, bool t_bHasSip = true>
1388 class CFullScreenFrame
1389 {
1390 public:
1391 bool m_bFullScreen;
1392
1393 CFullScreenFrame() : m_bFullScreen(false)
1394 { }
1395
1396 // Operation
1397 void SetFullScreen(bool bFull)
1398 {
1399 m_bFullScreen = bFull;
1400 ShowTaskBar(!bFull, false);
1401 ShowMenuBar(!bFull);
1402 }
1403
1404 // Manage TaskBar for modal dialogs and property sheets
1405 template <class D>
1406 int FSDoModal(D& dlg)
1407 {
1408 T* pT = static_cast<T*>(this);
1409 pT; // avoid level 4 warning
1410 ATLASSERT(pT->IsWindow());
1411 if (m_bFullScreen) // Show taskbar if hidden
1412 ShowTaskBar(true, false);
1413 int iRet = dlg.DoModal();
1414 if (m_bFullScreen) // Hide taskbar if restored
1415 ShowTaskBar(false);
1416 return iRet;
1417 }
1418
1419 // Implementation
1420 void ShowMenuBar(bool bShow)
1421 {
1422 T* pT = static_cast<T*>(this);
1423 ATLASSERT(pT->IsWindow());
1424 ATL::CWindow MenuBar = pT->m_hWndCECommandBar;
1425 ATLASSERT(MenuBar.IsWindow());
1426 MenuBar.ShowWindow(bShow ? SW_SHOWNORMAL : SW_HIDE);
1427 pT->SizeToMenuBar();
1428 }
1429
1430 void ShowTaskBar(bool bShow, bool bRepaint = true)
1431 {
1432 T* pT = static_cast<T*>(this);
1433 ATLASSERT(pT->IsWindow());
1434 RECT rect = { 0 };
1435 SystemParametersInfo(SPI_GETWORKAREA, NULL, &rect, FALSE);
1436 if (!bShow)
1437 rect.top = 0;
1438
1439 #ifdef WIN32_PLATFORM_PSPC // Pocket PC code
1440 UINT uShow = t_bHasSip ? SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON : SHFS_SHOWTASKBAR | SHFS_HIDESIPBUTTON;
1441 SHFullScreen(pT->m_hWnd, bShow ? uShow : SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON);
1442 #elif _WIN32_WCE > 0x500 // Smartphone 2005 code
1443 SHFullScreen(pT->m_hWnd, bShow ? SHFS_SHOWTASKBAR : SHFS_HIDETASKBAR);
1444 #else // Smartphone 2003
1445 HWND hTaskBar = FindWindow(_T("tray"), NULL);
1446 ATLASSERT(::IsWindow(hTaskBar));
1447 ::ShowWindow(hTaskBar, bShow ? SW_SHOW : SW_HIDE);
1448 #endif // WIN32_PLATFORM_PSPC
1449
1450 pT->MoveWindow(&rect, bRepaint);
1451 }
1452
1453 // Message map and handler
1454 BEGIN_MSG_MAP(CFullScreenFrame)
1455 MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
1456 MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
1457 END_MSG_MAP()
1458
1459 LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
1460 {
1461 #ifndef SETTINGCHANGE_RESET // not defined for PPC 2002
1462 #define SETTINGCHANGE_RESET SPI_SETWORKAREA
1463 #endif
1464 if (m_bFullScreen && (wParam == SETTINGCHANGE_RESET))
1465 SetFullScreen(m_bFullScreen);
1466 return bHandled = FALSE;
1467 }
1468
1469 LRESULT OnActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
1470 {
1471 if (m_bFullScreen)
1472 {
1473 ShowTaskBar(!wParam);
1474 ShowMenuBar(!wParam);
1475 }
1476 return bHandled = FALSE;
1477 }
1478 };
1479
1480 #endif // _WTL_CE_NO_FULLSCREEN
1481
1482
1483 // --- WinCE zoom support ---
1484
1485 #ifndef _WTL_CE_NO_ZOOMSCROLL
1486
1487 ///////////////////////////////////////////////////////////////////////////////
1488 // CZoomScrollImpl - WinCE zooming implementation on top of CScrollImpl
1489
1490 template <class T>
1491 class CZoomScrollImpl: public CScrollImpl< T >
1492 {
1493 public:
1494 // Data members
1495 _WTYPES_NS::CSize m_sizeTrue;
1496 double m_fzoom;
1497
1498 // Creation
1499 CZoomScrollImpl() : m_sizeTrue(0), m_fzoom(1.)
1500 { }
1501
1502 // Zoom operations and access
1503 void SetZoomScrollSize(_WTYPES_NS::CSize sizeTrue, double fzoom = 1., BOOL bRedraw = TRUE)
1504 {
1505 ATLASSERT(fzoom > 0.);
1506 m_sizeTrue = sizeTrue;
1507 m_fzoom = fzoom;
1508
1509 CScrollImpl< T >::SetScrollSize(sizeTrue / fzoom, bRedraw);
1510 }
1511
1512 void SetZoomScrollSize(int cx, int cy, double fzoom=1., BOOL bRedraw = TRUE)
1513 {
1514 SetZoomScrollSize(_WTYPES_NS::CSize(cx, cy), fzoom, bRedraw);
1515 }
1516
1517 void SetZoom(double fzoom, BOOL bRedraw = TRUE)
1518 {
1519 _WTYPES_NS::CPoint ptCenter = WndtoTrue(m_sizeClient / 2);
1520 _WTYPES_NS::CSize sizePage = GetScrollPage();
1521 _WTYPES_NS::CSize sizeLine = GetScrollLine();
1522
1523 SetZoomScrollSize(GetScrollSize(), fzoom, bRedraw);
1524
1525 SetScrollLine(sizeLine);
1526 SetScrollPage(sizePage);
1527 _WTYPES_NS::CPoint ptOffset = ptCenter - (m_sizeClient / 2) * fzoom;
1528 SetScrollOffset(ptOffset, bRedraw);
1529 }
1530
1531 double GetZoom()
1532 {
1533 return m_fzoom;
1534 }
1535
1536 // CScrollImpl overrides
1537 void SetScrollOffset(int x, int y, BOOL bRedraw = TRUE)
1538 {
1539 CScrollImpl< T >::SetScrollOffset((int)(x / m_fzoom), (int)(y / m_fzoom), bRedraw);
1540 }
1541
1542 void SetScrollOffset(POINT ptOffset, BOOL bRedraw = TRUE)
1543 {
1544 SetScrollOffset(ptOffset.x, ptOffset.y, bRedraw);
1545 }
1546
1547 void GetScrollOffset(POINT& ptOffset)
1548 {
1549 ptOffset.x = (LONG)(m_ptOffset.x * m_fzoom);
1550 ptOffset.y = (LONG)(m_ptOffset.y * m_fzoom);
1551 }
1552
1553 void SetScrollSize(int cx, int cy, BOOL bRedraw = TRUE)
1554 {
1555 SetZoomScrollSize(cx, cy, GetZoom(), bRedraw);
1556 }
1557
1558 void SetScrollSize(SIZE sizeTrue, BOOL bRedraw = TRUE)
1559 {
1560 SetZoomScrollSize(sizeTrue, GetZoom(), bRedraw);
1561 }
1562
1563 void GetScrollSize(SIZE& sizeTrue) const
1564 {
1565 sizeTrue = m_sizeTrue;
1566 }
1567
1568 void SetScrollPage(int cxPage, int cyPage)
1569 {
1570 SetScrollPage(_WTYPES_NS::CSize(cxPage, cyPage));
1571 }
1572
1573 void SetScrollPage(SIZE sizePage)
1574 {
1575 CScrollImpl< T >::SetScrollPage(sizePage / m_fzoom);
1576 }
1577
1578 void GetScrollPage(SIZE& sizePage) const
1579 {
1580 sizePage = m_sizePage * m_fzoom;
1581 }
1582
1583 void SetScrollLine(int cxLine, int cyLine)
1584 {
1585 SetScrollLine(_WTYPES_NS::CSize(cxLine, cyLine));
1586 }
1587
1588 void SetScrollLine(SIZE sizeLine)
1589 {
1590 CScrollImpl< T >::SetScrollLine(sizeLine / m_fzoom);
1591 }
1592
1593 void GetScrollLine(SIZE& sizeLine) const
1594 {
1595 sizeLine = m_sizeLine * m_fzoom;
1596 }
1597
1598 // Data access complements
1599 _WTYPES_NS::CSize GetScrollSize()
1600 {
1601 return m_sizeTrue;
1602 }
1603
1604 _WTYPES_NS::CSize GetScrollPage()
1605 {
1606 return m_sizePage * m_fzoom;
1607 }
1608
1609 _WTYPES_NS::CSize GetScrollLine()
1610 {
1611 return m_sizeLine * m_fzoom;
1612 }
1613
1614 _WTYPES_NS::CPoint GetScrollOffset()
1615 {
1616 return (_WTYPES_NS::CSize)m_ptOffset * m_fzoom;
1617 }
1618
1619 // Helper coordinate functions
1620 _WTYPES_NS::CPoint WndtoTrue(CPoint ptW)
1621 {
1622 return (_WTYPES_NS::CSize)ptW * GetZoom() + GetScrollOffset();
1623 }
1624
1625 void WndtoTrue(LPPOINT aptW, int nPts) // in place coord transformation
1626 {
1627 for (int i = 0 ; i < nPts ; i++)
1628 aptW[i] = WndtoTrue(aptW[i]);
1629 }
1630
1631 void WndtoTrue(LPRECT prectW) // in place coord transformation
1632 {
1633 WndtoTrue((LPPOINT)prectW, 2);
1634 }
1635
1636 _WTYPES_NS::CPoint TruetoWnd(CPoint ptT)
1637 {
1638 return (ptT - GetScrollOffset()) / GetZoom();
1639 }
1640
1641 void TruetoWnd(LPPOINT aptT, int nPts) // in place coord transformation
1642 {
1643 for (int i = 0 ; i < nPts ; i++)
1644 aptT[i] = TruetoWnd(aptT[i]);
1645 }
1646
1647 void TruetoWnd(LPRECT prectT) // in place coord transformation
1648 {
1649 TruetoWnd((LPPOINT)prectT, 2);
1650 }
1651
1652 // Drawing operations : assume adequate setting of data members
1653 BOOL Draw(HBITMAP hbm, HDC hdestDC, DWORD dwROP = SRCCOPY)
1654 {
1655 CDC memDC = CreateCompatibleDC(hdestDC);
1656 CBitmapHandle bmpOld = memDC.SelectBitmap(hbm);
1657 BOOL bRes = Draw(memDC, hdestDC, dwROP);
1658 memDC.SelectBitmap(bmpOld);
1659 return bRes;
1660 }
1661
1662 BOOL Draw(HDC hsourceDC, HDC hdestDC, DWORD dwROP = SRCCOPY)
1663 {
1664 CDCHandle destDC = hdestDC;
1665 destDC.SetViewportOrg(0,0);
1666 _WTYPES_NS::CPoint ptOffset = GetScrollOffset();
1667 _WTYPES_NS::CSize sizeZClient = m_sizeClient * GetZoom();
1668 return destDC.StretchBlt(0, 0, m_sizeClient.cx, m_sizeClient.cy, hsourceDC, ptOffset.x, ptOffset.y, sizeZClient.cx, sizeZClient.cy, dwROP);
1669 }
1670
1671 #ifdef _IMAGING_H
1672 BOOL Draw(IImage* pIImage, HDC hdestDC)
1673 {
1674 CDCHandle destDC = hdestDC;
1675 destDC.SetViewportOrg(0,0);
1676 return SUCCEEDED(pIImage->Draw(destDC, _WTYPES_NS::CRect(-_WTYPES_NS::CPoint(m_ptOffset), m_sizeAll), NULL));
1677 }
1678 #endif
1679
1680 // Message map and handlers
1681 BEGIN_MSG_MAP(CZoomScrollImpl< T >)
1682 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
1683 CHAIN_MSG_MAP(CScrollImpl< T >)
1684 END_MSG_MAP()
1685
1686 LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
1687 {
1688 T* pT = static_cast<T*>(this);
1689 ATLASSERT(::IsWindow(pT->m_hWnd));
1690 if ((GetScrollExtendedStyle() & SCRL_ERASEBACKGROUND))
1691 {
1692 _WTYPES_NS::CRect rect;
1693 pT->GetClientRect(rect);
1694 _WTYPES_NS::CSize sizeClient=rect.Size();
1695
1696 if (m_sizeAll.cx < sizeClient.cx || m_sizeAll.cy < sizeClient.cy)
1697 {
1698 CDCHandle hdc = (HDC)wParam;
1699 HBRUSH hbr = GetSysColorBrush((int)T::GetWndClassInfo().m_wc.hbrBackground - 1);
1700
1701 if (m_sizeAll.cx < sizeClient.cx)
1702 {
1703 _WTYPES_NS::CRect rectBG(_WTYPES_NS::CPoint(m_sizeAll.cx, 0), sizeClient);
1704 hdc.FillRect(rectBG, hbr);
1705 }
1706
1707 if (m_sizeAll.cy < sizeClient.cy)
1708 {
1709 _WTYPES_NS::CRect rectBG(_WTYPES_NS::CPoint(0, m_sizeAll.cy), sizeClient);
1710 hdc.FillRect(rectBG, hbr);
1711 }
1712 }
1713 }
1714 else
1715 {
1716 bHandled = FALSE;
1717 }
1718
1719 return 1;
1720 }
1721 };
1722
1723 #endif // _WTL_CE_NO_ZOOMSCROLL
1724
1725 #ifndef _WTL_CE_NO_CONTROLS
1726
1727 // --- PPC bottom TabView control ---
1728
1729 #if defined(__ATLCTRLX_H__) && defined(WIN32_PLATFORM_PSPC)
1730
1731 ///////////////////////////////////////////////////////////////////////////////
1732 // CBottomTabViewImpl
1733
1734 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
1735 class ATL_NO_VTABLE CBottomTabViewImpl : public CTabViewImpl<T, TBase, TWinTraits>
1736 {
1737 public:
1738 DECLARE_WND_CLASS_EX(NULL, 0, COLOR_APPWORKSPACE)
1739
1740 // Implementation overrideables
1741 bool CreateTabControl()
1742 {
1743 m_tab.Create(m_hWnd, rcDefault, NULL, WS_CHILD | TCS_BOTTOM, 0, m_nTabID);
1744
1745 ATLASSERT(m_tab.m_hWnd != NULL);
1746 if(m_tab.m_hWnd == NULL)
1747 return false;
1748
1749 m_tab.SendMessage(CCM_SETVERSION, COMCTL32_VERSION);
1750 m_tab.SetItemExtra(sizeof(TABVIEWPAGE));
1751
1752 T* pT = static_cast<T*>(this);
1753 m_cyTabHeight = pT->CalcTabHeight();
1754
1755 return true;
1756 }
1757
1758 int CalcTabHeight()
1759 {
1760 int nCount = m_tab.GetItemCount();
1761 TCITEMEXTRA tcix = { 0 };
1762 tcix.tciheader.mask = TCIF_TEXT;
1763 tcix.tciheader.pszText = _T("NS");
1764 int nIndex = m_tab.InsertItem(nCount, tcix);
1765
1766 RECT rect = { 0 };
1767 SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
1768 RECT rcWnd = rect;
1769
1770 m_tab.AdjustRect(FALSE, &rect);
1771 rcWnd.top = rect.bottom;
1772 ::AdjustWindowRectEx(&rcWnd, m_tab.GetStyle(), FALSE, m_tab.GetExStyle());
1773 m_tab.DeleteItem(nIndex);
1774
1775 return rcWnd.bottom - rcWnd.top;
1776 }
1777
1778 void UpdateLayout()
1779 {
1780 RECT rect = { 0 };
1781 GetClientRect(&rect);
1782
1783 if(m_tab.IsWindow() && ((m_tab.GetStyle() & WS_VISIBLE) != 0))
1784 m_tab.SetWindowPos(NULL, 0, rect.bottom - m_cyTabHeight, rect.right - rect.left, m_cyTabHeight, SWP_NOZORDER /*| SWP_SHOWWINDOW*/);
1785
1786 if(m_nActivePage != -1)
1787 ::SetWindowPos(GetPageHWND(m_nActivePage), NULL, 0, 0, rect.right - rect.left, rect.bottom - m_cyTabHeight, SWP_NOZORDER);
1788 }
1789
1790 };
1791
1792 class CBottomTabView : public CBottomTabViewImpl<CBottomTabView>
1793 {
1794 public:
1795 DECLARE_WND_CLASS_EX(_T("WTL_BottomTabView"), 0, COLOR_APPWORKSPACE)
1796 };
1797
1798 #endif // defined(__ATLCTRLX_H__) && defined(WIN32_PLATFORM_PSPC)
1799
1800
1801 // --- PPC/SmartPhone controls ---
1802
1803 ////////////////////////////////////////////////////////////////////////////////
1804 // These are wrapper classes for the Pocket PC 2002/2003 and SmartPhone 2003 controls
1805 // To implement a window based on a control, use following:
1806 // Example: Implementing a window based on a Html control
1807 //
1808 // class CMyHtml : CWindowImpl<CMyHtml, CHtmlCtrl>
1809 // {
1810 // public:
1811 // BEGIN_MSG_MAP(CMyHtml)
1812 // // put your message handler entries here
1813 // END_MSG_MAP()
1814 // };
1815 ///////////////////////////////////////////////////////////////////////////////
1816
1817 ///////////////////////////////////////////////////////////////////////////////
1818 // CHtmlCtrl
1819
1820 template <class TBase>
1821 class CHtmlCtrlT : public TBase
1822 {
1823 public:
1824 // Constructors
1825 CHtmlCtrlT(HWND hWnd = NULL) : TBase(hWnd)
1826 { }
1827
1828 CHtmlCtrlT< TBase >& operator =(HWND hWnd)
1829 {
1830 m_hWnd = hWnd;
1831 return *this;
1832 }
1833
1834 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
1835 DWORD dwStyle = 0, DWORD dwExStyle = 0,
1836 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
1837 {
1838 HWND hWnd = TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
1839 ATLASSERT(hWnd != NULL); // Did you remember to call InitHTMLControl(hInstance) ??
1840 return hWnd;
1841 }
1842
1843 // Attributes
1844 static LPCTSTR GetWndClassName()
1845 {
1846 return WC_HTML;
1847 }
1848
1849 #if (_WIN32_WCE >= 400)
1850 void AddStyle(LPCWSTR pszStyle)
1851 {
1852 ATLASSERT(::IsWindow(m_hWnd));
1853 ::SendMessage(m_hWnd, DTM_ADDSTYLE, 0, (LPARAM)pszStyle);
1854 }
1855 #endif // (_WIN32_WCE >= 400)
1856
1857 void AddText(BOOL bPlainText, LPCSTR pszText)
1858 {
1859 ATLASSERT(::IsWindow(m_hWnd));
1860 ::SendMessage(m_hWnd, DTM_ADDTEXT, (WPARAM)bPlainText, (LPARAM)pszText);
1861 }
1862
1863 void AddHTML(LPCSTR pszHTML)
1864 {
1865 ATLASSERT(::IsWindow(m_hWnd));
1866 ::SendMessage(m_hWnd, DTM_ADDTEXT, (WPARAM)FALSE, (LPARAM)pszHTML);
1867 }
1868
1869 void AddText(BOOL bPlainText, LPCWSTR pszText)
1870 {
1871 ATLASSERT(::IsWindow(m_hWnd));
1872 ::SendMessage(m_hWnd, DTM_ADDTEXTW, (WPARAM)bPlainText, (LPARAM)pszText);
1873 }
1874
1875 void AddHTML(LPCWSTR pszHTML)
1876 {
1877 ATLASSERT(::IsWindow(m_hWnd));
1878 ::SendMessage(m_hWnd, DTM_ADDTEXTW, (WPARAM)FALSE, (LPARAM)pszHTML);
1879 }
1880
1881 void Anchor(LPCSTR pszAnchor)
1882 {
1883 ATLASSERT(::IsWindow(m_hWnd));
1884 ::SendMessage(m_hWnd, DTM_ANCHOR, 0, (LPARAM)pszAnchor);
1885 }
1886
1887 void Anchor(LPCWSTR pszAnchor)
1888 {
1889 ATLASSERT(::IsWindow(m_hWnd));
1890 ::SendMessage(m_hWnd, DTM_ANCHORW, 0, (LPARAM)pszAnchor);
1891 }
1892
1893 #if (_WIN32_WCE >= 420)
1894 void GetBrowserDispatch(IDispatch** ppDispatch)
1895 {
1896 ATLASSERT(::IsWindow(m_hWnd));
1897 ATLASSERT(ppDispatch);
1898 ATLASSERT(*ppDispatch==NULL);
1899 ::SendMessage(m_hWnd, DTM_BROWSERDISPATCH, 0, (LPARAM)ppDispatch);
1900 }
1901 void GetDocumentDispatch(IDispatch** ppDispatch)
1902 {
1903 ATLASSERT(::IsWindow(m_hWnd));
1904 ATLASSERT(ppDispatch);
1905 ATLASSERT(*ppDispatch==NULL);
1906 ::SendMessage(m_hWnd, DTM_DOCUMENTDISPATCH , 0, (LPARAM)ppDispatch);
1907 }
1908 #endif // (_WIN32_WCE >= 420)
1909
1910 void Clear()
1911 {
1912 ATLASSERT(::IsWindow(m_hWnd));
1913 ::SendMessage(m_hWnd, DTM_CLEAR, 0, 0L);
1914 }
1915
1916 void EnableClearType(BOOL bEnable = TRUE)
1917 {
1918 ATLASSERT(::IsWindow(m_hWnd));
1919 ::SendMessage(m_hWnd, DTM_ENABLECLEARTYPE, 0, (LPARAM)bEnable);
1920 }
1921
1922 void EnableContextMenu(BOOL bEnable = TRUE)
1923 {
1924 ATLASSERT(::IsWindow(m_hWnd));
1925 ::SendMessage(m_hWnd, DTM_ENABLECONTEXTMENU, 0, (LPARAM)bEnable);
1926 }
1927
1928 void EnableScripting(BOOL bEnable = TRUE)
1929 {
1930 ATLASSERT(::IsWindow(m_hWnd));
1931 ::SendMessage(m_hWnd, DTM_ENABLESCRIPTING, 0, (LPARAM)bEnable);
1932 }
1933
1934 void EnableShrink(BOOL bEnable = TRUE)
1935 {
1936 ATLASSERT(::IsWindow(m_hWnd));
1937 ::SendMessage(m_hWnd, DTM_ENABLESHRINK, 0, (LPARAM)bEnable);
1938 }
1939
1940 void EndOfSource()
1941 {
1942 ATLASSERT(::IsWindow(m_hWnd));
1943 ::SendMessage(m_hWnd, DTM_ENDOFSOURCE, 0, 0L);
1944 }
1945
1946 void ImageFail(DWORD dwCookie)
1947 {
1948 ATLASSERT(::IsWindow(m_hWnd));
1949 ::SendMessage(m_hWnd, DTM_IMAGEFAIL, 0, (LPARAM)dwCookie);
1950 }
1951
1952 int GetLayoutHeight() const
1953 {
1954 ATLASSERT(::IsWindow(m_hWnd));
1955 return (int)::SendMessage(m_hWnd, DTM_LAYOUTHEIGHT, 0, 0L);
1956 }
1957
1958 int GetLayoutWidth() const
1959 {
1960 ATLASSERT(::IsWindow(m_hWnd));
1961 return (int)::SendMessage(m_hWnd, DTM_LAYOUTWIDTH, 0, 0L);
1962 }
1963
1964 void Navigate(LPCTSTR pstrURL, UINT uFlags = 0)
1965 {
1966 ATLASSERT(::IsWindow(m_hWnd));
1967 ATLASSERT(pstrURL);
1968 ::SendMessage(m_hWnd, DTM_NAVIGATE, (WPARAM)uFlags, (LPARAM)pstrURL);
1969 }
1970
1971 void SelectAll()
1972 {
1973 ATLASSERT(::IsWindow(m_hWnd));
1974 ::SendMessage(m_hWnd, DTM_SELECTALL, 0, 0L);
1975 }
1976
1977 void SetImage(INLINEIMAGEINFO* pImageInfo)
1978 {
1979 ATLASSERT(::IsWindow(m_hWnd));
1980 ATLASSERT(pImageInfo);
1981 ::SendMessage(m_hWnd, DTM_SETIMAGE, 0, (LPARAM)pImageInfo);
1982 }
1983
1984 void ZoomLevel(int iLevel)
1985 {
1986 ATLASSERT(::IsWindow(m_hWnd));
1987 ::SendMessage(m_hWnd, DTM_ZOOMLEVEL, 0, (LPARAM)iLevel);
1988 }
1989
1990 #if (_WIN32_WCE >= 400)
1991 void Stop()
1992 {
1993 ATLASSERT(::IsWindow(m_hWnd));
1994 ::SendMessage(m_hWnd, DTM_STOP, 0, 0L);
1995 }
1996 #endif // (_WIN32_WCE >= 400)
1997
1998 void GetScriptDispatch(IDispatch** ppDispatch)
1999 {
2000 ATLASSERT(::IsWindow(m_hWnd));
2001 ATLASSERT(ppDispatch);
2002 ATLASSERT(*ppDispatch==NULL);
2003 ::SendMessage(m_hWnd, DTM_SCRIPTDISPATCH, 0, (LPARAM)ppDispatch);
2004 }
2005 };
2006
2007 typedef CHtmlCtrlT<ATL::CWindow> CHtmlCtrl;
2008
2009
2010 #ifdef WIN32_PLATFORM_PSPC
2011
2012 ///////////////////////////////////////////////////////////////////////////////
2013 // CRichInkCtrl
2014
2015 template <class TBase>
2016 class CRichInkCtrlT : public TBase
2017 {
2018 public:
2019 // Constructors
2020 CRichInkCtrlT(HWND hWnd = NULL) : TBase(hWnd)
2021 { }
2022
2023 CRichInkCtrlT< TBase >& operator =(HWND hWnd)
2024 {
2025 m_hWnd = hWnd;
2026 return *this;
2027 }
2028
2029 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
2030 DWORD dwStyle = 0, DWORD dwExStyle = 0,
2031 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
2032 {
2033 HWND hWnd = TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
2034 ATLASSERT(hWnd != NULL); // Did you remember to call InitRichInkDLL() ??
2035 return hWnd;
2036 }
2037
2038 // Attributes
2039 static LPCTSTR GetWndClassName()
2040 {
2041 return WC_RICHINK;
2042 }
2043
2044 BOOL CanPaste(UINT uFormat = 0) const
2045 {
2046 ATLASSERT(::IsWindow(m_hWnd));
2047 return (BOOL)::SendMessage(m_hWnd, EM_CANPASTE, (WPARAM)uFormat, 0L);
2048 }
2049
2050 BOOL CanRedo() const
2051 {
2052 ATLASSERT(::IsWindow(m_hWnd));
2053 return (BOOL)::SendMessage(m_hWnd, EM_CANREDO, 0, 0L);
2054 }
2055
2056 BOOL CanUndo() const
2057 {
2058 ATLASSERT(::IsWindow(m_hWnd));
2059 return (BOOL)::SendMessage(m_hWnd, EM_CANUNDO, 0, 0L);
2060 }
2061
2062 void ClearAll(BOOL bRepaint = TRUE) const
2063 {
2064 ATLASSERT(::IsWindow(m_hWnd));
2065 ::SendMessage(m_hWnd, EM_CLEARALL, (WPARAM)bRepaint, 0L);
2066 }
2067
2068 BOOL GetModify() const
2069 {
2070 ATLASSERT(::IsWindow(m_hWnd));
2071 return (BOOL)::SendMessage(m_hWnd, EM_GETMODIFY, 0, 0L);
2072 }
2073
2074 UINT GetPageStyle() const
2075 {
2076 ATLASSERT(::IsWindow(m_hWnd));
2077 return (UINT)::SendMessage(m_hWnd, EM_GETPAGESTYLE, 0, 0L);
2078 }
2079
2080 UINT GetPenMode() const
2081 {
2082 ATLASSERT(::IsWindow(m_hWnd));
2083 return (UINT)::SendMessage(m_hWnd, EM_GETPENMODE, 0, 0L);
2084 }
2085
2086 UINT GetViewStyle() const
2087 {
2088 ATLASSERT(::IsWindow(m_hWnd));
2089 return (UINT)::SendMessage(m_hWnd, EM_GETVIEW, 0, 0L);
2090 }
2091
2092 UINT GetWrapMode() const
2093 {
2094 ATLASSERT(::IsWindow(m_hWnd));
2095 return (UINT)::SendMessage(m_hWnd, EM_GETWRAPMODE, 0, 0L);
2096 }
2097
2098 UINT GetZoomPercent() const
2099 {
2100 ATLASSERT(::IsWindow(m_hWnd));
2101 return (UINT)::SendMessage(m_hWnd, EM_GETZOOMPERCENT, 0, 0L);
2102 }
2103
2104 void InsertLinks(LPWSTR lpString, int cchLength = -1)
2105 {
2106 ATLASSERT(::IsWindow(m_hWnd));
2107 if(cchLength == -1)
2108 cchLength = lstrlen(lpString);
2109 ::SendMessage(m_hWnd, EM_INSERTLINKS, (WPARAM)cchLength, (LPARAM)lpString);
2110 }
2111
2112 void RedoEvent()
2113 {
2114 ATLASSERT(::IsWindow(m_hWnd));
2115 ::SendMessage(m_hWnd, EM_REDOEVENT, 0, 0L);
2116 }
2117
2118 UINT SetInkLayer(UINT uLayer)
2119 {
2120 ATLASSERT(::IsWindow(m_hWnd));
2121 return (UINT)::SendMessage(m_hWnd, EM_SETINKLAYER, (WPARAM)uLayer, 0L);
2122 }
2123
2124 void SetPageStyle(UINT uStyle)
2125 {
2126 ATLASSERT(::IsWindow(m_hWnd));
2127 ::SendMessage(m_hWnd, EM_SETPAGESTYLE, (WPARAM)uStyle, 0L);
2128 }
2129
2130 void SetPenMode(UINT uMode)
2131 {
2132 ATLASSERT(::IsWindow(m_hWnd));
2133 ::SendMessage(m_hWnd, EM_SETPENMODE, (WPARAM)uMode, 0L);
2134 }
2135
2136 void SetViewStyle(UINT uStyle)
2137 {
2138 ATLASSERT(::IsWindow(m_hWnd));
2139 ::SendMessage(m_hWnd, EM_SETVIEW, (WPARAM)uStyle, 0L);
2140 }
2141
2142 void SetViewAttributes(VIEWATTRIBUTES* pAttribs)
2143 {
2144 ATLASSERT(::IsWindow(m_hWnd));
2145 ATLASSERT(pAttribs);
2146 ::SendMessage(m_hWnd, EM_SETVIEWATTRIBUTES, 0, (LPARAM)pAttribs);
2147 }
2148
2149 void SetWrapMode(UINT uMode)
2150 {
2151 ATLASSERT(::IsWindow(m_hWnd));
2152 ::SendMessage(m_hWnd, EM_SETWRAPMODE, (WPARAM)uMode, 0L);
2153 }
2154
2155 void SetZoomPercent(UINT uPercent)
2156 {
2157 ATLASSERT(::IsWindow(m_hWnd));
2158 ::SendMessage(m_hWnd, EM_SETZOOMPERCENT, (WPARAM)uPercent, 0L);
2159 }
2160
2161 LONG StreamIn(UINT uFormat, EDITSTREAM& es)
2162 {
2163 ATLASSERT(::IsWindow(m_hWnd));
2164 return (LONG)::SendMessage(m_hWnd, EM_STREAMIN, (WPARAM)uFormat, (LPARAM)&es);
2165 }
2166
2167 LONG StreamOut(UINT uFormat, EDITSTREAM& es)
2168 {
2169 ATLASSERT(::IsWindow(m_hWnd));
2170 return (LONG)::SendMessage(m_hWnd, EM_STREAMOUT, (WPARAM)uFormat, (LPARAM)&es);
2171 }
2172
2173 void UndoEvent()
2174 {
2175 ATLASSERT(::IsWindow(m_hWnd));
2176 ::SendMessage(m_hWnd, EM_UNDOEVENT, 0, 0L);
2177 }
2178
2179 void Undo()
2180 {
2181 UndoEvent();
2182 }
2183
2184 // Standard EM_xxx messages
2185 DWORD GetSel() const
2186 {
2187 ATLASSERT(::IsWindow(m_hWnd));
2188 ATLASSERT(GetViewStyle() != VT_DRAWINGVIEW);
2189 return (DWORD)::SendMessage(m_hWnd, EM_GETSEL, 0, 0L);
2190 }
2191
2192 void GetSel(int& nStartChar, int& nEndChar) const
2193 {
2194 ATLASSERT(::IsWindow(m_hWnd));
2195 ATLASSERT(GetViewStyle() != VT_DRAWINGVIEW);
2196 ::SendMessage(m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar);
2197 }
2198
2199 void SetSel(int nStartChar, int nEndChar)
2200 {
2201 ATLASSERT(::IsWindow(m_hWnd));
2202 ATLASSERT(GetViewStyle() != VT_DRAWINGVIEW);
2203 ::SendMessage(m_hWnd, EM_SETSEL, nStartChar, nEndChar);
2204 }
2205
2206 void ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo = FALSE)
2207 {
2208 ATLASSERT(::IsWindow(m_hWnd));
2209 ATLASSERT(GetViewStyle() != VT_DRAWINGVIEW);
2210 ::SendMessage(m_hWnd, EM_REPLACESEL, (WPARAM)bCanUndo, (LPARAM)lpszNewText);
2211 }
2212
2213 void SetModify(BOOL bModified = TRUE)
2214 {
2215 ATLASSERT(::IsWindow(m_hWnd));
2216 ::SendMessage(m_hWnd, EM_SETMODIFY, (WPARAM)bModified, 0L);
2217 }
2218
2219 int GetTextLength() const
2220 {
2221 ATLASSERT(::IsWindow(m_hWnd));
2222 return (int)::SendMessage(m_hWnd, WM_GETTEXTLENGTH, 0, 0L);
2223 }
2224
2225 // Clipboard operations
2226 void Clear()
2227 {
2228 ATLASSERT(::IsWindow(m_hWnd));
2229 ::SendMessage(m_hWnd, WM_CLEAR, 0, 0L);
2230 }
2231
2232 void Copy()
2233 {
2234 ATLASSERT(::IsWindow(m_hWnd));
2235 ::SendMessage(m_hWnd, WM_COPY, 0, 0L);
2236 }
2237
2238 void Cut()
2239 {
2240 ATLASSERT(::IsWindow(m_hWnd));
2241 ::SendMessage(m_hWnd, WM_CUT, 0, 0L);
2242 }
2243
2244 void Paste()
2245 {
2246 ATLASSERT(::IsWindow(m_hWnd));
2247 ::SendMessage(m_hWnd, WM_PASTE, 0, 0L);
2248 }
2249 };
2250
2251 typedef CRichInkCtrlT<ATL::CWindow> CRichInkCtrl;
2252
2253
2254 ///////////////////////////////////////////////////////////////////////////////
2255 // CInkXCtrl
2256
2257 template <class TBase>
2258 class CInkXCtrlT : public TBase
2259 {
2260 public:
2261 // Constructors
2262 CInkXCtrlT(HWND hWnd = NULL) : TBase(hWnd)
2263 { }
2264
2265 CInkXCtrlT< TBase >& operator =(HWND hWnd)
2266 {
2267 m_hWnd = hWnd;
2268 return *this;
2269 }
2270
2271 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
2272 DWORD dwStyle = 0, DWORD dwExStyle = 0,
2273 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
2274 {
2275 HWND hWnd = TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
2276 ATLASSERT(hWnd != NULL); // Did you remember to call InitInkX() ??
2277 return hWnd;
2278 }
2279
2280 // Attributes
2281 static LPCTSTR GetWndClassName()
2282 {
2283 return WC_INKX;
2284 }
2285
2286 static UINT GetHotRecordingMessage()
2287 {
2288 return ::RegisterWindowMessage(szHotRecording);
2289 }
2290
2291 void ClearAll()
2292 {
2293 ATLASSERT(::IsWindow(m_hWnd));
2294 ::SendMessage(m_hWnd, IM_CLEARALL, 0, 0L);
2295 }
2296
2297 int GetData(BYTE* lpBuffer, INT cbBuffer) const
2298 {
2299 ATLASSERT(::IsWindow(m_hWnd));
2300 ATLASSERT(lpBuffer);
2301 return (int)::SendMessage(m_hWnd, IM_GETDATA, (WPARAM)cbBuffer, (LPARAM)lpBuffer);
2302 }
2303
2304 int GetDataLen() const
2305 {
2306 ATLASSERT(::IsWindow(m_hWnd));
2307 return (int)::SendMessage(m_hWnd, IM_GETDATALEN, 0, 0L);
2308 }
2309
2310 CRichInkCtrl GetRichInk() const
2311 {
2312 ATLASSERT(::IsWindow(m_hWnd));
2313 return (HWND)::SendMessage(m_hWnd, IM_GETRICHINK, 0, 0L);
2314 }
2315
2316 BOOL IsRecording() const
2317 {
2318 ATLASSERT(::IsWindow(m_hWnd));
2319 return (BOOL)::SendMessage(m_hWnd, IM_RECORDING, 0, 0L);
2320 }
2321
2322 void ReInit()
2323 {
2324 ATLASSERT(::IsWindow(m_hWnd));
2325 ::SendMessage(m_hWnd, IM_REINIT, 0, 0L);
2326 }
2327
2328 void SetData(const BYTE* lpInkData, INT cbInkData)
2329 {
2330 ATLASSERT(::IsWindow(m_hWnd));
2331 ATLASSERT(lpInkData);
2332 ::SendMessage(m_hWnd, IM_SETDATA, (WPARAM)cbInkData, (LPARAM)lpInkData);
2333 }
2334
2335 void VoicePlay()
2336 {
2337 ATLASSERT(::IsWindow(m_hWnd));
2338 ::SendMessage(m_hWnd, IM_VOICE_PLAY, 0, 0L);
2339 }
2340
2341 BOOL IsVoicePlaying() const
2342 {
2343 ATLASSERT(::IsWindow(m_hWnd));
2344 return (BOOL)::SendMessage(m_hWnd, IM_VOICE_PLAYING, 0, 0L);
2345 }
2346
2347 BOOL VoiceRecord()
2348 {
2349 ATLASSERT(::IsWindow(m_hWnd));
2350 return (BOOL)::SendMessage(m_hWnd, IM_VOICE_RECORD, 0, 0L);
2351 }
2352
2353 void VoiceStop()
2354 {
2355 ATLASSERT(::IsWindow(m_hWnd));
2356 ::SendMessage(m_hWnd, IM_VOICE_STOP, 0, 0L);
2357 }
2358
2359 void ShowVoiceBar(BOOL bShow = TRUE)
2360 {
2361 ATLASSERT(::IsWindow(m_hWnd));
2362 ::SendMessage(m_hWnd, IM_VOICEBAR, (WPARAM)bShow, 0L);
2363 }
2364 };
2365
2366 typedef CInkXCtrlT<ATL::CWindow> CInkXCtrl;
2367
2368 #endif // WIN32_PLATFORM_PSPC
2369
2370
2371 ///////////////////////////////////////////////////////////////////////////////
2372 // CVoiceRecorderCtrl
2373
2374 template <class TBase>
2375 class CVoiceRecorderCtrlT : public TBase
2376 {
2377 public:
2378 // Constructors
2379 CVoiceRecorderCtrlT(HWND hWnd = NULL) : TBase(hWnd)
2380 { }
2381
2382 CVoiceRecorderCtrlT< TBase >& operator =(HWND hWnd)
2383 {
2384 m_hWnd = hWnd;
2385 return *this;
2386 }
2387
2388 HWND Create(HWND hWndParent, const POINT pt, LPTSTR pstrFileName, UINT nID, DWORD dwStyle = 0)
2389 {
2390 ATLASSERT(pstrFileName != NULL);
2391 CM_VOICE_RECORDER cmvr = { 0 };
2392 cmvr.cb = sizeof(CM_VOICE_RECORDER);
2393 cmvr.dwStyle = dwStyle;
2394 cmvr.xPos = pt.x;
2395 cmvr.yPos = pt.y;
2396 cmvr.hwndParent = hWndParent;
2397 cmvr.id = nID;
2398 cmvr.lpszRecordFileName = pstrFileName;
2399 m_hWnd = VoiceRecorder_Create(&cmvr);
2400 return m_hWnd;
2401 }
2402
2403 HWND Create(LPCM_VOICE_RECORDER pAttribs)
2404 {
2405 ATLASSERT(pAttribs);
2406 m_hWnd = VoiceRecorder_Create(pAttribs);
2407 return m_hWnd;
2408 }
2409
2410 // Attributes
2411 void Record()
2412 {
2413 ATLASSERT(::IsWindow(m_hWnd));
2414 ::SendMessage(m_hWnd, VRM_RECORD, 0, 0L);
2415 }
2416
2417 void Play()
2418 {
2419 ATLASSERT(::IsWindow(m_hWnd));
2420 ::SendMessage(m_hWnd, VRM_PLAY, 0, 0L);
2421 }
2422
2423 void Stop()
2424 {
2425 ATLASSERT(::IsWindow(m_hWnd));
2426 ::SendMessage(m_hWnd, VRM_STOP, 0, 0L);
2427 }
2428
2429 void Cancel()
2430 {
2431 ATLASSERT(::IsWindow(m_hWnd));
2432 ::SendMessage(m_hWnd, VRM_CANCEL, 0, 0L);
2433 }
2434
2435 void Done()
2436 {
2437 ATLASSERT(::IsWindow(m_hWnd));
2438 ::SendMessage(m_hWnd, VRM_OK, 0, 0L);
2439 }
2440 };
2441
2442 typedef CVoiceRecorderCtrlT<ATL::CWindow> CVoiceRecorderCtrl;
2443
2444
2445 #ifdef WIN32_PLATFORM_PSPC
2446
2447 ///////////////////////////////////////////////////////////////////////////////
2448 // CDocListCtrl
2449
2450 template <class TBase>
2451 class CDocListCtrlT : public TBase
2452 {
2453 public:
2454 // Attributes
2455 DOCLISTCREATE m_dlc;
2456 TCHAR m_szPath[MAX_PATH];
2457
2458 // Constructors
2459 CDocListCtrlT(HWND hWnd = NULL) : TBase(hWnd)
2460 { }
2461
2462 CDocListCtrlT< TBase >& operator =(HWND hWnd)
2463 {
2464 m_hWnd = hWnd;
2465 return *this;
2466 }
2467
2468 HWND Create(HWND hWndParent, WORD wId, LPCTSTR pszFolder = NULL, LPCTSTR pstrFilter = NULL,
2469 WORD wFilterIndex = 0, DWORD dwFlags = DLF_SHOWEXTENSION)
2470 {
2471 ATLASSERT(pstrFilter != NULL); // It seems to need a filter badly!!
2472 ::ZeroMemory(&m_dlc, sizeof(DOCLISTCREATE));
2473 ::ZeroMemory(m_szPath, sizeof(m_szPath));
2474 if(pszFolder != NULL)
2475 SecureHelper::strncpy_x(m_szPath, MAX_PATH, pszFolder, MAX_PATH - 1);
2476 m_dlc.dwStructSize = sizeof(DOCLISTCREATE);
2477 m_dlc.hwndParent = hWndParent;
2478 m_dlc.pszFolder = m_szPath;
2479 m_dlc.pstrFilter = pstrFilter;
2480 m_dlc.wFilterIndex = wFilterIndex;
2481 m_dlc.wId = wId;
2482 m_dlc.dwFlags = dwFlags;
2483 m_hWnd = DocList_Create(&m_dlc);
2484 return m_hWnd;
2485 }
2486
2487 HWND Create(DOCLISTCREATE* pDlc)
2488 {
2489 m_dlc = *pDlc;
2490 m_hWnd = DocList_Create(&m_dlc);
2491 return m_hWnd;
2492 }
2493
2494 // Attributes
2495 void DeleteSel()
2496 {
2497 ATLASSERT(::IsWindow(m_hWnd));
2498 ::SendMessage(m_hWnd, DLM_DELETESEL, 0, 0L);
2499 }
2500
2501 void DisableUpdates()
2502 {
2503 ATLASSERT(::IsWindow(m_hWnd));
2504 ::SendMessage(m_hWnd, DLM_DISABLEUPDATES, 0, 0L);
2505 }
2506
2507 void EnableUpdates()
2508 {
2509 ATLASSERT(::IsWindow(m_hWnd));
2510 ::SendMessage(m_hWnd, DLM_ENABLEUPDATES, 0, 0L);
2511 }
2512
2513 int GetFilterIndex() const
2514 {
2515 ATLASSERT(::IsWindow(m_hWnd));
2516 return (int)::SendMessage(m_hWnd, DLM_GETFILTERINDEX, 0, 0L);
2517 }
2518
2519 int GetItemCount() const
2520 {
2521 ATLASSERT(::IsWindow(m_hWnd));
2522 return (int)::SendMessage(m_hWnd, DLM_GETITEMCOUNT, 0, 0L);
2523 }
2524
2525 int GetNextItem(int iIndex, DWORD dwRelation = LVNI_ALL) const
2526 {
2527 ATLASSERT(::IsWindow(m_hWnd));
2528 return (int)::SendMessage(m_hWnd, DLM_GETNEXTITEM, (WPARAM)iIndex, (LPARAM)dwRelation);
2529 }
2530
2531 int GetFirstItem(DWORD dwRelation = LVNI_ALL) const
2532 {
2533 ATLASSERT(::IsWindow(m_hWnd));
2534 return (int)::SendMessage(m_hWnd, DLM_GETNEXTITEM, (WPARAM)-1, (LPARAM)dwRelation);
2535 }
2536
2537 BOOL GetNextWave(int* pIndex) const
2538 {
2539 ATLASSERT(::IsWindow(m_hWnd));
2540 ATLASSERT(pIndex);
2541 return (BOOL)::SendMessage(m_hWnd, DLM_GETNEXTWAVE, 0, (LPARAM)pIndex);
2542 }
2543
2544 BOOL GetPrevWave(int* pIndex) const
2545 {
2546 ATLASSERT(::IsWindow(m_hWnd));
2547 ATLASSERT(pIndex);
2548 return (BOOL)::SendMessage(m_hWnd, DLM_GETPREVWAVE, 0, (LPARAM)pIndex);
2549 }
2550
2551 int GetSelCount() const
2552 {
2553 ATLASSERT(::IsWindow(m_hWnd));
2554 return (int)::SendMessage(m_hWnd, DLM_GETSELCOUNT, 0, 0L);
2555 }
2556
2557 BOOL GetSelPathName(LPTSTR pstrPath, int cchMax) const
2558 {
2559 ATLASSERT(::IsWindow(m_hWnd));
2560 ATLASSERT(pstrPath);
2561 return (BOOL)::SendMessage(m_hWnd, DLM_GETSELPATHNAME, (WPARAM)cchMax, (LPARAM)pstrPath);
2562 }
2563
2564 void ReceiveIR(LPCTSTR pstrPath) const
2565 {
2566 ATLASSERT(::IsWindow(m_hWnd));
2567 ATLASSERT(pstrPath);
2568 ::SendMessage(m_hWnd, DLM_RECEIVEIR, 0, (LPARAM)pstrPath);
2569 }
2570
2571 void Refresh()
2572 {
2573 ATLASSERT(::IsWindow(m_hWnd));
2574 ::SendMessage(m_hWnd, DLM_REFRESH, 0, 0L);
2575 }
2576
2577 BOOL RenameMoveSelectedItems()
2578 {
2579 ATLASSERT(::IsWindow(m_hWnd));
2580 return (BOOL)::SendMessage(m_hWnd, DLM_RENAMEMOVE, 0, 0L);
2581 }
2582
2583 int SelectAll()
2584 {
2585 ATLASSERT(::IsWindow(m_hWnd));
2586 return (int)::SendMessage(m_hWnd, DLM_SELECTALL, 0, 0L);
2587 }
2588
2589 HRESULT SelectItem(LPCTSTR pstrPath, BOOL bVisible = TRUE)
2590 {
2591 ATLASSERT(::IsWindow(m_hWnd));
2592 ATLASSERT(pstrPath);
2593 return (HRESULT)::SendMessage(m_hWnd, DLM_SELECTITEM, (WPARAM)bVisible, (LPARAM)pstrPath);
2594 }
2595
2596 void SendEMail(LPCTSTR pstrAttachment)
2597 {
2598 ATLASSERT(::IsWindow(m_hWnd));
2599 ::SendMessage(m_hWnd, DLM_SENDEMAIL, 0, (LPARAM)pstrAttachment);
2600 }
2601
2602 void SendIR(LPCTSTR pstrPath)
2603 {
2604 ATLASSERT(::IsWindow(m_hWnd));
2605 ::SendMessage(m_hWnd, DLM_SENDIR, 0, (LPARAM)pstrPath);
2606 }
2607
2608 HRESULT SetFilterIndex(int iIndex)
2609 {
2610 ATLASSERT(::IsWindow(m_hWnd));
2611 return (HRESULT)::SendMessage(m_hWnd, DLM_SETFILTERINDEX, (WPARAM)iIndex, 0L);
2612 }
2613
2614 void SetFolder(LPCTSTR pstrPath)
2615 {
2616 ATLASSERT(::IsWindow(m_hWnd));
2617 ATLASSERT(pstrPath);
2618 ::SendMessage(m_hWnd, DLM_SETFOLDER, 0, (LPARAM)pstrPath);
2619 }
2620
2621 BOOL SetItemState(int iIndex, const LVITEM* pItem)
2622 {
2623 ATLASSERT(::IsWindow(m_hWnd));
2624 ATLASSERT(pItem);
2625 return (BOOL)::SendMessage(m_hWnd, DLM_SETITEMSTATE, (WPARAM)iIndex, (LPARAM)pItem);
2626 }
2627
2628 BOOL SetItemState(int iIndex, UINT uState, UINT uMask)
2629 {
2630 ATLASSERT(::IsWindow(m_hWnd));
2631 LVITEM lvi = { 0 };
2632 lvi.stateMask = uMask;
2633 lvi.state = uState;
2634 return (BOOL)::SendMessage(m_hWnd, DLM_SETITEMSTATE, (WPARAM)iIndex, (LPARAM)&lvi);
2635 }
2636
2637 void SetOneItem(int iIndex, LPCVOID pPA)
2638 {
2639 ATLASSERT(::IsWindow(m_hWnd));
2640 ::SendMessage(m_hWnd, DLM_SETONEITEM, (WPARAM)iIndex, (LPARAM)pPA);
2641 }
2642
2643 void SetSelect(int iIndex)
2644 {
2645 ATLASSERT(::IsWindow(m_hWnd));
2646 ::SendMessage(m_hWnd, DLM_SETSELECT, (WPARAM)iIndex, 0L);
2647 }
2648
2649 void SetSelPathName(LPCTSTR pstrPath)
2650 {
2651 ATLASSERT(::IsWindow(m_hWnd));
2652 ATLASSERT(pstrPath);
2653 ::SendMessage(m_hWnd, DLM_SETSELPATHNAME, 0, (LPARAM)pstrPath);
2654 }
2655
2656 BOOL SetSortOrder()
2657 {
2658 ATLASSERT(::IsWindow(m_hWnd));
2659 return (BOOL)::SendMessage(m_hWnd, DLM_SETSORTORDER, 0, 0L);
2660 }
2661
2662 HRESULT Update()
2663 {
2664 ATLASSERT(::IsWindow(m_hWnd));
2665 return (HRESULT)::SendMessage(m_hWnd, DLM_UPDATE, 0, 0L);
2666 }
2667
2668 BOOL ValidateFolder()
2669 {
2670 ATLASSERT(::IsWindow(m_hWnd));
2671 return (BOOL)::SendMessage(m_hWnd, DLM_VALIDATEFOLDER, 0, 0L);
2672 }
2673
2674 // Functions
2675 BOOL GetFirstSelectedWaveFile(int* pIndex, LPTSTR szPath, const size_t cchPath)
2676 {
2677 ATLASSERT(::IsWindow(m_hWnd));
2678 return DocList_GetFirstSelectedWaveFile(m_hWnd, pIndex, szPath, cchPath);
2679 }
2680
2681 BOOL GetNextSelectedWaveFile(int* pIndex, LPTSTR szPath, const size_t cchPath)
2682 {
2683 ATLASSERT(::IsWindow(m_hWnd));
2684 return DocList_GetNextSelectedWaveFile(m_hWnd, pIndex, szPath, cchPath);
2685 }
2686 };
2687
2688 typedef CDocListCtrlT<ATL::CWindow> CDocListCtrl;
2689
2690 #endif // WIN32_PLATFORM_PSPC
2691
2692
2693 ///////////////////////////////////////////////////////////////////////////////
2694 // CCapEdit
2695
2696 template <class TBase>
2697 class CCapEditT : public TBase
2698 {
2699 public:
2700 // Constructors
2701 CCapEditT(HWND hWnd = NULL) : TBase(hWnd)
2702 { }
2703
2704 CCapEditT< TBase >& operator =(HWND hWnd)
2705 {
2706 m_hWnd = hWnd;
2707 return *this;
2708 }
2709
2710 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
2711 DWORD dwStyle = 0, DWORD dwExStyle = 0,
2712 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
2713 {
2714 HWND hWnd = /*TBase*/CWindow::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
2715 ATLASSERT(hWnd != NULL); // Did you remember to call SHInitExtraControls() ??
2716 return hWnd;
2717 }
2718
2719 // Attributes
2720 static LPCTSTR GetWndClassName()
2721 {
2722 return WC_CAPEDIT;
2723 }
2724 };
2725
2726 typedef CCapEditT<WTL::CEdit> CCapEdit;
2727
2728 ///////////////////////////////////////////////////////////////////////////////
2729 // CTTStatic
2730
2731 #ifndef WIN32_PLATFORM_WFSP // Tooltips not supported on SmartPhone
2732
2733 template <class TBase>
2734 class CTTStaticT : public TBase
2735 {
2736 public:
2737 // Constructors
2738 CTTStaticT(HWND hWnd = NULL) : TBase(hWnd)
2739 { }
2740
2741 CTTStaticT< TBase >& operator =(HWND hWnd)
2742 {
2743 m_hWnd = hWnd;
2744 return *this;
2745 }
2746
2747 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
2748 DWORD dwStyle = 0, DWORD dwExStyle = 0,
2749 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
2750 {
2751 HWND hWnd = TBase::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
2752 ATLASSERT(hWnd != NULL); // Did you remember to call SHInitExtraControls() ??
2753 return hWnd;
2754 }
2755
2756 // Attributes
2757 static LPCTSTR GetWndClassName()
2758 {
2759 return WC_TSTATIC;
2760 }
2761
2762 // Operations
2763 BOOL SetToolTipText(LPCTSTR pstrTipText)
2764 {
2765 ATLASSERT(::IsWindow(m_hWnd));
2766 ATLASSERT(pstrTipText);
2767 ATLASSERT(lstrlen(pstrTipText) <= 253);
2768 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
2769 int cchLen = lstrlen(pstrTipText) + 3;
2770 LPTSTR pstr = buff.Allocate(cchLen);
2771 if(pstr == NULL)
2772 return FALSE;
2773 SecureHelper::strcpy_x(pstr, cchLen, _T("~~"));
2774 SecureHelper::strcat_x(pstr, cchLen, pstrTipText);
2775 return SetWindowText(pstr);
2776 }
2777 };
2778
2779 typedef CTTStaticT<WTL::CStatic> CTTStatic;
2780
2781
2782 ///////////////////////////////////////////////////////////////////////////////
2783 // CTTButton
2784
2785 template <class TBase>
2786 class CTTButtonT : public TBase
2787 {
2788 public:
2789 // Constructors
2790 CTTButtonT(HWND hWnd = NULL) : TBase(hWnd)
2791 { }
2792
2793 CTTButtonT< TBase >& operator =(HWND hWnd)
2794 {
2795 m_hWnd = hWnd;
2796 return *this;
2797 }
2798
2799 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
2800 DWORD dwStyle = 0, DWORD dwExStyle = 0,
2801 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
2802 {
2803 HWND hWnd = TBase::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
2804 ATLASSERT(hWnd != NULL); // Did you remember to call SHInitExtraControls() ??
2805 return hWnd;
2806 }
2807
2808 // Attributes
2809 static LPCTSTR GetWndClassName()
2810 {
2811 return WC_TBUTTON;
2812 }
2813
2814 // Operations
2815 BOOL SetToolTipText(LPCTSTR pstrTipText)
2816 {
2817 ATLASSERT(::IsWindow(m_hWnd));
2818 ATLASSERT(pstrTipText);
2819 ATLASSERT(lstrlen(pstrTipText) <= 253);
2820 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
2821 int cchLen = lstrlen(pstrTipText) + 3;
2822 LPTSTR pstr = buff.Allocate(cchLen);
2823 if(pstr == NULL)
2824 return FALSE;
2825 SecureHelper::strcpy_x(pstr, cchLen, _T("~~"));
2826 SecureHelper::strcat_x(pstr, cchLen, pstrTipText);
2827 return SetWindowText(pstr);
2828 }
2829 };
2830
2831 typedef CTTButtonT<WTL::CButton> CTTButton;
2832
2833 #endif // !WIN32_PLATFORM_WFSP
2834
2835
2836 // --- SmartPhone specific controls ---
2837
2838 #ifdef WIN32_PLATFORM_WFSP
2839
2840 ///////////////////////////////////////////////////////////////////////////////
2841 // CSpinCtrlT - CSpinCtrl : SmartPhone adapted UpDown control
2842
2843 template <class TBase>
2844 class CSpinCtrlT : public CUpDownCtrlT< TBase >
2845 {
2846 public:
2847 // Constructors
2848 CSpinCtrlT(HWND hWnd = NULL) : CUpDownCtrlT< TBase >(hWnd)
2849 { }
2850
2851 CSpinCtrlT< TBase >& operator =(HWND hWnd)
2852 {
2853 m_hWnd = hWnd;
2854 return *this;
2855 }
2856
2857 HWND Create(HWND hWndParent, HWND hBuddy, DWORD dwStyle, int nID, LPCTSTR szExpandedName = NULL)
2858 {
2859 ATLASSERT(::IsWindow(hWndParent));
2860 CUpDownCtrlT< TBase >::Create(hWndParent, NULL, szExpandedName, dwStyle, 0, nID, NULL);
2861 ATLASSERT(m_hWnd != NULL); // Did you remember to call AtlInitCommonControls(ICC_UPDOWN_CLASS)?
2862 if (hBuddy != NULL)
2863 {
2864 ATLASSERT(::IsWindow(hBuddy));
2865 SetBuddy(hBuddy);
2866 }
2867 return m_hWnd;
2868 }
2869 };
2870
2871 typedef CSpinCtrlT<ATL::CWindow> CSpinCtrl;
2872
2873
2874 ///////////////////////////////////////////////////////////////////////////////
2875 // CSpinned - SmartPhone association of control and Spin
2876
2877 template <class TBase, bool t_bExpandOnly>
2878 class CSpinned : public TBase
2879 {
2880 public:
2881 CSpinCtrl m_SpinCtrl;
2882 DWORD m_dwSpinnedStyle;
2883
2884 // Constructors
2885 CSpinned(HWND hWnd = NULL) : TBase(hWnd)
2886 {
2887 m_dwSpinnedStyle = WS_VISIBLE | UDS_ALIGNRIGHT | UDS_EXPANDABLE;
2888
2889 if (t_bExpandOnly == true)
2890 m_dwSpinnedStyle |= UDS_NOSCROLL;
2891 else
2892 m_dwSpinnedStyle |= UDS_HORZ | UDS_ARROWKEYS | UDS_SETBUDDYINT | UDS_WRAP;
2893
2894 if (hWnd != NULL)
2895 AttachOrCreateSpinCtrl();
2896 }
2897
2898 CSpinned<TBase, t_bExpandOnly>& operator =(HWND hWnd)
2899 {
2900 Attach(hWnd);
2901 return *this;
2902 }
2903
2904 void Attach(HWND hWnd)
2905 {
2906 ATLASSERT(!IsWindow());
2907 TBase* pT = static_cast<TBase*>(this);
2908 pT->m_hWnd = hWnd;
2909 if (hWnd != NULL)
2910 AttachOrCreateSpinCtrl();
2911 }
2912
2913 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szExpandedName = NULL,
2914 DWORD dwStyle = 0, DWORD dwExStyle = 0,
2915 ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
2916 {
2917
2918 TBase* pT = static_cast<TBase*>(this);
2919 TBase::Create(hWndParent, rect, NULL, dwStyle, dwExStyle, MenuOrID, lpCreateParam);
2920 ATLASSERT(pT->m_hWnd != NULL);
2921
2922 m_SpinCtrl.Create(hWndParent, pT->m_hWnd, m_dwSpinnedStyle, ATL_IDW_SPIN_ID + (int)MenuOrID.m_hMenu, szExpandedName);
2923
2924 ATLASSERT(m_SpinCtrl.m_hWnd != NULL); // Did you remember to call AtlInitCommonControls(ICC_UPDOWN_CLASS)?
2925
2926 return pT->m_hWnd;
2927 }
2928
2929 // Attributes
2930 CSpinCtrl& GetSpinCtrl()
2931 {
2932 return m_SpinCtrl;
2933 }
2934
2935 // Implementation
2936 // Attach our existing SpinCtrl or create one
2937 bool AttachOrCreateSpinCtrl()
2938 {
2939 TBase* pT = static_cast<TBase*>(this);
2940
2941 HWND hSpin = ::GetDlgItem(pT->GetParent(), ATL_IDW_SPIN_ID + pT->GetDlgCtrlID());
2942
2943 if (hSpin != NULL)
2944 {
2945 m_SpinCtrl.Attach(hSpin);
2946 #ifdef DEBUG
2947 TCHAR sClassName[16] = { 0 };
2948 ::GetClassName(hSpin, sClassName, 16);
2949 ATLASSERT(!_tcscmp(sClassName, UPDOWN_CLASS));
2950 ATLASSERT(m_SpinCtrl.GetBuddy().m_hWnd == pT->m_hWnd);
2951 #endif // DEBUG
2952 }
2953 else
2954 {
2955 m_SpinCtrl.Create(pT->GetParent(), pT->m_hWnd, m_dwSpinnedStyle, ATL_IDW_SPIN_ID + pT->GetDlgCtrlID());
2956 }
2957
2958 return m_SpinCtrl.m_hWnd != NULL;
2959 }
2960 };
2961
2962
2963 ///////////////////////////////////////////////////////////////////////////////
2964 // CSpinListBox - SmartPhone spinned ListBox control
2965 // CExpandListBox - SmartPhone expandable ListBox control
2966 // CExpandEdit - SmartPhone expandable Edit control
2967 // CExpandCapEdit - SmartPhone expandable CapEdit control
2968
2969 typedef CSpinned<CListBox, false> CSpinListBox;
2970 typedef CSpinned<CListBox, true> CExpandListBox;
2971 typedef CSpinned<CEdit, true> CExpandEdit;
2972 typedef CSpinned<CCapEdit, true> CExpandCapEdit;
2973
2974 #endif // WIN32_PLATFORM_WFSP
2975
2976 #endif // _WTL_CE_NO_CONTROLS
2977
2978 }; // namespace WTL
2979
2980 #endif // __ATLWINCE_H__
+0
-522
src/third_party/wtl/Include/atlwinx.h less more
0 // Windows Template Library - WTL version 9.10
1 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
2 //
3 // This file is a part of the Windows Template Library.
4 // The use and distribution terms for this software are covered by the
5 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
6 // which can be found in the file MS-PL.txt at the root folder.
7
8 #ifndef __ATLWINX_H__
9 #define __ATLWINX_H__
10
11 #pragma once
12
13 #ifndef __ATLAPP_H__
14 #error atlwinx.h requires atlapp.h to be included first
15 #endif
16
17 #if (_ATL_VER >= 0x0700)
18 #include <atlwin.h>
19 #endif // (_ATL_VER >= 0x0700)
20
21
22 ///////////////////////////////////////////////////////////////////////////////
23 // Classes in this file:
24 //
25 // _U_RECT
26 // _U_MENUorID
27 // _U_STRINGorID
28
29
30 ///////////////////////////////////////////////////////////////////////////////
31 // Command Chaining Macros
32
33 #define CHAIN_COMMANDS(theChainClass) \
34 if(uMsg == WM_COMMAND) \
35 CHAIN_MSG_MAP(theChainClass)
36
37 #define CHAIN_COMMANDS_ALT(theChainClass, msgMapID) \
38 if(uMsg == WM_COMMAND) \
39 CHAIN_MSG_MAP_ALT(theChainClass, msgMapID)
40
41 #define CHAIN_COMMANDS_MEMBER(theChainMember) \
42 if(uMsg == WM_COMMAND) \
43 CHAIN_MSG_MAP_MEMBER(theChainMember)
44
45 #define CHAIN_COMMANDS_ALT_MEMBER(theChainMember, msgMapID) \
46 if(uMsg == WM_COMMAND) \
47 CHAIN_MSG_MAP_ALT_MEMBER(theChainMember, msgMapID)
48
49
50 ///////////////////////////////////////////////////////////////////////////////
51 // Macros for parent message map to selectively reflect control messages
52
53 // NOTE: ReflectNotifications is a member of ATL's CWindowImplRoot
54 // (and overridden in 2 cases - CContainedWindowT and CAxHostWindow)
55 // Since we can't modify ATL, we'll provide the needed additions
56 // in a separate function (that is not a member of CWindowImplRoot)
57
58 namespace WTL
59 {
60
61 inline LRESULT WtlReflectNotificationsFiltered(HWND hWndParent, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled,
62 UINT uMsgFilter = WM_NULL, UINT_PTR idFromFilter = 0, HWND hWndChildFilter = NULL)
63 {
64 if((uMsgFilter != WM_NULL) && (uMsgFilter != uMsg))
65 {
66 // The notification message doesn't match the filter.
67 bHandled = FALSE;
68 return 1;
69 }
70
71 HWND hWndChild = NULL;
72 UINT_PTR idFrom = 0;
73
74 switch(uMsg)
75 {
76 case WM_COMMAND:
77 if(lParam != NULL) // not from a menu
78 {
79 hWndChild = (HWND)lParam;
80 idFrom = (UINT_PTR)LOWORD(wParam);
81 }
82 break;
83 case WM_NOTIFY:
84 hWndChild = ((LPNMHDR)lParam)->hwndFrom;
85 idFrom = ((LPNMHDR)lParam)->idFrom;
86 break;
87 #ifndef _WIN32_WCE
88 case WM_PARENTNOTIFY:
89 switch(LOWORD(wParam))
90 {
91 case WM_CREATE:
92 case WM_DESTROY:
93 hWndChild = (HWND)lParam;
94 idFrom = (UINT_PTR)HIWORD(wParam);
95 break;
96 default:
97 hWndChild = ::GetDlgItem(hWndParent, HIWORD(wParam));
98 idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild);
99 break;
100 }
101 break;
102 #endif // !_WIN32_WCE
103 case WM_DRAWITEM:
104 if(wParam) // not from a menu
105 {
106 hWndChild = ((LPDRAWITEMSTRUCT)lParam)->hwndItem;
107 idFrom = (UINT_PTR)wParam;
108 }
109 break;
110 case WM_MEASUREITEM:
111 if(wParam) // not from a menu
112 {
113 hWndChild = ::GetDlgItem(hWndParent, ((LPMEASUREITEMSTRUCT)lParam)->CtlID);
114 idFrom = (UINT_PTR)wParam;
115 }
116 break;
117 case WM_COMPAREITEM:
118 if(wParam) // not from a menu
119 {
120 hWndChild = ((LPCOMPAREITEMSTRUCT)lParam)->hwndItem;
121 idFrom = (UINT_PTR)wParam;
122 }
123 break;
124 case WM_DELETEITEM:
125 if(wParam) // not from a menu
126 {
127 hWndChild = ((LPDELETEITEMSTRUCT)lParam)->hwndItem;
128 idFrom = (UINT_PTR)wParam;
129 }
130 break;
131 case WM_VKEYTOITEM:
132 case WM_CHARTOITEM:
133 case WM_HSCROLL:
134 case WM_VSCROLL:
135 hWndChild = (HWND)lParam;
136 idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild);
137 break;
138 case WM_CTLCOLORBTN:
139 case WM_CTLCOLORDLG:
140 case WM_CTLCOLOREDIT:
141 case WM_CTLCOLORLISTBOX:
142 case WM_CTLCOLORMSGBOX:
143 case WM_CTLCOLORSCROLLBAR:
144 case WM_CTLCOLORSTATIC:
145 hWndChild = (HWND)lParam;
146 idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild);
147 break;
148 default:
149 break;
150 }
151
152 if((hWndChild == NULL) ||
153 ((hWndChildFilter != NULL) && (hWndChildFilter != hWndChild)))
154 {
155 // Either hWndChild isn't valid, or
156 // hWndChild doesn't match the filter.
157 bHandled = FALSE;
158 return 1;
159 }
160
161 if((idFromFilter != 0) && (idFromFilter != idFrom))
162 {
163 // The dialog control id doesn't match the filter.
164 bHandled = FALSE;
165 return 1;
166 }
167
168 ATLASSERT(::IsWindow(hWndChild));
169 LRESULT lResult = ::SendMessage(hWndChild, OCM__BASE + uMsg, wParam, lParam);
170 if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC))
171 {
172 // Try to prevent problems with WM_CTLCOLOR* messages when
173 // the message wasn't really handled
174 bHandled = FALSE;
175 }
176
177 return lResult;
178 }
179
180 }; // namespace WTL
181
182 // Try to prevent problems with WM_CTLCOLOR* messages when
183 // the message wasn't really handled
184 #define REFLECT_NOTIFICATIONS_EX() \
185 { \
186 bHandled = TRUE; \
187 lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
188 if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC)) \
189 bHandled = FALSE; \
190 if(bHandled) \
191 return TRUE; \
192 }
193
194 #define REFLECT_NOTIFICATIONS_MSG_FILTERED(uMsgFilter) \
195 { \
196 bHandled = TRUE; \
197 lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, NULL); \
198 if(bHandled) \
199 return TRUE; \
200 }
201
202 #define REFLECT_NOTIFICATIONS_ID_FILTERED(idFromFilter) \
203 { \
204 bHandled = TRUE; \
205 lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, idFromFilter, NULL); \
206 if(bHandled) \
207 return TRUE; \
208 }
209
210 #define REFLECT_NOTIFICATIONS_HWND_FILTERED(hWndChildFilter) \
211 { \
212 bHandled = TRUE; \
213 lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, 0, hWndChildFilter); \
214 if(bHandled) \
215 return TRUE; \
216 }
217
218 #define REFLECT_NOTIFICATIONS_MSG_ID_FILTERED(uMsgFilter, idFromFilter) \
219 { \
220 bHandled = TRUE; \
221 lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, idFromFilter, NULL); \
222 if(bHandled) \
223 return TRUE; \
224 }
225
226 #define REFLECT_NOTIFICATIONS_MSG_HWND_FILTERED(uMsgFilter, hWndChildFilter) \
227 { \
228 bHandled = TRUE; \
229 lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, hWndChildFilter); \
230 if(bHandled) \
231 return TRUE; \
232 }
233
234 #define REFLECT_COMMAND(id, code) \
235 if(uMsg == WM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \
236 { \
237 bHandled = TRUE; \
238 lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
239 if(bHandled) \
240 return TRUE; \
241 }
242
243 #define REFLECT_COMMAND_ID(id) \
244 if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \
245 { \
246 bHandled = TRUE; \
247 lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
248 if(bHandled) \
249 return TRUE; \
250 }
251
252 #define REFLECT_COMMAND_CODE(code) \
253 if(uMsg == WM_COMMAND && code == HIWORD(wParam)) \
254 { \
255 bHandled = TRUE; \
256 lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
257 if(bHandled) \
258 return TRUE; \
259 }
260
261 #define REFLECT_COMMAND_RANGE(idFirst, idLast) \
262 if(uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
263 { \
264 bHandled = TRUE; \
265 lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
266 if(bHandled) \
267 return TRUE; \
268 }
269
270 #define REFLECT_COMMAND_RANGE_CODE(idFirst, idLast, code) \
271 if(uMsg == WM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
272 { \
273 bHandled = TRUE; \
274 lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
275 if(bHandled) \
276 return TRUE; \
277 }
278
279 #define REFLECT_NOTIFY(id, cd) \
280 if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \
281 { \
282 bHandled = TRUE; \
283 lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
284 if(bHandled) \
285 return TRUE; \
286 }
287
288 #define REFLECT_NOTIFY_ID(id) \
289 if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \
290 { \
291 bHandled = TRUE; \
292 lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
293 if(bHandled) \
294 return TRUE; \
295 }
296
297 #define REFLECT_NOTIFY_CODE(cd) \
298 if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \
299 { \
300 bHandled = TRUE; \
301 lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
302 if(bHandled) \
303 return TRUE; \
304 }
305
306 #define REFLECT_NOTIFY_RANGE(idFirst, idLast) \
307 if(uMsg == WM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
308 { \
309 bHandled = TRUE; \
310 lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
311 if(bHandled) \
312 return TRUE; \
313 }
314
315 #define REFLECT_NOTIFY_RANGE_CODE(idFirst, idLast, cd) \
316 if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
317 { \
318 bHandled = TRUE; \
319 lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
320 if(bHandled) \
321 return TRUE; \
322 }
323
324
325 ///////////////////////////////////////////////////////////////////////////////
326 // Reflected message handler macros for message maps (for ATL 3.0)
327
328 #if (_ATL_VER < 0x0700)
329
330 #define REFLECTED_COMMAND_HANDLER(id, code, func) \
331 if(uMsg == OCM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \
332 { \
333 bHandled = TRUE; \
334 lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
335 if(bHandled) \
336 return TRUE; \
337 }
338
339 #define REFLECTED_COMMAND_ID_HANDLER(id, func) \
340 if(uMsg == OCM_COMMAND && id == LOWORD(wParam)) \
341 { \
342 bHandled = TRUE; \
343 lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
344 if(bHandled) \
345 return TRUE; \
346 }
347
348 #define REFLECTED_COMMAND_CODE_HANDLER(code, func) \
349 if(uMsg == OCM_COMMAND && code == HIWORD(wParam)) \
350 { \
351 bHandled = TRUE; \
352 lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
353 if(bHandled) \
354 return TRUE; \
355 }
356
357 #define REFLECTED_COMMAND_RANGE_HANDLER(idFirst, idLast, func) \
358 if(uMsg == OCM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
359 { \
360 bHandled = TRUE; \
361 lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
362 if(bHandled) \
363 return TRUE; \
364 }
365
366 #define REFLECTED_COMMAND_RANGE_CODE_HANDLER(idFirst, idLast, code, func) \
367 if(uMsg == OCM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
368 { \
369 bHandled = TRUE; \
370 lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
371 if(bHandled) \
372 return TRUE; \
373 }
374
375 #define REFLECTED_NOTIFY_HANDLER(id, cd, func) \
376 if(uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \
377 { \
378 bHandled = TRUE; \
379 lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
380 if(bHandled) \
381 return TRUE; \
382 }
383
384 #define REFLECTED_NOTIFY_ID_HANDLER(id, func) \
385 if(uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \
386 { \
387 bHandled = TRUE; \
388 lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
389 if(bHandled) \
390 return TRUE; \
391 }
392
393 #define REFLECTED_NOTIFY_CODE_HANDLER(cd, func) \
394 if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \
395 { \
396 bHandled = TRUE; \
397 lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
398 if(bHandled) \
399 return TRUE; \
400 }
401
402 #define REFLECTED_NOTIFY_RANGE_HANDLER(idFirst, idLast, func) \
403 if(uMsg == OCM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
404 { \
405 bHandled = TRUE; \
406 lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
407 if(bHandled) \
408 return TRUE; \
409 }
410
411 #define REFLECTED_NOTIFY_RANGE_CODE_HANDLER(idFirst, idLast, cd, func) \
412 if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
413 { \
414 bHandled = TRUE; \
415 lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
416 if(bHandled) \
417 return TRUE; \
418 }
419
420 #endif // (_ATL_VER < 0x0700)
421
422
423 ///////////////////////////////////////////////////////////////////////////////
424 // Dual argument helper classes (for ATL 3.0)
425
426 #if (_ATL_VER < 0x0700)
427
428 namespace ATL
429 {
430
431 class _U_RECT
432 {
433 public:
434 _U_RECT(LPRECT lpRect) : m_lpRect(lpRect)
435 { }
436 _U_RECT(RECT& rc) : m_lpRect(&rc)
437 { }
438 LPRECT m_lpRect;
439 };
440
441 class _U_MENUorID
442 {
443 public:
444 _U_MENUorID(HMENU hMenu) : m_hMenu(hMenu)
445 { }
446 _U_MENUorID(UINT nID) : m_hMenu((HMENU)LongToHandle(nID))
447 { }
448 HMENU m_hMenu;
449 };
450
451 class _U_STRINGorID
452 {
453 public:
454 _U_STRINGorID(LPCTSTR lpString) : m_lpstr(lpString)
455 { }
456 _U_STRINGorID(UINT nID) : m_lpstr(MAKEINTRESOURCE(nID))
457 { }
458 LPCTSTR m_lpstr;
459 };
460
461 }; // namespace ATL
462
463 #endif // (_ATL_VER < 0x0700)
464
465
466 namespace WTL
467 {
468
469 ///////////////////////////////////////////////////////////////////////////////
470 // Forward notifications support for message maps (for ATL 3.0)
471
472 #if (_ATL_VER < 0x0700)
473
474 // forward notifications support
475 #define FORWARD_NOTIFICATIONS() \
476 { \
477 bHandled = TRUE; \
478 lResult = WTL::Atl3ForwardNotifications(m_hWnd, uMsg, wParam, lParam, bHandled); \
479 if(bHandled) \
480 return TRUE; \
481 }
482
483 static LRESULT Atl3ForwardNotifications(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
484 {
485 LRESULT lResult = 0;
486 switch(uMsg)
487 {
488 case WM_COMMAND:
489 case WM_NOTIFY:
490 #ifndef _WIN32_WCE
491 case WM_PARENTNOTIFY:
492 #endif // !_WIN32_WCE
493 case WM_DRAWITEM:
494 case WM_MEASUREITEM:
495 case WM_COMPAREITEM:
496 case WM_DELETEITEM:
497 case WM_VKEYTOITEM:
498 case WM_CHARTOITEM:
499 case WM_HSCROLL:
500 case WM_VSCROLL:
501 case WM_CTLCOLORBTN:
502 case WM_CTLCOLORDLG:
503 case WM_CTLCOLOREDIT:
504 case WM_CTLCOLORLISTBOX:
505 case WM_CTLCOLORMSGBOX:
506 case WM_CTLCOLORSCROLLBAR:
507 case WM_CTLCOLORSTATIC:
508 lResult = ::SendMessage(::GetParent(hWnd), uMsg, wParam, lParam);
509 break;
510 default:
511 bHandled = FALSE;
512 break;
513 }
514 return lResult;
515 }
516
517 #endif // (_ATL_VER < 0x0700)
518
519 }; // namespace WTL
520
521 #endif // __ATLWINX_H__
+0
-22
src/third_party/wtl/LICENSE less more
0 Microsoft Public License (MS-PL)
1
2 This license governs use of the accompanying software. If you use the software, you
3 accept this license. If you do not accept the license, do not use the software.
4
5 1. Definitions
6 The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
7 same meaning here as under U.S. copyright law.
8 A "contribution" is the original software, or any additions or changes to the software.
9 A "contributor" is any person that distributes its contribution under this license.
10 "Licensed patents" are a contributor's patent claims that read directly on its contribution.
11
12 2. Grant of Rights
13 (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
14 (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
15
16 3. Conditions and Limitations
17 (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
18 (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
19 (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
20 (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
21 (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
+0
-22
src/third_party/wtl/MS-PL.txt less more
0 Microsoft Public License (MS-PL)
1
2 This license governs use of the accompanying software. If you use the software, you
3 accept this license. If you do not accept the license, do not use the software.
4
5 1. Definitions
6 The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
7 same meaning here as under U.S. copyright law.
8 A "contribution" is the original software, or any additions or changes to the software.
9 A "contributor" is any person that distributes its contribution under this license.
10 "Licensed patents" are a contributor's patent claims that read directly on its contribution.
11
12 2. Grant of Rights
13 (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
14 (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
15
16 3. Conditions and Limitations
17 (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
18 (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
19 (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
20 (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
21 (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
+0
-11
src/third_party/wtl/README.mozc less more
0 URL: http://sourceforge.net/projects/wtl/files/WTL%209.1/WTL%209.1.5321%20Final/
1 Version: WTL version 9.1.5321
2 License: Ms-PL
3 License File: LICENSE
4
5 Local Modifications:
6 Removed following non-essential directories, to save space.
7 - AppWiz/
8 - AppWizCE/
9 - AppWizMobile/
10 - Samples/
+0
-3653
src/third_party/wtl/ReadMe.html less more
0 <html>
1
2 <head>
3 <meta http-equiv="Content-Language" content="en-us">
4 <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
5 <title>Windows Template Library</title>
6 <style type="text/css">
7 html, body {
8 width: 800px;
9 }
10 .style1 {
11 font-family: Arial;
12 font-weight: bold;
13 font-size: x-small;
14 }
15 .style2 {
16 font-family: Courier;
17 font-size: small;
18 }
19 .style3 {
20 text-align: right;
21 }
22 </style>
23 </head>
24
25 <body>
26
27 <table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" id="AutoNumber3">
28 <tr>
29 <td class="style3">
30 <p style="text-align: left"><font face="Arial"><b>Windows Template Library - WTL Version 9.1</b></font><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
31 (build 5321 final) 2015-11-17</font></td>
32 </tr>
33 <tr>
34 <td><hr></td>
35 </tr>
36 <tr>
37 <td><font face="Arial" size="2">Copyright &#169; 2015 Microsoft Corporation, WTL Team. All rights reserved.</font></td>
38 </tr>
39 <tr>
40 <td>&nbsp;</td>
41 </tr>
42 <tr>
43 <td><font face="Arial" size="2">This file is a part of the Windows Template
44 Library.<br>
45 The use and distribution terms for this software are covered by the<br>
46 Microsoft Public License (<a target="_blank" href="http://opensource.org/licenses/MS-PL">http://opensource.org/licenses/MS-PL</a>)<br>
47 which can be found in the file MS-PL.txt at the root folder.<br></font></td>
48 </tr>
49 <tr>
50 <td><hr></td>
51 </tr>
52 </table>
53
54 <p style=margin:0in>&nbsp;</p>
55
56 <p style=margin:0in>&nbsp;</p>
57
58 <p style=margin:0in><font face="Arial" size="2">Welcome to the Windows Template Library, version
59 9.1. This document contains the following topics:</font></p>
60 <p style=margin:0in>&nbsp;</p>
61 <ul style="margin-top:0in;margin-bottom:0in">
62 <li><font face="Arial" size="2"><a href="#Introduction">Introduction</a></font></li>
63 <li><font face="Arial" size="2"><a href="#Features and Installation">Features
64 and Installation</a></font></li>
65 <li><font face="Arial" size="2"><a href="#Packing List">Packing List</a></font></li>
66 <li><font face="Arial" size="2"><a href="#Class Overview">Class Overview</a></font></li>
67 <li><font face="Arial" size="2"><a href="#ATL/WTL AppWizard">ATL/WTL AppWizard</a></font></li>
68 <li><a href="#Support for Windows CE"><font face="Arial" size="2">S</font></a><font face="Arial" size="2"><a href="#Support for Windows CE">upport
69 for Windows CE</a></font></li>
70 <li><font face="Arial" size="2">
71 <a href="#Support for Visual C++ Express">Support for Visual C++
72 Express</a></font></li>
73 <li><font face="Arial" size="2"><a href="#Notes">Notes</a></font></li>
74 <li><font face="Arial" size="2"><a href="#Changes Between WTL 9.1 and 9.0">Changes Between WTL
75 9.1 and 9.0</a></font></li>
76 <li><font face="Arial" size="2"><a href="#Changes Between WTL 9.0 and 8.0">Changes Between WTL
77 9.0 and 8.0</a></font></li>
78 <li><font face="Arial" size="2"><a href="#Changes Between WTL 8.0 and 7.5">Changes Between WTL
79 8.0 and 7.5</a></font></li>
80 <li><font face="Arial" size="2"><a href="#Changes Between WTL 7.5 and 7.1">Changes Between WTL 7.5 and 7.1</a></font></li>
81 <li><font face="Arial" size="2"><a href="#Changes Between WTL 7.1 and 7.0">Changes Between WTL
82 7.1 and 7.0</a></font></li>
83 <li><font face="Arial" size="2"><a href="#Changes Between WTL 7.0 and 3.1">Changes Between WTL
84 7.0 and 3.1</a></font></li>
85 <li><font face="Arial" size="2"><a href="#Changes Between WTL 3.1 and 3.0">Changes Between WTL 3.1 and 3.0</a></font></li>
86 </ul>
87 <p style=margin:0in>&nbsp;</p>
88 <p style=margin:0in>&nbsp;</p>
89 <p style=margin:0in><font face="Arial">
90 <b><a name="Introduction"></a>Introduction</b></font></p>
91 <p style=margin:0in>&nbsp;</p>
92 <p style=margin:0in><font face="Arial" size="2">Windows Template Library, or WTL, is a set of
93 classes that extend ATL to support more complex user interfaces for either
94 applications or various UI components, while maintaining the big advantage of
95 ATL - small and fast code. WTL classes were designed to be the best and the
96 easiest way to implement rich Win32 based UI for ATL based applications,
97 servers, components, and controls.</font></p>
98 <p style=margin:0in>&nbsp;</p>
99 <p style=margin:0in><font face="Arial" size="2">WTL provides support for implementing
100 many
101 user interface elements, from frame and popup windows, to MDI, standard and
102 common controls, common dialogs, property sheets and pages, GDI objects, UI
103 updating, scrollable windows, splitter windows, command bars, etc. The WTL
104 classes are mostly templated and use minimal instance data and inline functions.
105 They were not designed as a framework, so they do not force a particular
106 application model, and can accommodate any. The classes do not use hooks or
107 thread local storage, so they have no restrictions that those techniques impose.
108 They also have no inter-dependencies and can be freely mixed with straight SDK
109 code. In summary, WTL delivers very small and efficient code, very close in size
110 and speed to SDK programs, while presenting a more logical, object oriented
111 model to a programmer.</font></p>
112 <p style=margin:0in>&nbsp;</p>
113 <p style=margin:0in>&nbsp;</p>
114 <p style=margin:0in><font face="Arial">
115 <b><a name="Features and Installation"></a>Features and Installation</b></font></p>
116 <p style=margin:0in>&nbsp;</p>
117 <p style=margin:0in><font face="Arial" size="2">This is the eigth public release
118 of WTL, after WTL 3.0, 3.1, 7.0, 7.1, 7.5, 8.0, and 9.0. This version is released
119 under the Microsoft Public License, enabling developers from the WTL community to
120 contribute to the library.</font></p>
121 <p style=margin:0in>&nbsp;</p>
122 <p style=margin:0in><font face="Arial" size="2">WTL classes can be used with either VC++ 6.0, VC++ .NET 2002 or 2003, VC++ 2005 or 2008 or 2010 or 2012 or 2013 or 2015,
123 or EVC++ 4.0 or 3.0. AppWizard for Visual Studio is
124 included.</font></p>
125 <p style=margin:0in>&nbsp;</p>
126 <p style=margin:0in><font face="Arial" size="2">The WTL classes are provided in
127 header files located in the include directory. The only header files that must
128 be included is atlapp.h, while others can be used when needed. The name of the
129 file doesn't mean that you have to create an application, just that
130 atlapp.h contains base definitions required for WTL projects.</font></p>
131 <p style=margin:0in>&nbsp;</p>
132 <p style=margin:0in><font face="Arial" size="2">To install WTL, just copy the whole directory
133 structure, or unpack the archive file, to the location of your choice. Please be sure to
134 <b>add the WTL\include
135 directory</b> to the list of include directories in VC++, so that the compiler
136 can find them when you include them in your projects..</font></p>
137 <p style=margin:0in>&nbsp;</p>
138 <p style=margin:0in><font face="Arial" size="2">Setup programs for the AppWizard are provided. After executing the setup script, ATL/WTL AppWizard will appear in the list of AppWizards when you select File.New.Project
139 in VC++ IDE. The file AppWiz\setup.js is the setup script for all supported versions of Visual Studio, while
140 AppWizards for Windows CE have separate scripts for VS2005 and VS2008 SmartDevice projects.</font></p>
141 <p style=margin:0in>&nbsp;</p>
142 <p style=margin:0in><font face="Arial" size="2">To manually install AppWizard
143 for VC++ .NET 2002/2003, copy all WTLAppWiz.* files from AppWiz\Files to VC++ .NET
144 projects directory, %VC7DIR%\Vc7\vcprojects, where %VC7DIR% is the directory
145 where VC++ .NET 2002/2003 is installed. After that,&nbsp;open WTLAppWiz.vsz and modify the
146 like that contains ABSOLUTE_PATH to contain %WTLDIR%\AppWiz\Files, where
147 %WTLDIR% is the directory where WTL files are.</font></p>
148 <p style=margin:0in>&nbsp;</p>
149 <p style=margin:0in><font face="Arial" size="2">Platform support and
150 requirements:</font></p>
151 <p style=margin:0in>&nbsp;</p>
152 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; Compiler/IDE/ATL:</font></p>
153 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
154 Visual C++ 6.0&nbsp;&nbsp; (ATL 3.0)</font></p>
155 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
156 Visual C++.NET 2002&nbsp;&nbsp; (ATL 7.0)</font></p>
157 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
158 Visual C++.NET 2003&nbsp;&nbsp; (ATL 7.1)</font></p>
159 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
160 Visual C++ 2005&nbsp;&nbsp; (ATL 8.0)</font></p>
161 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
162 Visual C++ 2008&nbsp;&nbsp; (ATL 9.0)</font></p>
163 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
164 Visual C++ 2010&nbsp;&nbsp; (ATL 10.0)</font></p>
165 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
166 Visual C++ 2012&nbsp;&nbsp; (ATL 11.0)</font></p>
167 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
168 Visual C++ 2013&nbsp;&nbsp; (ATL 12.0)</font></p>
169 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
170 Visual C++ 2015&nbsp;&nbsp; (ATL 14.0)</font></p>
171 <p style=margin:0in>&nbsp;</p>
172 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; SDK
173 (optional):</font></p>
174 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
175 Any Platform SDK from January 2000 release up to the latest Windows SDK</font></p>
176 <p style=margin:0in>&nbsp;</p>
177 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; Windows CE
178 development:</font></p>
179 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
180 eMbedded Visual C++ 3.0 - Pocket PC, Pocket PC 2002</font></p>
181 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
182 eMbedded Visual C++ 4.0 - STANDARDSDK_410, Pocket PC 2003, Smartphone 2003,
183 </font></p>
184 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
185 STANDARDSDK_500, Pocket PC 2003 SE, Smartphone 2003 SE</font></p>
186 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
187 Visual C++ 2005 - Pocket PC 2003 SE, Smartphone 2003 SE, STANDARDSDK_500,</font></p>
188 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
189 Windows Mobile 5.0 (Pocket PC and Smartphone),<br>
190 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
191 Windows Mobile 6.0 (Standard and Professional)</font></p>
192 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
193 Visual C++ 2008 - Pocket PC 2003 SE, Smartphone 2003 SE, STANDARDSDK_500,</font></p>
194 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
195 Windows Mobile 5.0 (Pocket PC and Smartphone),<br>
196 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
197 Windows Mobile 6.0 (Standard and Professional)</font></p>
198 <p style=margin:0in>&nbsp;</p>
199 <p style=margin:0in>&nbsp;</p>
200 <p style=margin:0in><font face="Arial">
201 <b><a name="Packing List"></a>Packing List</b></font></p>
202 <p style=margin:0in>&nbsp;</p>
203 <table border="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="497" id="AutoNumber2">
204 <tr>
205 <td width="136"><font face="Arial" size="2">File Name:</font></td>
206 <td width="358"><font face="Arial" size="2">Description:</font></td>
207 </tr>
208 <tr>
209 <td width="494" colspan="2"><hr></td>
210 </tr>
211 <tr>
212 <td width="136"><font face="Arial" size="2">readme.html</font></td>
213 <td width="358"><font face="Arial" size="2">this file</font></td>
214 </tr>
215 <tr>
216 <td width="136"><font face="Arial" size="2">MS-PL.txt</font></td>
217 <td width="358"><font face="Arial" size="2">Microsoft Public License</font></td>
218 </tr>
219 <tr>
220 <td width="494" colspan="2">&nbsp;</td>
221 </tr>
222 <tr>
223 <td width="494" colspan="2"><font face="Arial" size="2">include\</font></td>
224 </tr>
225 <tr>
226 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlapp.h</font></td>
227 <td width="358"><font face="Arial" size="2">message loop, interfaces,
228 general app stuff</font></td>
229 </tr>
230 <tr>
231 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlcrack.h</font></td>
232 <td width="358"><font face="Arial" size="2">message cracker macros</font></td>
233 </tr>
234 <tr>
235 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlctrls.h</font></td>
236 <td width="358"><font face="Arial" size="2">standard and common control
237 classes</font></td>
238 </tr>
239 <tr>
240 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlctrlw.h</font></td>
241 <td width="358"><font face="Arial" size="2">command bar class</font></td>
242 </tr>
243 <tr>
244 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlctrlx.h</font></td>
245 <td width="358"><font face="Arial" size="2">bitmap button, check list view,
246 and other controls</font></td>
247 </tr>
248 <tr>
249 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlddx.h</font></td>
250 <td width="358"><font face="Arial" size="2">data exchange for dialogs and
251 windows</font></td>
252 </tr>
253 <tr>
254 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atldlgs.h</font></td>
255 <td width="358"><font face="Arial" size="2">common dialog classes, property
256 sheet and page classes</font></td>
257 </tr>
258 <tr>
259 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atldwm.h</font></td>
260 <td width="358"><font face="Arial" size="2">DWM support classes</font></td>
261 </tr>
262 <tr>
263 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlfind.h</font></td>
264 <td width="358"><font face="Arial" size="2">Find/Replace support for Edit
265 and RichEdit</font></td>
266 </tr>
267 <tr>
268 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlframe.h</font></td>
269 <td width="358"><font face="Arial" size="2">frame window classes, MDI,
270 update UI classes</font></td>
271 </tr>
272 <tr>
273 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlgdi.h</font></td>
274 <td width="358"><font face="Arial" size="2">DC classes, GDI object classes</font></td>
275 </tr>
276 <tr>
277 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlmisc.h</font></td>
278 <td width="358"><font face="Arial" size="2">WTL ports of CPoint, CRect,
279 CSize, CString, etc.</font></td>
280 </tr>
281 <tr>
282 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlprint.h</font></td>
283 <td width="358"><font face="Arial" size="2">printing and print preview</font></td>
284 </tr>
285 <tr>
286 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlres.h</font></td>
287 <td width="358"><font face="Arial" size="2">standard resource IDs</font></td>
288 </tr>
289 <tr>
290 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlresce.h</font></td>
291 <td width="358"><font face="Arial" size="2">standard resource IDs for
292 Windows CE</font></td>
293 </tr>
294 <tr>
295 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlribbon.h</font></td>
296 <td width="358"><font face="Arial" size="2">RibbonUI support</font></td>
297 </tr>
298 <tr>
299 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlscrl.h</font></td>
300 <td width="358"><font face="Arial" size="2">scrollable windows</font></td>
301 </tr>
302 <tr>
303 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlsplit.h</font></td>
304 <td width="358"><font face="Arial" size="2">splitter windows</font></td>
305 </tr>
306 <tr>
307 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atltheme.h</font></td>
308 <td width="358"><font face="Arial" size="2">Windows XP theme classes</font></td>
309 </tr>
310 <tr>
311 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atluser.h</font></td>
312 <td width="358"><font face="Arial" size="2">menu class, USER object classes</font></td>
313 </tr>
314 <tr>
315 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlwince.h</font></td>
316 <td width="358"><font face="Arial" size="2">specific support for Windows CE
317 Mobile platforms</font></td>
318 </tr>
319 <tr>
320 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; atlwinx.h</font></td>
321 <td width="358"><font face="Arial" size="2">extensions of ATL windowing
322 support</font></td>
323 </tr>
324 <tr>
325 <td width="494" colspan="2">&nbsp;</td>
326 </tr>
327 <tr>
328 <td width="494" colspan="2"><font face="Arial" size="2">Samples\</font></td>
329 </tr>
330 <tr>
331 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; Aero\...</font></td>
332 <td width="358"><font face="Arial" size="2">Vista Aero glass showcase</font></td>
333 </tr>
334 <tr>
335 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; Alpha\...</font></td>
336 <td width="358"><font face="Arial" size="2">Windows XP 32-bit (alpha)
337 toolbar images</font></td>
338 </tr>
339 <tr>
340 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; BmpView\...</font></td>
341 <td width="358"><font face="Arial" size="2">bitmap file view sample</font></td>
342 </tr>
343 <tr>
344 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; GuidGen\...</font></td>
345 <td width="358"><font face="Arial" size="2">WTL version of the GuidGen
346 sample</font></td>
347 </tr>
348 <tr>
349 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; ImageView\...</font></td>
350 <td width="358"><font face="Arial" size="2">Full-featured PPC frame-view
351 application</font></td>
352 </tr>
353 <tr>
354 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; MDIDocVw\...</font></td>
355 <td width="358"><font face="Arial" size="2">WTL version of the MDI sample</font></td>
356 </tr>
357 <tr>
358 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; MemDlg\...</font></td>
359 <td width="358"><font face="Arial" size="2">In-memory dialog sample</font></td>
360 </tr>
361 <tr>
362 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; MiniPie\...</font></td>
363 <td width="358"><font face="Arial" size="2">port of the SDK sample for
364 Mobile devices</font></td>
365 </tr>
366 <tr>
367 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; MTPad\...</font></td>
368 <td width="358"><font face="Arial" size="2">multithreaded notepad sample</font></td>
369 </tr>
370 <tr>
371 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; MTPad7\...</font></td>
372 <td width="358"><font face="Arial" size="2">MTPad with RibbonUI</font></td>
373 </tr>
374 <tr>
375 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; SPControls\...</font></td>
376 <td width="358"><font face="Arial" size="2">Barebone SmartPhone dialog
377 application</font></td>
378 </tr>
379 <tr>
380 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; TabBrowser\...</font></td>
381 <td width="358"><font face="Arial" size="2">Web browser using TabView</font></td>
382 </tr>
383 <tr>
384 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; Wizard97Test\...</font></td>
385 <td width="358"><font face="Arial" size="2">Wizard97 showcase
386 sample</font></td>
387 </tr>
388 <tr>
389 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; WTLExplorer\...</font></td>
390 <td width="358"><font face="Arial" size="2">Explorer-like application
391 sample</font></td>
392 </tr>
393 <tr>
394 <td width="494" colspan="2">&nbsp;</td>
395 </tr>
396 <tr>
397 <td width="494" colspan="2"><font face="Arial" size="2">AppWiz\</font></td>
398 </tr>
399 <tr>
400 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; setup.js</font></td>
401 <td width="358"><font face="Arial" size="2">AppWizard setup program for all versions of
402 Visual Studio</font></td>
403 </tr>
404 <tr>
405 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; Files\...</font></td>
406 <td width="358"><font face="Arial" size="2">WTL AppWizard files</font></td>
407 </tr>
408 <tr>
409 <td width="494" colspan="2">&nbsp;</td>
410 </tr>
411 <tr>
412 <td width="494" colspan="2"><font face="Arial" size="2">AppWizCE\</font></td>
413 </tr>
414 <tr>
415 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; setup80.js</font></td>
416 <td width="358"><font face="Arial" size="2">AppWizard setup program for VC++
417 2005</font></td>
418 </tr>
419 <tr>
420 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; setup90.js</font></td>
421 <td width="358"><font face="Arial" size="2">AppWizard setup program for VC++
422 2008</font></td>
423 </tr>
424 <tr>
425 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; Files\...</font></td>
426 <td width="358"><font face="Arial" size="2">WTL AppWizard CE files</font></td>
427 </tr>
428 <tr>
429 <td width="494" colspan="2">&nbsp;</td>
430 </tr>
431 <tr>
432 <td width="494" colspan="2"><font face="Arial" size="2">AppWizMobile\</font></td>
433 </tr>
434 <tr>
435 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; setup80.js</font></td>
436 <td width="358"><font face="Arial" size="2">AppWizard Mobile setup program for VC++
437 2005</font></td>
438 </tr>
439 <tr>
440 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; setup90.js</font></td>
441 <td width="358"><font face="Arial" size="2">AppWizard Mobile setup program for VC++
442 2008</font></td>
443 </tr>
444 <tr>
445 <td width="136"><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; Files\...</font></td>
446 <td width="358"><font face="Arial" size="2">WTL AppWizard Mobile files</font></td>
447 </tr>
448 </table>
449 <p style=margin:0in>&nbsp;</p>
450 <p style=margin:0in>&nbsp;</p>
451 <p style=margin:0in><font face="Arial">
452 <b><a name="Class Overview"></a>Class Overview</b></font></p>
453 <p style=margin:0in>&nbsp;</p>
454 <table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" id="AutoNumber4">
455 <tr>
456 <td><font face="Arial" size="2">usage:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
457 </font></td>
458 <td><font face="Arial" size="2"><b>mi base</b></font></td>
459 <td>&nbsp;&nbsp; -</td>
460 <td><font face="Arial" size="2">&nbsp;&nbsp; a base class (multiple
461 inheritance)</font></td>
462 </tr>
463 <tr>
464 <td>&nbsp;</td>
465 <td><font face="Arial" size="2"><b>client</b></font></td>
466 <td>&nbsp;&nbsp; -</td>
467 <td><font face="Arial" size="2">&nbsp;&nbsp; wrapper class for a handle</font></td>
468 </tr>
469 <tr>
470 <td>&nbsp;</td>
471 <td><font face="Arial" size="2"><b>as-is</b></font></td>
472 <td>&nbsp;&nbsp; -</td>
473 <td><font face="Arial" size="2">&nbsp;&nbsp; to be used directly</font></td>
474 </tr>
475 <tr>
476 <td>&nbsp;</td>
477 <td><font face="Arial" size="2"><b>impl</b></font></td>
478 <td>&nbsp;&nbsp; -</td>
479 <td><font face="Arial" size="2">&nbsp;&nbsp; implements a window (has
480 WindowProc) or other support</font></td>
481 </tr>
482 <tr>
483 <td>&nbsp;</td>
484 <td><font face="Arial" size="2"><b>helper</b></font></td>
485 <td>&nbsp;&nbsp; -</td>
486 <td><font face="Arial" size="2">&nbsp;&nbsp; a helper class</font></td>
487 </tr>
488 <tr>
489 <td>&nbsp;</td>
490 <td><font face="Arial" size="2"><b>base</b></font></td>
491 <td>&nbsp;&nbsp; -</td>
492 <td><font face="Arial" size="2">&nbsp;&nbsp; implementation base class</font></td>
493 </tr>
494 </table>
495 <p style=margin:0in>&nbsp;</p>
496 <table border="1" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" id="AutoNumber1" width="600">
497 <tr>
498 <td width="220"><b><font face="Arial" size="2">class name:</font></b></td>
499 <td width="114"><b><font face="Arial" size="2">usage:</font></b></td>
500 <td width="253"><b><font face="Arial" size="2">description:</font></b></td>
501 </tr>
502 <tr>
503 <td colspan="3" width="593"><font size="2" face="Arial"><br>App/module support</font></td>
504 </tr>
505 <tr>
506 <td width="221"><b><font face="Arial" size="2">CAppModule</font></b></td>
507 <td width="115"><font face="Arial" size="2">as-is</font></td>
508 <td width="255"><font face="Arial" size="2">app support, CComModule derived</font></td>
509 </tr>
510 <tr>
511 <td width="221"><b><font face="Arial" size="2">CServerAppModule</font></b></td>
512 <td width="115"><font face="Arial" size="2">as-is</font></td>
513 <td width="255"><font face="Arial" size="2">module for COM servers</font></td>
514 </tr>
515 <tr>
516 <td width="221"><b><font face="Arial" size="2">CMessageLoop</font></b></td>
517 <td width="115"><font face="Arial" size="2">as-is</font></td>
518 <td width="255"><font face="Arial" size="2">message loop</font></td>
519 </tr>
520 <tr>
521 <td width="221"><b><font face="Arial" size="2">CMessageFilter</font></b></td>
522 <td width="115"><font face="Arial" size="2">mi base</font></td>
523 <td width="255"><font face="Arial" size="2">message filter interface</font></td>
524 </tr>
525 <tr>
526 <td width="221"><b><font face="Arial" size="2">CIdleHandler</font></b></td>
527 <td width="115"><font face="Arial" size="2">mi base</font></td>
528 <td width="255"><font face="Arial" size="2">idle time handler interface</font></td>
529 </tr>
530 <tr>
531 <td colspan="3" width="593"><font face="Arial" size="2"><br>Frame windows</font></td>
532 </tr>
533 <tr>
534 <td width="221"><b><font face="Arial" size="2">CFrameWindowImplBase</font></b></td>
535 <td width="115"><font face="Arial" size="2">base</font></td>
536 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
537 </tr>
538 <tr>
539 <td width="221"><b><font face="Arial" size="2">CFrameWindowImpl</font></b></td>
540 <td width="115"><font face="Arial" size="2">impl</font></td>
541 <td width="255"><font face="Arial" size="2">frame window support</font></td>
542 </tr>
543 <tr>
544 <td width="221"><b><font face="Arial" size="2">COwnerDraw</font></b></td>
545 <td width="115"><font face="Arial" size="2">impl mi base</font></td>
546 <td width="255"><font face="Arial" size="2">owner-draw msg map and handlers</font></td>
547 </tr>
548 <tr>
549 <td width="221"><b><font face="Arial" size="2">CDialogResize</font>
550 </b></td>
551 <td width="115"><font face="Arial" size="2">impl mi base</font></td>
552 <td width="255"><font face="Arial" size="2">support for resizing dialogs</font></td>
553 </tr>
554 <tr>
555 <td width="221"><b><font face="Arial" size="2">CDoubleBufferImpl</font>
556 </b></td>
557 <td width="115"><font face="Arial" size="2">impl mi</font></td>
558 <td width="255"><font face="Arial" size="2">double-buffer painting support</font></td>
559 </tr>
560 <tr>
561 <td width="221"><b><font face="Arial" size="2">CDoubleBufferWindowImpl</font>
562 </b></td>
563 <td width="115"><font face="Arial" size="2">impl</font></td>
564 <td width="255"><font face="Arial" size="2">double-buffer painting window</font></td>
565 </tr>
566 <tr>
567 <td colspan="3" width="593"><font face="Arial" size="2"><br>MDI windows</font></td>
568 </tr>
569 <tr>
570 <td width="221"><b><font face="Arial" size="2">CMDIWindow</font></b></td>
571 <td width="115"><font face="Arial" size="2">client</font></td>
572 <td width="255"><font face="Arial" size="2">MDI methods</font></td>
573 </tr>
574 <tr>
575 <td width="221"><b><font face="Arial" size="2">CMDIFrameWindowImpl</font></b></td>
576 <td width="115"><font face="Arial" size="2">impl</font></td>
577 <td width="255"><font face="Arial" size="2">MDI frame window</font></td>
578 </tr>
579 <tr>
580 <td width="221"><b><font face="Arial" size="2">CMDIChildWindowImpl</font></b></td>
581 <td width="115"><font face="Arial" size="2">impl</font></td>
582 <td width="255"><font face="Arial" size="2">MDI child window</font></td>
583 </tr>
584 <tr>
585 <td colspan="3" width="593"><font face="Arial" size="2"><br>Update UI</font></td>
586 </tr>
587 <tr>
588 <td width="221"><b><font face="Arial" size="2">CUpdateUIBase</font></b></td>
589 <td width="115"><font face="Arial" size="2">base</font></td>
590 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
591 </tr>
592 <tr>
593 <td width="221"><b><font face="Arial" size="2">CUpdateUI</font></b></td>
594 <td width="115"><font face="Arial" size="2">mi base class</font></td>
595 <td width="255"><font face="Arial" size="2">provides support for UI update</font></td>
596 </tr>
597 <tr>
598 <td width="221"><b><font face="Arial" size="2">CDynamicUpdateUI</font></b></td>
599 <td width="115"><font face="Arial" size="2">mi base class</font></td>
600 <td width="255"><font face="Arial" size="2">provides dynamic support for UI update</font></td>
601 </tr>
602 <tr>
603 <td colspan="3" width="593"><font face="Arial" size="2"><br>Standard controls</font></td>
604 </tr>
605 <tr>
606 <td width="221"><b><font face="Arial" size="2">CStatic</font></b></td>
607 <td width="115"><font face="Arial" size="2">client</font></td>
608 <td width="255"><font face="Arial" size="2">static ctrl</font></td>
609 </tr>
610 <tr>
611 <td width="221"><b><font face="Arial" size="2">CButton</font></b></td>
612 <td width="115"><font face="Arial" size="2">client</font></td>
613 <td width="255"><font face="Arial" size="2">button ctrl</font></td>
614 </tr>
615 <tr>
616 <td width="221"><b><font face="Arial" size="2">CListBox</font></b></td>
617 <td width="115"><font face="Arial" size="2">client</font></td>
618 <td width="255"><font face="Arial" size="2">list box ctrl</font></td>
619 </tr>
620 <tr>
621 <td width="221"><b><font face="Arial" size="2">CComboBox</font></b></td>
622 <td width="115"><font face="Arial" size="2">client</font></td>
623 <td width="255"><font face="Arial" size="2">combo box ctrl</font></td>
624 </tr>
625 <tr>
626 <td width="221"><b><font face="Arial" size="2">CEdit</font></b></td>
627 <td width="115"><font face="Arial" size="2">client</font></td>
628 <td width="255"><font face="Arial" size="2">edit ctrl</font></td>
629 </tr>
630 <tr>
631 <td width="221"><b><font face="Arial" size="2">CEditCommands</font></b></td>
632 <td width="115"><font face="Arial" size="2">mi</font></td>
633 <td width="255"><font face="Arial" size="2">standard edit command support</font></td>
634 </tr>
635 <tr>
636 <td width="221"><b><font face="Arial" size="2">CScrollBar</font></b></td>
637 <td width="115"><font face="Arial" size="2">client</font></td>
638 <td width="255"><font face="Arial" size="2">scroll bar ctrl</font></td>
639 </tr>
640 <tr>
641 <td colspan="3" width="593"><font face="Arial" size="2"><br>Common controls</font></td>
642 </tr>
643 <tr>
644 <td width="221"><b><font face="Arial" size="2">CImageList</font></b></td>
645 <td width="115"><font face="Arial" size="2">client</font></td>
646 <td width="255"><font face="Arial" size="2">image list</font></td>
647 </tr>
648 <tr>
649 <td width="221"><b><font face="Arial" size="2">CListViewCtrl</font></b></td>
650 <td width="115"><font face="Arial" size="2">client</font></td>
651 <td width="255"><font face="Arial" size="2">list view ctrl</font></td>
652 </tr>
653 <tr>
654 <td width="221"><b><font face="Arial" size="2">CTreeViewCtrl</font></b></td>
655 <td width="115"><font face="Arial" size="2">client</font></td>
656 <td width="255"><font face="Arial" size="2">tree view ctrl</font></td>
657 </tr>
658 <tr>
659 <td width="221"><b><font face="Arial" size="2">CTreeItem</font></b></td>
660 <td width="115"><font face="Arial" size="2">helper</font></td>
661 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
662 </tr>
663 <tr>
664 <td width="221"><b><font face="Arial" size="2">CTreeViewCtrlEx</font></b></td>
665 <td width="115"><font face="Arial" size="2">client</font></td>
666 <td width="255"><font face="Arial" size="2">uses CTreeItem</font></td>
667 </tr>
668 <tr>
669 <td width="221"><b><font face="Arial" size="2">CHeaderCtrl</font></b></td>
670 <td width="115"><font face="Arial" size="2">client</font></td>
671 <td width="255"><font face="Arial" size="2">header bar ctrl</font></td>
672 </tr>
673 <tr>
674 <td width="221"><b><font face="Arial" size="2">CToolBarCtrl</font></b></td>
675 <td width="115"><font face="Arial" size="2">client</font></td>
676 <td width="255"><font face="Arial" size="2">toolbar ctrl</font></td>
677 </tr>
678 <tr>
679 <td width="221"><b><font face="Arial" size="2">CStatusBarCtrl</font></b></td>
680 <td width="115"><font face="Arial" size="2">client</font></td>
681 <td width="255"><font face="Arial" size="2">status bar ctrl</font></td>
682 </tr>
683 <tr>
684 <td width="221"><b><font face="Arial" size="2">CTabCtrl</font></b></td>
685 <td width="115"><font face="Arial" size="2">client</font></td>
686 <td width="255"><font face="Arial" size="2">tab ctrl</font></td>
687 </tr>
688 <tr>
689 <td width="221"><b><font face="Arial" size="2">CToolTipCtrl</font></b></td>
690 <td width="115"><font face="Arial" size="2">client</font></td>
691 <td width="255"><font face="Arial" size="2">tool tip ctrl</font></td>
692 </tr>
693 <tr>
694 <td width="221"><b><font face="Arial" size="2">CToolInfo</font></b></td>
695 <td width="115"><font face="Arial" size="2">helper</font></td>
696 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
697 </tr>
698 <tr>
699 <td width="221"><b><font face="Arial" size="2">CTrackBarCtrl</font></b></td>
700 <td width="115"><font face="Arial" size="2">client</font></td>
701 <td width="255"><font face="Arial" size="2">trackbar ctrl</font></td>
702 </tr>
703 <tr>
704 <td width="221"><b><font face="Arial" size="2">CUpDownCtrl</font></b></td>
705 <td width="115"><font face="Arial" size="2">client</font></td>
706 <td width="255"><font face="Arial" size="2">up-down ctrl</font></td>
707 </tr>
708 <tr>
709 <td width="221"><b><font face="Arial" size="2">CProgressBarCtrl</font></b></td>
710 <td width="115"><font face="Arial" size="2">client</font></td>
711 <td width="255"><font face="Arial" size="2">progress bar ctrl</font></td>
712 </tr>
713 <tr>
714 <td width="221"><b><font face="Arial" size="2">CHotKeyCtrl</font></b></td>
715 <td width="115"><font face="Arial" size="2">client</font></td>
716 <td width="255"><font face="Arial" size="2">hot key ctrl</font></td>
717 </tr>
718 <tr>
719 <td width="221"><b><font face="Arial" size="2">CAnimateCtrl</font></b></td>
720 <td width="115"><font face="Arial" size="2">client</font></td>
721 <td width="255"><font face="Arial" size="2">animation ctrl</font></td>
722 </tr>
723 <tr>
724 <td width="221"><b><font face="Arial" size="2">CRichEditCtrl</font></b></td>
725 <td width="115"><font face="Arial" size="2">client</font></td>
726 <td width="255"><font face="Arial" size="2">rich edit ctrl</font></td>
727 </tr>
728 <tr>
729 <td width="221"><b><font face="Arial" size="2">CRichEditCommands</font></b></td>
730 <td width="115"><font face="Arial" size="2">mi</font></td>
731 <td width="255"><font face="Arial" size="2">std rich edit commands support</font></td>
732 </tr>
733 <tr>
734 <td width="221"><b><font face="Arial" size="2">CDragListBox</font></b></td>
735 <td width="115"><font face="Arial" size="2">client</font></td>
736 <td width="255"><font face="Arial" size="2">drag list box</font></td>
737 </tr>
738 <tr>
739 <td width="221"><b><font face="Arial" size="2">CDragListNotifyImpl</font></b></td>
740 <td width="115"><font face="Arial" size="2">impl mi class</font></td>
741 <td width="255"><font face="Arial" size="2">support for notifications</font></td>
742 </tr>
743 <tr>
744 <td width="221"><b><font face="Arial" size="2">CReBarCtrl</font></b></td>
745 <td width="115"><font face="Arial" size="2">client</font></td>
746 <td width="255"><font face="Arial" size="2">rebar ctrl</font></td>
747 </tr>
748 <tr>
749 <td width="221"><b><font face="Arial" size="2">CComboBoxEx</font></b></td>
750 <td width="115"><font face="Arial" size="2">client</font></td>
751 <td width="255"><font face="Arial" size="2">extended combo box</font></td>
752 </tr>
753 <tr>
754 <td width="221"><b><font face="Arial" size="2">CDateTimePickerCtrl</font></b></td>
755 <td width="115"><font face="Arial" size="2">client</font></td>
756 <td width="255"><font face="Arial" size="2">date-time ctrl</font></td>
757 </tr>
758 <tr>
759 <td width="221"><b><font face="Arial" size="2">CFlatScrollBarImpl</font></b></td>
760 <td width="115"><font face="Arial" size="2">mi impl</font></td>
761 <td width="255"><font face="Arial" size="2">flat scroll bars support</font></td>
762 </tr>
763 <tr>
764 <td width="221"><b><font face="Arial" size="2">CFlatScrollBar</font></b></td>
765 <td width="115"><font face="Arial" size="2">as-is</font></td>
766 <td width="255"><font face="Arial" size="2">flat scroll bars support</font></td>
767 </tr>
768 <tr>
769 <td width="221"><b><font face="Arial" size="2">CIPAddressCtrl</font></b></td>
770 <td width="115"><font face="Arial" size="2">client</font></td>
771 <td width="255"><font face="Arial" size="2">IP address ctrl</font></td>
772 </tr>
773 <tr>
774 <td width="221"><b><font face="Arial" size="2">CMonthCalendarCtrl</font></b></td>
775 <td width="115"><font face="Arial" size="2">client</font></td>
776 <td width="255"><font face="Arial" size="2">month calendar ctrl</font></td>
777 </tr>
778 <tr>
779 <td width="221"><b><font face="Arial" size="2">CCustomDraw</font></b></td>
780 <td width="115"><font face="Arial" size="2">impl mi class</font></td>
781 <td width="255"><font face="Arial" size="2">custom draw handling support</font></td>
782 </tr>
783 <tr>
784 <td colspan="3" width="593"><font face="Arial" size="2"><br>Windows CE controls</font></td>
785 </tr>
786 <tr>
787 <td width="221"><b><font face="Arial" size="2">CCECommandBarCtrl</font></b></td>
788 <td width="115"><font face="Arial" size="2">client</font></td>
789 <td width="255"><font face="Arial" size="2">command bar ctrl</font></td>
790 </tr>
791 <tr>
792 <td width="221"><b><font face="Arial" size="2">CCECommandBandsCtrl</font></b></td>
793 <td width="115"><font face="Arial" size="2">client</font></td>
794 <td width="255"><font face="Arial" size="2">command bands ctrl</font></td>
795 </tr>
796 <tr>
797 <td colspan="3" width="593"><font face="Arial" size="2"><br>Property sheet &amp; page</font></td>
798 </tr>
799 <tr>
800 <td width="221"><b><font face="Arial" size="2">CPropertySheetWindow</font></b></td>
801 <td width="115"><font face="Arial" size="2">client</font></td>
802 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
803 </tr>
804 <tr>
805 <td width="221"><b><font face="Arial" size="2">CPropertySheetImpl</font></b></td>
806 <td width="115"><font face="Arial" size="2">impl</font></td>
807 <td width="255"><font face="Arial" size="2">property sheet </font></td>
808 </tr>
809 <tr>
810 <td width="221"><b><font face="Arial" size="2">CPropertySheet</font></b></td>
811 <td width="115"><font face="Arial" size="2">as-is</font></td>
812 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
813 </tr>
814 <tr>
815 <td width="221"><b><font face="Arial" size="2">CPropertyPageWindow</font></b></td>
816 <td width="115"><font face="Arial" size="2">client</font></td>
817 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
818 </tr>
819 <tr>
820 <td width="221"><b><font face="Arial" size="2">CPropertyPageImpl</font></b></td>
821 <td width="115"><font face="Arial" size="2">impl</font></td>
822 <td width="255"><font face="Arial" size="2">property page</font></td>
823 </tr>
824 <tr>
825 <td width="221"><b><font face="Arial" size="2">CPropertyPage</font></b></td>
826 <td width="115"><font face="Arial" size="2">as-is</font></td>
827 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
828 </tr>
829 <tr>
830 <td width="221"><b><font face="Arial" size="2">CAxPropertyPageImpl</font></b></td>
831 <td width="115"><font face="Arial" size="2">impl</font></td>
832 <td width="255"><font face="Arial" size="2">property page with ActiveX</font></td>
833 </tr>
834 <tr>
835 <td width="221"><b><font face="Arial" size="2">CAxPropertyPage</font></b></td>
836 <td width="115"><font face="Arial" size="2">as-is</font></td>
837 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
838 </tr>
839 <tr>
840 <td width="221"><b><font face="Arial" size="2">CWizard97SheetWindow</font></b></td>
841 <td width="115"><font face="Arial" size="2">client</font></td>
842 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
843 </tr>
844 <tr>
845 <td width="221"><b><font face="Arial" size="2">CWizard97SheetImpl</font></b></td>
846 <td width="115"><font face="Arial" size="2">impl</font></td>
847 <td width="255"><font face="Arial" size="2">Wizard97 property sheet</font></td>
848 </tr>
849 <tr>
850 <td width="221"><b><font face="Arial" size="2">CWizard97Sheet</font></b></td>
851 <td width="115"><font face="Arial" size="2">as-is</font></td>
852 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
853 </tr>
854 <tr>
855 <td width="221"><b><font face="Arial" size="2">CWizard97PageWindow</font></b></td>
856 <td width="115"><font face="Arial" size="2">client</font></td>
857 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
858 </tr>
859 <tr>
860 <td width="221"><b><font face="Arial" size="2">CWizard97PageImpl</font></b></td>
861 <td width="115"><font face="Arial" size="2">impl</font></td>
862 <td width="255"><font face="Arial" size="2">Wizard97 property page</font></td>
863 </tr>
864 <tr>
865 <td width="221"><b><font face="Arial" size="2">CWizard97ExteriorPageImpl</font></b></td>
866 <td width="115"><font face="Arial" size="2">impl</font></td>
867 <td width="255"><font face="Arial" size="2">Wizard97 exterior page</font></td>
868 </tr>
869 <tr>
870 <td width="221"><b><font face="Arial" size="2">CWizard97InteriorPageImpl</font></b></td>
871 <td width="115"><font face="Arial" size="2">impl</font></td>
872 <td width="255"><font face="Arial" size="2">Wizard97 interior page</font></td>
873 </tr>
874 <tr>
875 <td width="221"><b><font face="Arial" size="2">CAeroWizardFrameWindow</font></b></td>
876 <td width="115"><font face="Arial" size="2">client</font></td>
877 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
878 </tr>
879 <tr>
880 <td width="221"><b><font face="Arial" size="2">CAeroWizardFrameImpl</font></b></td>
881 <td width="115"><font face="Arial" size="2">impl</font></td>
882 <td width="255"><font face="Arial" size="2">Aero Wizard frame</font></td>
883 </tr>
884 <tr>
885 <td width="221"><b><font face="Arial" size="2">CAeroWizardFrame</font></b></td>
886 <td width="115"><font face="Arial" size="2">as-is</font></td>
887 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
888 </tr>
889 <tr>
890 <td width="221"><b><font face="Arial" size="2">CAeroWizardPageWindow</font></b></td>
891 <td width="115"><font face="Arial" size="2">client</font></td>
892 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
893 </tr>
894 <tr>
895 <td width="221"><b><font face="Arial" size="2">CAeroWizardPageImpl</font></b></td>
896 <td width="115"><font face="Arial" size="2">impl</font></td>
897 <td width="255"><font face="Arial" size="2">Aero Wizard page</font></td>
898 </tr>
899 <tr>
900 <td width="221"><b><font face="Arial" size="2">CAeroWizardPage</font></b></td>
901 <td width="115"><font face="Arial" size="2">as-is</font></td>
902 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
903 </tr>
904 <tr>
905 <td width="221"><b><font face="Arial" size="2">CAeroWizardAxPageImpl</font></b></td>
906 <td width="115"><font face="Arial" size="2">impl</font></td>
907 <td width="255"><font face="Arial" size="2">Aero Wizard page with ActiveX</font></td>
908 </tr>
909 <tr>
910 <td width="221"><b><font face="Arial" size="2">CAeroWizardAxPage</font></b></td>
911 <td width="115"><font face="Arial" size="2">as-is</font></td>
912 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
913 </tr>
914 <tr>
915 <td colspan="3" width="593"><font face="Arial" size="2"><br>Common dialogs</font></td>
916 </tr>
917 <tr>
918 <td width="221"><b><font face="Arial" size="2">CFileDialogImpl</font></b></td>
919 <td width="115"><font face="Arial" size="2">impl</font></td>
920 <td width="255"><font face="Arial" size="2">GetOpenFileName/GetSaveFileName</font></td>
921 </tr>
922 <tr>
923 <td width="221"><b><font face="Arial" size="2">CFileDialog</font></b></td>
924 <td width="115"><font face="Arial" size="2">as-is</font></td>
925 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
926 </tr>
927 <tr>
928 <td width="221"><b><font face="Arial" size="2">CMultiFileDialogImpl</font></b></td>
929 <td width="115"><font face="Arial" size="2">impl</font></td>
930 <td width="255"><font face="Arial" size="2">Multi-select GetOpenFileName</font></td>
931 </tr>
932 <tr>
933 <td width="221"><b><font face="Arial" size="2">CMultiFileDialog</font></b></td>
934 <td width="115"><font face="Arial" size="2">as-is</font></td>
935 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
936 </tr>
937 <tr>
938 <td width="221"><b><font face="Arial" size="2">CShellFileDialogImpl</font></b></td>
939 <td width="115"><font face="Arial" size="2">base</font></td>
940 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
941 </tr>
942 <tr>
943 <td width="221"><b><font face="Arial" size="2">CShellFileOpenDialogImpl</font></b></td>
944 <td width="115"><font face="Arial" size="2">impl</font></td>
945 <td width="255"><font face="Arial" size="2">Shell File Open dialog</font></td>
946 </tr>
947 <tr>
948 <td width="221"><b><font face="Arial" size="2">CShellFileOpenDialog</font></b></td>
949 <td width="115"><font face="Arial" size="2">as-is</font></td>
950 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
951 </tr>
952 <tr>
953 <td width="221"><b><font face="Arial" size="2">CShellFileSaveDialogImpl</font></b></td>
954 <td width="115"><font face="Arial" size="2">impl</font></td>
955 <td width="255"><font face="Arial" size="2">Shell File Save dialog</font></td>
956 </tr>
957 <tr>
958 <td width="221"><b><font face="Arial" size="2">CShellFileSaveDialog</font></b></td>
959 <td width="115"><font face="Arial" size="2">as-is</font></td>
960 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
961 </tr>
962 <tr>
963 <td width="221"><b><font face="Arial" size="2">CFolderDialogImpl</font></b></td>
964 <td width="115"><font face="Arial" size="2">impl</font></td>
965 <td width="255"><font face="Arial" size="2">directory picker</font></td>
966 </tr>
967 <tr>
968 <td width="221"><b><font face="Arial" size="2">CFolderDialog</font></b></td>
969 <td width="115"><font face="Arial" size="2">as-is</font></td>
970 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
971 </tr>
972 <tr>
973 <td width="221"><b><font face="Arial" size="2">CFontDialogImpl</font></b></td>
974 <td width="115"><font face="Arial" size="2">impl</font></td>
975 <td width="255"><font face="Arial" size="2">ChooseFont common dialog</font></td>
976 </tr>
977 <tr>
978 <td width="221"><b><font face="Arial" size="2">CFontDialog</font></b></td>
979 <td width="115"><font face="Arial" size="2">as-is</font></td>
980 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
981 </tr>
982 <tr>
983 <td width="221"><b><font face="Arial" size="2">CRichEditFontDialogImpl</font></b></td>
984 <td width="115"><font face="Arial" size="2">impl</font></td>
985 <td width="255"><font face="Arial" size="2">ChooseFont for rich edit</font></td>
986 </tr>
987 <tr>
988 <td width="221"><b><font face="Arial" size="2">CRichEditFontDialog</font></b></td>
989 <td width="115"><font face="Arial" size="2">as-is</font></td>
990 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
991 </tr>
992 <tr>
993 <td width="221"><b><font face="Arial" size="2">CColorDialogImpl</font></b></td>
994 <td width="115"><font face="Arial" size="2">impl</font></td>
995 <td width="255"><font face="Arial" size="2">ChooseColor common dialog</font></td>
996 </tr>
997 <tr>
998 <td width="221"><b><font face="Arial" size="2">CColorDialog</font></b></td>
999 <td width="115"><font face="Arial" size="2">as-is</font></td>
1000 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1001 </tr>
1002 <tr>
1003 <td width="221"><b><font face="Arial" size="2">CPrintDialogImpl</font></b></td>
1004 <td width="115"><font face="Arial" size="2">impl</font></td>
1005 <td width="255"><font face="Arial" size="2">PrintDlg common dialog</font></td>
1006 </tr>
1007 <tr>
1008 <td width="221"><b><font face="Arial" size="2">CPrintDialog</font></b></td>
1009 <td width="115"><font face="Arial" size="2">as-is</font></td>
1010 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1011 </tr>
1012 <tr>
1013 <td width="221"><b><font face="Arial" size="2">CPrintDialogExImpl</font></b></td>
1014 <td width="115"><font face="Arial" size="2">impl</font></td>
1015 <td width="255"><font face="Arial" size="2">new Win2000 print dialog</font></td>
1016 </tr>
1017 <tr>
1018 <td width="221"><b><font face="Arial" size="2">CPrintDialogEx</font></b></td>
1019 <td width="115"><font face="Arial" size="2">as-is</font></td>
1020 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1021 </tr>
1022 <tr>
1023 <td width="221"><b><font face="Arial" size="2">CPageSetupDialogImpl</font></b></td>
1024 <td width="115"><font face="Arial" size="2">impl</font></td>
1025 <td width="255"><font face="Arial" size="2">PageSetupDlg common dialog</font></td>
1026 </tr>
1027 <tr>
1028 <td width="221"><b><font face="Arial" size="2">CPageSetupDialog</font></b></td>
1029 <td width="115"><font face="Arial" size="2">as-is</font></td>
1030 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1031 </tr>
1032 <tr>
1033 <td width="221"><b><font face="Arial" size="2">CFindReplaceDialogImpl</font></b></td>
1034 <td width="115"><font face="Arial" size="2">impl</font></td>
1035 <td width="255"><font face="Arial" size="2">FindText/ReplaceText</font></td>
1036 </tr>
1037 <tr>
1038 <td width="221"><b><font face="Arial" size="2">CFindReplaceDialog</font></b></td>
1039 <td width="115"><font face="Arial" size="2">as-is</font></td>
1040 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1041 </tr>
1042 <tr>
1043 <td colspan="3" width="593"><font face="Arial" size="2"><br>User support</font></td>
1044 </tr>
1045 <tr>
1046 <td width="221"><b><font face="Arial" size="2">CMenu</font></b></td>
1047 <td width="115"><font face="Arial" size="2">client</font></td>
1048 <td width="255"><font face="Arial" size="2">menu support</font></td>
1049 </tr>
1050 <tr>
1051 <td width="221"><b><font face="Arial" size="2">CMenuItemInfo</font></b></td>
1052 <td width="115"><font face="Arial" size="2">as-is</font></td>
1053 <td width="255"><font face="Arial" size="2">MENUITEMINFO wrapper</font></td>
1054 </tr>
1055 <tr>
1056 <td width="221"><b><font face="Arial" size="2">CAccelerator</font></b></td>
1057 <td width="115"><font face="Arial" size="2">client</font></td>
1058 <td width="255"><font face="Arial" size="2">accelerator table</font></td>
1059 </tr>
1060 <tr>
1061 <td width="221"><b><font face="Arial" size="2">CIcon</font></b></td>
1062 <td width="115"><font face="Arial" size="2">client</font></td>
1063 <td width="255"><font face="Arial" size="2">icon object</font></td>
1064 </tr>
1065 <tr>
1066 <td width="221"><b><font face="Arial" size="2">CCursor</font></b></td>
1067 <td width="115"><font face="Arial" size="2">client</font></td>
1068 <td width="255"><font face="Arial" size="2">cursor object</font></td>
1069 </tr>
1070 <tr>
1071 <td width="221"><b><font face="Arial" size="2">CResource</font></b></td>
1072 <td width="115"><font face="Arial" size="2">client</font></td>
1073 <td width="255"><font face="Arial" size="2">generic resource object</font></td>
1074 </tr>
1075 <tr>
1076 <td colspan="3" width="593"><font face="Arial" size="2"><br>GDI support</font></td>
1077 </tr>
1078 <tr>
1079 <td width="221"><b><font face="Arial" size="2">CDC</font></b></td>
1080 <td width="115"><font face="Arial" size="2">client</font></td>
1081 <td width="255"><font face="Arial" size="2">DC support</font></td>
1082 </tr>
1083 <tr>
1084 <td width="221"><b><font face="Arial" size="2">CPaintDC</font></b></td>
1085 <td width="115"><font face="Arial" size="2">client</font></td>
1086 <td width="255"><font face="Arial" size="2">for handling WM_PAINT</font></td>
1087 </tr>
1088 <tr>
1089 <td width="221"><b><font face="Arial" size="2">CClientDC</font></b></td>
1090 <td width="115"><font face="Arial" size="2">client</font></td>
1091 <td width="255"><font face="Arial" size="2">for GetDC</font></td>
1092 </tr>
1093 <tr>
1094 <td width="221"><b><font face="Arial" size="2">CWindowDC</font></b></td>
1095 <td width="115"><font face="Arial" size="2">client</font></td>
1096 <td width="255"><font face="Arial" size="2">for GetWindowDC</font></td>
1097 </tr>
1098 <tr>
1099 <td width="221"><b><font face="Arial" size="2">CMemoryDC</font></b></td>
1100 <td width="115"><font face="Arial" size="2">client</font></td>
1101 <td width="255"><font face="Arial" size="2">in-memory DC</font></td>
1102 </tr>
1103 <tr>
1104 <td width="221"><b><font face="Arial" size="2">CPen</font></b></td>
1105 <td width="115"><font face="Arial" size="2">client</font></td>
1106 <td width="255"><font face="Arial" size="2">GDI pen object</font></td>
1107 </tr>
1108 <tr>
1109 <td width="221"><b><font face="Arial" size="2">CBrush</font></b></td>
1110 <td width="115"><font face="Arial" size="2">client</font></td>
1111 <td width="255"><font face="Arial" size="2">GDI brush object</font></td>
1112 </tr>
1113 <tr>
1114 <td width="221"><b><font face="Arial" size="2">CLogFont</font></b></td>
1115 <td width="115"><font face="Arial" size="2">as-is</font></td>
1116 <td width="255"><font face="Arial" size="2">LOGFONT wrapper</font></td>
1117 </tr>
1118 <tr>
1119 <td width="221"><b><font face="Arial" size="2">CFont</font></b></td>
1120 <td width="115"><font face="Arial" size="2">client</font></td>
1121 <td width="255"><font face="Arial" size="2">GDI font object</font></td>
1122 </tr>
1123 <tr>
1124 <td width="221"><b><font face="Arial" size="2">CBitmap</font></b></td>
1125 <td width="115"><font face="Arial" size="2">client</font></td>
1126 <td width="255"><font face="Arial" size="2">GDI bitmap object</font></td>
1127 </tr>
1128 <tr>
1129 <td width="221"><b><font face="Arial" size="2">CPalette</font></b></td>
1130 <td width="115"><font face="Arial" size="2">client</font></td>
1131 <td width="255"><font face="Arial" size="2">GDI palette object</font></td>
1132 </tr>
1133 <tr>
1134 <td width="221"><b><font face="Arial" size="2">CRgn</font></b></td>
1135 <td width="115"><font face="Arial" size="2">client</font></td>
1136 <td width="255"><font face="Arial" size="2">GDI region object</font></td>
1137 </tr>
1138 <tr>
1139 <td colspan="3" width="593"><font face="Arial" size="2"><br>Enhanced controls</font></td>
1140 </tr>
1141 <tr>
1142 <td width="221"><b><font face="Arial" size="2">CCommandBarCtrlImpl</font></b></td>
1143 <td width="115"><font face="Arial" size="2">impl</font></td>
1144 <td width="255"><font face="Arial" size="2">command bar</font></td>
1145 </tr>
1146 <tr>
1147 <td width="221"><b><font face="Arial" size="2">CCommandBarCtrl</font></b></td>
1148 <td width="115"><font face="Arial" size="2">as-is</font></td>
1149 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1150 </tr>
1151 <tr>
1152 <td width="221"><b><font face="Arial" size="2">CBitmapButtonImpl</font></b></td>
1153 <td width="115"><font face="Arial" size="2">impl</font></td>
1154 <td width="255"><font face="Arial" size="2">bitmap button</font></td>
1155 </tr>
1156 <tr>
1157 <td width="221"><b><font face="Arial" size="2">CBitmapButton</font></b></td>
1158 <td width="115"><font face="Arial" size="2">as-is</font></td>
1159 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1160 </tr>
1161 <tr>
1162 <td width="221"><b><font face="Arial" size="2">CCheckListViewCtrlImpl</font></b></td>
1163 <td width="115"><font face="Arial" size="2">impl</font></td>
1164 <td width="255"><font face="Arial" size="2">check list box</font></td>
1165 </tr>
1166 <tr>
1167 <td width="221"><b><font face="Arial" size="2">CCheckListViewCtrl</font></b></td>
1168 <td width="115"><font face="Arial" size="2">as-is</font></td>
1169 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1170 </tr>
1171 <tr>
1172 <td width="221"><b><font face="Arial" size="2">CHyperLinkImpl</font></b></td>
1173 <td width="115"><font face="Arial" size="2">impl</font></td>
1174 <td width="255"><font face="Arial" size="2">hyper link control</font></td>
1175 </tr>
1176 <tr>
1177 <td width="221"><b><font face="Arial" size="2">CHyperLink</font></b></td>
1178 <td width="115"><font face="Arial" size="2">as-is</font></td>
1179 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1180 </tr>
1181 <tr>
1182 <td width="221"><b><font face="Arial" size="2">CWaitCursor</font></b></td>
1183 <td width="115"><font face="Arial" size="2">as-is</font></td>
1184 <td width="255"><font face="Arial" size="2">wait cursor</font></td>
1185 </tr>
1186 <tr>
1187 <td width="221"><b><font face="Arial" size="2">CCustomWaitCursor</font></b></td>
1188 <td width="115"><font face="Arial" size="2">as-is</font></td>
1189 <td width="255"><font face="Arial" size="2">custom and animated wait cursor</font></td>
1190 </tr>
1191 <tr>
1192 <td width="221"><b><font face="Arial" size="2">CMultiPaneStatusBarCtrlImpl</font></b></td>
1193 <td width="115"><font face="Arial" size="2">impl</font></td>
1194 <td width="255"><font face="Arial" size="2">status bar with multiple panes</font></td>
1195 </tr>
1196 <tr>
1197 <td width="221"><b><font face="Arial" size="2">CMultiPaneStatusBarCtrl</font></b></td>
1198 <td width="115"><font face="Arial" size="2">as-is</font></td>
1199 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1200 </tr>
1201 <tr>
1202 <td width="221"><b><font face="Arial" size="2">CPaneContainerImpl</font></b></td>
1203 <td width="115"><font face="Arial" size="2">impl</font></td>
1204 <td width="255"><font face="Arial" size="2">pane window container</font></td>
1205 </tr>
1206 <tr>
1207 <td width="221"><b><font face="Arial" size="2">CPaneContainer</font></b></td>
1208 <td width="115"><font face="Arial" size="2">as-is</font></td>
1209 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1210 </tr>
1211 <tr>
1212 <td width="221"><b><font face="Arial" size="2">CSortListViewImpl</font></b></td>
1213 <td width="115"><font face="Arial" size="2">impl</font></td>
1214 <td width="255"><font face="Arial" size="2">sorting list view control</font></td>
1215 </tr>
1216 <tr>
1217 <td width="221"><b><font face="Arial" size="2">CSortListViewCtrlImpl</font></b></td>
1218 <td width="115"><font face="Arial" size="2">impl</font></td>
1219 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1220 </tr>
1221 <tr>
1222 <td width="221"><b><font face="Arial" size="2">CSortListViewCtrl</font></b></td>
1223 <td width="115"><font face="Arial" size="2">as-is</font></td>
1224 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1225 </tr>
1226 <tr>
1227 <td width="221"><b><font face="Arial" size="2">CTabViewImpl;</font></b></td>
1228 <td width="115"><font face="Arial" size="2">impl</font></td>
1229 <td width="255"><font face="Arial" size="2">tab view window</font></td>
1230 </tr>
1231 <tr>
1232 <td width="221"><b><font face="Arial" size="2">CTabView</font></b></td>
1233 <td width="115"><font face="Arial" size="2">as-is</font></td>
1234 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1235 </tr>
1236 <tr>
1237 <td colspan="3" width="593"><font face="Arial" size="2"><br>Scrolling window support</font></td>
1238 </tr>
1239 <tr>
1240 <td width="221"><b><font face="Arial" size="2">CScrollImpl</font></b></td>
1241 <td width="115"><font face="Arial" size="2">impl mi</font></td>
1242 <td width="255"><font face="Arial" size="2">scrolling support</font></td>
1243 </tr>
1244 <tr>
1245 <td width="221"><b><font face="Arial" size="2">CScrollWindowImpl</font></b></td>
1246 <td width="115"><font face="Arial" size="2">impl</font></td>
1247 <td width="255"><font face="Arial" size="2">scrollable window</font></td>
1248 </tr>
1249 <tr>
1250 <td width="221"><b><font face="Arial" size="2">CMapScrollImpl</font></b></td>
1251 <td width="115"><font face="Arial" size="2">impl mi</font></td>
1252 <td width="255"><font face="Arial" size="2">scrolling support with map modes</font></td>
1253 </tr>
1254 <tr>
1255 <td width="221"><b><font face="Arial" size="2">CMapScrollWindowImpl</font></b></td>
1256 <td width="115"><font face="Arial" size="2">impl</font></td>
1257 <td width="255"><font face="Arial" size="2">scrollable window with map modes</font></td>
1258 </tr>
1259 <tr>
1260 <td width="221"><b><font face="Arial" size="2">CZoomScrollImpl</font></b></td>
1261 <td width="115"><font face="Arial" size="2">impl mi</font></td>
1262 <td width="255"><font face="Arial" size="2">zooming support</font></td>
1263 </tr>
1264 <tr>
1265 <td width="221"><b><font face="Arial" size="2">CZoomScrollWindowImpl</font></b></td>
1266 <td width="115"><font face="Arial" size="2">impl</font></td>
1267 <td width="255"><font face="Arial" size="2">zooming window</font></td>
1268 </tr>
1269 <tr>
1270 <td width="221"><b><font face="Arial" size="2">CScrollContainerImpl</font></b></td>
1271 <td width="115"><font face="Arial" size="2">impl</font></td>
1272 <td width="255"><font face="Arial" size="2">scroll container window</font></td>
1273 </tr>
1274 <tr>
1275 <td width="221"><b><font face="Arial" size="2">CScrollContainer</font></b></td>
1276 <td width="115"><font face="Arial" size="2">as-is</font></td>
1277 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1278 </tr>
1279 <tr>
1280 <td colspan="3" width="593"><font face="Arial" size="2"><br>Splitter window support</font></td>
1281 </tr>
1282 <tr>
1283 <td width="221"><b><font face="Arial" size="2">CSplitterImpl</font></b></td>
1284 <td width="115"><font face="Arial" size="2">impl mi</font></td>
1285 <td width="255"><font face="Arial" size="2">splitter support</font></td>
1286 </tr>
1287 <tr>
1288 <td width="221"><b><font face="Arial" size="2">CSplitterWindowImpl</font></b></td>
1289 <td width="115"><font face="Arial" size="2">impl</font></td>
1290 <td width="255"><font face="Arial" size="2">splitter window</font></td>
1291 </tr>
1292 <tr>
1293 <td width="221"><b><font face="Arial" size="2">CSplitterWindow</font></b></td>
1294 <td width="115"><font face="Arial" size="2">as-is</font></td>
1295 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1296 </tr>
1297 <tr>
1298 <td colspan="3" width="593"><font face="Arial" size="2"><br>Theming support</font></td>
1299 </tr>
1300 <tr>
1301 <td width="221"><b><font face="Arial" size="2">CTheme</font></b></td>
1302 <td width="115"><font face="Arial" size="2">client</font></td>
1303 <td width="255"><font face="Arial" size="2">Windows XP theme</font></td>
1304 </tr>
1305 <tr>
1306 <td width="221"><b><font face="Arial" size="2">CThemeImpl</font></b></td>
1307 <td width="115"><font face="Arial" size="2">impl</font></td>
1308 <td width="255"><font face="Arial" size="2">theming support for a window</font></td>
1309 </tr>
1310 <tr>
1311 <td colspan="3" width="593"><font face="Arial" size="2"><br>Buffered paint and animation support</font></td>
1312 </tr>
1313 <tr>
1314 <td width="221"><b><font face="Arial" size="2">CBufferedPaint</font></b></td>
1315 <td width="115"><font face="Arial" size="2">as-is</font></td>
1316 <td width="255"><font face="Arial" size="2">buffered paint</font></td>
1317 </tr>
1318 <tr>
1319 <td width="221"><b><font face="Arial" size="2">CBufferedPaintImpl</font></b></td>
1320 <td width="115"><font face="Arial" size="2">impl mi</font></td>
1321 <td width="255"><font face="Arial" size="2">buffered paint support</font></td>
1322 </tr>
1323 <tr>
1324 <td width="221"><b><font face="Arial" size="2">CBufferedPaintWindowImpl</font></b></td>
1325 <td width="115"><font face="Arial" size="2">impl</font></td>
1326 <td width="255"><font face="Arial" size="2">window with buffered paint</font></td>
1327 </tr>
1328 <tr>
1329 <td width="221"><b><font face="Arial" size="2">CBufferedAnimation</font></b></td>
1330 <td width="115"><font face="Arial" size="2">as-is</font></td>
1331 <td width="255"><font face="Arial" size="2">buffered animation</font></td>
1332 </tr>
1333 <tr>
1334 <td width="221"><b><font face="Arial" size="2">CBufferedAnimationImpl</font></b></td>
1335 <td width="115"><font face="Arial" size="2">impl mi</font></td>
1336 <td width="255"><font face="Arial" size="2">buffered animation support</font></td>
1337 </tr>
1338 <tr>
1339 <td width="221"><b><font face="Arial" size="2">CBufferedAnimationWindowImpl</font></b></td>
1340 <td width="115"><font face="Arial" size="2">impl</font></td>
1341 <td width="255"><font face="Arial" size="2">window with buffered animation</font></td>
1342 </tr>
1343 <tr>
1344 <td colspan="3" width="593"><font face="Arial" size="2"><br>Edit and RichEdit Find/Replace support</font></td>
1345 </tr>
1346 <tr>
1347 <td width="221"><b><font face="Arial" size="2">CEditFindReplaceImplBase</font></b></td>
1348 <td width="115"><font face="Arial" size="2">base</font></td>
1349 <td width="255"><font face="Arial" size="2">&nbsp;</td>
1350 </tr>
1351 <tr>
1352 <td width="221"><b><font face="Arial" size="2">CEditFindReplaceImpl</font></b></td>
1353 <td width="115"><font face="Arial" size="2">mi</font></td>
1354 <td width="255"><font face="Arial" size="2">Edit Find/Replace support</font></td>
1355 </tr>
1356 <tr>
1357 <td width="221"><b><font face="Arial" size="2">CRichEditFindReplaceImpl</font></b></td>
1358 <td width="115"><font face="Arial" size="2">mi</font></td>
1359 <td width="255"><font face="Arial" size="2">RichEdit Find/Replace support</font></td>
1360 </tr>
1361 <tr>
1362 <td colspan="3" width="593"><font face="Arial" size="2"><br>Printing support</font></td>
1363 </tr>
1364 <tr>
1365 <td width="221"><b><font face="Arial" size="2">CPrinterInfo</font></b></td>
1366 <td width="115"><font face="Arial" size="2">as-is</font></td>
1367 <td width="255"><font face="Arial" size="2">print info support</font></td>
1368 </tr>
1369 <tr>
1370 <td width="221"><b><font face="Arial" size="2">CPrinter</font></b></td>
1371 <td width="115"><font face="Arial" size="2">client</font></td>
1372 <td width="255"><font face="Arial" size="2">printer handle wrapper</font></td>
1373 </tr>
1374 <tr>
1375 <td width="221"><b><font face="Arial" size="2">CDevMode</font></b></td>
1376 <td width="115"><font face="Arial" size="2">client</font></td>
1377 <td width="255"><font face="Arial" size="2">DEVMODE wrapper</font></td>
1378 </tr>
1379 <tr>
1380 <td width="221"><b><font face="Arial" size="2">CPrinterDC</font></b></td>
1381 <td width="115"><font face="Arial" size="2">client</font></td>
1382 <td width="255"><font face="Arial" size="2">printing DC support</font></td>
1383 </tr>
1384 <tr>
1385 <td width="221"><b><font face="Arial" size="2">CPrintJobInfo</font></b></td>
1386 <td width="115"><font face="Arial" size="2">client</font></td>
1387 <td width="255"><font face="Arial" size="2">print job info</font></td>
1388 </tr>
1389 <tr>
1390 <td width="221"><b><font face="Arial" size="2">CPrintJob</font></b></td>
1391 <td width="115"><font face="Arial" size="2">client</font></td>
1392 <td width="255"><font face="Arial" size="2">print job support</font></td>
1393 </tr>
1394 <tr>
1395 <td width="221"><b><font face="Arial" size="2">CPrintPreview</font></b></td>
1396 <td width="115"><font face="Arial" size="2">mi</font></td>
1397 <td width="255"><font face="Arial" size="2">print preview support</font></td>
1398 </tr>
1399 <tr>
1400 <td width="221"><b><font face="Arial" size="2">CPrintPreviewWindowImpl</font></b></td>
1401 <td width="115"><font face="Arial" size="2">impl</font></td>
1402 <td width="255"><font face="Arial" size="2">print preview window</font></td>
1403 </tr>
1404 <tr>
1405 <td width="221"><b><font face="Arial" size="2">CPrintPreviewWindow</font></b></td>
1406 <td width="115"><font face="Arial" size="2">as-is</font></td>
1407 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1408 </tr>
1409 <tr>
1410 <td width="221"><b><font face="Arial" size="2">CZoomPrintPreviewWindowImpl</font></b></td>
1411 <td width="115"><font face="Arial" size="2">impl</font></td>
1412 <td width="255"><font face="Arial" size="2">zooming print preview window</font></td>
1413 </tr>
1414 <tr>
1415 <td width="221"><b><font face="Arial" size="2">CZoomPrintPreviewWindow</font></b></td>
1416 <td width="115"><font face="Arial" size="2">as-is</font></td>
1417 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1418 </tr>
1419 <tr>
1420 <td colspan="3" width="593"><font face="Arial" size="2"><br>Miscellaneous</font></td>
1421 </tr>
1422 <tr>
1423 <td width="221"><b><font face="Arial" size="2">CSize</font></b></td>
1424 <td width="115"><font face="Arial" size="2">as-is</font></td>
1425 <td width="255"><font face="Arial" size="2">WTL port of MFC's CSize</font></td>
1426 </tr>
1427 <tr>
1428 <td width="221"><b><font face="Arial" size="2">CPoint</font></b></td>
1429 <td width="115"><font face="Arial" size="2">as-is</font></td>
1430 <td width="255"><font face="Arial" size="2">WTL port of MFC's CPoint</font></td>
1431 </tr>
1432 <tr>
1433 <td width="221"><b><font face="Arial" size="2">CRect</font></b></td>
1434 <td width="115"><font face="Arial" size="2">as-is</font></td>
1435 <td width="255"><font face="Arial" size="2">WTL port of MFC's CRect</font></td>
1436 </tr>
1437 <tr>
1438 <td width="221"><b><font face="Arial" size="2">CString</font></b></td>
1439 <td width="115"><font face="Arial" size="2">as-is</font></td>
1440 <td width="255"><font face="Arial" size="2">WTL port of MFC's CString</font></td>
1441 </tr>
1442 <tr>
1443 <td width="221"><b><font face="Arial" size="2">CWinDataExchange</font></b></td>
1444 <td width="115"><font face="Arial" size="2">mi</font></td>
1445 <td width="255"><font face="Arial" size="2">data exchange for controls</font></td>
1446 </tr>
1447 <tr>
1448 <td width="221"><b><font face="Arial" size="2">CRecentDocumentList</font></b></td>
1449 <td width="115"><font face="Arial" size="2">mi or as-is</font></td>
1450 <td width="255"><font face="Arial" size="2">support for MRU list</font></td>
1451 </tr>
1452 <tr>
1453 <td width="221"><b><font face="Arial" size="2">CFindFile</font></b></td>
1454 <td width="115"><font face="Arial" size="2">as-is</font></td>
1455 <td width="255"><font face="Arial" size="2">file search support</font></td>
1456 </tr>
1457 <tr>
1458 <td colspan="3" width="593"><font face="Arial" size="2"><br>In-memory dialog</font></td>
1459 </tr>
1460 <tr>
1461 <td width="221"><b><font face="Arial" size="2">CDialogBaseUnits</font></b></td>
1462 <td width="115"><font face="Arial" size="2">helper</font></td>
1463 <td width="255"><font face="Arial" size="2">dialog units helper</font></td>
1464 </tr>
1465 <tr>
1466 <td width="221"><b><font face="Arial" size="2">CMemDlgTemplate</font></b></td>
1467 <td width="115"><font face="Arial" size="2">as-is</font></td>
1468 <td width="255"><font face="Arial" size="2">In-memory dialog template</font></td>
1469 </tr>
1470 <tr>
1471 <td width="221"><b><font face="Arial" size="2">CIndirectDialogImpl</font></b></td>
1472 <td width="115"><font face="Arial" size="2">impl</font></td>
1473 <td width="255"><font face="Arial" size="2">In-memory dialog class</font></td>
1474 </tr>
1475 <tr>
1476 <td colspan="3" width="593"><font face="Arial" size="2"><br>Task dialog</font></td>
1477 </tr>
1478 <tr>
1479 <td width="221"><b><font face="Arial" size="2">CTaskDialogImpl</font></b></td>
1480 <td width="115"><font face="Arial" size="2">impl</font></td>
1481 <td width="255"><font face="Arial" size="2">Task Dialog in Vista</font></td>
1482 </tr>
1483 <tr>
1484 <td width="221"><b><font face="Arial" size="2">CTaskDialog</font></b></td>
1485 <td width="115"><font face="Arial" size="2">as-is</font></td>
1486 <td width="255"><font face="Arial" size="2">&nbsp;</font></td>
1487 </tr>
1488 <tr>
1489 <td colspan="3" width="593"><font face="Arial" size="2"><br>DWM classes</font></td>
1490 </tr>
1491 <tr>
1492 <td width="221"><b><font face="Arial" size="2">CDwm</font></b></td>
1493 <td width="115"><font face="Arial" size="2">client</font></td>
1494 <td width="255"><font face="Arial" size="2">DWM handle warapper</font></td>
1495 </tr>
1496 <tr>
1497 <td width="221"><b><font face="Arial" size="2">CDwmImpl</font></b></td>
1498 <td width="115"><font face="Arial" size="2">impl base</font></td>
1499 <td width="255"><font face="Arial" size="2">DWM support</font></td>
1500 </tr>
1501 <tr>
1502 <td width="221"><b><font face="Arial" size="2">CDwmWindow</font></b></td>
1503 <td width="115"><font face="Arial" size="2">impl</font></td>
1504 <td width="255"><font face="Arial" size="2">DWM window support</font></td>
1505 </tr>
1506 <tr>
1507 <td width="221"><b><font face="Arial" size="2">CDwmThumbnail</font></b></td>
1508 <td width="115"><font face="Arial" size="2">client</font></td>
1509 <td width="255"><font face="Arial" size="2">DWM thumbnail wrapper</font></td>
1510 </tr>
1511 <tr>
1512 <td width="221"><b><font face="Arial" size="2">CAeroControlImpl</font></b></td>
1513 <td width="115"><font face="Arial" size="2">impl</font></td>
1514 <td width="255"><font face="Arial" size="2">support for Aero controls</font></td>
1515 </tr>
1516 <tr>
1517 <td colspan="3" width="593"><font face="Arial" size="2"><br>Ribbon classes</font></td>
1518 </tr>
1519 <tr>
1520 <td width="221"><b><font face="Arial" size="2">CRibbonUpdateUI</font></b></td>
1521 <td width="115"><font face="Arial" size="2">mi base</font></td>
1522 <td width="255"><font face="Arial" size="2">automatic mapping of ribbon UI elements</font></td>
1523 </tr>
1524 <tr>
1525 <td width="221"><b><font face="Arial" size="2">RibbonUI::CtrlImpl</font></b></td>
1526 <td width="115"><font face="Arial" size="2">base impl</font></td>
1527 <td width="255"><font face="Arial" size="2">base class for all ribbon controls</font></td>
1528 </tr>
1529 <tr>
1530 <td width="221"><b><font face="Arial" size="2">RibbonUI::CommandCtrlImpl</font></b></td>
1531 <td width="115"><font face="Arial" size="2">base impl</font></td>
1532 <td width="255"><font face="Arial" size="2">base class for ribbon controls</font></td>
1533 </tr>
1534 <tr>
1535 <td width="221"><b><font face="Arial" size="2">RibbonUI::CollectionImplBase</font></b></td>
1536 <td width="115"><font face="Arial" size="2">base</font></td>
1537 <td width="255"><font face="Arial" size="2">base class for all RibbonUI collections</font></td>
1538 </tr>
1539 <tr>
1540 <td width="221"><b><font face="Arial" size="2">RibbonUI::CollectionImpl</font></b></td>
1541 <td width="115"><font face="Arial" size="2">impl</font></td>
1542 <td width="255"><font face="Arial" size="2">RibbonUI collections</font></td>
1543 </tr>
1544 <tr>
1545 <td width="221"><b><font face="Arial" size="2">RibbonUI::CollectionCtrlImpl</font></b></td>
1546 <td width="115"><font face="Arial" size="2">impl</font></td>
1547 <td width="255"><font face="Arial" size="2">specializable class for ribbon collection controls</font></td>
1548 </tr>
1549 <tr>
1550 <td width="221"><b><font face="Arial" size="2">RibbonUI::ToolbarGalleryCtrlImpl</font></b></td>
1551 <td width="115"><font face="Arial" size="2">base impl</font></td>
1552 <td width="255"><font face="Arial" size="2">base class for ribbon toolbar gallery controls</font></td>
1553 </tr>
1554 <tr>
1555 <td width="221"><b><font face="Arial" size="2">RibbonUI::CRibbonImpl</font></b></td>
1556 <td width="115"><font face="Arial" size="2">impl</font></td>
1557 <td width="255"><font face="Arial" size="2">Ribbon implementation class</font></td>
1558 </tr>
1559 <tr>
1560 <td width="221"><b><font face="Arial" size="2">CRibbonFrameWindowImplBase</font></b></td>
1561 <td width="115"><font face="Arial" size="2">base</font></td>
1562 <td width="255"><font face="Arial" size="2">base frame class for Ribbon</font></td>
1563 </tr>
1564 <tr>
1565 <td width="221"><b><font face="Arial" size="2">CRibbonFrameWindowImpl</font></b></td>
1566 <td width="115"><font face="Arial" size="2">impl</font></td>
1567 <td width="255"><font face="Arial" size="2">Ribbon frame window class</font></td>
1568 </tr>
1569 <tr>
1570 <td width="221"><b><font face="Arial" size="2">CRibbonMDIFrameWindowImpl</font></b></td>
1571 <td width="115"><font face="Arial" size="2">impl</font></td>
1572 <td width="255"><font face="Arial" size="2">Ribbon MDI frame window class</font></td>
1573 </tr>
1574 <tr>
1575 <td width="221"><b><font face="Arial" size="2">CRibbonPersist</font></b></td>
1576 <td width="115"><font face="Arial" size="2">as-is</font></td>
1577 <td width="255"><font face="Arial" size="2">Ribbon persistance support</font></td>
1578 </tr>
1579 <tr>
1580 <td colspan="3" width="593"><font face="Arial" size="2"><br>Windows CE support</font></td>
1581 </tr>
1582 <tr>
1583 <td width="221"><b><font face="Arial" size="2">CStdDialogBase</font></b></td>
1584 <td width="115"><font face="Arial" size="2">base</font></td>
1585 <td width="255"><font face="Arial" size="2">standard dialog base class</font></td>
1586 </tr>
1587 <tr>
1588 <td width="221"><b><font face="Arial" size="2">CStdDialogImpl</font></b></td>
1589 <td width="115"><font face="Arial" size="2">impl</font></td>
1590 <td width="255"><font face="Arial" size="2">standard dialog implementation</font></td>
1591 </tr>
1592 <tr>
1593 <td width="221"><b><font face="Arial" size="2">CStdSimpleDialog</font></b></td>
1594 <td width="115"><font face="Arial" size="2">as-is</font></td>
1595 <td width="255"><font face="Arial" size="2">standard simple dialog</font></td>
1596 </tr>
1597 <tr>
1598 <td width="221"><b><font face="Arial" size="2">CStdDialogResizeBase</font></b></td>
1599 <td width="115"><font face="Arial" size="2">base</font></td>
1600 <td width="255"><font face="Arial" size="2">orientation aware standard dialog base class</font></td>
1601 </tr>
1602 <tr>
1603 <td width="221"><b><font face="Arial" size="2">CStdDialogResizeImpl</font></b></td>
1604 <td width="115"><font face="Arial" size="2">impl</font></td>
1605 <td width="255"><font face="Arial" size="2">orientation aware standard dialog implementation</font></td>
1606 </tr>
1607 <tr>
1608 <td width="221"><b><font face="Arial" size="2">CStdSimpleDialogResizeImpl</font></b></td>
1609 <td width="115"><font face="Arial" size="2">impl</font></td>
1610 <td width="255"><font face="Arial" size="2">standard resizing simple dialog implementation</font></td>
1611 </tr>
1612 <tr>
1613 <td width="221"><b><font face="Arial" size="2">CStdOrientedDialogBase</font></b></td>
1614 <td width="115"><font face="Arial" size="2">base</font></td>
1615 <td width="255"><font face="Arial" size="2">oriented dialog base class</font></td>
1616 </tr>
1617 <tr>
1618 <td width="221"><b><font face="Arial" size="2">CStdOrientedDialogImpl</font></b></td>
1619 <td width="115"><font face="Arial" size="2">impl</font></td>
1620 <td width="255"><font face="Arial" size="2">oriented dialog implementation</font></td>
1621 </tr>
1622 <tr>
1623 <td width="221"><b><font face="Arial" size="2">CStdSimpleOrientedDialog</font></b></td>
1624 <td width="115"><font face="Arial" size="2">as-is</font></td>
1625 <td width="255"><font face="Arial" size="2">standard simple oriented dialog</font></td>
1626 </tr>
1627 <tr>
1628 <td width="221"><b><font face="Arial" size="2">CAppInfoBase</font></b></td>
1629 <td width="115"><font face="Arial" size="2">base</font></td>
1630 <td width="255"><font face="Arial" size="2">application state save/restore to registry</font></td>
1631 </tr>
1632 <tr>
1633 <td width="221"><b><font face="Arial" size="2">CAppInfoT</font></b></td>
1634 <td width="115"><font face="Arial" size="2">impl</font></td>
1635 <td width="255"><font face="Arial" size="2">CAppInfoBase constructed from a CAppWindow&lt;T&gt;</font></td>
1636 </tr>
1637 <tr>
1638 <td width="221"><b><font face="Arial" size="2">CAppWindow&lt;&gt;</font></b></td>
1639 <td width="115"><font face="Arial" size="2">mi</font></td>
1640 <td width="255"><font face="Arial" size="2">PPC/SmartPhone well-behaved application window class</font></td>
1641 </tr>
1642 <tr>
1643 <td width="221"><b><font face="Arial" size="2">CAppDialog</font></b></td>
1644 <td width="115"><font face="Arial" size="2">mi</font></td>
1645 <td width="255"><font face="Arial" size="2">PPC/SmartPhone well-behaved application non-modal dialog class</font></td>
1646 </tr>
1647 <tr>
1648 <td width="221"><b><font face="Arial" size="2">CAppStdDialogImpl</font></b></td>
1649 <td width="115"><font face="Arial" size="2">impl</font></td>
1650 <td width="255"><font face="Arial" size="2">PPC/SmartPhone implementation of non-modal standard dialog application</font></td>
1651 </tr>
1652 <tr>
1653 <td width="221"><b><font face="Arial" size="2">CFullScreenFrame</font></b></td>
1654 <td width="115"><font face="Arial" size="2">impl</font></td>
1655 <td width="255"><font face="Arial" size="2">Full screen frame class</font></td>
1656 </tr>
1657 <tr>
1658 <td width="221"><b><font face="Arial" size="2">CZoomScrollImpl</font></b></td>
1659 <td width="115"><font face="Arial" size="2">mi</font></td>
1660 <td width="255"><font face="Arial" size="2">WinCE zooming implementation</font></td>
1661 </tr>
1662 <tr>
1663 <td width="221"><b><font face="Arial" size="2">CHtmlCtrl</font></b></td>
1664 <td width="115"><font face="Arial" size="2">client</font></td>
1665 <td width="255"><font face="Arial" size="2">HTML control</font></td>
1666 </tr>
1667 <tr>
1668 <td width="221"><b><font face="Arial" size="2">CRichInkCtrl</font></b></td>
1669 <td width="115"><font face="Arial" size="2">client</font></td>
1670 <td width="255"><font face="Arial" size="2">RichInk control</font></td>
1671 </tr>
1672 <tr>
1673 <td width="221"><b><font face="Arial" size="2">CInkXCtrl</font></b></td>
1674 <td width="115"><font face="Arial" size="2">client</font></td>
1675 <td width="255"><font face="Arial" size="2">InkX control</font></td>
1676 </tr>
1677 <tr>
1678 <td width="221"><b><font face="Arial" size="2">CVoiceRecorderCtrl</font></b></td>
1679 <td width="115"><font face="Arial" size="2">client</font></td>
1680 <td width="255"><font face="Arial" size="2">VoiceRecorder control</font></td>
1681 </tr>
1682 <tr>
1683 <td width="221"><b><font face="Arial" size="2">CDocListCtrl</font></b></td>
1684 <td width="115"><font face="Arial" size="2">client</font></td>
1685 <td width="255"><font face="Arial" size="2">DocList control</font></td>
1686 </tr>
1687 <tr>
1688 <td width="221"><b><font face="Arial" size="2">CCapEdit</font></b></td>
1689 <td width="115"><font face="Arial" size="2">client</font></td>
1690 <td width="255"><font face="Arial" size="2">CapEdit control</font></td>
1691 </tr>
1692 <tr>
1693 <td width="221"><b><font face="Arial" size="2">CTTStatic</font></b></td>
1694 <td width="115"><font face="Arial" size="2">client</font></td>
1695 <td width="255"><font face="Arial" size="2">TT Static control</font></td>
1696 </tr>
1697 <tr>
1698 <td width="221"><b><font face="Arial" size="2">CTTButton</font></b></td>
1699 <td width="115"><font face="Arial" size="2">client</font></td>
1700 <td width="255"><font face="Arial" size="2">TT Button control</font></td>
1701 </tr>
1702 <tr>
1703 <td width="221"><b><font face="Arial" size="2">CSpinCtrl</font></b></td>
1704 <td width="115"><font face="Arial" size="2">client</font></td>
1705 <td width="255"><font face="Arial" size="2">Spin control</font></td>
1706 </tr>
1707 <tr>
1708 <td width="221"><b><font face="Arial" size="2">CSpinListBox</font></b></td>
1709 <td width="115"><font face="Arial" size="2">client</font></td>
1710 <td width="255"><font face="Arial" size="2">Spin List Box control</font></td>
1711 </tr>
1712 <tr>
1713 <td width="221"><b><font face="Arial" size="2">CExpandListBox</font></b></td>
1714 <td width="115"><font face="Arial" size="2">client</font></td>
1715 <td width="255"><font face="Arial" size="2">Expand List Box control</font></td>
1716 </tr>
1717 <tr>
1718 <td width="221"><b><font face="Arial" size="2">CExpandEdit</font></b></td>
1719 <td width="115"><font face="Arial" size="2">client</font></td>
1720 <td width="255"><font face="Arial" size="2">Expand Edit control</font></td>
1721 </tr>
1722 <tr>
1723 <td width="221"><b><font face="Arial" size="2">CExpandCapEdit</font></b></td>
1724 <td width="115"><font face="Arial" size="2">client</font></td>
1725 <td width="255"><font face="Arial" size="2">Expand CapEdit control</font></td>
1726 </tr>
1727 </table>
1728 <p style=margin:0in>&nbsp;</p>
1729 <p style=margin:0in>&nbsp;</p>
1730 <p style=margin:0in><font face="Arial">
1731 <b><a name="ATL/WTL AppWizard"></a>ATL/WTL AppWizard</b></font></p>
1732 <p style=margin:0in>&nbsp;</p>
1733 <p style=margin:0in><font face="Arial" size="2">ATL/WTL AppWizard generates starting code for a
1734 WTL application. It has options to create code for different application types and features.</font></p>
1735 <p style=margin:0in>&nbsp;</p>
1736 <p style=margin:0in><font face="Arial" size="2">You can choose the following options:</font></p>
1737 <ul style='margin-top:0in;margin-bottom:0in'>
1738 <li><font face="Arial" size="2">Application type (SDI, multi thread SDI, MDI,
1739 TabView, Explorer, dialog based)</font></li>
1740 <li><font face="Arial" size="2">Support for hosting ActiveX controls</font></li>
1741 <li><font face="Arial" size="2">COM server support</font></li>
1742 <li><font face="Arial" size="2">Class implementation in .CPP files</font></li>
1743 <li><font face="Arial" size="2">Common Control manifest</font></li>
1744 <li><font face="Arial" size="2">Unicode character set</font></li>
1745 <li><font face="Arial" size="2">Toolbar, rebar, command bar, status bar</font></li>
1746 <li><font face="Arial" size="2">View window, and it's type (generic, dialog
1747 based form, or a list box, edit, list view, tree view, rich edit based, HTML
1748 page, scroll window)</font></li>
1749 <li><font face="Arial" size="2">For dialog based apps or a form based view
1750 window - support for hosting ActiveX controls in the dialog</font></li>
1751 </ul>
1752 <p style=margin:0in>&nbsp;</p>
1753 <p style=margin:0in><font face="Arial" size="2">ATL/WTL AppWizard supports VC++
1754 .NET 2002 and 2003, VC++ 2005, 2008, 2010, 2012, 2013, and 2015.</font></p>
1755 <p style=margin:0in>&nbsp;</p>
1756 <p style=margin:0in>&nbsp;</p>
1757 <p style=margin:0in><b><font face="Arial">
1758 <a name="Support for Windows CE"></a>Support for
1759 Windows CE</font></b></p>
1760 <p style=margin:0in>&nbsp;</p>
1761 <p style=margin:0in><font face="Arial" size="2">WTL fully supports building
1762 projects for the Windows CE platforms. The initial support for Windows CE was implemented primarily for
1763 eMbedded Visual C++ 4.0 with Pocket PC 2003 and
1764 SmartPhone 2003 SDKs. However, it can be used with other versions and
1765 configurations. For instance, Standard SDK 4.1 or 5.0 is supported as well. Considerable effort was made to provide the best Windows CE support,
1766 however, there might be some limitations because different platforms provide different
1767 programming support. SmartDevice projects with Visual Studio 2005 and 2008 are also
1768 supported, and it also includes an AppWizard for VS2005 and VS2008.</font></p>
1769 <p style=margin:0in>&nbsp;</p>
1770 <p style=margin:0in><font face="Arial" size="2">The support for Windows CE was
1771 not designed to port projects for the desktop version of Windows as-is to the
1772 Windows CE platforms, but to allow use of the same library, WTL, for both
1773 desktop Windows and Windows CE. Applications for Windows CE are often designed
1774 in a different way, and they use different platform services. WTL depends on the
1775 version of ATL provided with each Windows CE platform, and supports controls and
1776 services that are appropriate and supported for each Windows CE platform.</font></p>
1777 <p style=margin:0in>&nbsp;</p>
1778 <p style=margin:0in>&nbsp;</p>
1779 <p style=margin:0in><b><font face="Arial">
1780 <a name="Support for Visual C++ Express"></a>Support for
1781 Visual C++ Express</font></b></p>
1782 <p style=margin:0in>&nbsp;</p>
1783 <p style=margin:0in><font face="Arial" size="2">Note: Visual Studio Express is not the only or the best free development environment any more - <b>Visual Studio Community</b> provides a complete release of Visual Studio for free.</font></p>
1784 <p style=margin:0in>&nbsp;</p>
1785 <p style=margin:0in><font face="Arial" size="2">WTL supports using Visual C++ Express Edition to build projects. Since Visual C++ Express ships without ATL, you have to use a version of ATL that ships with Windows Driver Kit 7.1.0 or Platform SDK (Windows Server 2003 R2 Platform SDK).</font></p>
1786 <p style=margin:0in>&nbsp;</p>
1787 <p style=margin:0in><font face="Arial" size="2">Windows Driver Kit 7.1.0 contains ATL version 8, while Platform SDK has ATL version 3. We recomend ATL from Windows Driver Kit since it is newer and better version. However, you can still use ATL from Platform SDK since WTL still fully supports ATL3.</font></p>
1788 <p style=margin:0in>&nbsp;</p>
1789 <p style=margin:0in><font face="Arial" size="2">The WTL App Wizard can be installed by running AppWiz\setup.js program. The App Wizard generates code in the stdafx.h file that allows use of ATL. That code is used if _WTL_SUPPORT_EXTERNAL_ATL is defined, so you can comment the line in stdafx.h that defines _WTL_SUPPORT_EXTERNAL_ATL to use the project with different versions of Visual C++ or ATL.</font></p>
1790 <p style=margin:0in>&nbsp;</p>
1791 <p style=margin:0in><font face="Arial" size="2">Note that Release builds might generate some warnings, since ATL3 from Platform SDK is an old version of ATL which doesn't quite match the newer compiler and CRT files. You can ignore those warnings, as they do not indicate any real problems with the code.</font></p>
1792 <p style=margin:0in>&nbsp;</p>
1793 <p style=margin:0in><font face="Arial" size="2">Supported VC++ versions:</font></p>
1794 <ul style='margin-top:0in;margin-bottom:0in'>
1795 <li><font face="Arial" size="2">VC++ 2005 Express</font></li>
1796 <li><font face="Arial" size="2">VC++ 2008 Express</font></li>
1797 <li><font face="Arial" size="2">VC++ 2010 Express</font></li>
1798 <li><font face="Arial" size="2">VC++ Express 2012 for Windows Desktop</font></li>
1799 <li><font face="Arial" size="2">VC++ Express 2013 for Windows Desktop</font></li>
1800 <li><font face="Arial" size="2">VC++ Express 2015 for Windows Desktop</font></li>
1801 </ul>
1802 <p style=margin:0in>&nbsp;</p>
1803 <p style=margin:0in><font face="Arial" size="2">Supported ATL versions:</font></p>
1804 <ul style='margin-top:0in;margin-bottom:0in'>
1805 <li><font face="Arial" size="2">from Platform SDK (ATL 3)</font></li>
1806 <li><font face="Arial" size="2">from Windows Driver Kit (ATL 8)</font></li>
1807 </ul>
1808 <p style=margin:0in>&nbsp;</p>
1809 <p style=margin:0in><font face="Arial" size="2">Download Links:</font></p>
1810 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a target="_blank" href="https://www.visualstudio.com/downloads/download-visual-studio-vs#d-community">Visual Studio Community 2013 and 2015</a></font></p>
1811 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a target="_blank" href="https://www.visualstudio.com/downloads/download-visual-studio-vs">Visual Studio Express 2013 and 2015 for Windows Desktop</a></font></p>
1812 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a target="_blank" href="http://www.microsoft.com/en-us/download/details.aspx?id=34673">Visual Studio Express 2012 for Windows Desktop</a></font></p>
1813 <p style=margin:0in>&nbsp;</p>
1814 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a target="_blank" href="http://www.microsoft.com/en-us/download/details.aspx?id=11800">Windows Driver Kit Version 7.1.0</a></font></p>
1815 <p style=margin:0in>&nbsp;</p>
1816 <p style=margin:0in><font face="Arial" size="2">Older versions are not avilable for download any more. If you already have them, you can use them as descibed here.</font></p>
1817 <p style=margin:0in>&nbsp;</p>
1818 <p style=margin:0in>&nbsp;</p>
1819 <p style=margin:0in><b><font face="Arial">
1820 <a name="Notes"></a>Notes</font></b></p>
1821 <p style=margin:0in>&nbsp;</p>
1822 <p style=margin:0in><font face="Arial" size="2"><b>~</b>&nbsp;&nbsp;&nbsp; WTL provides
1823 several classes that are also present in ATL 7.0 and 7.1. The classes are: <b>
1824 CSize</b>, <b>CPoint</b>, <b>CRect</b>, and <b>CString</b> in atlmisc.h.
1825 While their existence will not cause any problems, their usage might. You should
1826 qualify the class you want to use with a namespace to resolve ambiguity, either
1827 ATL or WTL namespace, depending on which implementation you want to use.
1828 Alternatively, you can conditionally exclude WTL implementations, by defining
1829 preprocessor symbol <b>_WTL_NO_WTYPES</b> for CSize, CPoint, and CRect; and <b>_WTL_NO_CSTRING</b>
1830 for CString.</font></p>
1831 <p style=margin:0in>&nbsp;</p>
1832 <p style=margin:0in><font face="Arial" size="2"><b>~</b>&nbsp;&nbsp;&nbsp; If
1833 you use WTL 9.0 with VC++ 6.0/ATL 3.0 and define _ATL_STATIC_REGISTRY, you'll
1834 get errors referring to the ambiguous symbol ATL. This is caused by a bug in ATL
1835 3.0 - in atlbase.h, the file statreg.h is included inside of the ATL namespace,
1836 and it contains another namespace ATL declaration. Because of that, the compiler
1837 cannot decide between ATL:: and ATL::ATL:: namespaces. The solution is either to
1838 fix the atlbase.h, or to surround atlbase.h include declaration with following
1839 statements:</font></p>
1840 <p style=margin:0in>&nbsp;</p>
1841 <p style=margin:0in><font face="Arial" size="2"><b>&nbsp;&nbsp;&nbsp; #define
1842 ATL&nbsp;&nbsp; ATLFIX</b></font></p>
1843 <p style=margin:0in><font face="Arial" size="2">&nbsp;&nbsp;&nbsp; #include &lt;atlapp.h&gt;</font></p>
1844 <p style=margin:0in><font face="Arial" size="2">
1845 <b>&nbsp;&nbsp;&nbsp; #undef ATL</b></font></p>
1846 <p style=margin:0in><font face="Arial" size="2">
1847 <b>&nbsp;&nbsp;&nbsp; namespace ATL = ::ATLFIX;</b></font></p>
1848 <p style=margin:0in>&nbsp;</p>
1849 <p style=margin:0in><font face="Arial" size="2"><b>~</b>&nbsp;&nbsp;&nbsp;
1850 Windows XP allows applications to use Common Controls version 6, which supports
1851 only Unicode applications. While WTL allows creation of Ansi applications that
1852 use Common Controls 6, that should be used only for test programs and is not
1853 recommended or supported for released projects. If you want to use Common
1854 Controls 6, build your application as Unicode.</font></p>
1855 <p style=margin:0in>&nbsp;</p>
1856 <p style=margin:0in><font face="Arial" size="2"><b>~</b>&nbsp;&nbsp;&nbsp;
1857 If you build your app that hosts ActiveX controls
1858 with VC++ 7.x, you can see this assert failing:<br>
1859 <span class="style2"><strong><br>
1860 &nbsp;&nbsp;&nbsp; !InlineIsEqualGUID(*m_plibid, GUID_NULL) &amp;&amp; &quot;Did you forget
1861 to pass the LIBID to CComModule::Init?&quot;<br>
1862 <br>
1863 </strong></span><font face="Arial" size="2">There are two ways to fix this:</font></p>
1864 <ul>
1865 <li>
1866 <p style=margin:0in><font face="Arial" size="2">In the main .CPP file of your
1867 project, replace the line</font><br>
1868 <span class="style2"><strong>&nbsp;&nbsp;&nbsp; hRes = _Module.Init(NULL, hInstance);<br>
1869 </strong></span><font face="Arial" size="2">with this one</font><br>
1870 <span class="style2"><strong>&nbsp;&nbsp;&nbsp; hRes = _Module.Init(NULL, hInstance, &amp;LIBID_ATLLib);<br>
1871 &nbsp;</strong></span></p>
1872 </li>
1873 <li>
1874 <p style=margin:0in><font face="Arial" size="2">Compile you project with _ATL_DLL
1875 defined (dynamic link to ATL)</font></p>
1876 </li>
1877 </ul>
1878 <p style=margin:0in><font face="Arial" size="2"><b>~</b>&nbsp;&nbsp;&nbsp;
1879 Several of the sample programs included with WTL were extended to support
1880 building for Windows CE. These samples are not specially redesigned for Windows
1881 CE, but just modified to allow you to compile and run them on the Windows CE
1882 platforms. The samples are: BmpView, GuidGen, and MTPad.</font></p>
1883 <p style=margin:0in>&nbsp;</p>
1884 <p style=margin:0in><font face="Arial" size="2"><b>~</b>&nbsp;&nbsp;&nbsp; WTL
1885 supports building projects with EVC++ 3.0 only for Pocket PC and Pocket PC 2002
1886 platforms, as other platforms don't provide minimum support for ATL or other
1887 required libraries.</font></p>
1888 <p style=margin:0in>&nbsp;</p>
1889 <p style=margin:0in><font face="Arial" size="2"><b>~</b>&nbsp;&nbsp;&nbsp; The
1890 old AppWizards for VC++ 6.0 and eVC++ 4.0/3.0 are not included in this version
1891 of WTL because they cannot be a part of an Open Source project. They are still
1892 available in the previous release, WTL 7.1.</font></p>
1893 <p style=margin:0in>&nbsp;</p>
1894 <p style=margin:0in><font face="Arial" size="2"><b>~</b>&nbsp;&nbsp;&nbsp; Visual
1895 Studio 2012 and higher use default subsystem version 6.0 (Windows Vista). Previous
1896 versions of Visual Studio used 5.01 (Windows XP). That means that applications built
1897 with Visual Studio 2012 and higher cannot run on Windows XP. Attempting to run would
1898 result in an error that it is not a valid Win32 application. If you want to run your
1899 applications on Windows XP, you need to change subsystem version to 5.01. You can do
1900 that by going to Project Properties -> Linker -> System -> Minimum Required Version,
1901 and entering 5.01 as a value.</font></p>
1902 <p style=margin:0in>&nbsp;</p>
1903 <p style=margin:0in>&nbsp;</p>
1904 <p style=margin:0in><b><font face="Arial">
1905
1906 <a name="Changes Between WTL 9.1 and 9.0"></a>Changes Between WTL 9.1 and 9.0</font></b></p>
1907 <p style=margin:0in>&nbsp;</p>
1908 <p style=margin:0in><font face="Arial" size="2">New and improved:</font></p>
1909 <blockquote style='margin-top:0in;margin-bottom:0in'>
1910 <p style=margin:0in><font face="Arial" size="2">
1911 Full compatibility with VS2015<br>
1912 NuGet support and package<br>
1913 Microsoft Public License (MS-PL)<br>
1914 New sample: MemDlg - demonstrates use of in-memory dialogs
1915 </blockquote>
1916 <p style=margin:0in>&nbsp;</p>
1917 <p style=margin:0in><font face="Arial" size="2">Fixes and enhancements:</font></p>
1918 <blockquote style='margin-top:0in;margin-bottom:0in'>
1919 <p style=margin:0in><font face="Arial" size="2">
1920 Fixes for code analysis warnings<br>
1921 Fixes for strict const-qualification conformance (/Zc:strictStrings)<br>
1922 CEditFindReplaceImpl::UseShadowBuffer(): Use AtlGetCommCtrlVersion() instead of GetProcAddress()<br>
1923 Misc improvements: missing initialization, undefined messages, better #ifdefs<br>
1924 CFrameWndClassInfo: Use GetSystemMetrics() for icon sizes<br>
1925 BEGIN_MSG_MAP_EX and BEGIN_DDX_MAP: Fix for C4555: expression has no effect<br>
1926 CResource::LoadEx(): Fix for the wrong order for parameters to ::FindResourceEx()<br>
1927 CPaneContainerImpl:</font></p>
1928 <ul style='margin-top:0in;margin-bottom:0in'>
1929 <li><p style=margin:0in><font face="Arial" size="2">New extended styles: PANECNT_DIVIDER and PANECNT_GRADIENT</font></p></li>
1930 <li><p style=margin:0in><font face="Arial" size="2">Fixed background drawing for close button</font></p></li>
1931 </ul>
1932 <p style=margin:0in><font face="Arial" size="2">
1933 CImageListManaged: Fix for assert when using attach or operator =<br>
1934 WTLExplorer sample cleanup<br>
1935 GenericWndClass::Register(): Fix for Windows CE<br>
1936 App Wizard: Improved code for generating project configurations<br>
1937 CSplitterImpl::OnCaptureChanged(): Fixed so it moves splitter bar only if move was in progress<br>
1938 CDynamicUpdateUI::UIRemoveUpdateElement() leaks memory if UPDUI_TEXT is set<br>
1939 CToolInfo and CToolTipCtrl: nIDTool argument should be UINT_PTR instead of UINT<br>
1940 CSplitterImpl: Added GetSplitterPosPct()<br>
1941 CCommandBarCtrlImpl: Fixed incorrect use of m_wndParent when AttachToWindow() is used
1942 </blockquote>
1943 <p style=margin:0in>&nbsp;</p>
1944 <p style=margin:0in>&nbsp;</p>
1945 <p style=margin:0in><b><font face="Arial">
1946
1947 <a name="Changes Between WTL 9.0 and 8.0"></a>Changes Between WTL 9.0 and 8.0</font></b></p>
1948 <p style=margin:0in>&nbsp;</p>
1949 <p style=margin:0in><font face="Arial" size="2">New and improved:</font></p>
1950 <blockquote style='margin-top:0in;margin-bottom:0in'>
1951 <p style=margin:0in><font face="Arial" size="2">
1952 Full compatibility with VS2008, VS2010, VS2012, and VS2013<br>
1953 New CRegKeyEx class for uniform support for registry<br>
1954 New MinCrtHelper functions for uniform support for _ATL_MIN_CRT<br>
1955 New DWM classes in atldwm.h<br>
1956 New Ribbon classes in atlribbon.h<br>
1957 New CDialogBaseUnits class<br>
1958 Extended DDX support to TabCtrl, ComboBox, ListBox and ListView selection index<br>
1959 Improved font handling in CHyperLink, CPaneContainer, CTabView<br>
1960 CHyperlink: Added options for auto-create link font and single-line mode<br>
1961 CBitmapButtonImpl: Added checked state, GetCheck()/SetCheck(), and check mode extended styles<br>
1962 UpdateUI: Added support for radio menu items for popup menus<br>
1963 Added support for new VersionHelpers.h in WinSDK 8.1 - GetVersionEx() is now deprecated<br>
1964 Improved global support for old SDK headers, and for original headers in VC6 and VC7.x<br>
1965 Global support for builds with NOMINMAX defined<br>
1966 Global support for builds with STRICT_TYPED_ITEMIDS defined<br>
1967 Global support for builds with _ATL_ALL_USER_WARNINGS defined<br>
1968 Splitter Window:</font></p>
1969 <ul style='margin-top:0in;margin-bottom:0in'>
1970 <li><p style=margin:0in><font face="Arial" size="2">Added keyboard handling</font></p></li>
1971 <li><p style=margin:0in><font face="Arial" size="2">Added default position for splitter bar</font></p></li>
1972 <li><p style=margin:0in><font face="Arial" size="2">Changed orientation from template argument to data member to reduce memory use</font></p></li>
1973 <li><p style=margin:0in><font face="Arial" size="2">Added SPLIT_GRADIENTBAR and SPLIT_FIXEDBARSIZE extended styles</font></p></li>
1974 </ul>
1975 <p style=margin:0in><font face="Arial" size="2">
1976 Added CImageListManaged to manage the lifetime of wrapped image list<br>
1977 Added Vista standard menu bar look option for Command bar<br>
1978 Added new Rich Edit wrappers for _RICHEDIT_VER >= 0x0800<br>
1979 Added new Win8 methods to Theme classes<br>
1980 Added override of SubclassWindow() to CSplitterWindowImpl, CPaneContainerImpl, CTabViewImpl,<br>
1981 &nbsp;&nbsp;CScrollImpl, CMapScrollImpl, CZoomScrollImpl, and CScrollContainerImpl<br>
1982 CZoomScrollImpl:</font></p>
1983 <ul style='margin-top:0in;margin-bottom:0in'>
1984 <li><p style=margin:0in><font face="Arial" size="2">Added zoom child windows option</font></p></li>
1985 <li><p style=margin:0in><font face="Arial" size="2">Added zoom scale max limit</font></p></li>
1986 </ul>
1987 <p style=margin:0in><font face="Arial" size="2">
1988 AppWizard:</font></p>
1989 <ul style='margin-top:0in;margin-bottom:0in'>
1990 <li><p style=margin:0in><font face="Arial" size="2">Support for VS2008, VS2010, VS2012, and VS2013</font></p></li>
1991 <li><p style=margin:0in><font face="Arial" size="2">New universal setup for all versions of Visual Studio</font></p></li>
1992 <li><p style=margin:0in><font face="Arial" size="2">Support for ribbon control</font></p></li>
1993 </ul>
1994 <p style=margin:0in><font face="Arial" size="2">
1995 Updated samples and added VS2005 project files<br>
1996 New sample: MTPad7 - demonstrates Ribbon UI</font></p>
1997 </blockquote>
1998 <p style=margin:0in>&nbsp;</p>
1999 <p style=margin:0in><font face="Arial" size="2">Fixes and enhancements:</font></p>
2000 <blockquote style='margin-top:0in;margin-bottom:0in'>
2001 <p style=margin:0in><font face="Arial" size="2">General:</font></p>
2002 <ul style='margin-top:0in;margin-bottom:0in'>
2003 <li><p style=margin:0in><font face="Arial" size="2">Fixed security warning for _vstprintf in atlapp.h</font></p></li>
2004 <li><p style=margin:0in><font face="Arial" size="2">Added RunTimeHelper::IsThemeAvailable that detects if themes can be used in the app</font></p></li>
2005 <li><p style=margin:0in><font face="Arial" size="2">VS2012: DLL version functions are defined as they are removed from ATL11</font></p></li>
2006 <li><p style=margin:0in><font face="Arial" size="2">Added CWndProcThunk initialization for _ATL_VER >= 0x0800</font></p></li>
2007 <li><p style=margin:0in><font face="Arial" size="2">Added RunTimeHelper::SizeOf_TOOLINFO() for different Windows versions at runtime</font></p></li>
2008 <li><p style=margin:0in><font face="Arial" size="2">Added AtlCreateControlFont()</font></p></li>
2009 </ul>
2010 <p style=margin:0in>&nbsp;</p>
2011 <p style=margin:0in><font face="Arial" size="2">Controls:</font></p>
2012 <ul style='margin-top:0in;margin-bottom:0in'>
2013 <li><p style=margin:0in><font face="Arial" size="2">Extended CListViewCtrl::SelectItem() to multi-selection list view controls</font></p></li>
2014 <li><p style=margin:0in><font face="Arial" size="2">Added another variant of CListViewCtrl::FindItem for strings</font></p></li>
2015 <li><p style=margin:0in><font face="Arial" size="2">Added new CToolBarCtrl methods - InsertSeparator() and AddSeparator()</font></p></li>
2016 <li><p style=margin:0in><font face="Arial" size="2">Added CToolBarCtrl::GetItemDropDownRect()</font></p></li>
2017 <li><p style=margin:0in><font face="Arial" size="2">Added another variant of CToolTipCtrl::TrackActivate()</font></p></li>
2018 </ul>
2019 <p style=margin:0in>&nbsp;</p>
2020 <p style=margin:0in><font face="Arial" size="2">Cracked Handlers:</font></p>
2021 <ul style='margin-top:0in;margin-bottom:0in'>
2022 <li><p style=margin:0in><font face="Arial" size="2">Fixed handlers with menu arguments</font></p></li>
2023 <li><p style=margin:0in><font face="Arial" size="2">Fixed MSG_WM_SYSCOMMAND handler</font></p></li>
2024 <li><p style=margin:0in><font face="Arial" size="2">Added MSG_WM_MOUSEHWHEEL handler</font></p></li>
2025 </ul>
2026 <p style=margin:0in>&nbsp;</p>
2027 <p style=margin:0in><font face="Arial" size="2">App Wizard:</font></p>
2028 <ul style='margin-top:0in;margin-bottom:0in'>
2029 <li><p style=margin:0in><font face="Arial" size="2">Fix for TabView project code generation</font></p></li>
2030 <li><p style=margin:0in><font face="Arial" size="2">Improved generated code for VC++ Express to support various versions of ATL</font></p></li>
2031 <li><p style=margin:0in><font face="Arial" size="2">Fix for missing UIUpdateChildWindows() in dialog projects</font></p></li>
2032 </ul>
2033 <p style=margin:0in>&nbsp;</p>
2034 <p style=margin:0in><font face="Arial" size="2">App Wizard CE / App Wizard Mobile:</font></p>
2035 <ul style='margin-top:0in;margin-bottom:0in'>
2036 <li><p style=margin:0in><font face="Arial" size="2">Updated AppWizCE for VS2008 - used different CLSID for Platforms object</font></p></li>
2037 <li><p style=margin:0in><font face="Arial" size="2">Fix: VS2008 uses _SECURE_ATL code only</font></p></li>
2038 <li><p style=margin:0in><font face="Arial" size="2">Fix for resource creation failure</font></p></li>
2039 </ul>
2040 <p style=margin:0in>&nbsp;</p>
2041 <p style=margin:0in><font face="Arial" size="2">Misc:</font></p>
2042 <ul style='margin-top:0in;margin-bottom:0in'>
2043 <li><p style=margin:0in><font face="Arial" size="2">Fix: CLogFont uses ::GetDeviceCaps with wrong default hDC = NULL</font></p></li>
2044 <li><p style=margin:0in><font face="Arial" size="2">Fixed CPen::GetExtLogPen</font></p></li>
2045 <li><p style=margin:0in><font face="Arial" size="2">Fixed CFrameWindowImpl::OnToolTipText*() handlers not to reset text buffer</font></p></li>
2046 <li><p style=margin:0in><font face="Arial" size="2">Added support for chevron menus for multi-line toolbars</font></p></li>
2047 <li><p style=margin:0in><font face="Arial" size="2">Fix: CFileDialog(false) fails on Windows Mobile 5 or 6</font></p></li>
2048 <li><p style=margin:0in><font face="Arial" size="2">Fix: CFolderDialog::SetOKText should use lParam for string</font></p></li>
2049 <li><p style=margin:0in><font face="Arial" size="2">Added CFolderDialog::SetPidlRoot()</font></p></li>
2050 <li><p style=margin:0in><font face="Arial" size="2">Fixed CMemDlgTemplate::AddControl</font></p></li>
2051 <li><p style=margin:0in><font face="Arial" size="2">Added option to disable item dragging in CTabViewImpl</font></p></li>
2052 <li><p style=margin:0in><font face="Arial" size="2">Fixed CTabView::ShowTabControl(false) and UpdateLayout() to hide empty space</font></p></li>
2053 <li><p style=margin:0in><font face="Arial" size="2">CTabView: Fixed value of the active page when inserting pages before it</font></p></li>
2054 <li><p style=margin:0in><font face="Arial" size="2">PaneContainer: Added support for vertical title bar text</font></p></li>
2055 <li><p style=margin:0in><font face="Arial" size="2">atlsplit.h: Added missing support for WM_PRINTCLIENT</font></p></li>
2056 <li><p style=margin:0in><font face="Arial" size="2">Fix: CScrollImpl should not scroll horizontally if not needed</font></p></li>
2057 <li><p style=margin:0in><font face="Arial" size="2">Fixed CScrollImpl<T>::ScrollToView() to use offset correctly</font></p></li>
2058 <li><p style=margin:0in><font face="Arial" size="2">Fixed CPrintDialogExImpl::GetDefaults()</font></p></li>
2059 <li><p style=margin:0in><font face="Arial" size="2">atltheme.h: Added CBufferedAnimation::StopAllAnimations()</font></p></li>
2060 <li><p style=margin:0in><font face="Arial" size="2">Added support for I64 format to CString::Format()</font></p></li>
2061 <li><p style=margin:0in><font face="Arial" size="2">Fix: CStdIndirectDialogImpl - DLGTEMPLATEEX not supported on Mobile devices</font></p></li>
2062 <li><p style=margin:0in><font face="Arial" size="2">Fix: Missing CRichInkCtrlT::SetSel(), added CRichInkCtrlT::Undo()</font></p></li>
2063 </ul>
2064 </blockquote>
2065 <p style=margin:0in>&nbsp;</p>
2066 <p style=margin:0in>&nbsp;</p>
2067 <p style=margin:0in><b><font face="Arial">
2068 <a name="Changes Between WTL 8.0 and 7.5"></a>Changes Between WTL 8.0 and 7.5</font></b></p>
2069 <p style=margin:0in>&nbsp;</p>
2070 <p style=margin:0in><font face="Arial" size="2">New and improved:</font></p>
2071 <blockquote style='margin-top:0in;margin-bottom:0in'>
2072 <p style=margin:0in><font face="Arial" size="2">RunTimeHelper functions for
2073 correct struct sizes on different versions of Windows<br>ModuleHelper functions for uniform support of ATL3 and ATL7 module classes<br>SecureHelper functions for support of secure and non-secure run-time
2074 functions<br>Support for new Vista features:</font></p>
2075 <ul style='margin-top:0in;margin-bottom:0in'>
2076 <li>
2077 <p style=margin:0in><font face="Arial" size="2">Support for new messages for common controls, dialogs, etc.</font></p>
2078 </li>
2079 <li>
2080 <p style=margin:0in><font face="Arial" size="2">Support for TaskDialog</font></p>
2081 </li>
2082 <li>
2083 <p style=margin:0in><font face="Arial" size="2">New Shell file dialogs (IFileOpenDialog and IFileSaveDialog)</font></p>
2084 </li>
2085 <li>
2086 <p style=margin:0in><font face="Arial" size="2">New Aero Wizard support classes</font></p>
2087 </li>
2088 <li>
2089 <p style=margin:0in><font face="Arial" size="2">New classes for Buffered Paint and Buffered Animation</font></p>
2090 </li>
2091 </ul>
2092 <p style=margin:0in><font face="Arial" size="2">New TabView classes<br>New dialog class that uses in-memory dialog templates<br>New CMultiFileDialogImpl and CMultiFileDialog classes that support
2093 multi-select file dialogs<br>Added message cracker handler prototypes for all handlers<br>Replaced use of _alloca with CTempBuffer everywhere (and added CTempBuffer
2094 version for ATL3)<br>New classes for find/replace support for Edit or RichEdit<br>New class CFileDialogEx that supports GetOpenFileNameEx for Windows Mobile 5<br>
2095 New features for the App Wizard:</font></p>
2096 <ul style='margin-top:0in;margin-bottom:0in'>
2097 <li>
2098 <p style=margin:0in><font face="Arial" size="2">New default version values</font></p>
2099 </li>
2100 <li>
2101 <p style=margin:0in><font face="Arial" size="2">Unicode build option</font></p>
2102 </li>
2103 <li>
2104 <p style=margin:0in><font face="Arial" size="2">Support for TabView applications</font></p>
2105 </li>
2106 <li>
2107 <p style=margin:0in><font face="Arial" size="2">Support for Explorer applications</font></p>
2108 </li>
2109 </ul>
2110 <p style=margin:0in><font face="Arial" size="2">Updates for the desktop App Wizard:</font></p>
2111 <ul style='margin-top:0in;margin-bottom:0in'>
2112 <li>
2113 <p style=margin:0in><font face="Arial" size="2">Added calls to set font for views based on controls that use font</font></p>
2114 </li>
2115 <li>
2116 <p style=margin:0in><font face="Arial" size="2">Added scroll window as another view type</font></p>
2117 </li>
2118 </ul>
2119 <p style=margin:0in><font face="Arial" size="2">Support for VC2005 Express:</font></p>
2120 <ul style='margin-top:0in;margin-bottom:0in'>
2121 <li>
2122 <p style=margin:0in><font face="Arial" size="2">Setup for VS2005x</font></p>
2123 </li>
2124 <li>
2125 <p style=margin:0in><font face="Arial" size="2">Changes in default.js to take into account that VC2005x does not have a
2126 resource editor</font></p></li>
2127 <li>
2128 <p style=margin:0in><font face="Arial" size="2">Generated code allows use of ATL3 from the Platform SDK</font></p>
2129 </li>
2130 </ul>
2131 <p style=margin:0in><font face="Arial" size="2">New AppWizard for Mobile 2003 and 2005 platforms<br>
2132 New samples:</font></p>
2133 <ul style='margin-top:0in;margin-bottom:0in'>
2134 <li>
2135 <p style=margin:0in><font face="Arial" size="2">Aero - demonstrates the
2136 Vista Glass UI</font></p></li>
2137 <li>
2138 <p style=margin:0in><font face="Arial" size="2">MiniPie - Windows Mobile 2005 PPC and Smartphone sample</font></p>
2139 </li>
2140 <li>
2141 <p style=margin:0in><font face="Arial" size="2">TabBrowser - a web browser using TabView class</font></p>
2142 </li>
2143 </ul>
2144 <p style=margin:0in><font face="Arial" size="2">MTPad sample updated to show usage of CRichEditFindReplaceImpl and
2145 CEditCommands/CRichEditCommands</font></p>
2146 </blockquote>
2147 <p style=margin:0in>&nbsp;</p>
2148 <p style=margin:0in><font face="Arial" size="2">Fixes and enhancements:</font></p>
2149 <blockquote style='margin-top:0in;margin-bottom:0in'>
2150 <p style=margin:0in><font face="Arial" size="2">Command Bar:</font></p>
2151 <ul style='margin-top:0in;margin-bottom:0in'>
2152 <li>
2153 <p style=margin:0in><font face="Arial" size="2">Added support for menu items
2154 with bitmaps on Vista</font></p></li>
2155 <li>
2156 <p style=margin:0in><font face="Arial" size="2">Fix: Keyboard cues shown
2157 even if the window is disabled</font></p></li>
2158 </ul>
2159 <p style=margin:0in>&nbsp;</p>
2160 <p style=margin:0in><font face="Arial" size="2">CFolderDialog:</font></p>
2161 <ul style='margin-top:0in;margin-bottom:0in'>
2162 <li>
2163 <p style=margin:0in><font face="Arial" size="2">Added support for PIDLs in
2164 addition to the file path</font></p></li>
2165 <li>
2166 <p style=margin:0in><font face="Arial" size="2">Replaced use of SHGetMalloc
2167 with CoTaskMemFree</font></p></li>
2168 </ul>
2169 <p style=margin:0in>&nbsp;</p>
2170 <p style=margin:0in><font face="Arial" size="2">Scroll Windows:</font></p>
2171 <ul style='margin-top:0in;margin-bottom:0in'>
2172 <li>
2173 <p style=margin:0in><font face="Arial" size="2">Fix: CZoomScrollImpl - some
2174 methods should be overridable</font></p></li>
2175 <li>
2176 <p style=margin:0in><font face="Arial" size="2">Added support for
2177 WM_MOUSEHWHEEL in CScrollImpl</font></p></li>
2178 </ul>
2179 <p style=margin:0in>&nbsp;</p>
2180 <p style=margin:0in><font face="Arial" size="2">App Wizard:</font></p>
2181 <ul style='margin-top:0in;margin-bottom:0in'>
2182 <li>
2183 <p style=margin:0in><font face="Arial" size="2">Fix: AppWizard fails to add
2184 files if C:\Temp does not exist</font></p></li>
2185 <li>
2186 <p style=margin:0in><font face="Arial" size="2">Fix: App Wizard generates
2187 security warning when loaded</font></p></li>
2188 <li>
2189 <p style=margin:0in><font face="Arial" size="2">Fix: App Wizard generates
2190 level 4 warning for modal dlg project</font></p></li>
2191 <li>
2192 <p style=margin:0in><font face="Arial" size="2">Fix: App Wizard setupXX.js
2193 scripts silently fail on Vista</font></p></li>
2194 <li>
2195 <p style=margin:0in><font face="Arial" size="2">Fix: Added code to
2196 unregister message filer and idle processing</font></p></li>
2197 <li>
2198 <p style=margin:0in><font face="Arial" size="2">Fix: Added WS_CLIPSIBLINGS
2199 to dialog forms to avoid rebar drawing problems</font></p></li>
2200 </ul>
2201 <p style=margin:0in>&nbsp;</p>
2202 <p style=margin:0in><font face="Arial" size="2">App Wizard CE:</font></p>
2203 <ul style='margin-top:0in;margin-bottom:0in'>
2204 <li>
2205 <p style=margin:0in><font face="Arial" size="2">Fix: App Wizard CE should
2206 not have rich edit as a view option</font></p></li>
2207 <li>
2208 <p style=margin:0in><font face="Arial" size="2">Fix: App Wizard CE generates
2209 level 4 warnings for single instance apps</font></p></li>
2210 <li>
2211 <p style=margin:0in><font face="Arial" size="2">Added support for Windows
2212 Mobile 6 SDKs</font></p></li>
2213 </ul>
2214 <p style=margin:0in>&nbsp;</p>
2215 <p style=margin:0in><font face="Arial" size="2">Cracked Handlers:</font></p>
2216 <ul style='margin-top:0in;margin-bottom:0in'>
2217 <li>
2218 <p style=margin:0in><font face="Arial" size="2">Fix: Corrected MSG_WM_TIMER
2219 and handler prototype, removed unused argument (breaking change)</font></p>
2220 </li>
2221 <li>
2222 <p style=margin:0in><font face="Arial" size="2">Fix: atlcrack.h does not
2223 support WTL namespace</font></p></li>
2224 </ul>
2225 <p style=margin:0in>&nbsp;</p>
2226 <p style=margin:0in><font face="Arial" size="2">CDialogResize:</font></p>
2227 <ul style='margin-top:0in;margin-bottom:0in'>
2228 <li>
2229 <p style=margin:0in><font face="Arial" size="2">Added SetIcon(NULL, FALSE)
2230 for CDialogResize to remove the generic icon for resizable dialogs</font></p>
2231 </li>
2232 <li>
2233 <p style=margin:0in><font face="Arial" size="2">Fix: Enabled size/move for
2234 both X and Y</font></p></li>
2235 <li>
2236 <p style=margin:0in><font face="Arial" size="2">Added center flags for
2237 controls</font></p></li>
2238 </ul>
2239 <p style=margin:0in>&nbsp;</p>
2240 <p style=margin:0in><font face="Arial" size="2">CFrameWindowImpl:</font></p>
2241 <ul style='margin-top:0in;margin-bottom:0in'>
2242 <li>
2243 <p style=margin:0in><font face="Arial" size="2">Fix: Const issue with title
2244 argument of AddSimpleReBarBand</font></p></li>
2245 <li>
2246 <p style=margin:0in><font face="Arial" size="2">Fix: DECLARE_FRAME_WND_CLASS
2247 definition missing WTL namespace</font></p></li>
2248 </ul>
2249 <p style=margin:0in>&nbsp;</p>
2250 <p style=margin:0in><font face="Arial" size="2">Windows CE:</font></p>
2251 <ul style='margin-top:0in;margin-bottom:0in'>
2252 <li>
2253 <p style=margin:0in><font face="Arial" size="2">Fix: Some symbols not
2254 defined for CE 4.0</font></p></li>
2255 <li>
2256 <p style=margin:0in><font face="Arial" size="2">Fix: Incorrect WinCE
2257 exclusions</font></p></li>
2258 <li>
2259 <p style=margin:0in><font face="Arial" size="2">Fix: Pocket PC - assert
2260 after navigating a CHyperLink</font></p></li>
2261 <li>
2262 <p style=margin:0in><font face="Arial" size="2">Fix: Property sheet with
2263 listview on WM5.0 causes stack overflow</font></p></li>
2264 <li>
2265 <p style=margin:0in><font face="Arial" size="2">Fix: CFindFile::GetFilePath()
2266 fails on diskless root requests</font></p></li>
2267 <li>
2268 <p style=margin:0in><font face="Arial" size="2">Fix: VS 2005 dialog editor
2269 bug - DS_FIXEDSYS used but not defined</font></p></li>
2270 <li>
2271 <p style=margin:0in><font face="Arial" size="2">Fix: Windows Mobile 2005
2272 compatibility issues</font></p></li>
2273 <li>
2274 <p style=margin:0in><font face="Arial" size="2">Fix: CFullScreenFrame on
2275 Smartphone 20003</font></p></li>
2276 <li>
2277 <p style=margin:0in><font face="Arial" size="2">Fix: SmartPhone back key
2278 handling in CAppWindow</font></p></li>
2279 <li>
2280 <p style=margin:0in><font face="Arial" size="2">Added orientation aware
2281 support to CAppStdDialogImpl</font></p></li>
2282 <li>
2283 <p style=margin:0in><font face="Arial" size="2">Added CAxDialogImpl base for
2284 CStdDialogImpl, CStdDialogResizeImpl and CStdOrientedDialogImpl</font></p>
2285 </li>
2286 <li>
2287 <p style=margin:0in><font face="Arial" size="2">Added various CStdDialogxxx
2288 enhancements</font></p></li>
2289 <li>
2290 <p style=margin:0in><font face="Arial" size="2">Fix: CStdDialogBase does not
2291 scale dialog title on VGA</font></p></li>
2292 <li>
2293 <p style=margin:0in><font face="Arial" size="2">Fix: DIBINFO16 triggers code
2294 analysis warning</font></p></li>
2295 <li>
2296 <p style=margin:0in><font face="Arial" size="2">Added LPCTSTR
2297 AtlLoadString(UINT uID) - CE only overload</font></p></li>
2298 <li>
2299 <p style=margin:0in><font face="Arial" size="2">Added imaging draw support
2300 to CZoomScrollImpl</font></p></li>
2301 <li>
2302 <p style=margin:0in><font face="Arial" size="2">Added CBottomTabViewImpl and
2303 CBottomTabView classes for PPC</font></p></li>
2304 </ul>
2305 <p style=margin:0in>&nbsp;</p>
2306 <p style=margin:0in><font face="Arial" size="2">CFindFile:</font></p>
2307 <ul style='margin-top:0in;margin-bottom:0in'>
2308 <li>
2309 <p style=margin:0in><font face="Arial" size="2">Fix: CFindFile class uses
2310 CRT functions</font></p></li>
2311 <li>
2312 <p style=margin:0in><font face="Arial" size="2">Fix: FindFile() uses lstrcpy
2313 without checking length</font></p></li>
2314 </ul>
2315 <p style=margin:0in>&nbsp;</p>
2316 <p style=margin:0in><font face="Arial" size="2">General:</font></p>
2317 <ul style='margin-top:0in;margin-bottom:0in'>
2318 <li>
2319 <p style=margin:0in><font face="Arial" size="2">Fix: Adding ReBar bands
2320 fails with new Windows SDK</font></p></li>
2321 <li>
2322 <p style=margin:0in><font face="Arial" size="2">Added support for relative
2323 include paths</font></p></li>
2324 <li>
2325 <p style=margin:0in><font face="Arial" size="2">Fix: Using std::min and
2326 std::max</font></p></li>
2327 <li>
2328 <p style=margin:0in><font face="Arial" size="2">Fix: Problems using WTL with
2329 MFC</font></p></li>
2330 <li>
2331 <p style=margin:0in><font face="Arial" size="2">Improved support for Secure
2332 CRT</font></p></li>
2333 <li>
2334 <p style=margin:0in><font face="Arial" size="2">Changed implementation of
2335 CSize, CPoint, CRect, and CString to be inside class definitions</font></p>
2336 </li>
2337 <li>
2338 <p style=margin:0in><font face="Arial" size="2">atltheme.h: Corrected method
2339 signatures for differences in uxtheme.h versions</font></p></li>
2340 <li>
2341 <p style=margin:0in><font face="Arial" size="2">Replaced malloc/free with
2342 new/delete where appropriate</font></p></li>
2343 </ul>
2344 <p style=margin:0in>&nbsp;</p>
2345 <p style=margin:0in><font face="Arial" size="2">Misc:</font></p>
2346 <ul style='margin-top:0in;margin-bottom:0in'>
2347 <li>
2348 <p style=margin:0in><font face="Arial" size="2">Fix: CString::FormatV can
2349 cause GPF with Unicode strings</font></p></li>
2350 <li>
2351 <p style=margin:0in><font face="Arial" size="2">CHyperLink: Added handler
2352 for WM_SIZE</font></p></li>
2353 <li>
2354 <p style=margin:0in><font face="Arial" size="2">Fix: CTheme needs
2355 constructor from HTHEME handle</font></p></li>
2356 <li>
2357 <p style=margin:0in><font face="Arial" size="2">Added Add* methods to
2358 several control classes in atlctrls.h to augment Insert* methods</font></p>
2359 </li>
2360 <li>
2361 <p style=margin:0in><font face="Arial" size="2">Fix: Incorrect casting in
2362 CRichEditCtrl::GetLine()</font></p></li>
2363 <li>
2364 <p style=margin:0in><font face="Arial" size="2">Fix:
2365 CTreeViewCtrl::GetItemState changed to return only state-bits as specified
2366 by mask</font></p></li>
2367 <li>
2368 <p style=margin:0in><font face="Arial" size="2">Fix: CBitmapButton::DoPaint
2369 - wrong button image</font></p></li>
2370 <li>
2371 <p style=margin:0in><font face="Arial" size="2">Added another variant of
2372 CDCT::Drawtext with LPTSTR argument that allows text change</font></p></li>
2373 <li>
2374 <p style=margin:0in><font face="Arial" size="2">Fix:
2375 CRecentDocumentListBase::AddToList() uses lstrcpy</font></p></li>
2376 <li>
2377 <p style=margin:0in><font face="Arial" size="2">Fix: AtlLoadString(uID,
2378 lpBuffer, nBufferMax) has unnecessary code</font></p></li>
2379 <li>
2380 <p style=margin:0in><font face="Arial" size="2">Fix: CCursor::LoadOEMCursor
2381 asserts on IDC_HAND</font></p></li>
2382 <li>
2383 <p style=margin:0in><font face="Arial" size="2">Fix: Memory leak when using
2384 CRT functions while printing</font></p></li>
2385 <li>
2386 <p style=margin:0in><font face="Arial" size="2">Fix: Undefined CString
2387 namespace</font></p></li>
2388 <li>
2389 <p style=margin:0in><font face="Arial" size="2">CPaneContainer: Added border
2390 styles</font></p></li>
2391 <li>
2392 <p style=margin:0in><font face="Arial" size="2">CSplitterImpl: Added
2393 SetSplitterPosPct, and changed App Wizard code to use it</font></p></li>
2394 </ul>
2395 </blockquote>
2396 <p style=margin:0in>&nbsp;</p>
2397 <p style=margin:0in>&nbsp;</p>
2398 <p style=margin:0in><b><font face="Arial">
2399 <a name="Changes Between WTL 7.5 and 7.1"></a>Changes Between WTL 7.5 and 7.1</font></b></p>
2400 <p style=margin:0in>&nbsp;</p>
2401 <p style=margin:0in><font face="Arial" size="2">New and improved:</font></p>
2402 <blockquote style='margin-top:0in;margin-bottom:0in'>
2403 <p style=margin:0in><font face="Arial" size="2">VS2005 Compatibility:
2404 Added support for Visual Studio 2005 - both desktop and Windows CE<br>
2405 Classes for icons, cursors, accelerator tables<br>
2406 CSortListViewImpl, CSortListViewCtrlImpl, and CSortListViewCtrl classes<br>
2407 Impl classes for Wizard 97 style wizards: CWizard97Sheet,
2408 CWizard97Page, CWizard97ExteriorPage, CWizard97InteriorPage<br>
2409 CMemoryDC and CDoubleBufferWindowImpl classes<br>
2410 Windows CE specific classes in new header, atlwince.h<br>
2411 CScrollContainer class<br>
2412 CZoomScrollImpl and CZoomScrollWindowImpl classes<br>
2413 CZoomPrintPreviewWindowImpl and CZoomPrintPreviewWindow classes<br>
2414 Global functions: AtlGetBitmapResourceInfo,
2415 AtlGetBitmapResourceBitsPerPixel<br>
2416 New REFLECT_* macros to enable selective reflection of messages<br>
2417 App Wizard: Added App Wizard for VS2005<br>
2418 App Wizard: Added App Wizard for Windows CE for VS2005<br>
2419 New samples: WTLExplorer, ImageView, SPControls<br>
2420 &nbsp;</font></p>
2421 </blockquote>
2422 <p style=margin:0in><font face="Arial" size="2">Fixes and enhancements:</font></p>
2423 <blockquote style='margin-top:0in;margin-bottom:0in'>
2424 <p style=margin:0in><font face="Arial" size="2">Command Bar:</font></p>
2425 <ul style='margin-top:0in;margin-bottom:0in'>
2426 <li>
2427 <p style=margin:0in><font face="Arial" size="2">DrawBitmapDisabled()
2428 doesn't work correctly on Longhorn</font></p></li>
2429 <li>
2430 <p style=margin:0in><font face="Arial" size="2">Submenu size not correct if
2431 command bar is off-screen</font></p></li>
2432 <li>
2433 <p style=margin:0in><font face="Arial" size="2">Added handler for
2434 WM_SETTINGCHANGE to improve theme color changes</font></p></li>
2435 <li>
2436 <p style=margin:0in><font face="Arial" size="2">Better support for
2437 8/16/24-bit images</font></p></li>
2438 <li>
2439 <p style=margin:0in><font face="Arial" size="2">Command Bar with 2 Levels of
2440 submenus remains active</font></p></li>
2441 <li>
2442 <p style=margin:0in><font face="Arial" size="2">Hook procedure fails to call
2443 next hook</font></p></li>
2444 <li>
2445 <p style=margin:0in><font face="Arial" size="2">OnDestroy() should not
2446 decrement hook use if AttachToWindow() is used</font></p></li>
2447 </ul>
2448 <p style=margin:0in>&nbsp;</p>
2449 <p style=margin:0in><font face="Arial" size="2">MDI Command Bar:</font></p>
2450 <ul style='margin-top:0in;margin-bottom:0in'>
2451 <li>
2452 <p style=margin:0in><font face="Arial" size="2">Grows bigger if you
2453 switch between two maximized MDI child window types</font></p></li>
2454 <li>
2455 <p style=margin:0in><font face="Arial" size="2">Move all hook messages
2456 processing to a separate function and use pT</font></p></li>
2457 <li>
2458 <p style=margin:0in><font face="Arial" size="2">MDI icon &amp; buttons should
2459 have themed background</font></p></li>
2460 <li>
2461 <p style=margin:0in><font face="Arial" size="2">Should make MDI buttons gray
2462 when inactive<br>&nbsp;</font></p></li>
2463 </ul>
2464 <p style=margin:0in><font face="Arial" size="2">CString:</font></p>
2465 <ul style='margin-top:0in;margin-bottom:0in'>
2466 <li>
2467 <p style=margin:0in><font face="Arial" size="2">Helper functions not
2468 overloaded properly</font></p></li>
2469 <li>
2470 <p style=margin:0in><font face="Arial" size="2">Some return types are
2471 'const CString&amp;' and could be just 'CString&amp;'</font></p></li>
2472 <li>
2473 <p style=margin:0in><font face="Arial" size="2">FormatV() passes size in
2474 characters to _alloca, should be in bytes</font></p></li>
2475 <li>
2476 <p style=margin:0in><font face="Arial" size="2">Fixed stack corruption in
2477 FormatV()</font></p></li>
2478 <li>
2479 <p style=margin:0in><font face="Arial" size="2">Improved boundaries checking
2480 for integer overflows/underflows<br>&nbsp;</font></p></li>
2481 </ul>
2482 <p style=margin:0in><font face="Arial" size="2">CScrollImpl:</font></p>
2483 <ul style='margin-top:0in;margin-bottom:0in'>
2484 <li>
2485 <p style=margin:0in><font face="Arial" size="2">Scroll bars problem when
2486 changing range</font></p></li>
2487 <li>
2488 <p style=margin:0in><font face="Arial" size="2">SetScrollOffset() doesn't
2489 move child windows</font></p></li>
2490 <li>
2491 <p style=margin:0in><font face="Arial" size="2">Range and thumb drawing
2492 problems</font></p></li>
2493 <li>
2494 <p style=margin:0in><font face="Arial" size="2">Possible overflow in
2495 OnMouseWheel()</font></p></li>
2496 <li>
2497 <p style=margin:0in><font face="Arial" size="2">Support for
2498 SIF_DISABLENOSCROLL</font></p></li>
2499 <li>
2500 <p style=margin:0in><font face="Arial" size="2">Added ScrollToView methods</font></p>
2501 </li>
2502 </ul>
2503 <p style=margin:0in>&nbsp;</p>
2504 <p style=margin:0in><font face="Arial" size="2">CMapScrollImpl:</font></p>
2505 <ul style='margin-top:0in;margin-bottom:0in'>
2506 <li>
2507 <p style=margin:0in><font face="Arial" size="2">SetScrollSize() incorrectly
2508 inverts xMin and xMax</font></p></li>
2509 <li>
2510 <p style=margin:0in><font face="Arial" size="2">SetScrollSize() uses bRedraw
2511 = NULL</font></p></li>
2512 </ul>
2513 <p style=margin:0in>&nbsp;</p>
2514 <p style=margin:0in><font face="Arial" size="2">CTheme:</font></p>
2515 <ul style='margin-top:0in;margin-bottom:0in'>
2516 <li>
2517 <p style=margin:0in><font face="Arial" size="2">GetThemeFont() bad parameter
2518 ordering</font></p></li>
2519 <li>
2520 <p style=margin:0in><font face="Arial" size="2">Uses LOGFONT and TEXTMETRIC
2521 incorrectly (SDK header problem)</font></p></li>
2522 </ul>
2523 <p style=margin:0in>&nbsp;</p>
2524 <p style=margin:0in><font face="Arial" size="2">CFrameWindowImpl:</font></p>
2525 <ul style='margin-top:0in;margin-bottom:0in'>
2526 <li>
2527 <p style=margin:0in><font face="Arial" size="2">Improved sizing for Windows
2528 CE</font></p></li>
2529 <li>
2530 <p style=margin:0in><font face="Arial" size="2">CreateSimpleToolBarCtrl()
2531 should handle 24-bit bitmaps</font></p></li>
2532 <li>
2533 <p style=margin:0in><font face="Arial" size="2">Changed WinCE
2534 CCECommandBarCtrl typedef and added a PPC CMenuBarCtrl</font></p></li>
2535 <li>
2536 <p style=margin:0in><font face="Arial" size="2">UpdatesBarPosition() doesn't
2537 take Windows CE command bar into account</font></p></li>
2538 </ul>
2539 <p style=margin:0in>&nbsp;</p>
2540 <p style=margin:0in><font face="Arial" size="2">CDialogResize:</font></p>
2541 <ul style='margin-top:0in;margin-bottom:0in'>
2542 <li>
2543 <p style=margin:0in><font face="Arial" size="2">Enabled use for Windows CE</font></p>
2544 </li>
2545 <li>
2546 <p style=margin:0in><font face="Arial" size="2">Add WS_EX_DLGMODALFRAME to
2547 prevent empty icon</font></p></li>
2548 </ul>
2549 <p style=margin:0in>&nbsp;</p>
2550 <p style=margin:0in><font face="Arial" size="2">CReBarCtrl:</font></p>
2551 <ul style='margin-top:0in;margin-bottom:0in'>
2552 <li>
2553 <p style=margin:0in><font face="Arial" size="2">Background not painted when
2554 resized</font></p></li>
2555 <li>
2556 <p style=margin:0in><font face="Arial" size="2">Fixed typo in LockBands()</font></p>
2557 </li>
2558 <li>
2559 <p style=margin:0in><font face="Arial" size="2">MaximizeBand needs BOOL
2560 fIdeal argument</font></p></li>
2561 </ul>
2562 <p style=margin:0in>&nbsp;</p>
2563 <p style=margin:0in><font face="Arial" size="2">CRichEdit:</font></p>
2564 <ul style='margin-top:0in;margin-bottom:0in'>
2565 <li>
2566 <p style=margin:0in><font face="Arial" size="2">GetSelText() should
2567 support UNICODE strings</font></p>
2568 </li>
2569 <li>
2570 <p style=margin:0in><font face="Arial" size="2">GetSelText() uses lpstr instead of lpstrText</font></p></li>
2571 </ul>
2572 <p style=margin:0in>&nbsp;</p>
2573 <p style=margin:0in><font face="Arial" size="2">CHyperLink:</font></p>
2574 <ul style='margin-top:0in;margin-bottom:0in'>
2575 <li>
2576 <p style=margin:0in><font face="Arial" size="2">Added _xttoi() helper to
2577 avoid CRT in _ATL_MIN_CRT</font></p></li>
2578 <li>
2579 <p style=margin:0in><font face="Arial" size="2">Fixed resource leak by
2580 destroying tooltip window<br>&nbsp;</font></p></li>
2581 </ul>
2582 <p style=margin:0in><font face="Arial" size="2">CPropertySheetImpl:</font></p>
2583 <ul style='margin-top:0in;margin-bottom:0in'>
2584 <li>
2585 <p style=margin:0in><font face="Arial" size="2">Improved support for Windows
2586 CE</font></p></li>
2587 <li>
2588 <p style=margin:0in><font face="Arial" size="2">Sheet without title
2589 generates a memory fault on Windows CE</font></p></li>
2590 </ul>
2591 <p style=margin:0in>&nbsp;</p>
2592 <p style=margin:0in><font face="Arial" size="2">CFolderDialog:</font></p>
2593 <ul style='margin-top:0in;margin-bottom:0in'>
2594 <li>
2595 <p style=margin:0in><font face="Arial" size="2">Add a way to set an initial
2596 folder</font></p></li>
2597 <li>
2598 <p style=margin:0in><font face="Arial" size="2">Uses BFFM_IUNKNOWN which is
2599 not always defined</font></p></li>
2600 </ul>
2601 <p style=margin:0in>&nbsp;</p>
2602 <p style=margin:0in><font face="Arial" size="2">Update UI:</font></p>
2603 <ul style='margin-top:0in;margin-bottom:0in'>
2604 <li>
2605 <p style=margin:0in><font face="Arial" size="2">Add support to
2606 dynamically add UpdateUI elements</font></p></li>
2607 <li>
2608 <p style=margin:0in><font face="Arial" size="2">UIUpdateMenuBarElement()
2609 should use EnableMenu() instead of SetMenuItemInfo() for Windows CE</font></p>
2610 </li>
2611 </ul>
2612 <p style=margin:0in>&nbsp;</p>
2613 <p style=margin:0in><font face="Arial" size="2">CDC:</font></p>
2614 <ul style='margin-top:0in;margin-bottom:0in'>
2615 <li>
2616 <p style=margin:0in><font face="Arial" size="2">FillSolidRect() should
2617 restore background color</font></p></li>
2618 <li>
2619 <p style=margin:0in><font face="Arial" size="2">GetClipRgn() method
2620 missing</font></p></li>
2621 </ul>
2622 <p style=margin:0in>&nbsp;</p>
2623 <p style=margin:0in><font face="Arial" size="2">Printing:</font></p>
2624 <ul style='margin-top:0in;margin-bottom:0in'>
2625 <li>
2626 <p style=margin:0in><font face="Arial" size="2">
2627 CPrinter::CreatePrinterDC() and CreatePrinterIC() members should be
2628 const</font></p></li>
2629 <li>
2630 <p style=margin:0in><font face="Arial" size="2">CDevMode::CopyToHDEVMODE() is missing a call to GlobalUnlock()</font></p>
2631 </li>
2632 </ul>
2633 <p style=margin:0in>&nbsp;</p>
2634 <p style=margin:0in><font face="Arial" size="2">AppWizard:</font></p>
2635 <ul style='margin-top:0in;margin-bottom:0in'>
2636 <li>
2637 <p style=margin:0in><font face="Arial" size="2">Use WTL subfolder to
2638 create WTL category for VC7.x and VC8</font></p></li>
2639 <li>
2640 <p style=margin:0in><font face="Arial" size="2">Rename files from
2641 WTLApp7x to WTLAppWiz, and add VS2005 setup file</font></p></li>
2642 <li>
2643 <p style=margin:0in><font face="Arial" size="2">Fixed setup
2644 for x64</font></p></li>
2645 </ul>
2646 <p style=margin:0in>&nbsp;</p>
2647 <p style=margin:0in><font face="Arial" size="2">General:</font></p>
2648 <ul style='margin-top:0in;margin-bottom:0in'>
2649 <li>
2650 <p style=margin:0in><font face="Arial" size="2">Redefinition of _MAX_FNAME
2651 with Dinkumware Standard C++ Library on Windows CE</font></p></li>
2652 <li>
2653 <p style=margin:0in><font face="Arial" size="2">Added ATLVERIFY macro
2654 for ATL3</font></p></li>
2655 <li>
2656 <p style=margin:0in><font face="Arial" size="2">Support warning level 4</font></p>
2657 </li>
2658 <li>
2659 <p style=margin:0in><font face="Arial" size="2">Missing methods
2660 CToolBarCtrl::SetButtonInfo, InsertButton, CTabCtrl::SetItem,
2661 CComboBoxEx::InsertItem, SetItem</font></p></li>
2662 <li>
2663 <p style=margin:0in><font face="Arial" size="2">Missing support for
2664 WM_PRINTCLIENT</font></p></li>
2665 <li>
2666 <p style=margin:0in><font face="Arial" size="2">Removed usage of IsBad*
2667 functions</font></p></li>
2668 <li>
2669 <p style=margin:0in><font face="Arial" size="2">Fixed various compiler
2670 warnings</font></p></li>
2671 <li>
2672 <p style=margin:0in><font face="Arial" size="2">TCHAR bugs in various
2673 files</font></p></li>
2674 <li>
2675 <p style=margin:0in><font face="Arial" size="2">Improved Windows CE support and changes for Visual Studio 2005</font></p></li>
2676 </ul>
2677 <p style=margin:0in>&nbsp;</p>
2678 <p style=margin:0in><font face="Arial" size="2">Misc:</font></p>
2679 <ul style='margin-top:0in;margin-bottom:0in'>
2680 <li>
2681 <p style=margin:0in><font face="Arial" size="2">CMDIChildWindowImpl:
2682 HMENU should be destroyed in OnDestroy()</font></p>
2683 </li>
2684 <li>
2685 <p style=margin:0in><font face="Arial" size="2">CStatic: Should use
2686 STM_SETIMAGE instead of STM_SETICON for SetIcon() on Windows CE</font></p>
2687 </li>
2688 <li>
2689 <p style=margin:0in><font face="Arial" size="2">CButton: GetButtonStyle()
2690 uses wrong mask</font></p></li>
2691 <li>
2692 <p style=margin:0in><font face="Arial" size="2">CImageList: Made
2693 Duplicate() method const</font></p></li>
2694 <li>
2695 <p style=margin:0in><font face="Arial" size="2">CListViewCtrl: Made
2696 SubItemHitTest() method const</font></p></li>
2697 <li>
2698 <p style=margin:0in><font face="Arial" size="2">CTreeViewCtrl: GetItem()
2699 and SetItem() incorrectly restricted to _WIN32_IE &gt;= 0x0500</font></p>
2700 </li>
2701 <li>
2702 <p style=margin:0in><font face="Arial" size="2">CMonthCalendarCtrl:
2703 GetMonthRange() should be GetMaxTodayWidth()</font></p></li>
2704 <li>
2705 <p style=margin:0in><font face="Arial" size="2">CDateTimePickerCtrl:
2706 SetFormat() should have const argument</font></p></li>
2707 <li>
2708 <p style=margin:0in><font face="Arial" size="2">CBitmapButtonImpl: Fixed
2709 resource leak by destroying tooltip window</font></p></li>
2710 <li>
2711 <p style=margin:0in><font face="Arial" size="2">
2712 CMultiPaneStatusBarCtrlImpl: Cannot handle wide panes without resource
2713 strings</font></p></li>
2714 <li>
2715 <p style=margin:0in><font face="Arial" size="2">CCheckListViewCtrlImpl:
2716 Call CheckSelectedItems() through pT</font></p></li>
2717 <li>
2718 <p style=margin:0in><font face="Arial" size="2">CPaneContainerImpl:
2719 SetPaneContainerExtendedStyle() should use pT to call CalcSize()</font></p></li>
2720 <li>
2721 <p style=margin:0in><font face="Arial" size="2">CFindFile: Enabled for
2722 Windows CE</font></p></li>
2723 <li>
2724 <p style=margin:0in><font face="Arial" size="2">CPropertyPageImpl: Added
2725 handlers for callback messages</font></p></li>
2726 <li>
2727 <p style=margin:0in><font face="Arial" size="2">atlcrack.h: Added return
2728 value for MSG_WM_APPCOMMAND</font></p></li>
2729 <li>
2730 <p style=margin:0in><font face="Arial" size="2">CMenu: New method variants: AppendMenu, InsterMenu, ModifyMenu</font></p></li>
2731 <li>
2732 <p style=margin:0in><font face="Arial" size="2">CFont: Added arguments
2733 for bold and italic to CreatePointFont()</font></p></li>
2734 <li>
2735 <p style=margin:0in><font face="Arial" size="2">CSize: Added scalar
2736 operators for WTL::CSize and ATL::CSize</font></p></li>
2737 <li>
2738 <p style=margin:0in><font face="Arial" size="2">CRecentDocumentList:
2739 Allow changing the &quot;DocumentCount&quot; and &quot;Document%i&quot; registry values
2740 strings</font></p></li>
2741 <li>
2742 <p style=margin:0in><font face="Arial" size="2">CSplitterWindowImpl:
2743 Enabled use for Windows CE</font></p></li>
2744 </ul>
2745 </blockquote>
2746 <p style=margin:0in><br>
2747 &nbsp;</p>
2748 <p style=margin:0in><b><font face="Arial">
2749 <a name="Changes Between WTL 7.1 and 7.0"></a>Changes Between WTL 7.1 and 7.0</font></b></p>
2750 <p style=margin:0in>&nbsp;</p>
2751 <p style=margin:0in><font face="Arial" size="2">New and improved:</font></p>
2752 <blockquote style='margin-top:0in;margin-bottom:0in'>
2753 <p style=margin:0in><font face="Arial" size="2">VC7 Compatibility: Support for
2754 ATL7 Module classes and critical sections and AppWizard setup for VC++ 7.1</font></p>
2755 <p style=margin:0in><font face="Arial" size="2">Windows CE Support: Full
2756 compatibility with Windows CE platforms and AppWizard for eMbedded Visual C++</font></p>
2757 <p style=margin:0in><font face="Arial" size="2">Namespace Support: Automatic
2758 &quot;using ATL&quot; (ATL7 only) or &quot;using WTL&quot; can now be turned off</font></p>
2759 <p style=margin:0in><font face="Arial" size="2">CHyperLink New Features: not
2760 underlined, underlined when hover, command button, link tags</font></p>
2761 <p style=margin:0in><font face="Arial" size="2">CCustomWaitCursor class
2762 supports custom and animated wait cursors</font></p>
2763 <p style=margin:0in><font face="Arial" size="2">AtlCreateBoldFont() for
2764 creating bold version of an existing font</font></p>
2765 </blockquote>
2766 <p style=margin:0in>&nbsp;</p>
2767 <p style=margin:0in><font face="Arial" size="2">Fixes and enhancements:</font></p>
2768 <blockquote style='margin-top:0in;margin-bottom:0in'>
2769 <p style=margin:0in><font face="Arial" size="2">CFrameWindowImpl:</font></p>
2770 <ul style='margin-top:0in;margin-bottom:0in'>
2771 <li>
2772 <p style=margin:0in><font face="Arial" size="2">CreateSimpleToolBarCtrl() -
2773 remove dead code, improve error checking, add a global function that uses it</font></p>
2774 </li>
2775 <li>
2776 <p style=margin:0in><font face="Arial" size="2">Fix - PrepareChevronMenu() fails to
2777 get toolbar strings for Unicode</font></p>
2778 </li>
2779 <li>
2780 <p style=margin:0in><font face="Arial" size="2">CFrameWindowImplBase::Create()
2781 - improve ASSERT not to use m_hWnd if creation fails</font></p>
2782 </li>
2783 <li>
2784 <p style=margin:0in><font face="Arial" size="2">Fix - CFrameWndClassInfo::Register -
2785 should use %p formatting only for _WIN32_WINNT &gt;= 0x0500 or for _WIN64</font></p>
2786 </li>
2787 <li>
2788 <p style=margin:0in><font face="Arial" size="2">Fix - Chevron menus not positioned
2789 correctly with RTL</font></p>
2790 </li>
2791 <li>
2792 <p style=margin:0in><font face="Arial" size="2">Fix - CMDIChildWindowImpl: Problems
2793 creating maximized child windows and handling focus</font></p>
2794 </li>
2795 <li>
2796 <p style=margin:0in><font face="Arial" size="2">Fix - CMDIChildWindowImpl: Should
2797 activate on WM_MOUSEACTIVATE</font></p>
2798 </li>
2799 </ul>
2800 <p style=margin:0in>&nbsp;</p>
2801 <p style=margin:0in><font face="Arial" size="2">UpdateUI:</font></p>
2802 <ul style='margin-top:0in;margin-bottom:0in'>
2803 <li>
2804 <p style=margin:0in><font face="Arial" size="2">Fix - Incorrectly clears default
2805 item from the system menu in MDI apps</font></p>
2806 </li>
2807 <li>
2808 <p style=margin:0in><font face="Arial" size="2">Added UISetCheck with bool
2809 instead of int for the check state</font></p>
2810 </li>
2811 </ul>
2812 <p style=margin:0in>&nbsp;</p>
2813 <p style=margin:0in><font face="Arial" size="2">DDX:</font></p>
2814 <ul style='margin-top:0in;margin-bottom:0in'>
2815 <li>
2816 <p style=margin:0in><font face="Arial" size="2">Fix - Doesn't provide a way to
2817 change floating point precision</font></p>
2818 </li>
2819 <li>
2820 <p style=margin:0in><font face="Arial" size="2">Added DDX_CONTROL_HANDLE for
2821 non-CWindowImpl objects</font></p>
2822 </li>
2823 <li>
2824 <p style=margin:0in><font face="Arial" size="2">Added DDX_Check variant with
2825 bool instead of int for the check state</font></p>
2826 </li>
2827 </ul>
2828 <p style=margin:0in>&nbsp;</p>
2829 <p style=margin:0in><font face="Arial" size="2">Command Bar:</font></p>
2830 <ul style='margin-top:0in;margin-bottom:0in'>
2831 <li>
2832 <p style=margin:0in><font face="Arial" size="2">Fix - OnDrawItem() and OnMeasureItem()
2833 don't do a good check for owner-draw menu items</font></p>
2834 </li>
2835 <li>
2836 <p style=margin:0in><font face="Arial" size="2">Fix - Disabled 32-bit images not
2837 painted correctly in 3D menu mode</font></p>
2838 </li>
2839 <li>
2840 <p style=margin:0in><font face="Arial" size="2">Fix - Popup menus not positioned
2841 correctly with RTL</font></p>
2842 </li>
2843 <li>
2844 <p style=margin:0in><font face="Arial" size="2">Fix - Uses GCL_HICONSM instead of
2845 GCLP_HICONSM with GetClassLongPtr()</font></p>
2846 </li>
2847 </ul>
2848 <p style=margin:0in>&nbsp;</p>
2849 <p style=margin:0in><font face="Arial" size="2">MDI Command Bar:</font></p>
2850 <ul style='margin-top:0in;margin-bottom:0in'>
2851 <li>
2852 <p style=margin:0in><font face="Arial" size="2">Fix - Doesn't refresh icon if MDI
2853 children are different</font></p>
2854 </li>
2855 <li>
2856 <p style=margin:0in><font face="Arial" size="2">OnAllHookMessages() - improve
2857 code to handle MDI child window class icon</font></p>
2858 </li>
2859 <li>
2860 <p style=margin:0in><font face="Arial" size="2">Fix - OnNcLButtonDown() uses
2861 TPM_VERPOSANIMATION without checking Windows version</font></p>
2862 </li>
2863 <li>
2864 <p style=margin:0in><font face="Arial" size="2">Fix - Maximized MDI buttons in wrong
2865 place for RTL</font></p>
2866 </li>
2867 <li>
2868 <p style=margin:0in><font face="Arial" size="2">Should adjust cxIdeal for
2869 rebar bands for IE4</font></p>
2870 </li>
2871 <li>
2872 <p style=margin:0in><font face="Arial" size="2">Add support for different
2873 top-level menu widths by handling ideal size for rebar bands</font></p>
2874 </li>
2875 </ul>
2876 <p style=margin:0in>&nbsp;</p>
2877 <p style=margin:0in><font face="Arial" size="2">AppWizard:</font></p>
2878 <ul style='margin-top:0in;margin-bottom:0in'>
2879 <li>
2880 <p style=margin:0in><font face="Arial" size="2">Fix - Doesn't support MSDI
2881 application as a COM Server</font></p>
2882 </li>
2883 <li>
2884 <p style=margin:0in><font face="Arial" size="2">Fix - MDI with Form View - stack
2885 overflow closing maximized MDI child windows</font></p>
2886 </li>
2887 <li>
2888 <p style=margin:0in><font face="Arial" size="2">Fix - Generates VERSION resource
2889 name 'test1' regardless of the project name</font></p>
2890 </li>
2891 <li>
2892 <p style=margin:0in><font face="Arial" size="2">Fix - Dialog project with control
2893 hosting doesn't derive a dialog from CAxDialogImpl</font></p>
2894 </li>
2895 <li>
2896 <p style=margin:0in><font face="Arial" size="2">Fix - COM Server doesn't register
2897 type library</font></p>
2898 </li>
2899 <li>
2900 <p style=margin:0in><font face="Arial" size="2">Fix - COM Server doesn't register
2901 AppID properly</font></p>
2902 </li>
2903 </ul>
2904 <p style=margin:0in>&nbsp;</p>
2905 <p style=margin:0in><font face="Arial" size="2">CTreeViewCtrl:</font></p>
2906 <ul style='margin-top:0in;margin-bottom:0in'>
2907 <li>
2908 <p style=margin:0in><font face="Arial" size="2">Fix - GetItemData() needs better
2909 return value</font></p>
2910 </li>
2911 <li>
2912 <p style=margin:0in><font face="Arial" size="2">Fix - GetItemState() should use
2913 TVM_GETITEMSTATE instead of TVM_GETITEM for IE5</font></p>
2914 </li>
2915 <li>
2916 <p style=margin:0in><font face="Arial" size="2">GetItem() and SetItem() -
2917 added
2918 new variants that use TVITEMEX</font></p>
2919 </li>
2920 <li>
2921 <p style=margin:0in><font face="Arial" size="2">Fix - SortChildren() should add
2922 recurse flag argument</font></p>
2923 </li>
2924 <li>
2925 <p style=margin:0in><font face="Arial" size="2">Fix - CTreeItem doesn't support
2926 CTreeViewCtrlExT that has different TBase than CWindow</font></p>
2927 </li>
2928 </ul>
2929 <p style=margin:0in>&nbsp;</p>
2930 <p style=margin:0in><font face="Arial" size="2">CThemeImpl:</font></p>
2931 <ul style='margin-top:0in;margin-bottom:0in'>
2932 <li>
2933 <p style=margin:0in><font face="Arial" size="2">Fix - Uses scalar delete instead of
2934 the vector one</font></p>
2935 </li>
2936 <li>
2937 <p style=margin:0in><font face="Arial" size="2">Fix - EnableThemeDialogTexture()
2938 argument is BOOL instead of DWORD</font></p>
2939 </li>
2940 </ul>
2941 <p style=margin:0in>&nbsp;</p>
2942 <p style=margin:0in><font face="Arial" size="2">CFolderDialog:</font></p>
2943 <ul style='margin-top:0in;margin-bottom:0in'>
2944 <li>
2945 <p style=margin:0in><font face="Arial" size="2">Fix - EnableOK() passes wrong
2946 arguments to BFFM_ENABLEOK</font></p>
2947 </li>
2948 <li>
2949 <p style=margin:0in><font face="Arial" size="2">Fix - Always clears m_hWnd, which
2950 causes problem for nested messages</font></p>
2951 </li>
2952 </ul>
2953 <p style=margin:0in>&nbsp;</p>
2954 <p style=margin:0in><font face="Arial" size="2">CDialogResize:</font></p>
2955 <ul style='margin-top:0in;margin-bottom:0in'>
2956 <li>
2957 <p style=margin:0in><font face="Arial" size="2">Fix - DlgResize_Init() forces dialog
2958 to be visible by using SetRedraw()</font></p>
2959 </li>
2960 <li>
2961 <p style=margin:0in><font face="Arial" size="2">Forcing WS_THICKFRAME is not
2962 enough to make dialog resizable</font></p>
2963 </li>
2964 <li>
2965 <p style=margin:0in><font face="Arial" size="2">Min track size should be used
2966 for child dialogs as well</font></p>
2967 </li>
2968 <li>
2969 <p style=margin:0in><font face="Arial" size="2">Fix - DlgResize_PositionControl()
2970 incorrectly checks return value from MapWindowPoints()</font></p>
2971 </li>
2972 </ul>
2973 <p style=margin:0in>&nbsp;</p>
2974 <p style=margin:0in><font face="Arial" size="2">CAppModule:</font></p>
2975 <ul style='margin-top:0in;margin-bottom:0in'>
2976 <li>
2977 <p style=margin:0in><font face="Arial" size="2">Fix - CAppModule methods not
2978 thread-safe</font></p>
2979 </li>
2980 <li>
2981 <p style=margin:0in><font face="Arial" size="2">Fix - AddSettingChangeNotify()
2982 unusable in multithreaded apps because of delayed initialization</font></p>
2983 </li>
2984 </ul>
2985 <p style=margin:0in>&nbsp;</p>
2986 <p style=margin:0in><font face="Arial" size="2">CString:</font></p>
2987 <ul style='margin-top:0in;margin-bottom:0in'>
2988 <li>
2989 <p style=margin:0in><font face="Arial" size="2">Fix - Delete() doesn't allow
2990 deleting more than the length of the string</font></p>
2991 </li>
2992 <li>
2993 <p style=margin:0in><font face="Arial" size="2">Fix - Append() can cause buffer
2994 overrun</font></p>
2995 </li>
2996 <li>
2997 <p style=margin:0in><font face="Arial" size="2">Fix - MakeReverse() can cause an
2998 infinite loop</font></p>
2999 </li>
3000 <li>
3001 <p style=margin:0in><font face="Arial" size="2">Fix - _cstrstr() unnecessarily
3002 inefficient</font></p>
3003 </li>
3004 <li>
3005 <p style=margin:0in><font face="Arial" size="2">Fix - FindOneOf() is not DBCS-aware</font></p>
3006 </li>
3007 <li>
3008 <p style=margin:0in><font face="Arial" size="2">Fix - Format() does not recognize %E</font></p>
3009 </li>
3010 <li>
3011 <p style=margin:0in><font face="Arial" size="2">Fix - TrimLeft() and TrimRight() are
3012 only half-way DBCS-aware</font></p>
3013 </li>
3014 <li>
3015 <p style=margin:0in><font face="Arial" size="2">Fix - May cause assertions or
3016 undefined behavior with SBCS</font></p>
3017 </li>
3018 </ul>
3019 <p style=margin:0in>&nbsp;</p>
3020 <p style=margin:0in><font face="Arial" size="2">CRecentDocumentList:</font></p>
3021 <ul style='margin-top:0in;margin-bottom:0in'>
3022 <li>
3023 <p style=margin:0in><font face="Arial" size="2">Fix - SetMaxEntries() has an
3024 incorrect ASSERT</font></p>
3025 </li>
3026 <li>
3027 <p style=margin:0in><font face="Arial" size="2">Add CString variant of the
3028 GetFromList() method</font></p>
3029 </li>
3030 <li>
3031 <p style=margin:0in><font face="Arial" size="2">Add a way to replace command
3032 IDs used for the MRU list</font></p>
3033 </li>
3034 <li>
3035 <p style=margin:0in><font face="Arial" size="2">Add a way to replace registry
3036 key name</font></p>
3037 </li>
3038 </ul>
3039 <p style=margin:0in>&nbsp;</p>
3040 <p style=margin:0in><font face="Arial" size="2">Misc:</font></p>
3041 <ul style='margin-top:0in;margin-bottom:0in'>
3042 <li>
3043 <p style=margin:0in><font face="Arial" size="2">CMessageLoop::Run() - improve
3044 the loop by checking bDoIdle before calling PeekMessage()</font></p>
3045 </li>
3046 <li>
3047 <p style=margin:0in><font face="Arial" size="2">CServerAppModule: Clean-up
3048 unused code</font></p>
3049 </li>
3050 <li>
3051 <p style=margin:0in><font face="Arial" size="2">Fix - CServerAppModule::MonitorProc()
3052 - no need to call _endthreadex()</font></p>
3053 </li>
3054 <li>
3055 <p style=margin:0in><font face="Arial" size="2">Fix - CListBox::GetText() and
3056 CComboBox::GetLBText() (CString variants) don't check for LBERR/CB_ERR</font></p>
3057 </li>
3058 <li>
3059 <p style=margin:0in><font face="Arial" size="2">Fix - CAxPropertyPageImpl doesn't
3060 create ActiveX controls with ATL7</font></p>
3061 </li>
3062 <li>
3063 <p style=margin:0in><font face="Arial" size="2">Fix - CDC::GetTextExtentExPoint()
3064 missing</font></p>
3065 </li>
3066 <li>
3067 <p style=margin:0in><font face="Arial" size="2">CDC::SetWindowExt() should
3068 have default value NULL for the lpSizeRet argument</font></p>
3069 </li>
3070 <li>
3071 <p style=margin:0in><font face="Arial" size="2">Fix - CPropertySheetWindow missing
3072 methods for PSM_INSERTPAGE, PSM_SETHEADERTITLE, and PSM_SETHEADERSUBTITLE;
3073 AddPage should return BOOL</font></p>
3074 </li>
3075 <li>
3076 <p style=margin:0in><font face="Arial" size="2">Fix - CMapScrollImpl::SetScrollSize()
3077 uses wrong variable</font></p>
3078 </li>
3079 <li>
3080 <p style=margin:0in><font face="Arial" size="2">Fix - CHyperLink: WM_UPDATEUISTATE
3081 causes repaint without WM_PAINT</font></p>
3082 </li>
3083 <li>
3084 <p style=margin:0in><font face="Arial" size="2">Fix - CUpDownCtrl::GetPos() returns
3085 incorrect value</font></p>
3086 </li>
3087 <li>
3088 <p style=margin:0in><font face="Arial" size="2">Fix - CUpDownCtrl::GetPos32()
3089 doesn't have default arg value</font></p>
3090 </li>
3091 <li>
3092 <p style=margin:0in><font face="Arial" size="2">Fix - CMultiPaneStatusBarCtrl:
3093 Always uses size grip for positioning panes</font></p>
3094 </li>
3095 <li>
3096 <p style=margin:0in><font face="Arial" size="2">Fix - CTabCtrl::InsertItem() should
3097 return int, not BOOL</font></p>
3098 </li>
3099 <li>
3100 <p style=margin:0in><font face="Arial" size="2">CReBarCtrl: Added LockBands()
3101 method</font></p>
3102 </li>
3103 <li>
3104 <p style=margin:0in><font face="Arial" size="2">Fix - CFont: uninitialized variable
3105 passed to DPtoLP</font></p>
3106 </li>
3107 <li>
3108 <p style=margin:0in><font face="Arial" size="2">Fix - CPrintDialogImpl: Crash when
3109 displaying Print Setup dialog</font></p>
3110 </li>
3111 <li>
3112 <p style=margin:0in><font face="Arial" size="2">Fix -
3113 CPageSetupDialogImpl::PaintHookProc() - should use T* and return UINT_PTR
3114 instead of UINT</font></p>
3115 </li>
3116 <li>
3117 <p style=margin:0in><font face="Arial" size="2">Fix - CPrintJob doesn't support
3118 printing to a file</font></p>
3119 </li>
3120 <li>
3121 <p style=margin:0in><font face="Arial" size="2">Fix - CSplitterImpl: Doesn't handle
3122 WM_CAPTURECHANGED - can get in an invalid state</font></p>
3123 </li>
3124 <li>
3125 <p style=margin:0in><font face="Arial" size="2">CRichEditCtrl: Add method for
3126 EM_SETTABSTOPS</font></p>
3127 </li>
3128 <li>
3129 <p style=margin:0in><font face="Arial" size="2">Fix - CFindFile::GetFilePath()
3130 checks for a trailing slash, but doesn't use that info</font></p>
3131 </li>
3132 </ul>
3133 <p style=margin:0in>&nbsp;</p>
3134 <p style=margin:0in><font face="Arial" size="2">General:</font></p>
3135 <ul style='margin-top:0in;margin-bottom:0in'>
3136 <li>
3137 <p style=margin:0in><font face="Arial" size="2">Fix - Problems compiling with /Zc:forScope
3138 ('for' loop scope conformance)</font></p>
3139 </li>
3140 <li>
3141 <p style=margin:0in><font face="Arial" size="2">Use named constants instead of
3142 values for pixel sizes, buffer lengths, etc.</font></p>
3143 </li>
3144 <li>
3145 <p style=margin:0in><font face="Arial" size="2">Support building with Managed
3146 C++ (/CLR)</font></p>
3147 </li>
3148 <li>
3149 <p style=margin:0in><font face="Arial" size="2">CMenuItemInfo - add run-time
3150 support for different versions of Windows</font></p>
3151 </li>
3152 <li>
3153 <p style=margin:0in><font face="Arial" size="2">CommCtrl.h change - additional
3154 fields in IMAGELISTDRAWPARAMS now depend on _WIN32_IE instead of _WIN32_WINNT</font></p>
3155 </li>
3156 <li>
3157 <p style=margin:0in><font face="Arial" size="2">Fix - Incorrect usage of CRegKey::QueryStringValue()</font></p>
3158 </li>
3159 <li>
3160 <p style=margin:0in><font face="Arial" size="2">Fix - Operator = for GDI and USER
3161 wrappers leaks handle if it's managed variant</font></p>
3162 </li>
3163 <li>
3164 <p style=margin:0in><font face="Arial" size="2">Fix - GDI and USER wrappers break
3165 under self-assignments</font></p>
3166 </li>
3167 <li>
3168 <p style=margin:0in><font face="Arial" size="2">Fix - Chaining messages with cracked
3169 handlers broken with ATL7</font></p>
3170 </li>
3171 <li>
3172 <p style=margin:0in><font face="Arial" size="2">Initialize all variables and
3173 structures prior to use</font></p>
3174 </li>
3175 <li>
3176 <p style=margin:0in><font face="Arial" size="2">Use new common control struct
3177 names</font></p>
3178 </li>
3179 </ul>
3180 </blockquote>
3181 <p style=margin:0in>&nbsp;</p>
3182 <p style=margin:0in>&nbsp;</p>
3183 <p style=margin:0in><b><font face="Arial">
3184 <a name="Changes Between WTL 7.0 and 3.1"></a>Changes Between WTL 7.0 and 3.1</font></b></p>
3185 <p style=margin:0in>&nbsp;</p>
3186 <p style=margin:0in><font face="Arial" size="2">New classes and features:</font></p>
3187 <blockquote style='margin-top:0in;margin-bottom:0in'>
3188 <p style=margin:0in><font face="Arial" size="2">Support for new Common Controls v6 messages</font></p>
3189 <p style=margin:0in><font face="Arial" size="2">Support for Visual Studio .NET and ATL 7.0</font></p>
3190 <p style=margin:0in><font face="Arial" size="2">WTLApp70 - new AppWizard for Visual Studio
3191 .NET</font></p>
3192 <p style=margin:0in><font face="Arial" size="2">CThemeImpl - implements support for Windows XP
3193 themes</font></p>
3194 <p style=margin:0in><font face="Arial" size="2">CMDICommandBarCtrl - implements Command Bar for
3195 MDI applications</font></p>
3196 </blockquote>
3197 <p style=margin:0in>&nbsp;</p>
3198 <p style=margin:0in><font face="Arial" size="2">Fixes and enhancements:</font></p>
3199 <blockquote style='margin-top:0in;margin-bottom:0in'>
3200 <p style=margin:0in><font face="Arial" size="2">Command Bar:</font></p>
3201 <ul style='margin-top:0in;margin-bottom:0in'>
3202 <li><font face="Arial" size="2">Bogus assert in OnDestroy</font></li>
3203 <li><font face="Arial" size="2">Check marks can be truncated in large font
3204 settings</font></li>
3205 <li><font face="Arial" size="2">Use pT to access GetSystemSettings,
3206 DrawMenuText, DrawBitmapDisabled, Draw3DCheckmark, DoPopupMenu,
3207 DoTrackPopupMenu, TakeFocus, GiveFocusBack, so they can be overridden</font></li>
3208 <li><font face="Arial" size="2">No hot-tracking if main window is not active</font></li>
3209 <li><font face="Arial" size="2">Top level items not painted inactive if app
3210 looses activation while drop down menu is displayed</font></li>
3211 <li><font face="Arial" size="2">Added Windows XP flat menus support</font></li>
3212 <li><font face="Arial" size="2">Drop-down menu doesn't close if clicked
3213 again (Windows XP only)</font></li>
3214 <li><font face="Arial" size="2">Menu item text and accelerator text too
3215 close with some settings</font></li>
3216 <li><font face="Arial" size="2">Keyboard can still access clipped menu items</font></li>
3217 <li><font face="Arial" size="2">Added support for hiding keyboard navigation
3218 indicators until Alt key is pressed (system setting)</font></li>
3219 <li><font face="Arial" size="2">Added AddIcon and ReplaceIcon variants for
3220 icon resources</font></li>
3221 <li><font face="Arial" size="2">Image size calculated differently in
3222 different places</font></li>
3223 <li><font face="Arial" size="2">Add support for 32-bit (alpha channel)
3224 bitmaps for Windows XP</font></li>
3225 <li><font face="Arial" size="2">Fixed width calculation for default menu
3226 items</font></li>
3227 </ul>
3228 <p style=margin:0in>&nbsp;</p>
3229 <p style=margin:0in><font face="Arial" size="2">CFrameWindowImpl:</font></p>
3230 <ul style='margin-top:0in;margin-bottom:0in'>
3231 <li><font face="Arial" size="2">AddSimpleReBarBandCtrl sets toolbar extended
3232 styles without preserving old ones</font></li>
3233 <li><font face="Arial" size="2">PrepareChevronMenu should not create menu
3234 items for buttons with TBSTATE_HIDDEN</font></li>
3235 <li><font face="Arial" size="2">TPM_VERPOSANIMATION will not be defined in
3236 atlframe.h if atlctrlw.h is included first</font></li>
3237 <li><font face="Arial" size="2">CreateSimpleToolBarCtrl - height might be
3238 too small if large font is used</font></li>
3239 <li><font face="Arial" size="2">PrepareChevronMenu uses TB_GETBUTTONTEXT,
3240 better use TB_GETBUTTONINFO</font></li>
3241 <li><font face="Arial" size="2">Chevron menu doesn't close if clicked again
3242 (Windows XP only)</font></li>
3243 <li><font face="Arial" size="2">Should check local classes for superclassing</font></li>
3244 <li><font face="Arial" size="2">Add support for 32-bit (alpha channel)
3245 bitmaps for Windows XP</font></li>
3246 </ul>
3247 <p style=margin:0in>&nbsp;</p>
3248 <p style=margin:0in><font face="Arial" size="2">Update UI:</font></p>
3249 <ul style='margin-top:0in;margin-bottom:0in'>
3250 <li><font face="Arial" size="2">UISetText can clear other menu item flags</font></li>
3251 <li><font face="Arial" size="2">CUpdateUI::UIUpdateState assigns value with
3252 |= instead of =</font></li>
3253 <li><font face="Arial" size="2">Added UISetDefault() and fix default state
3254 to work with menus</font></li>
3255 </ul>
3256 <p style=margin:0in>&nbsp;</p>
3257 <p style=margin:0in><font face="Arial" size="2">CString:</font></p>
3258 <ul style='margin-top:0in;margin-bottom:0in'>
3259 <li><font face="Arial" size="2">GetBuffer() and GetBufferSetLength() should
3260 return NULL in out-of-memory condition</font></li>
3261 <li><font face="Arial" size="2">Added missing methods: separate c-tors for
3262 LPCSTR and LPCWSTR, CollateNoCase, TrimRight and TrimLeft variants, Find
3263 variants, moved FormatV to public</font></li>
3264 <li><font face="Arial" size="2">Fix _IsValidString usage</font></li>
3265 <li><font face="Arial" size="2">FormatV incorrectly calculates buffer size
3266 (too big)</font></li>
3267 <li><font face="Arial" size="2">Usage of _ttoi causes problems with _ATL_MIN_CRT
3268 in VC7</font></li>
3269 </ul>
3270 <p style=margin:0in>&nbsp;</p>
3271 <p style=margin:0in><font face="Arial" size="2">CDC:</font></p>
3272 <ul style='margin-top:0in;margin-bottom:0in'>
3273 <li><font face="Arial" size="2">GetTabbedTextExtent() should return DWORD
3274 instead of BOOL</font></li>
3275 <li><font face="Arial" size="2">Add FillRect() that accept color index
3276 instead of a brush handle</font></li>
3277 <li><font face="Arial" size="2">DrawDragRect() leaks regions and a brush</font></li>
3278 <li><font face="Arial" size="2">Improved DitherBlt() - added brushes as
3279 arguments for used colors</font></li>
3280 <li><font face="Arial" size="2">Added DrawShadowText() (uses LoadLibrary/GetProcAddress
3281 to run on older Windows)</font></li>
3282 </ul>
3283 <p style=margin:0in>&nbsp;</p>
3284 <p style=margin:0in><font face="Arial" size="2">CListViewCtrl:</font></p>
3285 <ul style='margin-top:0in;margin-bottom:0in'>
3286 <li><font face="Arial" size="2">SetItemState should use LVM_SETITEMSTATE</font></li>
3287 <li><font face="Arial" size="2">SetItemCount should return a BOOL</font></li>
3288 </ul>
3289 <p style=margin:0in>&nbsp;</p>
3290 <p style=margin:0in><font face="Arial" size="2">CRichEditCtrl:</font></p>
3291 <ul style='margin-top:0in;margin-bottom:0in'>
3292 <li><font face="Arial" size="2">Added SetCharFormat() variant that accepts
3293 flags (for SCF_ALL)</font></li>
3294 <li><font face="Arial" size="2">CharFromPos() should pass a pointer to
3295 POINTL in lParam</font></li>
3296 <li><font face="Arial" size="2">GetTextRange() - should add Unicode variant
3297 for rich edit version &gt;= 2</font></li>
3298 <li><font face="Arial" size="2">Added another FormatRange() that can accept
3299 a pointer to FORMATRANGE (needed for passing NULL to clear cache)</font></li>
3300 </ul>
3301 <p style=margin:0in>&nbsp;</p>
3302 <p style=margin:0in><font face="Arial" size="2">CHyperLink:</font></p>
3303 <ul style='margin-top:0in;margin-bottom:0in'>
3304 <li><font face="Arial" size="2">Allow overriding of Navigate and
3305 CalcLabelRect</font></li>
3306 <li><font face="Arial" size="2">Doesn't handle right or center alignment</font></li>
3307 </ul>
3308 <p style=margin:0in>&nbsp;</p>
3309 <p style=margin:0in><font face="Arial" size="2">CColorDialog:</font></p>
3310 <ul style='margin-top:0in;margin-bottom:0in'>
3311 <li><font face="Arial" size="2">Has static variables that were not
3312 initialized with _ATL_MIN_CRT</font></li>
3313 <li><font face="Arial" size="2">Fixed HookProc for ColorOK message - the
3314 message is not sent, but the hook proc is called directly</font></li>
3315 </ul>
3316 <p style=margin:0in>&nbsp;</p>
3317 <p style=margin:0in><font face="Arial" size="2">atlcrack.h:</font></p>
3318 <ul style='margin-top:0in;margin-bottom:0in'>
3319 <li><font face="Arial" size="2">MSG_WM_TIMER crack macro should cast to
3320 TIMERPROC instead of TIMERPROC*</font></li>
3321 <li><font face="Arial" size="2">Add cracked handlers for all new messages in
3322 Common Controls 6</font></li>
3323 </ul>
3324 <p style=margin:0in>&nbsp;</p>
3325 <p style=margin:0in><font face="Arial" size="2">atlapp.h:</font></p>
3326 <ul style='margin-top:0in;margin-bottom:0in'>
3327 <li><font face="Arial" size="2">Fixed problems with atlTraceUI with ATL7</font></li>
3328 <li><font face="Arial" size="2">#ifdefs for ATL7 were in the wrong place</font></li>
3329 </ul>
3330 <p style=margin:0in>&nbsp;</p>
3331 <p style=margin:0in><font face="Arial" size="2">atlctrls.h:</font></p>
3332 <ul style='margin-top:0in;margin-bottom:0in'>
3333 <li><font face="Arial" size="2">Add support in control classes for all new
3334 messages in Common Controls 6</font></li>
3335 </ul>
3336 <p style=margin:0in>&nbsp;</p>
3337 <p style=margin:0in><font face="Arial" size="2">CRecentDocumentList:</font></p>
3338 <ul style='margin-top:0in;margin-bottom:0in'>
3339 <li><font face="Arial" size="2">AtlCompactPath corrupts memory if filename
3340 is longer than requested compact size</font></li>
3341 <li><font face="Arial" size="2">ReadFromRegistry incorrectly checks for
3342 error when reading from registry</font></li>
3343 </ul>
3344 <p style=margin:0in>&nbsp;</p>
3345 <p style=margin:0in><font face="Arial" size="2">CSplitterWindow:</font></p>
3346 <ul style='margin-top:0in;margin-bottom:0in'>
3347 <li><font face="Arial" size="2">Incorrect calculation of middle position</font></li>
3348 <li><font face="Arial" size="2">3D border now drawn only if WS_EX_CLIENTEDGE
3349 is set</font></li>
3350 </ul>
3351 <p style=margin:0in>&nbsp;</p>
3352 <p style=margin:0in><font face="Arial" size="2">Printing:</font></p>
3353 <ul style='margin-top:0in;margin-bottom:0in'>
3354 <li><font face="Arial" size="2">Uses DWORD instead of an int for a job ID</font></li>
3355 <li><font face="Arial" size="2">CPrintJob::CancelPrintJob shouldn't have a
3356 return value</font></li>
3357 </ul>
3358 <p style=margin:0in>&nbsp;</p>
3359 <p style=margin:0in><font face="Arial" size="2">Misc:</font></p>
3360 <ul style='margin-top:0in;margin-bottom:0in'>
3361 <li><font face="Arial" size="2">CRegKey::QueryValue and SetValue are
3362 deprecated in ATL7</font></li>
3363 <li><font face="Arial" size="2">Added direct support for ATL7</font></li>
3364 <li><font face="Arial" size="2">Replace ScreenToClient and ClientToScreen
3365 with MapWindowPoints to support RTL layout</font></li>
3366 <li><font face="Arial" size="2">CFindFile::GetFilePath(LPTSTR...) returns
3367 path without the file name</font></li>
3368 <li><font face="Arial" size="2">MDI: Updating client edge in
3369 WM_WINDOWPOSCHANGING causes minimize/maximize/restore animation problems,
3370 use WM_WINDOWPOSCHANGED</font></li>
3371 <li><font face="Arial" size="2">Custom Draw: Added
3372 CCustomDraw::OnSubItemPrePaint() overrideable method</font></li>
3373 <li><font face="Arial" size="2">CFolderDialogImpl uses 'this' for
3374 BROWSEINFO.lParam instead of T*</font></li>
3375 <li><font face="Arial" size="2">CImageList::Destroy shouldn't use Detach()</font></li>
3376 <li><font face="Arial" size="2">ATL7 has its own AtlLoadString</font></li>
3377 <li><font face="Arial" size="2">CPropertySheet doesn't close when you press
3378 X button</font></li>
3379 <li><font face="Arial" size="2">Fixed problems for _U_STRINGorID and others
3380 that moved from atlbase.h to atlwin.h in ATL7</font></li>
3381 <li><font face="Arial" size="2">Add AtlMessageBox() that accepts either
3382 in-memory or resource strings</font></li>
3383 <li><font face="Arial" size="2">CScrollImpl: fixed bug with scrolling child
3384 windows</font></li>
3385 <li><font face="Arial" size="2">CPropertyPageImpl: Add new notification
3386 handlers to enable direct return values (use #ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS
3387 to use them)</font></li>
3388 <li><font face="Arial" size="2">Add AtlInitCommonControls() to simplify use</font></li>
3389 <li><font face="Arial" size="2">DDX: Fixed usage of the size of char arrays
3390 for DDX</font></li>
3391 <li><font face="Arial" size="2">CPageSetupDialog: changed usage of
3392 CWndProcThunk because of changes in ATL7</font></li>
3393 <li><font face="Arial" size="2">Fix confusing precedence in expressions</font></li>
3394 <li><font face="Arial" size="2">Removed forward declarations because default
3395 values for template arguments shouldn't be specified in two places (we don't
3396 need them anyway)</font></li>
3397 <li><font face="Arial" size="2">Win64: Fix /Wp64 warnings from 32-bit VC7
3398 compiler caused by SDK headers</font></li>
3399 <li><font face="Arial" size="2">Fix direct usage of English strings (they
3400 can be #defined to something else now)</font></li>
3401 <li><font face="Arial" size="2">AtlGetCommCtrlVersion not defined if _ATL_DLL
3402 is in ATL 3.0 (and CmdBar is using it)</font></li>
3403 </ul>
3404 <p style=margin:0in>&nbsp;</p>
3405 <p style=margin:0in><font face="Arial" size="2">AppWizard:</font></p>
3406 <ul style='margin-top:0in;margin-bottom:0in'>
3407 <li><font face="Arial" size="2">Added manifest for Common Controls 6</font></li>
3408 <li><font face="Arial" size="2">Loading Rich Edit DLL should use HMODULE</font></li>
3409 <li><font face="Arial" size="2">Should not use atlimpl.cpp for ATL7</font></li>
3410 <li><font face="Arial" size="2">Added message handler prototypes to
3411 generated files</font></li>
3412 <li><font face="Arial" size="2">VERSION resource always has VALUE &quot;OLESelfRegister&quot;
3413 (now only for COM servers)</font></li>
3414 <li><font face="Arial" size="2">Added option for putting implementation in
3415 CPP files</font></li>
3416 <li><font face="Arial" size="2">d-tor for the thread manager class in MSDI
3417 project executed after the heap is destroyed</font></li>
3418 <li><font face="Arial" size="2">Wrong settings when changing to a dialog
3419 project and back (AppWizard 6.0 only)</font></li>
3420 <li><font face="Arial" size="2">Remove cut/copy/paste accelerators for form
3421 view and dialogs projects</font></li>
3422 <li><font face="Arial" size="2">Fix toolbar bitmaps so they are not
3423 transparent (problem with Windows XP flat menus only)</font></li>
3424 <li><font face="Arial" size="2">Used CMDICommandBarCtrl for MDI apps</font></li>
3425 <li><font face="Arial" size="2">Add symbols required for VC7 Class Wizard to
3426 recognize an ATL project</font></li>
3427 <li><font face="Arial" size="2">Changed default styles for the rebar, so it
3428 does look OK without CmdBar and with manifest</font></li>
3429 <li><font face="Arial" size="2">Added setup programs for both AppWizards</font></li>
3430 <li><font face="Arial" size="2">Remove ignored resource attributes:
3431 MOVEABLE, PURE, etc. (AppWizard 7.0 only)</font></li>
3432 <li><font face="Arial" size="2">Add call to DefWindowProc to WinMain to
3433 resolve possible problems if MSLU is used</font></li>
3434 </ul>
3435 <p style=margin:0in>&nbsp;</p>
3436 <p style=margin:0in><font face="Arial" size="2">Samples:</font></p>
3437 <ul style='margin-top:0in;margin-bottom:0in'>
3438 <li><font face="Arial" size="2">Updated toolbar bitmaps, added #ifdefs for
3439 ATL7, added manifest file for CommCtrl6, qualified _U_RECT with WTL
3440 namespace, updated use of deprecated CRegKey functions, added VC7 projects</font></li>
3441 <li><font face="Arial" size="2">Added Alpha sample</font></li>
3442 </ul>
3443 </blockquote>
3444 <p style=margin:0in>&nbsp;</p>
3445 <p style=margin:0in>&nbsp;</p>
3446 <p style=margin:0in><b><font face="Arial">
3447 <a name="Changes Between WTL 3.1 and 3.0"></a>Changes Between WTL 3.1 and
3448 3.0</font></b></p>
3449 <p style=margin:0in>&nbsp;</p>
3450 <p style=margin:0in><font face="Arial" size="2">New classes:</font></p>
3451 <blockquote style='margin-top:0in;margin-bottom:0in'>
3452 <p style=margin:0in><font face="Arial" size="2">CPaneContainer - implements a window that
3453 provides a title bar and a close button (like Explorer)</font></p>
3454 <p style=margin:0in><font face="Arial" size="2">CDialogResize - an MI class that allows
3455 resizing of dialogs (or any windows with child windows/controls)</font></p>
3456 <p style=margin:0in><font face="Arial" size="2">CAxPropertyPageImpl - implements a property
3457 page that can host ActiveX controls</font></p>
3458 </blockquote>
3459 <p style=margin:0in>&nbsp;</p>
3460 <p style=margin:0in><font face="Arial" size="2">Fixes and enhancements:</font></p>
3461 <blockquote style='margin-top:0in;margin-bottom:0in'>
3462 <p style=margin:0in><font face="Arial" size="2">CServerAppModule now clears m_hEventShutdown to
3463 avoid calling CloseHandle twice</font></p>
3464 <p style=margin:0in>&nbsp;</p>
3465 <p style=margin:0in><font face="Arial" size="2">CString:</font></p>
3466 <ul style='margin-top:0in;margin-bottom:0in'>
3467 <li><font face="Arial" size="2">operator += now leaves original string
3468 intact if it's out of memory</font></li>
3469 <li><font face="Arial" size="2">Fixed bad DWORD_PTR usage in TrimRight,
3470 TrimLeft, Replace, Remove</font></li>
3471 <li><font face="Arial" size="2">Removed dependencies on CRT for projects
3472 that don't use it</font></li>
3473 <li><font face="Arial" size="2">Insert - fixed string corruption in release
3474 builds</font></li>
3475 <li><font face="Arial" size="2">Added optional floating point formatting
3476 (for projects that use CRT)</font></li>
3477 </ul>
3478 <p style=margin:0in>&nbsp;</p>
3479 <p style=margin:0in><font face="Arial" size="2">CEdit and CRichEditCtrl: SetSelAll and
3480 SetSelNone had reversed implementation</font></p>
3481 <p style=margin:0in>&nbsp;</p>
3482 <p style=margin:0in><font face="Arial" size="2">atlres.h: Changed IDs so that they are
3483 compatible with MFC's afxres.h</font></p>
3484 <p style=margin:0in>&nbsp;</p>
3485 <p style=margin:0in><font face="Arial" size="2">Command Bar:</font></p>
3486 <ul style='margin-top:0in;margin-bottom:0in'>
3487 <li><font face="Arial" size="2">Added LoadMappedImages()</font></li>
3488 <li><font face="Arial" size="2">Changed handling of left and right arrow
3489 keys so that they don't close context menus</font></li>
3490 <li><font face="Arial" size="2">Add code to handle left/right arrow keys
3491 correctly on mirrored (RTL) systems</font></li>
3492 <li><font face="Arial" size="2">Removed handler that eats parent window's
3493 WM_SETTINGCHANGE</font></li>
3494 <li><font face="Arial" size="2">Fixed bitmap resource leak in
3495 Draw3DCheckmark</font></li>
3496 <li><font face="Arial" size="2">Fixed incorrect usage of CharLower in
3497 OnMenuChar</font></li>
3498 <li><font face="Arial" size="2">Fixed wrong color for the disabled items in
3499 hi-contrast mode</font></li>
3500 <li><font face="Arial" size="2">Added code to gray menu items if main window
3501 is inactive</font></li>
3502 <li><font face="Arial" size="2">Fixed keyboard mnemonic handling for IE 4</font></li>
3503 <li><font face="Arial" size="2">Fixed hook problems with multiple cmdbars in
3504 the same thread</font></li>
3505 <li><font face="Arial" size="2">Added support for radio menu items</font></li>
3506 <li><font face="Arial" size="2">Added support for disabled top-level menu
3507 items (also added in CFrameWindowImpl::PrepareChevronMenu)</font></li>
3508 <li><font face="Arial" size="2">Added keyboard shortcut (Alt+/) to invoke
3509 chevron menu</font></li>
3510 <li><font face="Arial" size="2">Added support to override menu item length
3511 in a derived class</font></li>
3512 </ul>
3513 <p style=margin:0in>&nbsp;</p>
3514 <p style=margin:0in><font face="Arial" size="2">CBitmapButton:</font></p>
3515 <ul style='margin-top:0in;margin-bottom:0in'>
3516 <li><font face="Arial" size="2">Bypassed BUTTON DefWindowProc for hover
3517 style so that the button doesn't take focus</font></li>
3518 <li><font face="Arial" size="2">Added BMPBTN_AUTOFIRE extended style</font></li>
3519 </ul>
3520 <p style=margin:0in>&nbsp;</p>
3521 <p style=margin:0in><font face="Arial" size="2">CDC:</font></p>
3522 <ul style='margin-top:0in;margin-bottom:0in'>
3523 <li><font face="Arial" size="2">Added _WTL_FORWARD_DECLARE_CSTRING define to
3524 allow usage of methods that accept CString</font></li>
3525 <li><font face="Arial" size="2">Fixed errors in GetTextFace and
3526 GetMenuItemString</font></li>
3527 <li><font face="Arial" size="2">Added GetCharWidth32</font></li>
3528 <li><font face="Arial" size="2">Added DrawIconEx method</font></li>
3529 </ul>
3530 <p style=margin:0in>&nbsp;</p>
3531 <p style=margin:0in><font face="Arial" size="2">CMenu:</font></p>
3532 <ul style='margin-top:0in;margin-bottom:0in'>
3533 <li><font face="Arial" size="2">Implement following missing methods:<br>
3534 &nbsp;&nbsp;&nbsp; GetMenuDefaultItem<br>
3535 &nbsp;&nbsp;&nbsp; GetMenuInfo<br>
3536 &nbsp;&nbsp;&nbsp; GetMenuItemRect<br>
3537 &nbsp;&nbsp;&nbsp; HiliteMenuItem<br>
3538 &nbsp;&nbsp;&nbsp; IsMenu<br>
3539 &nbsp;&nbsp;&nbsp; MenuItemFromPoint<br>
3540 &nbsp;&nbsp;&nbsp; SetMenuDefaultItem<br>
3541 &nbsp;&nbsp;&nbsp; SetMenuInfo</font></li>
3542 <li><font face="Arial" size="2">GetMenuString - fixed to include space for
3543 terminating NULL character in returning string</font></li>
3544 </ul>
3545 <p style=margin:0in>&nbsp;</p>
3546 <p style=margin:0in><font face="Arial" size="2">GDI and USER classes should destroy the
3547 GDI/USER objects in Attach if GDI/USER resource is managed</font></p>
3548 <p style=margin:0in>&nbsp;</p>
3549 <p style=margin:0in><font face="Arial" size="2">CFrameWindowImpl:</font></p>
3550 <ul style='margin-top:0in;margin-bottom:0in'>
3551 <li><font face="Arial" size="2">OnToolTipText shouldn't save tool tip text
3552 if it's not for a menu</font></li>
3553 <li><font face="Arial" size="2">AddSimpleReBarBandCtrl now adds chevron
3554 style only for toolbars with buttons</font></li>
3555 <li><font face="Arial" size="2">AddSimpleReBarBand(Ctrl) - calc band ID if
3556 not specified</font></li>
3557 </ul>
3558 <p style=margin:0in>&nbsp;</p>
3559 <p style=margin:0in><font face="Arial" size="2">CRecentDocumentList:</font></p>
3560 <ul style='margin-top:0in;margin-bottom:0in'>
3561 <li><font face="Arial" size="2">Fix - UpdateMenu deletes wrong menu item
3562 when the list is empty</font></li>
3563 <li><font face="Arial" size="2">Added code to allow restricting the number
3564 of characters displayed by MRU menu items</font></li>
3565 </ul>
3566 <p style=margin:0in>&nbsp;</p>
3567 <p style=margin:0in><font face="Arial" size="2">Update UI:</font></p>
3568 <ul style='margin-top:0in;margin-bottom:0in'>
3569 <li><font face="Arial" size="2">Added support for blocking accelerators for
3570 disabled items</font></li>
3571 <li><font face="Arial" size="2">Improved search code assuming there are no
3572 duplicate entries (and added checks for duplicates)</font></li>
3573 </ul>
3574 <p style=margin:0in>&nbsp;</p>
3575 <p style=margin:0in><font face="Arial" size="2">CSplitterWindow:</font></p>
3576 <ul style='margin-top:0in;margin-bottom:0in'>
3577 <li><font face="Arial" size="2">CSplitterWindowImpl should derive from
3578 CSplitterImpl&lt;T , t_bVertical&gt; to allow overriding of methods</font></li>
3579 <li><font face="Arial" size="2">Added single pane mode and SetSinglePaneMode/GetSinglePaneMode</font></li>
3580 <li><font face="Arial" size="2">Added right/bottom aligned resize mode using
3581 extended styles SPLIT_RIGHTALIGNED/SPLIT_BOTTOMALIGNED</font></li>
3582 </ul>
3583 <p style=margin:0in>&nbsp;</p>
3584 <p style=margin:0in><font face="Arial" size="2">atlcrack.h: Added handlers for following new
3585 messages:<br>
3586 &nbsp;&nbsp;&nbsp; WM_APPCOMMAND<br>
3587 &nbsp;&nbsp;&nbsp; WM_NCXBUTTONDOWN<br>
3588 &nbsp;&nbsp;&nbsp; WM_NCXBUTTONUP<br>
3589 &nbsp;&nbsp;&nbsp; WM_NCXBUTTONDBLCLK<br>
3590 &nbsp;&nbsp;&nbsp; WM_XBUTTONDOWN<br>
3591 &nbsp;&nbsp;&nbsp; WM_XBUTTONUP<br>
3592 &nbsp;&nbsp;&nbsp; WM_XBUTTONDBLCLK</font></p>
3593 <p style=margin:0in>&nbsp;</p>
3594 <p style=margin:0in><font face="Arial" size="2">Win64:</font></p>
3595 <ul style='margin-top:0in;margin-bottom:0in'>
3596 <li><font face="Arial" size="2">Dialog return value should use
3597 DWLP_MSGRESULT and SetWindowLongPtr</font></li>
3598 <li><font face="Arial" size="2">CMenu::InsertMenu, AppendMenu, ModifyMenu
3599 should have UINT_PTR for the menu ID</font></li>
3600 <li><font face="Arial" size="2">Added appropriate type casts</font></li>
3601 <li><font face="Arial" size="2">CFrameWindowImpl::m_szAutoName - changed the
3602 size to fit the pointer value size</font></li>
3603 <li><font face="Arial" size="2">CListViewCtrl::SortItems should use LPARAM
3604 for user data instead of DWORD</font></li>
3605 </ul>
3606 <p style=margin:0in>&nbsp;</p>
3607 <p style=margin:0in><font face="Arial" size="2">Misc:</font></p>
3608 <ul style='margin-top:0in;margin-bottom:0in'>
3609 <li><font face="Arial" size="2">Added optional mask argument to all methods
3610 for setting extended styles</font></li>
3611 <li><font face="Arial" size="2">CMDIWindow::MDIRestore - fixed to send
3612 WM_MDIRESTORE instead of WM_MDIICONARRANGE</font></li>
3613 <li><font face="Arial" size="2">CListViewCtrl: Added SortItemsEx method</font></li>
3614 <li><font face="Arial" size="2">CToolBarCtrl::GetButtonInfo - fixed to
3615 return int instead of BOOL</font></li>
3616 <li><font face="Arial" size="2">Added CToolBarCtrl::SetButtonSize and
3617 SetBitmapSize that accept cx and cy instead of SIZE</font></li>
3618 <li><font face="Arial" size="2">Printing: Changed how GetNewDevModeForPage
3619 works (comments in code)</font></li>
3620 <li><font face="Arial" size="2">CFileDialogImpl::_OnTypeChange incorrectly
3621 calls pT-&gt;OnSelChange instead of pT-&gt;OnTypeChange</font></li>
3622 <li><font face="Arial" size="2">CMultiPaneStatusBarCtrl::GetPaneTipText -
3623 fixed to use index instead of and ID internally</font></li>
3624 <li><font face="Arial" size="2">CWinDataExchange: Added references to
3625 arguments of DoDataExchange, so there are no level 4 warning even if the map
3626 is empty</font></li>
3627 <li><font face="Arial" size="2">CPropertySheetWindow: Added new, IE 5.0
3628 specific methods</font></li>
3629 <li><font face="Arial" size="2">CPropertyPageImpl: Added new, IE 5.0
3630 specific methods</font></li>
3631 </ul>
3632 <p style=margin:0in>&nbsp;</p>
3633 <p style=margin:0in><font face="Arial" size="2">AppWizard:</font></p>
3634 <ul style='margin-top:0in;margin-bottom:0in'>
3635 <li><font face="Arial" size="2">added calls to RemoveMessageFilter and
3636 RemoveIdleHandler in CMainFrame::OnDestroy for COM server projects</font></li>
3637 <li><font face="Arial" size="2">added scroll bars for HTML view</font></li>
3638 <li><font face="Arial" size="2">CAppServerModule now handles -embedding as
3639 well as -automation</font></li>
3640 <li><font face="Arial" size="2">corrected code in CMainFrame::OnShowToolBar
3641 to correctly identify the toolbar in a rebar</font></li>
3642 <li><font face="Arial" size="2">dialog based app code now derives from
3643 CUpdateUI as public</font></li>
3644 </ul>
3645 </blockquote>
3646 <p style=margin:0in>&nbsp;</p>
3647
3648 <p style=margin:0in><font face="Arial" size="2">- end of readme.html -</font></p>
3649
3650 </body>
3651
3652 </html>
+0
-0
src/third_party/zinnia less more
(Empty file)