├── Base.h ├── km.h ├── Base.cpp ├── Guard.h ├── Thread.h ├── WinRT.h ├── handle.h ├── ComHelper.h ├── ISOReader.h ├── ReadMe.txt ├── RegHelper.h ├── StreamEx.h ├── WofHelper.h ├── XMLHelper.h ├── unzip.cpp ├── FileDialog2.h ├── FileHelper.h ├── IniHelper.cpp ├── MFC ├── Dialog2.h ├── TreeCtrlEx.h └── TreeCtrlEx.cpp ├── RegHelper.cpp ├── StreamEx.cpp ├── x64 └── ntdll.lib ├── x86 └── ntdll.lib ├── CabinetHelper.h ├── FileHelper.cpp ├── StringHelper.h ├── TreeViewCtrl2.h ├── VCCompatible.h ├── WinInetHelper.h ├── ListViewCtrlEdit.h ├── WinInetHelper.cpp ├── rapidxml ├── rapidxml.hpp ├── rapidxml_utils.hpp ├── license.txt ├── rapidxml_iterators.hpp └── rapidxml_print.hpp ├── CriticalSectionHelper.h ├── MsIsoReader ├── ImageReader.h ├── Udf │ ├── UdfFileSet.h │ ├── UdfFileExtent.h │ ├── ShortAllocationDescriptor.h │ ├── LogicalBlockAddress.h │ ├── LogicalVolume.h │ ├── UdfTime.h │ ├── IcbTag.h │ ├── FileExtent.h │ ├── LongAllocationDescriptor.h │ ├── Partition.h │ ├── VolumeTag.h │ ├── Enumerations.h │ ├── UdfFileInformation.h │ ├── UdfString.h │ └── UdfRecord.h └── ImageRecord.h ├── DiskHelper.h ├── WinnlsHelper.h ├── Buffer.h ├── CPPHelper.sln ├── BaseFunction.h ├── BaseFunction.cpp ├── DoubleBuffer.h ├── LICENSE.txt ├── DialogCTL.h ├── FileFindHelper.h ├── StringI.h ├── IniHelper.h ├── VirtDiskHelper.h ├── WofHelper.cpp ├── .gitattributes ├── WTL ├── atlresce.h ├── atlres.h ├── atldwm.h ├── atlwinx.h ├── atlddx.h └── atlfind.h ├── .gitignore ├── CPPHelper.vcxitems ├── CPPHelper.vcxitems.filters └── unzip.h /Base.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/Base.h -------------------------------------------------------------------------------- /km.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/km.h -------------------------------------------------------------------------------- /Base.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/Base.cpp -------------------------------------------------------------------------------- /Guard.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/Guard.h -------------------------------------------------------------------------------- /Thread.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/Thread.h -------------------------------------------------------------------------------- /WinRT.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/WinRT.h -------------------------------------------------------------------------------- /handle.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/handle.h -------------------------------------------------------------------------------- /ComHelper.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/ComHelper.h -------------------------------------------------------------------------------- /ISOReader.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/ISOReader.h -------------------------------------------------------------------------------- /ReadMe.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/ReadMe.txt -------------------------------------------------------------------------------- /RegHelper.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/RegHelper.h -------------------------------------------------------------------------------- /StreamEx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/StreamEx.h -------------------------------------------------------------------------------- /WofHelper.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/WofHelper.h -------------------------------------------------------------------------------- /XMLHelper.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/XMLHelper.h -------------------------------------------------------------------------------- /unzip.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/unzip.cpp -------------------------------------------------------------------------------- /FileDialog2.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/FileDialog2.h -------------------------------------------------------------------------------- /FileHelper.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/FileHelper.h -------------------------------------------------------------------------------- /IniHelper.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/IniHelper.cpp -------------------------------------------------------------------------------- /MFC/Dialog2.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/MFC/Dialog2.h -------------------------------------------------------------------------------- /RegHelper.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/RegHelper.cpp -------------------------------------------------------------------------------- /StreamEx.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/StreamEx.cpp -------------------------------------------------------------------------------- /x64/ntdll.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/x64/ntdll.lib -------------------------------------------------------------------------------- /x86/ntdll.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/x86/ntdll.lib -------------------------------------------------------------------------------- /CabinetHelper.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/CabinetHelper.h -------------------------------------------------------------------------------- /FileHelper.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/FileHelper.cpp -------------------------------------------------------------------------------- /MFC/TreeCtrlEx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/MFC/TreeCtrlEx.h -------------------------------------------------------------------------------- /StringHelper.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/StringHelper.h -------------------------------------------------------------------------------- /TreeViewCtrl2.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/TreeViewCtrl2.h -------------------------------------------------------------------------------- /VCCompatible.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/VCCompatible.h -------------------------------------------------------------------------------- /WinInetHelper.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/WinInetHelper.h -------------------------------------------------------------------------------- /ListViewCtrlEdit.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/ListViewCtrlEdit.h -------------------------------------------------------------------------------- /MFC/TreeCtrlEx.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/MFC/TreeCtrlEx.cpp -------------------------------------------------------------------------------- /WinInetHelper.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/WinInetHelper.cpp -------------------------------------------------------------------------------- /rapidxml/rapidxml.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/rapidxml/rapidxml.hpp -------------------------------------------------------------------------------- /CriticalSectionHelper.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/CriticalSectionHelper.h -------------------------------------------------------------------------------- /MsIsoReader/ImageReader.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chuyu-Team/CPPHelper/HEAD/MsIsoReader/ImageReader.h -------------------------------------------------------------------------------- /MsIsoReader/Udf/UdfFileSet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "LongAllocationDescriptor.h" 3 | #include "UdfTime.h" 4 | 5 | class UdfFileSet 6 | { 7 | public: 8 | UdfTime RecordingTime; 9 | 10 | LongAllocationDescriptor RootDirICB; 11 | }; -------------------------------------------------------------------------------- /DiskHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | _Check_return_ 6 | LSTATUS DiskUpdateBootCode( 7 | _In_z_ LPCWSTR BootPartition 8 | ); 9 | 10 | _Check_return_ 11 | LSTATUS DiskGetPartitionStyle( 12 | _In_z_ LPCWSTR Partition, 13 | _Out_ PARTITION_STYLE* pPartitionStyle 14 | ); -------------------------------------------------------------------------------- /WinnlsHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | 7 | static CString LCIDToName( 8 | _In_ DWORD Lcid 9 | ) 10 | { 11 | CString LanguagName; 12 | 13 | LanguagName.ReleaseBuffer(LCIDToLocaleName(Lcid, LanguagName.GetBuffer(LOCALE_NAME_MAX_LENGTH), LOCALE_NAME_MAX_LENGTH, 0) - 1); 14 | 15 | return LanguagName; 16 | } -------------------------------------------------------------------------------- /Buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class CBuffer :public CStringA 5 | { 6 | public: 7 | void Append(const void* pData, DWORD cbData) 8 | { 9 | auto NewLength = GetLength() + cbData; 10 | auto pBuffer = GetBuffer(NewLength); 11 | 12 | memcpy(pBuffer+ GetLength(), pData, cbData); 13 | 14 | ReleaseBufferSetLength(NewLength); 15 | } 16 | }; -------------------------------------------------------------------------------- /MsIsoReader/Udf/UdfFileExtent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //class UdfFileExtent 4 | //{ 5 | //public: 6 | // int Length; 7 | // 8 | // int Position; 9 | // 10 | // public void Parse(int start, byte[] buffer) { 11 | // this.Length = UdfHelper.Get32(start, buffer); 12 | // this.Position = UdfHelper.Get32(start + 4, buffer); 13 | // } 14 | //} 15 | #include "ShortAllocationDescriptor.h" 16 | 17 | typedef ShortAllocationDescriptor UdfFileExtent; -------------------------------------------------------------------------------- /MsIsoReader/Udf/ShortAllocationDescriptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class ShortAllocationDescriptor 5 | { 6 | public: 7 | int Length; 8 | 9 | int Position; 10 | 11 | void Parse(int start, byte* buffer) 12 | { 13 | buffer += start; 14 | //this.Length = UdfHelper.Get32(start, buffer); 15 | //this.Position = UdfHelper.Get32(start + 4, buffer); 16 | Length=*(int*)buffer; 17 | Position = *(int*)(buffer+4); 18 | } 19 | }; -------------------------------------------------------------------------------- /CPPHelper.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25123.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CPPHelper", "CPPHelper.vcxitems", "{45D41ACC-2C3C-43D2-BC10-02AA73FFC7C7}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionProperties) = preSolution 10 | HideSolutionNode = FALSE 11 | EndGlobalSection 12 | EndGlobal 13 | -------------------------------------------------------------------------------- /BaseFunction.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define UMDF_USING_NTSTATUS 3 | 4 | 5 | #include 6 | 7 | #include "Base.h" 8 | #include "ComHelper.h" 9 | #include "StringHelper.h" 10 | #include "RegHelper.h" 11 | #include "IniHelper.h" 12 | #include "FileHelper.h" 13 | #include "XMLHelper.h" 14 | #include "Guard.h" 15 | //#include "Power.h" 16 | #include "handle.h" 17 | #include "WofHelper.h" 18 | #include "StreamEx.h" 19 | #include "WinInetHelper.h" 20 | #include "WinnlsHelper.h" -------------------------------------------------------------------------------- /MsIsoReader/Udf/LogicalBlockAddress.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class LogicalBlockAddress 5 | { 6 | public: 7 | int Position; 8 | 9 | int PartitionReference; 10 | 11 | 12 | void Parse(int start, byte* buffer) 13 | { 14 | buffer += start; 15 | 16 | //this.Position = UdfHelper.Get32(start, buffer); 17 | //this.PartitionReference = UdfHelper.Get16(start + 4, buffer); 18 | 19 | Position = *(int*)buffer; 20 | PartitionReference = *(UINT16*)(buffer + 4); 21 | } 22 | }; -------------------------------------------------------------------------------- /MsIsoReader/Udf/LogicalVolume.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include "UdfString.h" 6 | #include "LongAllocationDescriptor.h" 7 | #include "UdfFileSet.h" 8 | 9 | class LogicalVolume 10 | { 11 | public: 12 | UdfString128 Id; 13 | 14 | LongAllocationDescriptor FileSetLocation; 15 | 16 | std::vector PartitionMaps; 17 | 18 | UdfFileSet FileSet; 19 | 20 | int BlockSize; 21 | 22 | CString Name() const 23 | { 24 | return Id.GetString(); 25 | } 26 | }; -------------------------------------------------------------------------------- /MsIsoReader/Udf/UdfTime.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | 5 | class UdfTime :public CTime 6 | { 7 | public: 8 | void Parse(int start, byte* buffer) 9 | { 10 | buffer += start; 11 | 12 | *(CTime*)this = CTime(*(WORD*)(buffer +2), buffer[4], buffer[5], buffer[6], buffer[7], buffer[8]); 13 | 14 | 15 | auto t = (*(WORD*)buffer) & 0xFFF; 16 | if ((t >> 11) != 0) 17 | t -= (1 << 12); 18 | if ((t > (60 * 24) || t < -(60 * 24))) 19 | { 20 | //? 0 : t; 21 | *(UINT64*)this += t*60; 22 | } 23 | 24 | } 25 | }; -------------------------------------------------------------------------------- /MsIsoReader/Udf/IcbTag.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "Enumerations.h" 4 | 5 | class IcbTag 6 | { 7 | public: 8 | IcbFileType FileType; 9 | 10 | IcbDescriptorType DescriptorType; 11 | 12 | 13 | bool IsDirectory() 14 | { 15 | return (FileType == IcbFileType::Directory); 16 | } 17 | 18 | void Parse(int start, byte* buffer) 19 | { 20 | buffer += start; 21 | 22 | FileType = *(IcbFileType*)(buffer + 11); 23 | 24 | 25 | auto flags = /*UdfHelper.Get16(18, buffer)*/*(UINT16*)(buffer+18); 26 | 27 | DescriptorType = (IcbDescriptorType)(flags & 3); 28 | } 29 | }; -------------------------------------------------------------------------------- /MsIsoReader/Udf/FileExtent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Enumerations.h" 3 | 4 | class FileExtent 5 | { 6 | private: 7 | int _length; 8 | 9 | public: 10 | int get_Length() 11 | { 12 | return _length & 0x3FFFFFFF; 13 | } 14 | 15 | void put_Length(int length) 16 | { 17 | _length = length; 18 | } 19 | 20 | int Position; 21 | 22 | int PartitionReference; 23 | 24 | ShortAllocDescType get_DataType() 25 | { 26 | return (ShortAllocDescType)(_length >> 30); 27 | } 28 | 29 | bool IsRecAndAlloc() 30 | { 31 | return get_DataType() == ShortAllocDescType::RecordedAndAllocated; 32 | } 33 | }; -------------------------------------------------------------------------------- /BaseFunction.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "BaseFunction.h" 4 | //#include "StringHelper.h" 5 | #include 6 | #include "Guard.h" 7 | #include 8 | #include 9 | #include "StringI.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #pragma comment(lib,"Crypt32.lib") 16 | #include "unzip.h" 17 | #ifndef USE_CBS_ZIP 18 | #include "unzip.cpp" 19 | #endif 20 | #include "Base.cpp" 21 | 22 | #include "FileHelper.cpp" 23 | #include "WofHelper.cpp" 24 | //#include "Hook.cpp" 25 | #include "RegHelper.cpp" 26 | //#include "Power.cpp" 27 | #include "IniHelper.cpp" 28 | //#include "XMLHelper.cpp" 29 | #include "WinInetHelper.cpp" 30 | #include "StreamEx.cpp" -------------------------------------------------------------------------------- /MsIsoReader/Udf/LongAllocationDescriptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Enumerations.h" 3 | #include "LogicalBlockAddress.h" 4 | 5 | class LongAllocationDescriptor 6 | { 7 | private: 8 | int _length; 9 | 10 | public: 11 | int get_Length() 12 | { 13 | return _length & 0x3FFFFFFF; 14 | } 15 | 16 | ShortAllocDescType get_DataType() 17 | { 18 | return (ShortAllocDescType)(_length >> 30); 19 | } 20 | 21 | bool get_IsRecAndAlloc() 22 | { 23 | return (get_DataType() == ShortAllocDescType::RecordedAndAllocated); 24 | } 25 | 26 | LogicalBlockAddress Location; 27 | 28 | void Parse(int start, byte* buffer) 29 | { 30 | buffer += start; 31 | 32 | //this.Length = UdfHelper.Get32(start, buffer); 33 | //this.Location.Parse(start + 4, buffer); 34 | 35 | _length = *(int*)buffer; 36 | 37 | Location.Parse(4,buffer); 38 | } 39 | }; -------------------------------------------------------------------------------- /MsIsoReader/Udf/Partition.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "UdfRecord.h" 5 | 6 | typedef std::map Map32; 7 | 8 | class Partition 9 | { 10 | public: 11 | int Number; 12 | 13 | int Position; 14 | 15 | int Length; 16 | 17 | int VolumeIndex; 18 | 19 | Map32 Map; 20 | 21 | Partition() 22 | :VolumeIndex( -1) 23 | { 24 | 25 | } 26 | 27 | Partition(byte* pBuffer) 28 | :VolumeIndex(-1) 29 | { 30 | Number = *(UINT16*)(22 + pBuffer); 31 | Position = *(UINT32*)(188 + pBuffer); 32 | Length = *(UINT32*)(192 + pBuffer); 33 | } 34 | }; 35 | 36 | struct PartitionMap 37 | { 38 | byte Type; 39 | int PartitionNumber; 40 | int PartitionIndex; 41 | }; 42 | 43 | //class Map32 : Dictionary 44 | //{ 45 | // public bool Set(int key, UdfRecord value) { 46 | // if (this.ContainsKey(key)) { 47 | // return false; 48 | // } 49 | // 50 | // this.Add(key, value); 51 | // return true; 52 | // } 53 | //} -------------------------------------------------------------------------------- /MsIsoReader/Udf/VolumeTag.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class VolumeTag 5 | { 6 | /// 7 | /// Gets or sets the tag identifier. 8 | /// 9 | public: 10 | int Identifier; 11 | 12 | /// 13 | /// Parses the tag information from the buffer. 14 | /// 15 | /// The start index of the tag information. 16 | /// The buffer containing the data. 17 | /// The number of bytes to read. 18 | /// Returns true if the data was parsed sucessfully. 19 | bool Parse(int start, byte* buffer, int size) 20 | { 21 | buffer += start; 22 | 23 | if (size < 16 || buffer[ 5] != 0) 24 | { 25 | return false; 26 | } 27 | 28 | int sum = 0; 29 | for (int i = 0; i < 16; i++) 30 | { 31 | if (i != 4) 32 | { 33 | sum = sum + buffer[ i]; 34 | } 35 | } 36 | 37 | int m = (sum % 256); 38 | if (m != buffer[ 4]) 39 | { 40 | return false; 41 | } 42 | Identifier = *(UINT16*)buffer; 43 | //this.Identifier = UdfHelper.Get16(start, buffer); 44 | return true; 45 | } 46 | }; -------------------------------------------------------------------------------- /DoubleBuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | //#include 3 | //#include 4 | 5 | 6 | #define MSG_WM_PAINT_Window(func) \ 7 | if (uMsg == WM_PAINT) \ 8 | { \ 9 | SetMsgHandled(TRUE); \ 10 | func(hWnd,(HDC)wParam); \ 11 | lResult = 0; \ 12 | if(IsMsgHandled()) \ 13 | return TRUE; \ 14 | } 15 | 16 | class CDoubleBuffer 17 | { 18 | public: 19 | 20 | BEGIN_MSG_MAP_EX(CDoubleBuffer) 21 | MSG_WM_ERASEBKGND(OnEraseBkgnd) 22 | MSG_WM_PAINT_Window(OnPaint) 23 | END_MSG_MAP() 24 | 25 | BOOL OnEraseBkgnd(CDCHandle dc) 26 | { 27 | return TRUE; 28 | } 29 | 30 | void OnPaint(CWindow hWnd, HDC dc) 31 | { 32 | if (dc) 33 | { 34 | RECT rect; 35 | hWnd.GetClientRect(&rect); 36 | 37 | CMemoryDC dcMem(dc, rect); 38 | 39 | dcMem.FillSolidRect(&rect, GetSysColor(COLOR_WINDOW)); 40 | 41 | DefWindowProc(hWnd, WM_PAINT, (WPARAM)dcMem.m_hDC, 0); 42 | } 43 | else 44 | { 45 | CPaintDC dc(hWnd); 46 | CMemoryDC dcMem(dc.m_hDC, dc.m_ps.rcPaint); 47 | 48 | dcMem.FillSolidRect(&dc.m_ps.rcPaint, GetSysColor(COLOR_WINDOW)); 49 | 50 | DefWindowProc(hWnd, WM_PAINT, (WPARAM)dcMem.m_hDC, 0); 51 | } 52 | } 53 | 54 | }; -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Chuyu-Team 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /DialogCTL.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | 5 | #define MSG_WM_ERASEBKGNDWithHWND(func) \ 6 | if (uMsg == WM_ERASEBKGND) \ 7 | { \ 8 | SetMsgHandled(TRUE); \ 9 | lResult = (LRESULT)func(hWnd,(HDC)wParam); \ 10 | if (IsMsgHandled()) \ 11 | return TRUE; \ 12 | } 13 | 14 | class CDialogCTL 15 | { 16 | public: 17 | 18 | BEGIN_MSG_MAP_EX(CDialogCTL) 19 | 20 | //MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd) 21 | 22 | MSG_WM_ERASEBKGNDWithHWND(OnEraseBkgnd) 23 | MESSAGE_RANGE_HANDLER(WM_CTLCOLORMSGBOX, WM_CTLCOLORSTATIC, OnCtlColor) 24 | //MSG_WM_CTLCOLORSTATIC(OnCtlColorStatic) 25 | //MSG_WM_CTLCOLORDLG(OnCtlColorStatic) 26 | //MSG_WM_CTLCOLORBTN(OnCtlColorStatic) 27 | END_MSG_MAP() 28 | 29 | HRESULT OnCtlColor(int /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) 30 | { 31 | CDCHandle dc((HDC)wParam); 32 | dc.SetBkMode(TRANSPARENT); 33 | //dc.SetBkColor(REG()); 34 | 35 | //dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT)); 36 | 37 | return (HRESULT)GetSysColorBrush(/*COLOR_WINDOWFRAME*/COLOR_WINDOW); 38 | } 39 | 40 | BOOL OnEraseBkgnd(CWindow hWnd, CDCHandle dc) 41 | { 42 | RECT Rect; 43 | hWnd.GetClientRect(&Rect); 44 | 45 | 46 | dc.FillSolidRect(&Rect, RGB(255, 255, 255)); 47 | 48 | 49 | return TRUE; 50 | } 51 | }; -------------------------------------------------------------------------------- /MsIsoReader/Udf/Enumerations.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum IcbDescriptorType 4 | { 5 | Short = 0, 6 | Long = 1, 7 | Extended = 2, 8 | Inline = 3 9 | }; 10 | 11 | enum IcbFileType 12 | { 13 | Other = 0, 14 | Directory = 4, 15 | File = 5 16 | }; 17 | 18 | enum ShortAllocDescType 19 | { 20 | RecordedAndAllocated = 0, 21 | NotRecordedButAllocated = 1, 22 | NotRecordedAndNotAllocated = 2, 23 | NextExtent = 3 24 | }; 25 | 26 | enum VolumeDescriptorType 27 | { 28 | VolumeDescriptorTypeSpoaringTable = 0, 29 | VolumeDescriptorTypePrimaryVolume = 1, 30 | VolumeDescriptorTypeAnchorVolumePtr = 2, 31 | VolumeDescriptorTypeVolumePtr = 3, 32 | VolumeDescriptorTypeImplUseVol = 4, 33 | VolumeDescriptorTypePartition = 5, 34 | VolumeDescriptorTypeLogicalVolume = 6, 35 | VolumeDescriptorTypeUnallocSpace = 7, 36 | VolumeDescriptorTypeTerminating = 8, 37 | VolumeDescriptorTypeLogicalVolumeIntegrity = 9, 38 | VolumeDescriptorTypeFileSet = 256, 39 | VolumeDescriptorTypeFileId = 257, 40 | VolumeDescriptorTypeAllocationExtent = 258, 41 | VolumeDescriptorTypeIndirect = 259, 42 | VolumeDescriptorTypeTerminal = 260, 43 | VolumeDescriptorTypeFile = 261, 44 | VolumeDescriptorTypeExtendedAttributesHeader = 262, 45 | VolumeDescriptorTypeUnallocatedSpace = 263, 46 | VolumeDescriptorTypeSpaceBitmap = 264, 47 | VolumeDescriptorTypePartitionIntegrity = 265, 48 | VolumeDescriptorTypeExtendedFile = 266, 49 | }; -------------------------------------------------------------------------------- /MsIsoReader/Udf/UdfFileInformation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "LongAllocationDescriptor.h" 4 | #include "UdfString.h" 5 | #include "VolumeTag.h" 6 | 7 | const byte FILEID_CHARACS_Parent = (1 << 3); 8 | 9 | class UdfFileInformation 10 | { 11 | private: 12 | 13 | byte _fileCharacteristics; 14 | 15 | public: 16 | UdfString Identifier; 17 | 18 | LongAllocationDescriptor Icb; 19 | 20 | bool IsItLinkParent() 21 | { 22 | return (_fileCharacteristics & FILEID_CHARACS_Parent) != 0; 23 | } 24 | 25 | bool Parse(int start, byte* buffer, int size, int& processed) 26 | { 27 | processed = 0; 28 | if (size < 38) 29 | return false; 30 | 31 | buffer += start; 32 | 33 | VolumeTag tag; 34 | tag.Parse(0, buffer, size); 35 | if (tag.Identifier != VolumeDescriptorType::VolumeDescriptorTypeFileId) 36 | return false; 37 | 38 | _fileCharacteristics = buffer[18]; 39 | 40 | int idLen = buffer[19]; 41 | 42 | Icb.Parse(20, buffer); 43 | //int impLen = UdfHelper.Get16(start + 36, buffer); 44 | int impLen = *(UINT16*)(buffer + 36); 45 | if (size < 38 + idLen + impLen) 46 | return false; 47 | 48 | processed = 38; 49 | processed += impLen; 50 | Identifier.Parse(processed, buffer, idLen); 51 | processed += idLen; 52 | for (; (processed & 3) != 0; processed++) 53 | { 54 | if (buffer[processed] != 0) 55 | return false; 56 | } 57 | 58 | return (processed <= size); 59 | } 60 | }; -------------------------------------------------------------------------------- /FileFindHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | 6 | class CFileFindHelperIterator 7 | { 8 | public: 9 | WIN32_FIND_DATA FindData; 10 | 11 | HANDLE hFileFind; 12 | 13 | CFileFindHelperIterator() 14 | :hFileFind(INVALID_HANDLE_VALUE) 15 | { 16 | } 17 | 18 | CFileFindHelperIterator(CFileFindHelperIterator& Item) 19 | { 20 | hFileFind = Item.hFileFind; 21 | Item.hFileFind = INVALID_HANDLE_VALUE; 22 | 23 | 24 | FindData = Item.FindData; 25 | } 26 | 27 | ~CFileFindHelperIterator() 28 | { 29 | if(hFileFind != INVALID_HANDLE_VALUE) 30 | FindClose(hFileFind); 31 | } 32 | 33 | CFileFindHelperIterator& operator++() 34 | { 35 | if (!FindNextFile(hFileFind, &FindData)) 36 | { 37 | FindClose(hFileFind); 38 | hFileFind = INVALID_HANDLE_VALUE; 39 | } 40 | 41 | return *this; 42 | } 43 | 44 | WIN32_FIND_DATA& operator*() 45 | { // return designated object 46 | return FindData; 47 | } 48 | 49 | 50 | bool operator!=(const CFileFindHelperIterator& Item) 51 | { 52 | return hFileFind != Item.hFileFind; 53 | } 54 | }; 55 | 56 | class CFileFindHelper 57 | { 58 | CString FindPath; 59 | public: 60 | 61 | CFileFindHelper(CString _FindPath) 62 | :FindPath(_FindPath) 63 | { 64 | 65 | } 66 | 67 | CFileFindHelperIterator begin() const 68 | { 69 | CFileFindHelperIterator Temp; 70 | 71 | Temp.hFileFind = FindFirstFile(FindPath, &Temp.FindData); 72 | return Temp; 73 | } 74 | 75 | CFileFindHelperIterator end() const 76 | { 77 | return CFileFindHelperIterator(); 78 | } 79 | }; -------------------------------------------------------------------------------- /StringI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | class CStringI : 7 | public CString 8 | { 9 | public: 10 | CStringI() 11 | :CString() 12 | { 13 | 14 | } 15 | 16 | CStringI(LPCWSTR Str) 17 | :CString(Str) 18 | { 19 | } 20 | CStringI(LPCWSTR Str,int cchStr) 21 | :CString(Str, cchStr) 22 | { 23 | } 24 | 25 | /*CStringI(CStringI& Str) 26 | :CString(Str) 27 | { 28 | }*/ 29 | CStringI(CString& Str) 30 | :CString(Str) 31 | { 32 | } 33 | CStringI(const CString& Str) 34 | :CString(Str) 35 | { 36 | } 37 | /*CStringI(const CStringI& Str) 38 | :CString(Str) 39 | { 40 | }*/ 41 | 42 | CStringI MakeLowerI() const 43 | { 44 | CStringI Temp = *this; 45 | 46 | Temp.MakeLower(); 47 | 48 | return Temp; 49 | } 50 | 51 | /*operator PCWSTR() const 52 | { 53 | return GetString(); 54 | }*/ 55 | 56 | friend bool operator!=(const CStringI& a, const CString& b) 57 | { 58 | return a.CompareNoCase(b) != 0; 59 | } 60 | 61 | friend bool operator==(const CStringI& a, const CStringI& b) 62 | { 63 | return a.CompareNoCase(b) == 0; 64 | } 65 | 66 | friend bool operator<(const CStringI& a, const CStringI& b) 67 | { 68 | return a.CompareNoCase(b)<0; 69 | } 70 | friend bool operator<=(const CStringI& a, const CStringI& b) 71 | { 72 | return a.CompareNoCase(b) <= 0; 73 | } 74 | 75 | friend bool operator>(const CStringI& a, const CStringI& b) 76 | { 77 | return a.CompareNoCase(b)>0; 78 | } 79 | friend bool operator>=(const CStringI& a, const CStringI& b) 80 | { 81 | return a.CompareNoCase(b) >= 0; 82 | } 83 | }; -------------------------------------------------------------------------------- /rapidxml/rapidxml_utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDXML_UTILS_HPP_INCLUDED 2 | #define RAPIDXML_UTILS_HPP_INCLUDED 3 | 4 | // Copyright (C) 2006, 2009 Marcin Kalicinski 5 | // Version 1.13 6 | // Revision $DateTime: 2009/05/13 01:46:17 $ 7 | //! \file rapidxml_utils.hpp This file contains high-level rapidxml utilities that can be useful 8 | //! in certain simple scenarios. They should probably not be used if maximizing performance is the main objective. 9 | 10 | #include "rapidxml.hpp" 11 | #include 12 | //#include 13 | //#include 14 | //#include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace rapidxml 20 | { 21 | //! Counts children of node. Time complexity is O(n). 22 | //! \return Number of children of node 23 | template 24 | inline std::size_t count_children(xml_node *node) 25 | { 26 | xml_node *child = node->first_node(); 27 | std::size_t count = 0; 28 | while (child) 29 | { 30 | ++count; 31 | child = child->next_sibling(); 32 | } 33 | return count; 34 | } 35 | 36 | //! Counts attributes of node. Time complexity is O(n). 37 | //! \return Number of attributes of node 38 | template 39 | inline std::size_t count_attributes(xml_node *node) 40 | { 41 | xml_attribute *attr = node->first_attribute(); 42 | std::size_t count = 0; 43 | while (attr) 44 | { 45 | ++count; 46 | attr = attr->next_attribute(); 47 | } 48 | return count; 49 | } 50 | 51 | } 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /IniHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | _Check_return_ 6 | BOOL IniReadString( 7 | _In_z_ LPCWSTR FilePath, 8 | _In_z_ LPCWSTR KeyPath, 9 | _In_z_ LPCWSTR ValueName, 10 | _Out_ CString& Str 11 | ); 12 | 13 | _Check_return_ 14 | BOOL IniReadBinaryData( 15 | _In_z_ LPCWSTR FilePath, 16 | _In_z_ LPCWSTR KeyPath, 17 | _In_z_ LPCWSTR ValueName, 18 | _Out_ CStringA& Data 19 | ); 20 | 21 | _Check_return_ 22 | BOOL IniWriteString( 23 | _In_z_ LPCWSTR FilePath, 24 | _In_z_ LPCWSTR KeyPath, 25 | _In_opt_z_ LPCWSTR ValueName, 26 | _In_opt_z_ LPCWSTR Str 27 | ); 28 | 29 | _Check_return_ 30 | BOOL IniWriteBinaryData( 31 | _In_z_ LPCWSTR FilePath, 32 | _In_z_ LPCWSTR KeyPath, 33 | _In_z_ LPCWSTR ValueName, 34 | _In_reads_bytes_(ccbData) const void* pBinaryData, 35 | _In_ DWORD ccbData 36 | ); 37 | 38 | _Check_return_ 39 | BOOL IniDeleteString( 40 | _In_z_ LPCWSTR FilePath, 41 | _In_z_ LPCWSTR KeyPath, 42 | _In_opt_z_ LPCWSTR ValueName 43 | ); 44 | 45 | _Check_return_ 46 | BOOL IniDeleteSection( 47 | _In_z_ LPCWSTR FilePath, 48 | _In_z_ LPCWSTR KeyPath 49 | ); 50 | 51 | _Check_return_ 52 | BOOL IniGetSectionNames( 53 | _In_z_ LPCWSTR FilePath, 54 | _Out_ CString& Names 55 | ); 56 | 57 | _Check_return_ 58 | BOOL IniGetValues( 59 | _In_z_ LPCWSTR FilePath, 60 | _In_z_ LPCWSTR Path, 61 | _Out_ CString& Values 62 | ); 63 | 64 | //BOOL IniSetValues(LPCWSTR FilePath, LPCWSTR Path, LPCWSTR Values); 65 | #define IniSetValues(FilePath, Path, Values) WritePrivateProfileSection(Path,Values,FilePath) -------------------------------------------------------------------------------- /MsIsoReader/Udf/UdfString.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class UdfString 6 | { 7 | public: 8 | CStringA Data; 9 | //byte type; 10 | 11 | void Parse(int start, byte* buffer, int size) 12 | { 13 | buffer += start; 14 | 15 | //type = *buffer; 16 | //Data = new byte[size]; 17 | //Data = UdfHelper.Readbytes(start, buffer, size); 18 | 19 | Data.SetString((char*)buffer, size); 20 | } 21 | 22 | CString GetString() const 23 | { 24 | return ParseString((byte*)Data.GetString(), Data.GetLength()); 25 | } 26 | 27 | static CString ParseString(byte* data, int size) 28 | { 29 | CString Temp; 30 | 31 | if(size==0) 32 | return Temp; 33 | 34 | /*if (size > 0 && data != null) 35 | { 36 | var sb = new StringBuilder(); 37 | if (type == 8) { 38 | for (int i = 1; i < size; i++) { 39 | char c = (char)data[i]; 40 | if (c == 0) 41 | break; 42 | sb.Append(c); 43 | } 44 | } 45 | else if (type == 16) { 46 | for (int i = 1; i + 2 <= size; i += 2) { 47 | char c = (char)((data[i + 1]) | data[i] << 8); 48 | sb.Append(c); 49 | } 50 | } 51 | return sb.ToString().TrimEnd(); 52 | } 53 | return string.Empty;*/ 54 | 55 | switch (*data) 56 | { 57 | case 8: 58 | Temp.GetBuffer(size); 59 | for (int i = 1;i != size&&data[i];++i) 60 | { 61 | Temp.AppendChar(data[i]); 62 | } 63 | 64 | break; 65 | 66 | case 16: 67 | --size; 68 | for (int i = 1;i < size;i+=2) 69 | { 70 | Temp.AppendChar(((wchar_t)data[i]<<8)| data[i+1]); 71 | } 72 | 73 | break; 74 | } 75 | 76 | return Temp; 77 | } 78 | }; 79 | 80 | class UdfString128 :public UdfString 81 | { 82 | public: 83 | void Parse(int start, byte* buffer) 84 | { 85 | UdfString::Parse(start, buffer,128); 86 | //buffer += start; 87 | //Data.SetString((char*)buffer, 128); 88 | 89 | //Data = UdfHelper.Readbytes(start, buffer, 128); 90 | //type = Data[0]; 91 | } 92 | }; -------------------------------------------------------------------------------- /MsIsoReader/ImageRecord.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "Udf\UdfTime.h" 4 | class ImageRecord 5 | { 6 | public: 7 | ImageRecord* pParent; 8 | 9 | std::vector _SubItems; 10 | ImageRecord() 11 | :pParent(NULL) 12 | { 13 | 14 | } 15 | virtual ~ImageRecord() 16 | { 17 | Clear(); 18 | } 19 | 20 | UdfTime _dateTime; 21 | CString _name; 22 | CString _path; 23 | UINT64 _size; 24 | long _location; 25 | bool _isDirectory; 26 | bool _isSystem; 27 | 28 | 29 | virtual UINT64 get_Size() 30 | { 31 | if (IsDirectory()) 32 | { 33 | if (_size == 0) 34 | _size = GetSize(this); 35 | return _size; 36 | } 37 | else 38 | return _size; 39 | 40 | } 41 | 42 | virtual long get_Location() 43 | { 44 | return _location; 45 | } 46 | 47 | virtual bool IsDirectory() 48 | { 49 | return _isDirectory; 50 | } 51 | 52 | virtual bool IsSystemItem() 53 | { 54 | return _isSystem; 55 | } 56 | 57 | virtual bool IsUdf() 58 | { 59 | return false; 60 | } 61 | 62 | virtual CString get_Name() 63 | { 64 | return _name; 65 | } 66 | 67 | virtual CString get_Path() 68 | { 69 | if (_path.IsEmpty()) 70 | _path = GetPath(); 71 | return _path; 72 | } 73 | 74 | 75 | virtual void Clear() 76 | { 77 | for (auto Item : _SubItems) 78 | delete Item; 79 | 80 | _SubItems.clear(); 81 | *(UINT64*)&_dateTime = 0; 82 | pParent = NULL; 83 | _name.Empty(); 84 | _path.Empty(); 85 | _location = 0; 86 | _size = 0; 87 | _isDirectory = false; 88 | } 89 | 90 | static UINT64 GetSize(ImageRecord* record) 91 | { 92 | UINT64 Size = 0; 93 | for (auto& Item : record->_SubItems) 94 | { 95 | Size += Item->get_Size(); 96 | } 97 | return Size; 98 | } 99 | 100 | static CString GetPath(ImageRecord* pItem) 101 | { 102 | CString Temp; 103 | 104 | if (pItem) 105 | { 106 | Temp += GetPath(pItem->pParent); 107 | 108 | Temp += pItem->get_Name(); 109 | Temp += L'\\'; 110 | } 111 | return Temp; 112 | } 113 | 114 | CString GetPath() 115 | { 116 | return GetPath(this); 117 | } 118 | }; -------------------------------------------------------------------------------- /VirtDiskHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "BaseFunction.h" 3 | #include 4 | #pragma comment(lib,"VirtDisk.lib") 5 | #include 6 | 7 | _Check_return_ _Success_(return != INVALID_HANDLE_VALUE) 8 | static HANDLE AttachVirtualDisk( 9 | _In_z_ LPCWSTR VirtualDiskPath, 10 | _In_ bool ReadOnly 11 | ) 12 | { 13 | OPEN_VIRTUAL_DISK_PARAMETERS openParameters = {}; 14 | VIRTUAL_DISK_ACCESS_MASK accessMask; 15 | 16 | if (StrCmpI(PathFindExtension(VirtualDiskPath), L".iso") == 0) 17 | { 18 | openParameters.Version = OPEN_VIRTUAL_DISK_VERSION_1; 19 | 20 | accessMask = VIRTUAL_DISK_ACCESS_READ; 21 | } 22 | else 23 | { 24 | openParameters.Version = OPEN_VIRTUAL_DISK_VERSION_2; 25 | 26 | openParameters.Version2.GetInfoOnly = FALSE; 27 | 28 | accessMask = VIRTUAL_DISK_ACCESS_NONE; 29 | } 30 | 31 | HANDLE vhdHandle = INVALID_HANDLE_VALUE; 32 | VIRTUAL_STORAGE_TYPE storageType = { VIRTUAL_STORAGE_TYPE_DEVICE_UNKNOWN }; 33 | 34 | 35 | auto opStatus = OpenVirtualDisk( 36 | 37 | &storageType, 38 | 39 | VirtualDiskPath, 40 | 41 | accessMask, 42 | 43 | OPEN_VIRTUAL_DISK_FLAG_NONE, 44 | 45 | &openParameters, 46 | 47 | &vhdHandle); 48 | 49 | if (opStatus) 50 | { 51 | SetLastError(opStatus); 52 | return INVALID_HANDLE_VALUE; 53 | } 54 | PSECURITY_DESCRIPTOR sd = NULL; 55 | 56 | if (!::ConvertStringSecurityDescriptorToSecurityDescriptor( 57 | 58 | L"O:BAG:BAD:(A;;GA;;;WD)", 59 | 60 | SDDL_REVISION_1, 61 | 62 | &sd, 63 | 64 | NULL)) 65 | 66 | { 67 | 68 | opStatus = ::GetLastError_s(); 69 | 70 | goto Cleanup; 71 | } 72 | 73 | 74 | ATTACH_VIRTUAL_DISK_PARAMETERS attachParameters = { ATTACH_VIRTUAL_DISK_VERSION_1 }; 75 | ATTACH_VIRTUAL_DISK_FLAG attachFlags= ReadOnly? (ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER| ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY) : ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER; 76 | 77 | 78 | opStatus = AttachVirtualDisk( 79 | 80 | vhdHandle, 81 | 82 | sd, 83 | 84 | attachFlags, 85 | 86 | 0, 87 | 88 | &attachParameters, 89 | 90 | NULL); 91 | 92 | 93 | 94 | if (opStatus != ERROR_SUCCESS) 95 | 96 | { 97 | goto Cleanup; 98 | } 99 | else 100 | { 101 | return vhdHandle; 102 | } 103 | 104 | 105 | Cleanup: 106 | CloseHandle(vhdHandle); 107 | LocalFree(sd); 108 | SetLastError(opStatus); 109 | return INVALID_HANDLE_VALUE; 110 | } -------------------------------------------------------------------------------- /WofHelper.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "WofHelper.h" 3 | #include "handle.h" 4 | #include "FileHelper.h" 5 | 6 | #pragma warning(push) 7 | #pragma warning(disable: 28251) 8 | 9 | BOOL IsWofCompress(LPCWSTR FilePath) 10 | { 11 | CHFile hFile = CreateFile(FilePath, /*0x181*/GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0x0A000000, 0); 12 | if (hFile.IsInvalid()) 13 | return FALSE; 14 | 15 | ExternalBacking Buffer = {}; 16 | DWORD BytesReturned = 0; 17 | 18 | return DeviceIoControl(hFile, FSCTL_GET_EXTERNAL_BACKING/*0x90310*/, NULL, 0, &Buffer, sizeof(ExternalBacking), &BytesReturned, NULL); 19 | } 20 | 21 | LSTATUS UnWofCompressFile(LPCWSTR FilePath) 22 | { 23 | CHFile hFile = CreateFile(FilePath, 0x181, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0x0A000000, 0); 24 | if (hFile.IsInvalid()) 25 | return GetLastError_s(); 26 | 27 | DWORD BytesReturned = 0; 28 | 29 | if (!DeviceIoControl(hFile, FSCTL_DELETE_EXTERNAL_BACKING/*0x90314*/, NULL, 0, NULL, 0, &BytesReturned, NULL)) 30 | return GetLastError_s(); 31 | 32 | return ERROR_SUCCESS; 33 | } 34 | 35 | LSTATUS WofCompressFile(LPCWSTR FilePath, DWORD CompressType) 36 | { 37 | if (IsWofCompress(FilePath)) 38 | { 39 | return ERROR_SUCCESS; 40 | } 41 | 42 | CHFile hFile = CreateFile(FilePath, 0x81, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0x0A000000, 0); 43 | if (hFile.IsInvalid()) 44 | return GetLastError_s(); 45 | ExternalBacking Temp = { WOF_EXTERNAL_INFO{ 1, 2 }, WIM_PROVIDER_EXTERNAL_INFO{ 1, CompressType } }; 46 | DWORD Ret = 0; 47 | 48 | return DeviceIoControl(hFile, FSCTL_SET_EXTERNAL_BACKING, &Temp, 0x14, NULL, 0, &Ret, NULL) ? ERROR_SUCCESS : GetLastError_s(); 49 | } 50 | 51 | LSTATUS UnWofCompressRoot(CString RootPath) 52 | { 53 | WIN32_FIND_DATA FindData; 54 | 55 | CHFileFind hFileFind = FindFirstFile(RootPath, &FindData); 56 | 57 | if (hFileFind.IsInvalid()) 58 | return GetLastError_s(); 59 | 60 | RootPath.ReleaseBufferSetLength(RootPath.ReverseFind(L'\\') + 1); 61 | 62 | 63 | do 64 | { 65 | if (FindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) 66 | { 67 | if (_IsDots(FindData.cFileName)) 68 | continue; 69 | 70 | UnWofCompressRoot(RootPath + FindData.cFileName + L"\\*"); 71 | } 72 | else 73 | { 74 | UnWofCompressFile(RootPath + FindData.cFileName); 75 | } 76 | 77 | } while (FindNextFile(hFileFind, &FindData)); 78 | 79 | return ERROR_SUCCESS; 80 | } 81 | 82 | 83 | #pragma warning(pop) -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /MsIsoReader/Udf/UdfRecord.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "FileExtent.h" 4 | #include 5 | #include "..\ImageRecord.h" 6 | #include "UdfString.h" 7 | #include "IcbTag.h" 8 | 9 | class UdfRecord :public ImageRecord 10 | { 11 | public: 12 | int VolumeIndex; 13 | int PartitionIndex; 14 | int Key; 15 | UdfString Id; 16 | IcbTag IcbTag; 17 | long NumLogBlockRecorded; 18 | UdfTime ATime; 19 | UdfTime MTime; 20 | bool IsInline; 21 | CStringA InlineData; 22 | 23 | std::vector Extents; 24 | UdfRecord() 25 | :VolumeIndex(-1) 26 | , PartitionIndex(-1) 27 | , Key(-1) 28 | , ImageRecord() 29 | { 30 | } 31 | 32 | virtual ~UdfRecord() 33 | { 34 | } 35 | 36 | bool IsUdf() 37 | { 38 | return true; 39 | } 40 | 41 | bool IsDirectory() 42 | { 43 | return IcbTag.IsDirectory(); 44 | } 45 | 46 | bool IsSystemItem() 47 | { 48 | if (Id.Data.IsEmpty()) 49 | return true; 50 | if (Id.Data.GetLength() != 1) 51 | return _isSystem; 52 | 53 | byte b = Id.Data[0]; 54 | _isSystem = (b == 0 || b == 1); 55 | return _isSystem; 56 | 57 | } 58 | 59 | CString get_Name() 60 | { 61 | return (_name.IsEmpty() ? _name = Id.GetString() : _name); 62 | } 63 | 64 | UdfTime get_DateTime() 65 | { 66 | return ATime; 67 | } 68 | 69 | void Parse(byte* buffer) 70 | { 71 | //_size = UdfHelper.Get64(56, buffer); 72 | _size = *(UINT64*)(buffer + 56); 73 | 74 | //NumLogBlockRecorded = UdfHelper.Get64(64, buffer); 75 | NumLogBlockRecorded = *(UINT64*)(buffer + 64); 76 | ATime.Parse(72, buffer); 77 | MTime.Parse(84, buffer); 78 | } 79 | 80 | bool CheckChunkSizes() 81 | { 82 | return GetChunksSumSize() == get_Size(); 83 | } 84 | 85 | bool IsRecAndAlloc() 86 | { 87 | /*for (int i = 0; i < Extents.size(); i++) 88 | if (!Extents[i].IsRecAndAlloc) 89 | return false;*/ 90 | 91 | for (auto& Item : Extents) 92 | { 93 | if(!Item.IsRecAndAlloc()) 94 | return false; 95 | } 96 | 97 | return true; 98 | } 99 | 100 | long GetChunksSumSize() 101 | { 102 | if (IsInline) 103 | return InlineData.GetLength(); 104 | long size = 0; 105 | 106 | /*for (int i = 0; i < Extents.Count; i++) 107 | size += Extents[i].Length;*/ 108 | for (auto& Item : Extents) 109 | { 110 | size += Item.get_Length(); 111 | } 112 | return size; 113 | } 114 | 115 | void Clear() 116 | { 117 | Extents.clear(); 118 | pParent = NULL; 119 | Id = UdfString(); 120 | //IcbTag = IcbTag(); 121 | memset(&IcbTag,NULL,sizeof(IcbTag)); 122 | ATime = UdfTime(); 123 | MTime = UdfTime(); 124 | NumLogBlockRecorded = 0; 125 | IsInline = false; 126 | InlineData.Empty(); 127 | ImageRecord::Clear(); 128 | } 129 | }; -------------------------------------------------------------------------------- /WTL/atlresce.h: -------------------------------------------------------------------------------- 1 | // Windows Template Library - WTL version 9.0 2 | // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved. 3 | // 4 | // This file is a part of the Windows Template Library. 5 | // The use and distribution terms for this software are covered by the 6 | // Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) 7 | // which can be found in the file CPL.TXT at the root of this distribution. 8 | // By using this software in any fashion, you are agreeing to be bound by 9 | // the terms of this license. You must not remove this notice, or 10 | // any other, from this software. 11 | 12 | #ifndef __ATLRESCE_H__ 13 | #define __ATLRESCE_H__ 14 | 15 | #pragma once 16 | 17 | #ifndef _WIN32_WCE 18 | #error atlresCE.h is only for Windows CE 19 | #endif 20 | 21 | 22 | #ifdef RC_INVOKED 23 | #ifndef _INC_WINDOWS 24 | 25 | #define VS_VERSION_INFO 1 26 | 27 | #ifdef APSTUDIO_INVOKED 28 | #define APSTUDIO_HIDDEN_SYMBOLS // Ignore following symbols 29 | #endif // APSTUDIO_INVOKED 30 | 31 | #ifndef WINVER 32 | #define WINVER 0x0400 // default to Windows Version 4.0 33 | #endif // !WINVER 34 | 35 | #if !defined(WCEOLE_ENABLE_DIALOGEX) 36 | #define DIALOGEX DIALOG DISCARDABLE 37 | #endif 38 | 39 | #include 40 | #define SHMENUBAR RCDATA 41 | 42 | #if defined(SHELLSDK_MODULES_AYGSHELL) 43 | #include 44 | #else 45 | #define NOMENU 0xFFFF 46 | #define IDS_SHNEW 1 47 | #define IDM_SHAREDNEW 10 48 | #define IDM_SHAREDNEWDEFAULT 11 49 | #endif 50 | #ifndef I_IMAGENONE 51 | #define I_IMAGENONE (-2) 52 | #endif 53 | 54 | #include 55 | 56 | #endif // !_INC_WINDOWS 57 | #endif // RC_INVOKED 58 | 59 | #include "atlres.h" 60 | 61 | #ifdef APSTUDIO_INVOKED 62 | #undef APSTUDIO_HIDDEN_SYMBOLS 63 | #endif // APSTUDIO_INVOKED 64 | 65 | // Visual Studio dialog editor bug fix 66 | #ifndef DS_FIXEDSYS 67 | #define DS_FIXEDSYS 0 68 | #endif 69 | 70 | #define IDC_INFOSTATIC 0xFFFE // == IDC_STATIC -1 71 | 72 | /////////////////////////////////////////////////////////////////////////////// 73 | // Smartphone and PPC 2005 Resource IDs 74 | 75 | // Command and associated string resource IDs 76 | #define ID_MENU_OK 0xE790 77 | #define ID_MENU_CANCEL 0xE791 78 | #define ID_MENU 0xE792 79 | #define ID_ACTION 0xE793 80 | #define ID_VIEW_FULLSCREEN 0xE802 81 | 82 | // MenuBar resource IDs 83 | #define ATL_IDM_MENU_DONE 0xE701 84 | #define ATL_IDM_MENU_CANCEL 0xE702 85 | #define ATL_IDM_MENU_DONECANCEL 0xE703 86 | 87 | // Default device MenuBar control ID and MenuBar resource ID 88 | #define ATL_IDW_MENU_BAR 0xE802 89 | 90 | // SmartPhone spinned controls ID offset for CSpinCtrl 91 | #define ATL_IDW_SPIN_ID 9999 92 | 93 | #endif // __ATLRESCE_H__ 94 | -------------------------------------------------------------------------------- /rapidxml/license.txt: -------------------------------------------------------------------------------- 1 | Use of this software is granted under one of the following two licenses, 2 | to be chosen freely by the user. 3 | 4 | 1. Boost Software License - Version 1.0 - August 17th, 2003 5 | =============================================================================== 6 | 7 | Copyright (c) 2006, 2007 Marcin Kalicinski 8 | 9 | Permission is hereby granted, free of charge, to any person or organization 10 | obtaining a copy of the software and accompanying documentation covered by 11 | this license (the "Software") to use, reproduce, display, distribute, 12 | execute, and transmit the Software, and to prepare derivative works of the 13 | Software, and to permit third-parties to whom the Software is furnished to 14 | do so, all subject to the following: 15 | 16 | The copyright notices in the Software and this entire statement, including 17 | the above license grant, this restriction and the following disclaimer, 18 | must be included in all copies of the Software, in whole or in part, and 19 | all derivative works of the Software, unless such copies or derivative 20 | works are solely in the form of machine-executable object code generated by 21 | a source language processor. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 26 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 27 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 28 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 29 | DEALINGS IN THE SOFTWARE. 30 | 31 | 2. The MIT License 32 | =============================================================================== 33 | 34 | Copyright (c) 2006, 2007 Marcin Kalicinski 35 | 36 | Permission is hereby granted, free of charge, to any person obtaining a copy 37 | of this software and associated documentation files (the "Software"), to deal 38 | in the Software without restriction, including without limitation the rights 39 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 40 | of the Software, and to permit persons to whom the Software is furnished to do so, 41 | subject to the following conditions: 42 | 43 | The above copyright notice and this permission notice shall be included in all 44 | copies or substantial portions of the Software. 45 | 46 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 47 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 48 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 49 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 50 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 51 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 52 | IN THE SOFTWARE. 53 | -------------------------------------------------------------------------------- /rapidxml/rapidxml_iterators.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDXML_ITERATORS_HPP_INCLUDED 2 | #define RAPIDXML_ITERATORS_HPP_INCLUDED 3 | 4 | // Copyright (C) 2006, 2009 Marcin Kalicinski 5 | // Version 1.13 6 | // Revision $DateTime: 2009/05/13 01:46:17 $ 7 | //! \file rapidxml_iterators.hpp This file contains rapidxml iterators 8 | 9 | #include "rapidxml.hpp" 10 | 11 | namespace rapidxml 12 | { 13 | 14 | //! Iterator of child nodes of xml_node 15 | template 16 | class node_iterator 17 | { 18 | 19 | public: 20 | 21 | typedef typename xml_node value_type; 22 | typedef typename xml_node &reference; 23 | typedef typename xml_node *pointer; 24 | typedef std::ptrdiff_t difference_type; 25 | typedef std::bidirectional_iterator_tag iterator_category; 26 | 27 | node_iterator() 28 | : m_node(0) 29 | { 30 | } 31 | 32 | node_iterator(xml_node *node) 33 | : m_node(node->first_node()) 34 | { 35 | } 36 | 37 | reference operator *() const 38 | { 39 | assert(m_node); 40 | return *m_node; 41 | } 42 | 43 | pointer operator->() const 44 | { 45 | assert(m_node); 46 | return m_node; 47 | } 48 | 49 | node_iterator& operator++() 50 | { 51 | assert(m_node); 52 | m_node = m_node->next_sibling(); 53 | return *this; 54 | } 55 | 56 | node_iterator operator++(int) 57 | { 58 | node_iterator tmp = *this; 59 | ++this; 60 | return tmp; 61 | } 62 | 63 | node_iterator& operator--() 64 | { 65 | assert(m_node && m_node->previous_sibling()); 66 | m_node = m_node->previous_sibling(); 67 | return *this; 68 | } 69 | 70 | node_iterator operator--(int) 71 | { 72 | node_iterator tmp = *this; 73 | ++this; 74 | return tmp; 75 | } 76 | 77 | bool operator ==(const node_iterator &rhs) 78 | { 79 | return m_node == rhs.m_node; 80 | } 81 | 82 | bool operator !=(const node_iterator &rhs) 83 | { 84 | return m_node != rhs.m_node; 85 | } 86 | 87 | private: 88 | 89 | xml_node *m_node; 90 | 91 | }; 92 | 93 | //! Iterator of child attributes of xml_node 94 | template 95 | class attribute_iterator 96 | { 97 | 98 | public: 99 | 100 | typedef typename xml_attribute value_type; 101 | typedef typename xml_attribute &reference; 102 | typedef typename xml_attribute *pointer; 103 | typedef std::ptrdiff_t difference_type; 104 | typedef std::bidirectional_iterator_tag iterator_category; 105 | 106 | attribute_iterator() 107 | : m_attribute(0) 108 | { 109 | } 110 | 111 | attribute_iterator(xml_node *node) 112 | : m_attribute(node->first_attribute()) 113 | { 114 | } 115 | 116 | reference operator *() const 117 | { 118 | assert(m_attribute); 119 | return *m_attribute; 120 | } 121 | 122 | pointer operator->() const 123 | { 124 | assert(m_attribute); 125 | return m_attribute; 126 | } 127 | 128 | attribute_iterator& operator++() 129 | { 130 | assert(m_attribute); 131 | m_attribute = m_attribute->next_attribute(); 132 | return *this; 133 | } 134 | 135 | attribute_iterator operator++(int) 136 | { 137 | attribute_iterator tmp = *this; 138 | ++this; 139 | return tmp; 140 | } 141 | 142 | attribute_iterator& operator--() 143 | { 144 | assert(m_attribute && m_attribute->previous_attribute()); 145 | m_attribute = m_attribute->previous_attribute(); 146 | return *this; 147 | } 148 | 149 | attribute_iterator operator--(int) 150 | { 151 | attribute_iterator tmp = *this; 152 | ++this; 153 | return tmp; 154 | } 155 | 156 | bool operator ==(const attribute_iterator &rhs) 157 | { 158 | return m_attribute == rhs.m_attribute; 159 | } 160 | 161 | bool operator !=(const attribute_iterator &rhs) 162 | { 163 | return m_attribute != rhs.m_attribute; 164 | } 165 | 166 | private: 167 | 168 | xml_attribute *m_attribute; 169 | 170 | }; 171 | 172 | } 173 | 174 | #endif 175 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Microsoft Azure ApplicationInsights config file 170 | ApplicationInsights.config 171 | 172 | # Windows Store app package directory 173 | AppPackages/ 174 | BundleArtifacts/ 175 | 176 | # Visual Studio cache files 177 | # files ending in .cache can be ignored 178 | *.[Cc]ache 179 | # but keep track of directories ending in .cache 180 | !*.[Cc]ache/ 181 | 182 | # Others 183 | ClientBin/ 184 | [Ss]tyle[Cc]op.* 185 | ~$* 186 | *~ 187 | *.dbmdl 188 | *.dbproj.schemaview 189 | *.pfx 190 | *.publishsettings 191 | node_modules/ 192 | orleans.codegen.cs 193 | 194 | # RIA/Silverlight projects 195 | Generated_Code/ 196 | 197 | # Backup & report files from converting an old project file 198 | # to a newer Visual Studio version. Backup files are not needed, 199 | # because we have git ;-) 200 | _UpgradeReport_Files/ 201 | Backup*/ 202 | UpgradeLog*.XML 203 | UpgradeLog*.htm 204 | 205 | # SQL Server files 206 | *.mdf 207 | *.ldf 208 | 209 | # Business Intelligence projects 210 | *.rdl.data 211 | *.bim.layout 212 | *.bim_*.settings 213 | 214 | # Microsoft Fakes 215 | FakesAssemblies/ 216 | 217 | # GhostDoc plugin setting file 218 | *.GhostDoc.xml 219 | 220 | # Node.js Tools for Visual Studio 221 | .ntvs_analysis.dat 222 | 223 | # Visual Studio 6 build log 224 | *.plg 225 | 226 | # Visual Studio 6 workspace options file 227 | *.opt 228 | 229 | # Visual Studio LightSwitch build output 230 | **/*.HTMLClient/GeneratedArtifacts 231 | **/*.DesktopClient/GeneratedArtifacts 232 | **/*.DesktopClient/ModelManifest.xml 233 | **/*.Server/GeneratedArtifacts 234 | **/*.Server/ModelManifest.xml 235 | _Pvt_Extensions 236 | 237 | # LightSwitch generated files 238 | GeneratedArtifacts/ 239 | ModelManifest.xml 240 | 241 | # Paket dependency manager 242 | .paket/paket.exe 243 | 244 | # FAKE - F# Make 245 | .fake/ -------------------------------------------------------------------------------- /CPPHelper.vcxitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | {45d41acc-2c3c-43d2-bc10-02aa73ffc7c7} 7 | 8 | 9 | 10 | %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /CPPHelper.vcxitems.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | rapidxml 6 | 7 | 8 | rapidxml 9 | 10 | 11 | rapidxml 12 | 13 | 14 | rapidxml 15 | 16 | 17 | MsIsoReader 18 | 19 | 20 | MsIsoReader 21 | 22 | 23 | MsIsoReader\Udf 24 | 25 | 26 | MsIsoReader\Udf 27 | 28 | 29 | MsIsoReader\Udf 30 | 31 | 32 | MsIsoReader\Udf 33 | 34 | 35 | MsIsoReader\Udf 36 | 37 | 38 | MsIsoReader\Udf 39 | 40 | 41 | MsIsoReader\Udf 42 | 43 | 44 | MsIsoReader\Udf 45 | 46 | 47 | MsIsoReader\Udf 48 | 49 | 50 | MsIsoReader\Udf 51 | 52 | 53 | MsIsoReader\Udf 54 | 55 | 56 | MsIsoReader\Udf 57 | 58 | 59 | MsIsoReader\Udf 60 | 61 | 62 | MsIsoReader\Udf 63 | 64 | 65 | MsIsoReader\Udf 66 | 67 | 68 | 头文件 69 | 70 | 71 | 头文件 72 | 73 | 74 | 头文件 75 | 76 | 77 | 头文件 78 | 79 | 80 | 头文件 81 | 82 | 83 | 头文件 84 | 85 | 86 | 头文件 87 | 88 | 89 | 头文件 90 | 91 | 92 | 头文件 93 | 94 | 95 | 头文件 96 | 97 | 98 | 头文件 99 | 100 | 101 | 头文件 102 | 103 | 104 | 头文件 105 | 106 | 107 | 头文件 108 | 109 | 110 | 头文件 111 | 112 | 113 | 头文件 114 | 115 | 116 | 头文件 117 | 118 | 119 | 头文件 120 | 121 | 122 | 头文件 123 | 124 | 125 | 头文件 126 | 127 | 128 | 头文件 129 | 130 | 131 | 头文件 132 | 133 | 134 | 头文件 135 | 136 | 137 | 头文件 138 | 139 | 140 | 头文件 141 | 142 | 143 | 头文件 144 | 145 | 146 | 头文件 147 | 148 | 149 | 头文件 150 | 151 | 152 | 头文件 153 | 154 | 155 | 头文件 156 | 157 | 158 | 头文件 159 | 160 | 161 | 162 | 163 | 164 | rapidxml 165 | 166 | 167 | 168 | 169 | {baa830b4-9789-4386-85ba-47427ed2e5fa} 170 | 171 | 172 | {4b82542d-3208-4e1f-9872-760ecb7cc910} 173 | 174 | 175 | {fa2e6278-35e2-4f1c-8812-b3b912c97ec3} 176 | 177 | 178 | {835fbe91-f796-4e90-ae19-e12602c737f5} 179 | 180 | 181 | {9c04e9a9-2040-4c84-9baa-03730ec86a2b} 182 | 183 | 184 | {55e67db0-1fcf-4d87-a5f8-aa505e3d8079} 185 | 186 | 187 | {105b0678-c0e0-40d9-b367-57f9343cb191} 188 | 189 | 190 | {0633ec94-703d-4edc-b92b-1bfe70aa9534} 191 | 192 | 193 | 194 | 195 | rapidxml 196 | 197 | 198 | 199 | 200 | 源文件 201 | 202 | 203 | 源文件 204 | 205 | 206 | 源文件 207 | 208 | 209 | 源文件 210 | 211 | 212 | 源文件 213 | 214 | 215 | 源文件 216 | 217 | 218 | 源文件 219 | 220 | 221 | 源文件 222 | 223 | 224 | 源文件 225 | 226 | 227 | 228 | 229 | lib\x64 230 | 231 | 232 | lib\x86 233 | 234 | 235 | lib\x64 236 | 237 | 238 | lib\x86 239 | 240 | 241 | -------------------------------------------------------------------------------- /unzip.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef _unzip_H 4 | #define _unzip_H 5 | 6 | #ifndef ZIPAPI 7 | #define ZIPAPI 8 | #endif 9 | 10 | #include 11 | 12 | // UNZIPPING functions -- for unzipping. 13 | // This file is a repackaged form of extracts from the zlib code available 14 | // at www.gzip.org/zlib, by Jean-Loup Gailly and Mark Adler. The original 15 | // copyright notice may be found in unzip.cpp. The repackaging was done 16 | // by Lucian Wischik to simplify and extend its use in Windows/C++. Also 17 | // encryption and unicode filenames have been added. 18 | 19 | 20 | #ifndef _zip_H 21 | DECLARE_HANDLE(HZIP); 22 | #endif 23 | // An HZIP identifies a zip file that has been opened 24 | 25 | typedef DWORD ZRESULT; 26 | // return codes from any of the zip functions. Listed later. 27 | 28 | typedef struct 29 | { 30 | int index; // index of this file within the zip 31 | TCHAR name[MAX_PATH]; // filename within the zip 32 | DWORD attr; // attributes, as in GetFileAttributes. 33 | FILETIME atime, ctime, mtime;// access, create, modify filetimes 34 | long comp_size; // sizes of item, compressed and uncompressed. These 35 | long unc_size; // may be -1 if not yet known (e.g. being streamed in) 36 | } ZIPENTRY; 37 | 38 | 39 | ZIPAPI HZIP OpenZip(const TCHAR *fn, const char *password); 40 | ZIPAPI HZIP OpenZip(void *z, unsigned int len, const char *password); 41 | ZIPAPI HZIP OpenZipHandle(HANDLE h, const char *password); 42 | // OpenZip - opens a zip file and returns a handle with which you can 43 | // subsequently examine its contents. You can open a zip file from: 44 | // from a pipe: OpenZipHandle(hpipe_read,0); 45 | // from a file (by handle): OpenZipHandle(hfile,0); 46 | // from a file (by name): OpenZip("c:\\test.zip","password"); 47 | // from a memory block: OpenZip(bufstart, buflen,0); 48 | // If the file is opened through a pipe, then items may only be 49 | // accessed in increasing order, and an item may only be unzipped once, 50 | // although GetZipItem can be called immediately before and after unzipping 51 | // it. If it's opened in any other way, then full random access is possible. 52 | // Note: pipe input is not yet implemented. 53 | // Note: zip passwords are ascii, not unicode. 54 | // Note: for windows-ce, you cannot close the handle until after CloseZip. 55 | // but for real windows, the zip makes its own copy of your handle, so you 56 | // can close yours anytime. 57 | 58 | ZIPAPI ZRESULT GetZipItem(HZIP hz, int index, ZIPENTRY *ze); 59 | // GetZipItem - call this to get information about an item in the zip. 60 | // If index is -1 and the file wasn't opened through a pipe, 61 | // then it returns information about the whole zipfile 62 | // (and in particular ze.index returns the number of index items). 63 | // Note: the item might be a directory (ze.attr & FILE_ATTRIBUTE_DIRECTORY) 64 | // See below for notes on what happens when you unzip such an item. 65 | // Note: if you are opening the zip through a pipe, then random access 66 | // is not possible and GetZipItem(-1) fails and you can't discover the number 67 | // of items except by calling GetZipItem on each one of them in turn, 68 | // starting at 0, until eventually the call fails. Also, in the event that 69 | // you are opening through a pipe and the zip was itself created into a pipe, 70 | // then then comp_size and sometimes unc_size as well may not be known until 71 | // after the item has been unzipped. 72 | 73 | ZIPAPI ZRESULT FindZipItem(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRY *ze); 74 | // FindZipItem - finds an item by name. ic means 'insensitive to case'. 75 | // It returns the index of the item, and returns information about it. 76 | // If nothing was found, then index is set to -1 and the function returns 77 | // an error code. 78 | 79 | ZIPAPI ZRESULT UnzipItem(HZIP hz, int index, const TCHAR *fn); 80 | ZIPAPI ZRESULT UnzipItem(HZIP hz, int index, void *z, unsigned int len); 81 | ZIPAPI ZRESULT UnzipItemHandle(HZIP hz, int index, HANDLE h); 82 | // UnzipItem - given an index to an item, unzips it. You can unzip to: 83 | // to a pipe: UnzipItemHandle(hz,i, hpipe_write); 84 | // to a file (by handle): UnzipItemHandle(hz,i, hfile); 85 | // to a file (by name): UnzipItem(hz,i, ze.name); 86 | // to a memory block: UnzipItem(hz,i, buf,buflen); 87 | // In the final case, if the buffer isn't large enough to hold it all, 88 | // then the return code indicates that more is yet to come. If it was 89 | // large enough, and you want to know precisely how big, GetZipItem. 90 | // Note: zip files are normally stored with relative pathnames. If you 91 | // unzip with ZIP_FILENAME a relative pathname then the item gets created 92 | // relative to the current directory - it first ensures that all necessary 93 | // subdirectories have been created. Also, the item may itself be a directory. 94 | // If you unzip a directory with ZIP_FILENAME, then the directory gets created. 95 | // If you unzip it to a handle or a memory block, then nothing gets created 96 | // and it emits 0 bytes. 97 | ZIPAPI ZRESULT SetUnzipBaseDir(HZIP hz, const TCHAR *dir); 98 | // if unzipping to a filename, and it's a relative filename, then it will be relative to here. 99 | // (defaults to current-directory). 100 | 101 | 102 | //ZIPAPI ZRESULT CloseZip(HZIP hz); 103 | // CloseZip - the zip handle must be closed with this function. 104 | 105 | unsigned int FormatZipMessage(ZRESULT code, TCHAR *buf, unsigned int len); 106 | // FormatZipMessage - given an error code, formats it as a string. 107 | // It returns the length of the error message. If buf/len points 108 | // to a real buffer, then it also writes as much as possible into there. 109 | 110 | 111 | // These are the result codes: 112 | #define ZR_OK 0x00000000 // nb. the pseudo-code zr-recent is never returned, 113 | #define ZR_RECENT 0x00000001 // but can be passed to FormatZipMessage. 114 | // The following come from general system stuff (e.g. files not openable) 115 | #define ZR_GENMASK 0x0000FF00 116 | #define ZR_NODUPH 0x00000100 // couldn't duplicate the handle 117 | #define ZR_NOFILE 0x00000200 // couldn't create/open the file 118 | #define ZR_NOALLOC 0x00000300 // failed to allocate some resource 119 | #define ZR_WRITE 0x00000400 // a general error writing to the file 120 | #define ZR_NOTFOUND 0x00000500 // couldn't find that file in the zip 121 | #define ZR_MORE 0x00000600 // there's still more data to be unzipped 122 | #define ZR_CORRUPT 0x00000700 // the zipfile is corrupt or not a zipfile 123 | #define ZR_READ 0x00000800 // a general error reading the file 124 | #define ZR_PASSWORD 0x00001000 // we didn't get the right password to unzip the file 125 | // The following come from mistakes on the part of the caller 126 | #define ZR_CALLERMASK 0x00FF0000 127 | #define ZR_ARGS 0x00010000 // general mistake with the arguments 128 | #define ZR_NOTMMAP 0x00020000 // tried to ZipGetMemory, but that only works on mmap zipfiles, which yours wasn't 129 | #define ZR_MEMSIZE 0x00030000 // the memory size is too small 130 | #define ZR_FAILED 0x00040000 // the thing was already failed when you called this function 131 | #define ZR_ENDED 0x00050000 // the zip creation has already been closed 132 | #define ZR_MISSIZE 0x00060000 // the indicated input file size turned out mistaken 133 | #define ZR_PARTIALUNZ 0x00070000 // the file had already been partially unzipped 134 | #define ZR_ZMODE 0x00080000 // tried to mix creating/opening a zip 135 | // The following come from bugs within the zip library itself 136 | #define ZR_BUGMASK 0xFF000000 137 | #define ZR_NOTINITED 0x01000000 // initialisation didn't work 138 | #define ZR_SEEK 0x02000000 // trying to seek in an unseekable file 139 | #define ZR_NOCHANGE 0x04000000 // changed its mind on storage, but not allowed 140 | #define ZR_FLATE 0x05000000 // an internal error in the de/inflation code 141 | 142 | 143 | 144 | 145 | 146 | // e.g. 147 | // 148 | // SetCurrentDirectory("c:\\docs\\stuff"); 149 | // HZIP hz = OpenZip("c:\\stuff.zip",0); 150 | // ZIPENTRY ze; GetZipItem(hz,-1,&ze); int numitems=ze.index; 151 | // for (int i=0; i 39 | 40 | // operation messages sent to DLGINIT 41 | #define LB_ADDSTRING (WM_USER+1) 42 | #define CB_ADDSTRING (WM_USER+3) 43 | #endif // !_WIN32_WCE 44 | 45 | #ifdef APSTUDIO_INVOKED 46 | #undef APSTUDIO_HIDDEN_SYMBOLS 47 | #endif // APSTUDIO_INVOKED 48 | 49 | #ifdef IDC_STATIC 50 | #undef IDC_STATIC 51 | #endif // IDC_STATIC 52 | #define IDC_STATIC (-1) 53 | 54 | #endif // !_INC_WINDOWS 55 | #endif // RC_INVOKED 56 | 57 | #ifdef APSTUDIO_INVOKED 58 | #define APSTUDIO_HIDDEN_SYMBOLS 59 | #endif // APSTUDIO_INVOKED 60 | 61 | /////////////////////////////////////////////////////////////////////////////// 62 | // ATL resource types 63 | 64 | #ifndef RC_INVOKED 65 | #define RT_DLGINIT MAKEINTRESOURCE(240) 66 | #define RT_TOOLBAR MAKEINTRESOURCE(241) 67 | #endif // RC_INVOKED 68 | 69 | /////////////////////////////////////////////////////////////////////////////// 70 | 71 | #ifdef APSTUDIO_INVOKED 72 | #undef APSTUDIO_HIDDEN_SYMBOLS 73 | #endif // APSTUDIO_INVOKED 74 | 75 | /////////////////////////////////////////////////////////////////////////////// 76 | // Standard window components 77 | 78 | #define ID_SEPARATOR 0 // special separator value 79 | #define ID_DEFAULT_PANE 0 // default status bar pane 80 | 81 | #ifndef RC_INVOKED // code only 82 | // standard control bars (IDW = window ID) 83 | #define ATL_IDW_TOOLBAR 0xE800 // main Toolbar for window 84 | #define ATL_IDW_STATUS_BAR 0xE801 // Status bar window 85 | #define ATL_IDW_COMMAND_BAR 0xE802 // Command bar window 86 | 87 | // parts of a frame window 88 | #define ATL_IDW_CLIENT 0xE900 89 | #define ATL_IDW_PANE_FIRST 0xE900 // first pane (256 max) 90 | #define ATL_IDW_PANE_LAST 0xE9FF 91 | #define ATL_IDW_HSCROLL_FIRST 0xEA00 // first Horz scrollbar (16 max) 92 | #define ATL_IDW_VSCROLL_FIRST 0xEA10 // first Vert scrollbar (16 max) 93 | 94 | #define ATL_IDW_SIZE_BOX 0xEA20 // size box for splitters 95 | #define ATL_IDW_PANE_SAVE 0xEA21 // to shift ATL_IDW_PANE_FIRST 96 | 97 | // bands for a rebar 98 | #define ATL_IDW_BAND_FIRST 0xEB00 99 | #define ATL_IDW_BAND_LAST 0xEBFF 100 | #endif // !RC_INVOKED 101 | 102 | /////////////////////////////////////////////////////////////////////////////// 103 | // Standard Commands 104 | 105 | // File commands 106 | #define ID_FILE_NEW 0xE100 107 | #define ID_FILE_OPEN 0xE101 108 | #define ID_FILE_CLOSE 0xE102 109 | #define ID_FILE_SAVE 0xE103 110 | #define ID_FILE_SAVE_AS 0xE104 111 | #define ID_FILE_PAGE_SETUP 0xE105 112 | #define ID_FILE_PRINT_SETUP 0xE106 113 | #define ID_FILE_PRINT 0xE107 114 | #define ID_FILE_PRINT_DIRECT 0xE108 115 | #define ID_FILE_PRINT_PREVIEW 0xE109 116 | #define ID_FILE_UPDATE 0xE10A 117 | #define ID_FILE_SAVE_COPY_AS 0xE10B 118 | #define ID_FILE_SEND_MAIL 0xE10C 119 | 120 | #define ID_FILE_MRU_FIRST 0xE110 121 | #define ID_FILE_MRU_FILE1 0xE110 // range - 16 max 122 | #define ID_FILE_MRU_FILE2 0xE111 123 | #define ID_FILE_MRU_FILE3 0xE112 124 | #define ID_FILE_MRU_FILE4 0xE113 125 | #define ID_FILE_MRU_FILE5 0xE114 126 | #define ID_FILE_MRU_FILE6 0xE115 127 | #define ID_FILE_MRU_FILE7 0xE116 128 | #define ID_FILE_MRU_FILE8 0xE117 129 | #define ID_FILE_MRU_FILE9 0xE118 130 | #define ID_FILE_MRU_FILE10 0xE119 131 | #define ID_FILE_MRU_FILE11 0xE11A 132 | #define ID_FILE_MRU_FILE12 0xE11B 133 | #define ID_FILE_MRU_FILE13 0xE11C 134 | #define ID_FILE_MRU_FILE14 0xE11D 135 | #define ID_FILE_MRU_FILE15 0xE11E 136 | #define ID_FILE_MRU_FILE16 0xE11F 137 | #define ID_FILE_MRU_LAST 0xE11F 138 | 139 | // Edit commands 140 | #define ID_EDIT_CLEAR 0xE120 141 | #define ID_EDIT_CLEAR_ALL 0xE121 142 | #define ID_EDIT_COPY 0xE122 143 | #define ID_EDIT_CUT 0xE123 144 | #define ID_EDIT_FIND 0xE124 145 | #define ID_EDIT_PASTE 0xE125 146 | #define ID_EDIT_PASTE_LINK 0xE126 147 | #define ID_EDIT_PASTE_SPECIAL 0xE127 148 | #define ID_EDIT_REPEAT 0xE128 149 | #define ID_EDIT_REPLACE 0xE129 150 | #define ID_EDIT_SELECT_ALL 0xE12A 151 | #define ID_EDIT_UNDO 0xE12B 152 | #define ID_EDIT_REDO 0xE12C 153 | #define ID_EDIT_DELETE ID_EDIT_CLEAR 154 | #define ID_EDIT_FIND_NEXT ID_EDIT_REPEAT 155 | #define ID_EDIT_FIND_PREVIOUS 0xE12D 156 | 157 | // Window commands 158 | #define ID_WINDOW_NEW 0xE130 159 | #define ID_WINDOW_ARRANGE 0xE131 160 | #define ID_WINDOW_CASCADE 0xE132 161 | #define ID_WINDOW_TILE_HORZ 0xE133 162 | #define ID_WINDOW_TILE_VERT 0xE134 163 | #define ID_WINDOW_SPLIT 0xE135 164 | #ifndef RC_INVOKED // code only 165 | #define ATL_IDM_WINDOW_FIRST 0xE130 166 | #define ATL_IDM_WINDOW_LAST 0xE13F 167 | #define ATL_IDM_FIRST_MDICHILD 0xFF00 // window list starts here 168 | #define ATL_IDM_LAST_MDICHILD 0xFFFD 169 | #endif // !RC_INVOKED 170 | // TabView 171 | #define ID_WINDOW_TABFIRST 0xFF00 // = ATL_IDM_FIRST_MDICHILD 172 | #define ID_WINDOW_TABLAST 0xFFFD 173 | #define ID_WINDOW_SHOWTABLIST 0xFFFE 174 | 175 | // Help and App commands 176 | #define ID_APP_ABOUT 0xE140 177 | #define ID_APP_EXIT 0xE141 178 | #define ID_HELP_INDEX 0xE142 179 | #define ID_HELP_FINDER 0xE143 180 | #define ID_HELP_USING 0xE144 181 | #define ID_CONTEXT_HELP 0xE145 // shift-F1 182 | // special commands for processing help 183 | #define ID_HELP 0xE146 // first attempt for F1 184 | #define ID_DEFAULT_HELP 0xE147 // last attempt 185 | 186 | // Misc 187 | #define ID_NEXT_PANE 0xE150 188 | #define ID_PREV_PANE 0xE151 189 | #define ID_PANE_CLOSE 0xE152 190 | #define ID_PANE_NEXT ID_NEXT_PANE 191 | #define ID_PANE_PREVIOUS ID_PREV_PANE 192 | 193 | // Format 194 | #define ID_FORMAT_FONT 0xE160 195 | 196 | // Scroll 197 | #define ID_SCROLL_UP 0xE170 198 | #define ID_SCROLL_DOWN 0xE171 199 | #define ID_SCROLL_PAGE_UP 0xE172 200 | #define ID_SCROLL_PAGE_DOWN 0xE173 201 | #define ID_SCROLL_TOP 0xE174 202 | #define ID_SCROLL_BOTTOM 0xE175 203 | #define ID_SCROLL_LEFT 0xE176 204 | #define ID_SCROLL_RIGHT 0xE177 205 | #define ID_SCROLL_PAGE_LEFT 0xE178 206 | #define ID_SCROLL_PAGE_RIGHT 0xE179 207 | #define ID_SCROLL_ALL_LEFT 0xE17A 208 | #define ID_SCROLL_ALL_RIGHT 0xE17B 209 | 210 | // OLE commands 211 | #define ID_OLE_INSERT_NEW 0xE200 212 | #define ID_OLE_EDIT_LINKS 0xE201 213 | #define ID_OLE_EDIT_CONVERT 0xE202 214 | #define ID_OLE_EDIT_CHANGE_ICON 0xE203 215 | #define ID_OLE_EDIT_PROPERTIES 0xE204 216 | #define ID_OLE_VERB_FIRST 0xE210 // range - 16 max 217 | #ifndef RC_INVOKED // code only 218 | #define ID_OLE_VERB_LAST 0xE21F 219 | #endif // !RC_INVOKED 220 | 221 | // View commands (same number used as IDW used for toolbar and status bar) 222 | #define ID_VIEW_TOOLBAR 0xE800 223 | #define ID_VIEW_STATUS_BAR 0xE801 224 | #define ID_VIEW_REFRESH 0xE803 225 | #define ID_VIEW_RIBBON 0xE804 226 | 227 | /////////////////////////////////////////////////////////////////////////////// 228 | // Standard control IDs 229 | 230 | #ifdef IDC_STATIC 231 | #undef IDC_STATIC 232 | #endif // IDC_STATIC 233 | #define IDC_STATIC (-1) // all static controls 234 | 235 | /////////////////////////////////////////////////////////////////////////////// 236 | // Standard string error/warnings 237 | 238 | // idle status bar message 239 | #define ATL_IDS_IDLEMESSAGE 0xE001 240 | 241 | #ifndef RC_INVOKED // code only 242 | #define ATL_IDS_SCFIRST 0xEF00 243 | #endif // !RC_INVOKED 244 | 245 | #define ATL_IDS_SCSIZE 0xEF00 246 | #define ATL_IDS_SCMOVE 0xEF01 247 | #define ATL_IDS_SCMINIMIZE 0xEF02 248 | #define ATL_IDS_SCMAXIMIZE 0xEF03 249 | #define ATL_IDS_SCNEXTWINDOW 0xEF04 250 | #define ATL_IDS_SCPREVWINDOW 0xEF05 251 | #define ATL_IDS_SCCLOSE 0xEF06 252 | #define ATL_IDS_SCRESTORE 0xEF12 253 | #define ATL_IDS_SCTASKLIST 0xEF13 254 | 255 | #define ATL_IDS_MDICHILD 0xEF1F 256 | #define ATL_IDS_MRU_FILE 0xEFDA 257 | 258 | /////////////////////////////////////////////////////////////////////////////// 259 | // Misc. control IDs 260 | 261 | // Property Sheet control id's (determined with Spy++) 262 | #define ID_APPLY_NOW 0x3021 263 | #define ID_WIZBACK 0x3023 264 | #define ID_WIZNEXT 0x3024 265 | #define ID_WIZFINISH 0x3025 266 | #define ATL_IDC_TAB_CONTROL 0x3020 267 | 268 | #endif // __ATLRES_H__ 269 | -------------------------------------------------------------------------------- /WTL/atldwm.h: -------------------------------------------------------------------------------- 1 | // Windows Template Library - WTL version 9.0 2 | // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved. 3 | // 4 | // This file is a part of the Windows Template Library. 5 | // The use and distribution terms for this software are covered by the 6 | // Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) 7 | // which can be found in the file CPL.TXT at the root of this distribution. 8 | // By using this software in any fashion, you are agreeing to be bound by 9 | // the terms of this license. You must not remove this notice, or 10 | // any other, from this software. 11 | 12 | #ifndef __ATLDWM_H__ 13 | #define __ATLDWM_H__ 14 | 15 | #pragma once 16 | 17 | #ifdef _WIN32_WCE 18 | #error atldwm.h is not supported on Windows CE 19 | #endif 20 | 21 | #ifndef __ATLAPP_H__ 22 | #error atldwm.h requires atlapp.h to be included first 23 | #endif 24 | 25 | #ifndef __ATLWIN_H__ 26 | #error atldwm.h requires atlwin.h to be included first 27 | #endif 28 | 29 | #if (_WIN32_WINNT < 0x0600) 30 | #error atldwm.h requires _WIN32_WINNT >= 0x0600 31 | #endif 32 | 33 | #ifndef _DWMAPI_H_ 34 | #include 35 | #endif 36 | #pragma comment(lib, "dwmapi.lib") 37 | 38 | // Note: To create an application that also runs on older versions of Windows, 39 | // use delay load of dwmapi.dll and ensure that no calls to the DWM API are 40 | // Delay load is NOT AUTOMATIC for VC++ 7, you have to link to delayimp.lib, 41 | // and add dwmapi.dll in the Linker.Input.Delay Loaded DLLs section of the 42 | // project properties. 43 | #if (_MSC_VER < 1300) && !defined(_WTL_NO_DWMAPI_DELAYLOAD) 44 | #pragma comment(lib, "delayimp.lib") 45 | #pragma comment(linker, "/delayload:dwmapi.dll") 46 | #endif // (_MSC_VER < 1300) && !defined(_WTL_NO_DWMAPI_DELAYLOAD) 47 | 48 | /////////////////////////////////////////////////////////////////////////////// 49 | // Classes in this file: 50 | // 51 | // CDwm 52 | // CDwmImpl 53 | // CDwmWindowT - CDwmWindow 54 | // CDwmThumbnailT 55 | // CDwmThumbnail 56 | // CDwmThumbnailHandle 57 | // CAeroControlImpl 58 | 59 | 60 | namespace WTL 61 | { 62 | 63 | /////////////////////////////////////////////////////////////////////////////// 64 | // CDwm - wrapper for DWM handle 65 | 66 | class CDwm 67 | { 68 | public: 69 | #ifdef DisableXP 70 | // Data members 71 | static int m_nIsDwmSupported; 72 | 73 | // Constructor 74 | 75 | CDwm() 76 | { 77 | IsDwmSupported(); 78 | } 79 | 80 | 81 | // Dwm support helper 82 | static bool IsDwmSupported() 83 | { 84 | if(m_nIsDwmSupported == -1) 85 | { 86 | CStaticDataInitCriticalSectionLock lock; 87 | if(FAILED(lock.Lock())) 88 | { 89 | ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CDwm::IsDwmSupported.\n")); 90 | ATLASSERT(FALSE); 91 | return false; 92 | } 93 | 94 | if(m_nIsDwmSupported == -1) 95 | { 96 | HMODULE hDwmDLL = ::LoadLibrary(_T("dwmapi.dll")); 97 | m_nIsDwmSupported = (hDwmDLL != NULL) ? 1 : 0; 98 | if(hDwmDLL != NULL) 99 | ::FreeLibrary(hDwmDLL); 100 | } 101 | 102 | lock.Unlock(); 103 | } 104 | 105 | ATLASSERT(m_nIsDwmSupported != -1); 106 | return (m_nIsDwmSupported == 1); 107 | } 108 | #else 109 | static bool IsDwmSupported() 110 | { 111 | return true; 112 | } 113 | #endif 114 | 115 | // Operations 116 | BOOL DwmIsCompositionEnabled() const 117 | { 118 | #ifdef DisableXP 119 | if(!IsDwmSupported()) 120 | return FALSE; 121 | #endif 122 | BOOL bRes = FALSE; 123 | return (SUCCEEDED(::DwmIsCompositionEnabled(&bRes)) && bRes) ? TRUE : FALSE; 124 | } 125 | 126 | BOOL DwmEnableComposition(UINT fEnable) 127 | { 128 | #ifdef DisableXP 129 | if(!IsDwmSupported()) 130 | return FALSE; 131 | #endif 132 | return SUCCEEDED(::DwmEnableComposition(fEnable)) ? TRUE : FALSE; 133 | } 134 | 135 | BOOL DwmEnableMMCSS(BOOL fEnableMMCSS) 136 | { 137 | #ifdef DisableXP 138 | if(!IsDwmSupported()) 139 | return FALSE; 140 | #endif 141 | return SUCCEEDED(::DwmEnableMMCSS(fEnableMMCSS)) ? TRUE : FALSE; 142 | } 143 | 144 | HRESULT DwmGetColorizationColor(DWORD* pcrColorization, BOOL* pfOpaqueBlend) 145 | { 146 | #ifdef DisableXP 147 | if(!IsDwmSupported()) 148 | return E_NOTIMPL; 149 | #endif 150 | return ::DwmGetColorizationColor(pcrColorization, pfOpaqueBlend); 151 | } 152 | 153 | HRESULT DwmFlush() 154 | { 155 | #ifdef DisableXP 156 | if(!IsDwmSupported()) 157 | return E_NOTIMPL; 158 | #endif 159 | return ::DwmFlush(); 160 | } 161 | }; 162 | #ifdef DisableXP 163 | __declspec(selectany) int CDwm::m_nIsDwmSupported = -1; 164 | #endif 165 | 166 | /////////////////////////////////////////////////////////////////////////////// 167 | // CDwmImpl - DWM window support 168 | 169 | template 170 | class CDwmImpl : public TBase 171 | { 172 | public: 173 | HRESULT DwmEnableBlurBehindWindow(const DWM_BLURBEHIND* pBB) 174 | { 175 | if(!IsDwmSupported()) 176 | return E_NOTIMPL; 177 | 178 | T* pT = static_cast(this); 179 | ATLASSERT(::IsWindow(pT->m_hWnd)); 180 | return ::DwmEnableBlurBehindWindow(pT->m_hWnd, pBB); 181 | } 182 | 183 | HRESULT DwmExtendFrameIntoClientArea(const MARGINS* pMargins) 184 | { 185 | if(!IsDwmSupported()) 186 | return E_NOTIMPL; 187 | 188 | T* pT = static_cast(this); 189 | ATLASSERT(::IsWindow(pT->m_hWnd)); 190 | return ::DwmExtendFrameIntoClientArea(pT->m_hWnd, pMargins); 191 | } 192 | 193 | HRESULT DwmExtendFrameIntoEntireClientArea() 194 | { 195 | MARGINS margins = { -1 }; 196 | return DwmExtendFrameIntoClientArea(&margins); 197 | } 198 | 199 | HRESULT DwmGetCompositionTimingInfo(DWM_TIMING_INFO* pTimingInfo) 200 | { 201 | if(!IsDwmSupported()) 202 | return E_NOTIMPL; 203 | 204 | T* pT = static_cast(this); 205 | ATLASSERT(::IsWindow(pT->m_hWnd)); 206 | return ::DwmGetCompositionTimingInfo(pT->m_hWnd, pTimingInfo); 207 | } 208 | 209 | HRESULT DwmGetWindowAttribute(DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute) 210 | { 211 | if(!IsDwmSupported()) 212 | return E_NOTIMPL; 213 | 214 | T* pT = static_cast(this); 215 | ATLASSERT(::IsWindow(pT->m_hWnd)); 216 | return ::DwmGetWindowAttribute(pT->m_hWnd, dwAttribute, pvAttribute, cbAttribute); 217 | } 218 | 219 | HRESULT DwmModifyPreviousDxFrameDuration(INT cRefreshes, BOOL fRelative) 220 | { 221 | if(!IsDwmSupported()) 222 | return E_NOTIMPL; 223 | 224 | T* pT = static_cast(this); 225 | ATLASSERT(::IsWindow(pT->m_hWnd)); 226 | return ::DwmModifyPreviousDxFrameDuration(pT->m_hWnd, cRefreshes, fRelative); 227 | } 228 | 229 | HRESULT DwmSetDxFrameDuration(INT cRefreshes) 230 | { 231 | if(!IsDwmSupported()) 232 | return E_NOTIMPL; 233 | 234 | T* pT = static_cast(this); 235 | ATLASSERT(::IsWindow(pT->m_hWnd)); 236 | return ::DwmSetDxFrameDuration(pT->m_hWnd, cRefreshes); 237 | } 238 | 239 | HRESULT DwmSetPresentParameters(DWM_PRESENT_PARAMETERS* pPresentParams) 240 | { 241 | if(!IsDwmSupported()) 242 | return E_NOTIMPL; 243 | 244 | T* pT = static_cast(this); 245 | ATLASSERT(::IsWindow(pT->m_hWnd)); 246 | return ::DwmSetPresentParameters(pT->m_hWnd, pPresentParams); 247 | } 248 | 249 | HRESULT DwmSetWindowAttribute(DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute) 250 | { 251 | if(!IsDwmSupported()) 252 | return E_NOTIMPL; 253 | 254 | T* pT = static_cast(this); 255 | ATLASSERT(::IsWindow(pT->m_hWnd)); 256 | return ::DwmSetWindowAttribute(pT->m_hWnd, dwAttribute, pvAttribute, cbAttribute); 257 | } 258 | 259 | HRESULT DwmAttachMilContent() 260 | { 261 | if(!IsDwmSupported()) 262 | return E_NOTIMPL; 263 | 264 | T* pT = static_cast(this); 265 | ATLASSERT(::IsWindow(pT->m_hWnd)); 266 | return ::DwmAttachMilContent(pT->m_hWnd); 267 | } 268 | 269 | HRESULT DwmDetachMilContent() 270 | { 271 | if(!IsDwmSupported()) 272 | return E_NOTIMPL; 273 | 274 | T* pT = static_cast(this); 275 | ATLASSERT(::IsWindow(pT->m_hWnd)); 276 | return ::DwmDetachMilContent(pT->m_hWnd); 277 | } 278 | }; 279 | 280 | template 281 | class CDwmWindowT : public TBase, public CDwmImpl > 282 | { 283 | public: 284 | CDwmWindowT(HWND hWnd = NULL) : TBase(hWnd) 285 | { } 286 | 287 | CDwmWindowT< TBase >& operator =(HWND hWnd) 288 | { 289 | m_hWnd = hWnd; 290 | return *this; 291 | } 292 | }; 293 | 294 | typedef CDwmWindowT CDwmWindow; 295 | 296 | 297 | /////////////////////////////////////////////////////////////////////////////// 298 | // CDwmThumbnail - provides DWM thumbnail support 299 | 300 | template 301 | class CDwmThumbnailT : public TBase 302 | { 303 | public: 304 | // Data members 305 | HTHUMBNAIL m_hThumbnail; 306 | 307 | // Constructor 308 | CDwmThumbnailT(HTHUMBNAIL hThumbnail = NULL) : m_hThumbnail(hThumbnail) 309 | { } 310 | 311 | ~CDwmThumbnailT() 312 | { 313 | if(t_bManaged && (m_hThumbnail != NULL)) 314 | Unregister(); 315 | } 316 | 317 | // Operations 318 | CDwmThumbnailT& operator =(HTHUMBNAIL hThumbnail) 319 | { 320 | Attach(hThumbnail); 321 | return *this; 322 | } 323 | 324 | void Attach(HTHUMBNAIL hThumbnailNew) 325 | { 326 | if(t_bManaged && m_hThumbnail != NULL && m_hThumbnail != hThumbnailNew) 327 | Unregister(); 328 | m_hThumbnail = hThumbnailNew; 329 | } 330 | 331 | HTHUMBNAIL Detach() 332 | { 333 | HTHUMBNAIL hThumbnail = m_hThumbnail; 334 | m_hThumbnail = NULL; 335 | return hThumbnail; 336 | } 337 | 338 | HRESULT Register(HWND hwndDestination, HWND hwndSource) 339 | { 340 | ATLASSERT(::IsWindow(hwndDestination)); 341 | ATLASSERT(::IsWindow(hwndSource)); 342 | ATLASSERT(m_hThumbnail==NULL); 343 | 344 | if(!IsDwmSupported()) 345 | return E_NOTIMPL; 346 | 347 | return ::DwmRegisterThumbnail(hwndDestination, hwndSource, &m_hThumbnail); 348 | } 349 | 350 | HRESULT Unregister() 351 | { 352 | if(!IsDwmSupported()) 353 | return E_NOTIMPL; 354 | if(m_hThumbnail == NULL) 355 | return S_FALSE; 356 | 357 | HRESULT Hr = ::DwmUnregisterThumbnail(m_hThumbnail); 358 | if(SUCCEEDED(Hr)) 359 | m_hThumbnail = NULL; 360 | 361 | return Hr; 362 | } 363 | 364 | operator HTHUMBNAIL() const { return m_hThumbnail; } 365 | 366 | bool IsNull() const { return (m_hThumbnail == NULL); } 367 | 368 | HRESULT UpdateProperties(const DWM_THUMBNAIL_PROPERTIES* ptnProperties) 369 | { 370 | if(!IsDwmSupported()) 371 | return E_NOTIMPL; 372 | 373 | ATLASSERT(m_hThumbnail != NULL); 374 | return ::DwmUpdateThumbnailProperties(m_hThumbnail, ptnProperties); 375 | } 376 | 377 | // Attributes 378 | HRESULT QuerySourceSize(PSIZE pSize) 379 | { 380 | if(!IsDwmSupported()) 381 | return E_NOTIMPL; 382 | 383 | ATLASSERT(m_hThumbnail != NULL); 384 | return ::DwmQueryThumbnailSourceSize(m_hThumbnail, pSize); 385 | } 386 | }; 387 | 388 | typedef CDwmThumbnailT CDwmThumbnail; 389 | typedef CDwmThumbnailT CDwmThumbnailHandle; 390 | 391 | 392 | #ifdef __ATLTHEME_H__ 393 | 394 | /////////////////////////////////////////////////////////////////////////////// 395 | // CAeroControlImpl - Base class for controls on Glass 396 | 397 | template 398 | class CAeroControlImpl : public CThemeImpl, 399 | public CBufferedPaintImpl, 400 | public ATL::CWindowImpl 401 | { 402 | public: 403 | typedef CThemeImpl _themeClass; 404 | typedef CBufferedPaintImpl _baseClass; 405 | typedef ATL::CWindowImpl _windowClass; 406 | 407 | CAeroControlImpl() 408 | { 409 | m_PaintParams.dwFlags = BPPF_ERASE; 410 | } 411 | 412 | static LPCWSTR GetThemeName() 413 | { 414 | #ifdef _UNICODE 415 | return TBase::GetWndClassName(); 416 | #else 417 | ATLASSERT(!_T("Return UNICODE string of window classname / theme class")); 418 | return NULL; 419 | #endif // _UNICODE 420 | } 421 | 422 | // Message map and handlers 423 | BEGIN_MSG_MAP(CAeroControlImpl) 424 | MESSAGE_HANDLER(WM_CREATE, OnCreate) 425 | MESSAGE_HANDLER(WM_ACTIVATE, OnActivate) 426 | CHAIN_MSG_MAP(_themeClass) 427 | CHAIN_MSG_MAP(_baseClass) 428 | END_MSG_MAP() 429 | 430 | LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) 431 | { 432 | T* pT = static_cast(this); 433 | pT->Init(); 434 | 435 | bHandled = FALSE; 436 | return 0; 437 | } 438 | 439 | LRESULT OnActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) 440 | { 441 | if(IsThemingSupported()) 442 | Invalidate(FALSE); 443 | 444 | bHandled = FALSE; 445 | return 0; 446 | } 447 | 448 | // Operations 449 | BOOL SubclassWindow(HWND hWnd) 450 | { 451 | ATLASSERT(m_hWnd == NULL); 452 | ATLASSERT(::IsWindow(hWnd)); 453 | BOOL bRet = _windowClass::SubclassWindow(hWnd); 454 | if(bRet) 455 | { 456 | T* pT = static_cast(this); 457 | pT->Init(); 458 | } 459 | 460 | return bRet; 461 | } 462 | 463 | // Implementation 464 | LRESULT DefWindowProc() 465 | { 466 | const ATL::_ATL_MSG* pMsg = m_pCurrentMsg; 467 | LRESULT lRes = 0; 468 | if(pMsg != NULL) 469 | lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg->lParam); 470 | 471 | return lRes; 472 | } 473 | 474 | LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) 475 | { 476 | T* pT = static_cast(this); 477 | LRESULT lRes = 0; 478 | if(::DwmDefWindowProc(pT->m_hWnd, uMsg, wParam, lParam, &lRes) != FALSE) 479 | return lRes; 480 | 481 | return _windowClass::DefWindowProc(uMsg, wParam, lParam); 482 | } 483 | 484 | void DoBufferedPaint(HDC hDC, RECT& rcPaint) 485 | { 486 | T* pT = static_cast(this); 487 | HDC hDCPaint = NULL; 488 | RECT rcClient = { 0 }; 489 | GetClientRect(&rcClient); 490 | m_BufferedPaint.Begin(hDC, &rcClient, m_dwFormat, &m_PaintParams, &hDCPaint); 491 | ATLASSERT(hDCPaint != NULL); 492 | pT->DoAeroPaint(hDCPaint, rcClient, rcPaint); 493 | m_BufferedPaint.End(); 494 | } 495 | 496 | void DoPaint(HDC /*hdc*/, RECT& /*rcClient*/) 497 | { 498 | DefWindowProc(); 499 | } 500 | 501 | // Overridables 502 | void Init() 503 | { 504 | T* pT = static_cast(this); 505 | pT; // avoid level 4 warning 506 | SetThemeClassList(pT->GetThemeName()); 507 | if(m_lpstrThemeClassList != NULL) 508 | OpenThemeData(); 509 | } 510 | 511 | void DoAeroPaint(HDC hDC, RECT& /*rcClient*/, RECT& rcPaint) 512 | { 513 | DefWindowProc(WM_PAINT, (WPARAM) hDC, 0L); 514 | m_BufferedPaint.MakeOpaque(&rcPaint); 515 | } 516 | }; 517 | 518 | #endif // __ATLTHEME_H__ 519 | 520 | }; // namespace WTL 521 | 522 | #endif // __ATLDWM_H__ 523 | -------------------------------------------------------------------------------- /rapidxml/rapidxml_print.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDXML_PRINT_HPP_INCLUDED 2 | #define RAPIDXML_PRINT_HPP_INCLUDED 3 | 4 | // Copyright (C) 2006, 2009 Marcin Kalicinski 5 | // Version 1.13 6 | // Revision $DateTime: 2009/05/13 01:46:17 $ 7 | //! \file rapidxml_print.hpp This file contains rapidxml printer implementation 8 | 9 | #include "rapidxml.hpp" 10 | #include 11 | 12 | namespace rapidxml 13 | { 14 | 15 | /////////////////////////////////////////////////////////////////////// 16 | // Printing flags 17 | 18 | const int print_no_indenting = 0x1; //!< Printer flag instructing the printer to suppress indenting of XML. See print() function. 19 | 20 | /////////////////////////////////////////////////////////////////////// 21 | // Internal 22 | 23 | //! \cond internal 24 | namespace internal 25 | { 26 | 27 | /////////////////////////////////////////////////////////////////////////// 28 | // Internal character operations 29 | 30 | // Copy characters from given range to given output iterator 31 | template 32 | inline void copy_chars(const Ch *begin, const Ch *end, CStringT& out) 33 | { 34 | while (begin != end) 35 | out+= *begin++; 36 | } 37 | 38 | // Copy characters from given range to given output iterator and expand 39 | // characters into references (< > ' " &) 40 | template 41 | inline void copy_and_expand_chars(const Ch *begin, const Ch *end, Ch noexpand, CStringT& out) 42 | { 43 | while (begin != end) 44 | { 45 | if (*begin == noexpand) 46 | { 47 | // No expansion, copy character 48 | out += *begin; 49 | //++begin; // Step to next character 50 | } 51 | else 52 | { 53 | switch (*begin) 54 | { 55 | case Ch('<'): 56 | out+= Ch('&'); 57 | out+= Ch('l'); 58 | out+= Ch('t'); 59 | out+= Ch(';'); 60 | break; 61 | case Ch('>'): 62 | out+= Ch('&'); 63 | out+= Ch('g'); 64 | out+= Ch('t'); 65 | out+= Ch(';'); 66 | break; 67 | case Ch('\''): 68 | out+= Ch('&'); 69 | out+= Ch('a'); 70 | out+= Ch('p'); 71 | out+= Ch('o'); 72 | out+= Ch('s'); 73 | out+= Ch(';'); 74 | break; 75 | case Ch('"'): 76 | out+= Ch('&'); 77 | out+= Ch('q'); 78 | out+= Ch('u'); 79 | out+= Ch('o'); 80 | out+= Ch('t'); 81 | out+= Ch(';'); 82 | break; 83 | case Ch('&'): 84 | out+= Ch('&'); 85 | out+= Ch('a'); 86 | out+= Ch('m'); 87 | out+= Ch('p'); 88 | out+= Ch(';'); 89 | break; 90 | default: 91 | out+= *begin; // No expansion, copy character 92 | break; 93 | } 94 | } 95 | ++begin; 96 | } 97 | } 98 | 99 | // Fill given output iterator with repetitions of the same character 100 | template 101 | inline void fill_chars(CStringT& out, int n, Ch ch) 102 | { 103 | for (int i = 0; i != n; ++i) 104 | out+= ch; 105 | // return out; 106 | } 107 | 108 | // Find character 109 | /* template 110 | inline bool find_char(const Ch *begin, const Ch *end) 111 | { 112 | while (begin != end) 113 | if (*begin++ == ch) 114 | return true; 115 | return false; 116 | }*/ 117 | 118 | /////////////////////////////////////////////////////////////////////////// 119 | // Internal printing operations 120 | 121 | // Print node 122 | template 123 | inline void print_node(CStringT& out, const xml_node *node, int flags, int indent); 124 | 125 | // Print children of the node 126 | template 127 | inline void print_children(CStringT& out, const xml_node *node, int flags, int indent) 128 | { 129 | for (xml_node *child = node->first_node(); child; child = child->next_sibling()) 130 | print_node(out, child, flags, indent); 131 | //return out; 132 | } 133 | 134 | // Print attributes of the node 135 | template 136 | inline void print_attributes(CStringT& out, const xml_node *node, int flags) 137 | { 138 | for (xml_attribute *attribute = node->first_attribute(); attribute; attribute = attribute->next_attribute()) 139 | { 140 | if (attribute->name() && attribute->value()) 141 | { 142 | // Print attribute name 143 | out += Ch(' '); 144 | copy_chars(attribute->name(), attribute->name() + attribute->name_size(), out); 145 | out += Ch('=');// , ++out; 146 | 147 | // Print attribute value using appropriate quote type 148 | // if (/*find_char(attribute->value(), attribute->value() + attribute->value_size())*/StrChrNW(attribute->value(),L'"', attribute->value_size())) 149 | //{ 150 | //out += Ch('\'');// , ++out; 151 | // copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('"'), out); 152 | //out += Ch('\'');// , ++out; 153 | // } 154 | // else 155 | { 156 | out += Ch('"');// , ++out; 157 | copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('\''), out); 158 | out += Ch('"');// , ++out; 159 | } 160 | } 161 | } 162 | // return out; 163 | } 164 | 165 | // Print data node 166 | template 167 | inline void print_data_node(CStringT& out, const xml_node *node, int flags, int indent) 168 | { 169 | assert(node->type() == node_data); 170 | if (!(flags & print_no_indenting)) 171 | fill_chars(out, indent, Ch('\t')); 172 | 173 | copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out); 174 | //return out; 175 | } 176 | 177 | // Print data node 178 | template 179 | inline void print_cdata_node(CStringT& out, const xml_node *node, int flags, int indent) 180 | { 181 | assert(node->type() == node_cdata); 182 | if (!(flags & print_no_indenting)) 183 | fill_chars(out, indent, Ch('\t')); 184 | 185 | out += Ch('<'); 186 | out += Ch('!'); 187 | out += Ch('['); 188 | out += Ch('C'); 189 | out += Ch('D'); 190 | out += Ch('A'); 191 | out += Ch('T'); 192 | out += Ch('A'); 193 | out += Ch('['); 194 | copy_chars(node->value(), node->value() + node->value_size(), out); 195 | out += Ch(']'); 196 | out += Ch(']'); 197 | out += Ch('>'); 198 | } 199 | 200 | // Print element node 201 | template 202 | inline void print_element_node(CStringT& out, const xml_node *node, int flags, int indent) 203 | { 204 | assert(node->type() == node_element); 205 | 206 | // Print element name and attributes, if any 207 | if (!(flags & print_no_indenting)) 208 | fill_chars(out, indent, Ch('\t')); 209 | 210 | out += Ch('<'); 211 | copy_chars(node->name(), node->name() + node->name_size(), out); 212 | print_attributes(out, node, flags); 213 | 214 | // If node is childless 215 | if (node->value_size() == 0 && !node->first_node()) 216 | { 217 | // Print childless node tag ending 218 | out += Ch('/'); 219 | out += Ch('>'); 220 | } 221 | else 222 | { 223 | // Print normal node tag ending 224 | out += Ch('>'); 225 | 226 | // Test if node contains a single data node only (and no other nodes) 227 | xml_node *child = node->first_node(); 228 | if (!child) 229 | { 230 | // If node has no children, only print its value without indenting 231 | copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out); 232 | } 233 | else if (child->next_sibling() == 0 && child->type() == node_data) 234 | { 235 | // If node has a sole data child, only print its value without indenting 236 | copy_and_expand_chars(child->value(), child->value() + child->value_size(), Ch(0), out); 237 | } 238 | else 239 | { 240 | // Print all children with full indenting 241 | if (!(flags & print_no_indenting)) 242 | out += Ch('\n'); 243 | print_children(out, node, flags, indent + 1); 244 | 245 | if (!(flags & print_no_indenting)) 246 | fill_chars(out, indent, Ch('\t')); 247 | } 248 | 249 | // Print node end 250 | out += Ch('<'); 251 | out += Ch('/'); 252 | copy_chars(node->name(), node->name() + node->name_size(), out); 253 | 254 | out += Ch('>'); 255 | } 256 | } 257 | 258 | // Print declaration node 259 | template 260 | inline void print_declaration_node(CStringT& out, const xml_node *node, int flags, int indent) 261 | { 262 | // Print declaration start 263 | if (!(flags & print_no_indenting)) 264 | fill_chars(out, indent, Ch('\t')); 265 | 266 | out += Ch('<'); 267 | out += Ch('?'); 268 | out += Ch('x'); 269 | out += Ch('m'); 270 | out += Ch('l'); 271 | 272 | // Print attributes 273 | print_attributes(out, node, flags); 274 | 275 | // Print declaration end 276 | out += Ch('?'); 277 | out += Ch('>'); 278 | 279 | //return out; 280 | } 281 | 282 | // Print comment node 283 | template 284 | inline void print_comment_node(CStringT& out, const xml_node *node, int flags, int indent) 285 | { 286 | assert(node->type() == node_comment); 287 | if (!(flags & print_no_indenting)) 288 | fill_chars(out, indent, Ch('\t')); 289 | 290 | out += Ch('<'); 291 | out += Ch('!'); 292 | out += Ch('-'); 293 | out += Ch('-'); 294 | 295 | copy_chars(node->value(), node->value() + node->value_size(), out); 296 | 297 | out += Ch('-'); 298 | out += Ch('-'); 299 | out += Ch('>'); 300 | } 301 | 302 | // Print doctype node 303 | template 304 | inline void print_doctype_node(CStringT& out, const xml_node *node, int flags, int indent) 305 | { 306 | assert(node->type() == node_doctype); 307 | if (!(flags & print_no_indenting)) 308 | fill_chars(out, indent, Ch('\t')); 309 | 310 | out += Ch('<'); 311 | out += Ch('!'); 312 | out += Ch('D'); 313 | out += Ch('O'); 314 | out += Ch('C'); 315 | out += Ch('T'); 316 | out += Ch('Y'); 317 | out += Ch('P'); 318 | out += Ch('E'); 319 | out += Ch(' '); 320 | 321 | copy_chars(node->value(), node->value() + node->value_size(), out); 322 | out += Ch('>'); 323 | } 324 | 325 | // Print pi node 326 | template 327 | inline void print_pi_node(CStringT& out, const xml_node *node, int flags, int indent) 328 | { 329 | assert(node->type() == node_pi); 330 | if (!(flags & print_no_indenting)) 331 | fill_chars(out, indent, Ch('\t')); 332 | 333 | out += Ch('<'); 334 | out += Ch('?'); 335 | copy_chars(node->name(), node->name() + node->name_size(), out); 336 | 337 | out += Ch(' '); 338 | copy_chars(node->value(), node->value() + node->value_size(), out); 339 | out += Ch('?'); 340 | out += Ch('>'); 341 | } 342 | 343 | // Print node 344 | template 345 | inline void print_node(CStringT& out, const xml_node *node, int flags, int indent) 346 | { 347 | // Print proper node type 348 | switch (node->type()) 349 | { 350 | 351 | // Document 352 | case node_document: 353 | print_children(out, node, flags, indent); 354 | break; 355 | 356 | // Element 357 | case node_element: 358 | print_element_node(out, node, flags, indent); 359 | break; 360 | 361 | // Data 362 | case node_data: 363 | print_data_node(out, node, flags, indent); 364 | break; 365 | 366 | // CDATA 367 | case node_cdata: 368 | print_cdata_node(out, node, flags, indent); 369 | break; 370 | 371 | // Declaration 372 | case node_declaration: 373 | print_declaration_node(out, node, flags, indent); 374 | break; 375 | 376 | // Comment 377 | case node_comment: 378 | print_comment_node(out, node, flags, indent); 379 | break; 380 | 381 | // Doctype 382 | case node_doctype: 383 | print_doctype_node(out, node, flags, indent); 384 | break; 385 | 386 | // Pi 387 | case node_pi: 388 | print_pi_node(out, node, flags, indent); 389 | break; 390 | 391 | // Unknown 392 | default: 393 | assert(0); 394 | break; 395 | } 396 | 397 | // If indenting not disabled, add line break after node 398 | if (!(flags & print_no_indenting)) 399 | out += Ch('\n'); 400 | 401 | // Return modified iterator 402 | //return out; 403 | } 404 | 405 | } 406 | //! \endcond 407 | 408 | /////////////////////////////////////////////////////////////////////////// 409 | // Printing 410 | 411 | //! Prints XML to given output iterator. 412 | //! \param out Output iterator to print to. 413 | //! \param node Node to be printed. Pass xml_document to print entire document. 414 | //! \param flags Flags controlling how XML is printed. 415 | //! \return Output iterator pointing to position immediately after last character of printed text. 416 | inline CStringA print(const xml_node &node, int flags = 0) 417 | { 418 | CStringA Temp; 419 | 420 | internal::print_node(Temp, &node, flags, 0); 421 | 422 | return Temp; 423 | } 424 | 425 | inline CStringW print(const xml_node &node, int flags = 0) 426 | { 427 | CStringW Temp; 428 | 429 | internal::print_node(Temp, &node, flags, 0); 430 | 431 | return Temp; 432 | } 433 | } 434 | 435 | #endif 436 | -------------------------------------------------------------------------------- /WTL/atlwinx.h: -------------------------------------------------------------------------------- 1 | // Windows Template Library - WTL version 9.0 2 | // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved. 3 | // 4 | // This file is a part of the Windows Template Library. 5 | // The use and distribution terms for this software are covered by the 6 | // Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) 7 | // which can be found in the file CPL.TXT at the root of this distribution. 8 | // By using this software in any fashion, you are agreeing to be bound by 9 | // the terms of this license. You must not remove this notice, or 10 | // any other, from this software. 11 | 12 | #ifndef __ATLWINX_H__ 13 | #define __ATLWINX_H__ 14 | 15 | #pragma once 16 | 17 | #ifndef __ATLAPP_H__ 18 | #error atlwinx.h requires atlapp.h to be included first 19 | #endif 20 | 21 | #if (_ATL_VER >= 0x0700) 22 | #include 23 | #endif // (_ATL_VER >= 0x0700) 24 | 25 | 26 | /////////////////////////////////////////////////////////////////////////////// 27 | // Classes in this file: 28 | // 29 | // _U_RECT 30 | // _U_MENUorID 31 | // _U_STRINGorID 32 | 33 | 34 | /////////////////////////////////////////////////////////////////////////////// 35 | // Command Chaining Macros 36 | 37 | #define CHAIN_COMMANDS(theChainClass) \ 38 | if(uMsg == WM_COMMAND) \ 39 | CHAIN_MSG_MAP(theChainClass) 40 | 41 | #define CHAIN_COMMANDS_ALT(theChainClass, msgMapID) \ 42 | if(uMsg == WM_COMMAND) \ 43 | CHAIN_MSG_MAP_ALT(theChainClass, msgMapID) 44 | 45 | #define CHAIN_COMMANDS_MEMBER(theChainMember) \ 46 | if(uMsg == WM_COMMAND) \ 47 | CHAIN_MSG_MAP_MEMBER(theChainMember) 48 | 49 | #define CHAIN_COMMANDS_ALT_MEMBER(theChainMember, msgMapID) \ 50 | if(uMsg == WM_COMMAND) \ 51 | CHAIN_MSG_MAP_ALT_MEMBER(theChainMember, msgMapID) 52 | 53 | 54 | /////////////////////////////////////////////////////////////////////////////// 55 | // Macros for parent message map to selectively reflect control messages 56 | 57 | // NOTE: ReflectNotifications is a member of ATL's CWindowImplRoot 58 | // (and overridden in 2 cases - CContainedWindowT and CAxHostWindow) 59 | // Since we can't modify ATL, we'll provide the needed additions 60 | // in a separate function (that is not a member of CWindowImplRoot) 61 | 62 | namespace WTL 63 | { 64 | 65 | inline LRESULT WtlReflectNotificationsFiltered(HWND hWndParent, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled, 66 | UINT uMsgFilter = WM_NULL, UINT_PTR idFromFilter = 0, HWND hWndChildFilter = NULL) 67 | { 68 | if((uMsgFilter != WM_NULL) && (uMsgFilter != uMsg)) 69 | { 70 | // The notification message doesn't match the filter. 71 | bHandled = FALSE; 72 | return 1; 73 | } 74 | 75 | HWND hWndChild = NULL; 76 | UINT_PTR idFrom = 0; 77 | 78 | switch(uMsg) 79 | { 80 | case WM_COMMAND: 81 | if(lParam != NULL) // not from a menu 82 | { 83 | hWndChild = (HWND)lParam; 84 | idFrom = (UINT_PTR)LOWORD(wParam); 85 | } 86 | break; 87 | case WM_NOTIFY: 88 | hWndChild = ((LPNMHDR)lParam)->hwndFrom; 89 | idFrom = ((LPNMHDR)lParam)->idFrom; 90 | break; 91 | #ifndef _WIN32_WCE 92 | case WM_PARENTNOTIFY: 93 | switch(LOWORD(wParam)) 94 | { 95 | case WM_CREATE: 96 | case WM_DESTROY: 97 | hWndChild = (HWND)lParam; 98 | idFrom = (UINT_PTR)HIWORD(wParam); 99 | break; 100 | default: 101 | hWndChild = ::GetDlgItem(hWndParent, HIWORD(wParam)); 102 | idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild); 103 | break; 104 | } 105 | break; 106 | #endif // !_WIN32_WCE 107 | case WM_DRAWITEM: 108 | if(wParam) // not from a menu 109 | { 110 | hWndChild = ((LPDRAWITEMSTRUCT)lParam)->hwndItem; 111 | idFrom = (UINT_PTR)wParam; 112 | } 113 | break; 114 | case WM_MEASUREITEM: 115 | if(wParam) // not from a menu 116 | { 117 | hWndChild = ::GetDlgItem(hWndParent, ((LPMEASUREITEMSTRUCT)lParam)->CtlID); 118 | idFrom = (UINT_PTR)wParam; 119 | } 120 | break; 121 | case WM_COMPAREITEM: 122 | if(wParam) // not from a menu 123 | { 124 | hWndChild = ((LPCOMPAREITEMSTRUCT)lParam)->hwndItem; 125 | idFrom = (UINT_PTR)wParam; 126 | } 127 | break; 128 | case WM_DELETEITEM: 129 | if(wParam) // not from a menu 130 | { 131 | hWndChild = ((LPDELETEITEMSTRUCT)lParam)->hwndItem; 132 | idFrom = (UINT_PTR)wParam; 133 | } 134 | break; 135 | case WM_VKEYTOITEM: 136 | case WM_CHARTOITEM: 137 | case WM_HSCROLL: 138 | case WM_VSCROLL: 139 | hWndChild = (HWND)lParam; 140 | idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild); 141 | break; 142 | case WM_CTLCOLORBTN: 143 | case WM_CTLCOLORDLG: 144 | case WM_CTLCOLOREDIT: 145 | case WM_CTLCOLORLISTBOX: 146 | case WM_CTLCOLORMSGBOX: 147 | case WM_CTLCOLORSCROLLBAR: 148 | case WM_CTLCOLORSTATIC: 149 | hWndChild = (HWND)lParam; 150 | idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild); 151 | break; 152 | default: 153 | break; 154 | } 155 | 156 | if((hWndChild == NULL) || 157 | ((hWndChildFilter != NULL) && (hWndChildFilter != hWndChild))) 158 | { 159 | // Either hWndChild isn't valid, or 160 | // hWndChild doesn't match the filter. 161 | bHandled = FALSE; 162 | return 1; 163 | } 164 | 165 | if((idFromFilter != 0) && (idFromFilter != idFrom)) 166 | { 167 | // The dialog control id doesn't match the filter. 168 | bHandled = FALSE; 169 | return 1; 170 | } 171 | 172 | ATLASSERT(::IsWindow(hWndChild)); 173 | LRESULT lResult = ::SendMessage(hWndChild, OCM__BASE + uMsg, wParam, lParam); 174 | if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC)) 175 | { 176 | // Try to prevent problems with WM_CTLCOLOR* messages when 177 | // the message wasn't really handled 178 | bHandled = FALSE; 179 | } 180 | 181 | return lResult; 182 | } 183 | 184 | }; // namespace WTL 185 | 186 | // Try to prevent problems with WM_CTLCOLOR* messages when 187 | // the message wasn't really handled 188 | #define REFLECT_NOTIFICATIONS_EX() \ 189 | { \ 190 | bHandled = TRUE; \ 191 | lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ 192 | if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC)) \ 193 | bHandled = FALSE; \ 194 | if(bHandled) \ 195 | return TRUE; \ 196 | } 197 | 198 | #define REFLECT_NOTIFICATIONS_MSG_FILTERED(uMsgFilter) \ 199 | { \ 200 | bHandled = TRUE; \ 201 | lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, NULL); \ 202 | if(bHandled) \ 203 | return TRUE; \ 204 | } 205 | 206 | #define REFLECT_NOTIFICATIONS_ID_FILTERED(idFromFilter) \ 207 | { \ 208 | bHandled = TRUE; \ 209 | lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, idFromFilter, NULL); \ 210 | if(bHandled) \ 211 | return TRUE; \ 212 | } 213 | 214 | #define REFLECT_NOTIFICATIONS_HWND_FILTERED(hWndChildFilter) \ 215 | { \ 216 | bHandled = TRUE; \ 217 | lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, 0, hWndChildFilter); \ 218 | if(bHandled) \ 219 | return TRUE; \ 220 | } 221 | 222 | #define REFLECT_NOTIFICATIONS_MSG_ID_FILTERED(uMsgFilter, idFromFilter) \ 223 | { \ 224 | bHandled = TRUE; \ 225 | lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, idFromFilter, NULL); \ 226 | if(bHandled) \ 227 | return TRUE; \ 228 | } 229 | 230 | #define REFLECT_NOTIFICATIONS_MSG_HWND_FILTERED(uMsgFilter, hWndChildFilter) \ 231 | { \ 232 | bHandled = TRUE; \ 233 | lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, hWndChildFilter); \ 234 | if(bHandled) \ 235 | return TRUE; \ 236 | } 237 | 238 | #define REFLECT_COMMAND(id, code) \ 239 | if(uMsg == WM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \ 240 | { \ 241 | bHandled = TRUE; \ 242 | lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ 243 | if(bHandled) \ 244 | return TRUE; \ 245 | } 246 | 247 | #define REFLECT_COMMAND_ID(id) \ 248 | if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \ 249 | { \ 250 | bHandled = TRUE; \ 251 | lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ 252 | if(bHandled) \ 253 | return TRUE; \ 254 | } 255 | 256 | #define REFLECT_COMMAND_CODE(code) \ 257 | if(uMsg == WM_COMMAND && code == HIWORD(wParam)) \ 258 | { \ 259 | bHandled = TRUE; \ 260 | lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ 261 | if(bHandled) \ 262 | return TRUE; \ 263 | } 264 | 265 | #define REFLECT_COMMAND_RANGE(idFirst, idLast) \ 266 | if(uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ 267 | { \ 268 | bHandled = TRUE; \ 269 | lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ 270 | if(bHandled) \ 271 | return TRUE; \ 272 | } 273 | 274 | #define REFLECT_COMMAND_RANGE_CODE(idFirst, idLast, code) \ 275 | if(uMsg == WM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ 276 | { \ 277 | bHandled = TRUE; \ 278 | lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ 279 | if(bHandled) \ 280 | return TRUE; \ 281 | } 282 | 283 | #define REFLECT_NOTIFY(id, cd) \ 284 | if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \ 285 | { \ 286 | bHandled = TRUE; \ 287 | lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ 288 | if(bHandled) \ 289 | return TRUE; \ 290 | } 291 | 292 | #define REFLECT_NOTIFY_ID(id) \ 293 | if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \ 294 | { \ 295 | bHandled = TRUE; \ 296 | lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ 297 | if(bHandled) \ 298 | return TRUE; \ 299 | } 300 | 301 | #define REFLECT_NOTIFY_CODE(cd) \ 302 | if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \ 303 | { \ 304 | bHandled = TRUE; \ 305 | lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ 306 | if(bHandled) \ 307 | return TRUE; \ 308 | } 309 | 310 | #define REFLECT_NOTIFY_RANGE(idFirst, idLast) \ 311 | if(uMsg == WM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ 312 | { \ 313 | bHandled = TRUE; \ 314 | lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ 315 | if(bHandled) \ 316 | return TRUE; \ 317 | } 318 | 319 | #define REFLECT_NOTIFY_RANGE_CODE(idFirst, idLast, cd) \ 320 | if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ 321 | { \ 322 | bHandled = TRUE; \ 323 | lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ 324 | if(bHandled) \ 325 | return TRUE; \ 326 | } 327 | 328 | 329 | /////////////////////////////////////////////////////////////////////////////// 330 | // Reflected message handler macros for message maps (for ATL 3.0) 331 | 332 | #if (_ATL_VER < 0x0700) 333 | 334 | #define REFLECTED_COMMAND_HANDLER(id, code, func) \ 335 | if(uMsg == OCM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \ 336 | { \ 337 | bHandled = TRUE; \ 338 | lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ 339 | if(bHandled) \ 340 | return TRUE; \ 341 | } 342 | 343 | #define REFLECTED_COMMAND_ID_HANDLER(id, func) \ 344 | if(uMsg == OCM_COMMAND && id == LOWORD(wParam)) \ 345 | { \ 346 | bHandled = TRUE; \ 347 | lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ 348 | if(bHandled) \ 349 | return TRUE; \ 350 | } 351 | 352 | #define REFLECTED_COMMAND_CODE_HANDLER(code, func) \ 353 | if(uMsg == OCM_COMMAND && code == HIWORD(wParam)) \ 354 | { \ 355 | bHandled = TRUE; \ 356 | lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ 357 | if(bHandled) \ 358 | return TRUE; \ 359 | } 360 | 361 | #define REFLECTED_COMMAND_RANGE_HANDLER(idFirst, idLast, func) \ 362 | if(uMsg == OCM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ 363 | { \ 364 | bHandled = TRUE; \ 365 | lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ 366 | if(bHandled) \ 367 | return TRUE; \ 368 | } 369 | 370 | #define REFLECTED_COMMAND_RANGE_CODE_HANDLER(idFirst, idLast, code, func) \ 371 | if(uMsg == OCM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ 372 | { \ 373 | bHandled = TRUE; \ 374 | lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ 375 | if(bHandled) \ 376 | return TRUE; \ 377 | } 378 | 379 | #define REFLECTED_NOTIFY_HANDLER(id, cd, func) \ 380 | if(uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \ 381 | { \ 382 | bHandled = TRUE; \ 383 | lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ 384 | if(bHandled) \ 385 | return TRUE; \ 386 | } 387 | 388 | #define REFLECTED_NOTIFY_ID_HANDLER(id, func) \ 389 | if(uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \ 390 | { \ 391 | bHandled = TRUE; \ 392 | lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ 393 | if(bHandled) \ 394 | return TRUE; \ 395 | } 396 | 397 | #define REFLECTED_NOTIFY_CODE_HANDLER(cd, func) \ 398 | if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \ 399 | { \ 400 | bHandled = TRUE; \ 401 | lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ 402 | if(bHandled) \ 403 | return TRUE; \ 404 | } 405 | 406 | #define REFLECTED_NOTIFY_RANGE_HANDLER(idFirst, idLast, func) \ 407 | if(uMsg == OCM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ 408 | { \ 409 | bHandled = TRUE; \ 410 | lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ 411 | if(bHandled) \ 412 | return TRUE; \ 413 | } 414 | 415 | #define REFLECTED_NOTIFY_RANGE_CODE_HANDLER(idFirst, idLast, cd, func) \ 416 | if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ 417 | { \ 418 | bHandled = TRUE; \ 419 | lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ 420 | if(bHandled) \ 421 | return TRUE; \ 422 | } 423 | 424 | #endif // (_ATL_VER < 0x0700) 425 | 426 | 427 | /////////////////////////////////////////////////////////////////////////////// 428 | // Dual argument helper classes (for ATL 3.0) 429 | 430 | #if (_ATL_VER < 0x0700) 431 | 432 | namespace ATL 433 | { 434 | 435 | class _U_RECT 436 | { 437 | public: 438 | _U_RECT(LPRECT lpRect) : m_lpRect(lpRect) 439 | { } 440 | _U_RECT(RECT& rc) : m_lpRect(&rc) 441 | { } 442 | LPRECT m_lpRect; 443 | }; 444 | 445 | class _U_MENUorID 446 | { 447 | public: 448 | _U_MENUorID(HMENU hMenu) : m_hMenu(hMenu) 449 | { } 450 | _U_MENUorID(UINT nID) : m_hMenu((HMENU)LongToHandle(nID)) 451 | { } 452 | HMENU m_hMenu; 453 | }; 454 | 455 | class _U_STRINGorID 456 | { 457 | public: 458 | _U_STRINGorID(LPCTSTR lpString) : m_lpstr(lpString) 459 | { } 460 | _U_STRINGorID(UINT nID) : m_lpstr(MAKEINTRESOURCE(nID)) 461 | { } 462 | LPCTSTR m_lpstr; 463 | }; 464 | 465 | }; // namespace ATL 466 | 467 | #endif // (_ATL_VER < 0x0700) 468 | 469 | 470 | namespace WTL 471 | { 472 | 473 | /////////////////////////////////////////////////////////////////////////////// 474 | // Forward notifications support for message maps (for ATL 3.0) 475 | 476 | #if (_ATL_VER < 0x0700) 477 | 478 | // forward notifications support 479 | #define FORWARD_NOTIFICATIONS() \ 480 | { \ 481 | bHandled = TRUE; \ 482 | lResult = WTL::Atl3ForwardNotifications(m_hWnd, uMsg, wParam, lParam, bHandled); \ 483 | if(bHandled) \ 484 | return TRUE; \ 485 | } 486 | 487 | static LRESULT Atl3ForwardNotifications(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 488 | { 489 | LRESULT lResult = 0; 490 | switch(uMsg) 491 | { 492 | case WM_COMMAND: 493 | case WM_NOTIFY: 494 | #ifndef _WIN32_WCE 495 | case WM_PARENTNOTIFY: 496 | #endif // !_WIN32_WCE 497 | case WM_DRAWITEM: 498 | case WM_MEASUREITEM: 499 | case WM_COMPAREITEM: 500 | case WM_DELETEITEM: 501 | case WM_VKEYTOITEM: 502 | case WM_CHARTOITEM: 503 | case WM_HSCROLL: 504 | case WM_VSCROLL: 505 | case WM_CTLCOLORBTN: 506 | case WM_CTLCOLORDLG: 507 | case WM_CTLCOLOREDIT: 508 | case WM_CTLCOLORLISTBOX: 509 | case WM_CTLCOLORMSGBOX: 510 | case WM_CTLCOLORSCROLLBAR: 511 | case WM_CTLCOLORSTATIC: 512 | lResult = ::SendMessage(::GetParent(hWnd), uMsg, wParam, lParam); 513 | break; 514 | default: 515 | bHandled = FALSE; 516 | break; 517 | } 518 | return lResult; 519 | } 520 | 521 | #endif // (_ATL_VER < 0x0700) 522 | 523 | }; // namespace WTL 524 | 525 | #endif // __ATLWINX_H__ 526 | -------------------------------------------------------------------------------- /WTL/atlddx.h: -------------------------------------------------------------------------------- 1 | // Windows Template Library - WTL version 9.0 2 | // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved. 3 | // 4 | // This file is a part of the Windows Template Library. 5 | // The use and distribution terms for this software are covered by the 6 | // Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) 7 | // which can be found in the file CPL.TXT at the root of this distribution. 8 | // By using this software in any fashion, you are agreeing to be bound by 9 | // the terms of this license. You must not remove this notice, or 10 | // any other, from this software. 11 | 12 | #ifndef __ATLDDX_H__ 13 | #define __ATLDDX_H__ 14 | 15 | #pragma once 16 | 17 | #ifndef __ATLAPP_H__ 18 | #error atlddx.h requires atlapp.h to be included first 19 | #endif 20 | 21 | #if defined(_ATL_USE_DDX_FLOAT) && defined(_ATL_MIN_CRT) 22 | #error Cannot use floating point DDX with _ATL_MIN_CRT defined 23 | #endif // defined(_ATL_USE_DDX_FLOAT) && defined(_ATL_MIN_CRT) 24 | 25 | #ifdef _ATL_USE_DDX_FLOAT 26 | #include 27 | #endif // _ATL_USE_DDX_FLOAT 28 | 29 | 30 | /////////////////////////////////////////////////////////////////////////////// 31 | // Classes in this file: 32 | // 33 | // CWinDataExchange 34 | 35 | 36 | namespace WTL 37 | { 38 | 39 | // Constants 40 | #define DDX_LOAD FALSE 41 | #define DDX_SAVE TRUE 42 | 43 | // DDX map macros 44 | #define BEGIN_DDX_MAP(thisClass) \ 45 | BOOL DoDataExchange(BOOL bSaveAndValidate = FALSE, UINT nCtlID = (UINT)-1) \ 46 | { \ 47 | bSaveAndValidate; \ 48 | nCtlID; 49 | 50 | #define DDX_TEXT(nID, var) \ 51 | if(nCtlID == (UINT)-1 || nCtlID == nID) \ 52 | { \ 53 | if(!DDX_Text(nID, var, sizeof(var), bSaveAndValidate)) \ 54 | return FALSE; \ 55 | } 56 | 57 | #define DDX_TEXT_LEN(nID, var, len) \ 58 | if(nCtlID == (UINT)-1 || nCtlID == nID) \ 59 | { \ 60 | if(!DDX_Text(nID, var, sizeof(var), bSaveAndValidate, TRUE, len)) \ 61 | return FALSE; \ 62 | } 63 | 64 | #define DDX_INT(nID, var) \ 65 | if(nCtlID == (UINT)-1 || nCtlID == nID) \ 66 | { \ 67 | if(!DDX_Int(nID, var, TRUE, bSaveAndValidate)) \ 68 | return FALSE; \ 69 | } 70 | 71 | #define DDX_INT_RANGE(nID, var, min, max) \ 72 | if(nCtlID == (UINT)-1 || nCtlID == nID) \ 73 | { \ 74 | if(!DDX_Int(nID, var, TRUE, bSaveAndValidate, TRUE, min, max)) \ 75 | return FALSE; \ 76 | } 77 | 78 | #define DDX_UINT(nID, var) \ 79 | if(nCtlID == (UINT)-1 || nCtlID == nID) \ 80 | { \ 81 | if(!DDX_Int(nID, var, FALSE, bSaveAndValidate)) \ 82 | return FALSE; \ 83 | } 84 | 85 | #define DDX_UINT_RANGE(nID, var, min, max) \ 86 | if(nCtlID == (UINT)-1 || nCtlID == nID) \ 87 | { \ 88 | if(!DDX_Int(nID, var, FALSE, bSaveAndValidate, TRUE, min, max)) \ 89 | return FALSE; \ 90 | } 91 | 92 | #ifdef _ATL_USE_DDX_FLOAT 93 | #define DDX_FLOAT(nID, var) \ 94 | if(nCtlID == (UINT)-1 || nCtlID == nID) \ 95 | { \ 96 | if(!DDX_Float(nID, var, bSaveAndValidate)) \ 97 | return FALSE; \ 98 | } 99 | 100 | #define DDX_FLOAT_RANGE(nID, var, min, max) \ 101 | if(nCtlID == (UINT)-1 || nCtlID == nID) \ 102 | { \ 103 | if(!DDX_Float(nID, var, bSaveAndValidate, TRUE, min, max)) \ 104 | return FALSE; \ 105 | } 106 | #define DDX_FLOAT_P(nID, var, precision) \ 107 | if(nCtlID == (UINT)-1 || nCtlID == nID) \ 108 | { \ 109 | if(!DDX_Float(nID, var, bSaveAndValidate, FALSE, 0, 0, precision)) \ 110 | return FALSE; \ 111 | } 112 | 113 | #define DDX_FLOAT_P_RANGE(nID, var, min, max, precision) \ 114 | if(nCtlID == (UINT)-1 || nCtlID == nID) \ 115 | { \ 116 | if(!DDX_Float(nID, var, bSaveAndValidate, TRUE, min, max, precision)) \ 117 | return FALSE; \ 118 | } 119 | #endif // _ATL_USE_DDX_FLOAT 120 | 121 | #define DDX_CONTROL(nID, obj) \ 122 | if(nCtlID == (UINT)-1 || nCtlID == nID) \ 123 | DDX_Control(nID, obj, bSaveAndValidate); 124 | 125 | #define DDX_CONTROL_HANDLE(nID, obj) \ 126 | if(nCtlID == (UINT)-1 || nCtlID == nID) \ 127 | DDX_Control_Handle(nID, obj, bSaveAndValidate); 128 | 129 | #define DDX_CHECK(nID, var) \ 130 | if(nCtlID == (UINT)-1 || nCtlID == nID) \ 131 | DDX_Check(nID, var, bSaveAndValidate); 132 | 133 | #define DDX_RADIO(nID, var) \ 134 | if(nCtlID == (UINT)-1 || nCtlID == nID) \ 135 | DDX_Radio(nID, var, bSaveAndValidate); 136 | 137 | #define END_DDX_MAP() \ 138 | return TRUE; \ 139 | } 140 | 141 | // DDX support for Tab, Combo, ListBox and ListView selection index 142 | // Note: Specialized versions require atlctrls.h to be included first 143 | #if (_MSC_VER >= 1300) 144 | 145 | #define DDX_INDEX(CtrlClass, nID, var) \ 146 | if(nCtlID == (UINT)-1 || nCtlID == nID) \ 147 | DDX_Index(nID, var, bSaveAndValidate); 148 | 149 | #ifdef __ATLCTRLS_H__ 150 | #define DDX_TAB_INDEX(nID, var) DDX_INDEX(WTL::CTabCtrl, nID, var) 151 | #ifndef WIN32_PLATFORM_WFSP // No COMBOBOX on SmartPhones 152 | #define DDX_COMBO_INDEX(nID, var) DDX_INDEX(WTL::CComboBox, nID, var) 153 | #endif 154 | #define DDX_LISTBOX_INDEX(nID, var) DDX_INDEX(WTL::CListBox, nID, var) 155 | #define DDX_LISTVIEW_INDEX(nID, var) DDX_INDEX(WTL::CListViewCtrl, nID, var) 156 | #endif // __ATLCTRLS_H__ 157 | 158 | #endif // (_MSC_VER >= 1300) 159 | 160 | 161 | /////////////////////////////////////////////////////////////////////////////// 162 | // CWinDataExchange - provides support for DDX 163 | 164 | template 165 | class CWinDataExchange 166 | { 167 | public: 168 | // Data exchange method - override in your derived class 169 | BOOL DoDataExchange(BOOL /*bSaveAndValidate*/ = FALSE, UINT /*nCtlID*/ = (UINT)-1) 170 | { 171 | // this one should never be called, override it in 172 | // your derived class by implementing DDX map 173 | ATLASSERT(FALSE); 174 | return FALSE; 175 | } 176 | 177 | // Helpers for validation error reporting 178 | enum _XDataType 179 | { 180 | ddxDataNull = 0, 181 | ddxDataText = 1, 182 | ddxDataInt = 2, 183 | ddxDataFloat = 3, 184 | ddxDataDouble = 4 185 | }; 186 | 187 | struct _XTextData 188 | { 189 | int nLength; 190 | int nMaxLength; 191 | }; 192 | 193 | struct _XIntData 194 | { 195 | long nVal; 196 | long nMin; 197 | long nMax; 198 | }; 199 | 200 | struct _XFloatData 201 | { 202 | double nVal; 203 | double nMin; 204 | double nMax; 205 | }; 206 | 207 | struct _XData 208 | { 209 | _XDataType nDataType; 210 | union 211 | { 212 | _XTextData textData; 213 | _XIntData intData; 214 | _XFloatData floatData; 215 | }; 216 | }; 217 | 218 | // Text exchange 219 | BOOL DDX_Text(UINT nID, LPTSTR lpstrText, int cbSize, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0) 220 | { 221 | T* pT = static_cast(this); 222 | BOOL bSuccess = TRUE; 223 | 224 | if(bSave) 225 | { 226 | HWND hWndCtrl = pT->GetDlgItem(nID); 227 | int nRetLen = ::GetWindowText(hWndCtrl, lpstrText, cbSize / sizeof(TCHAR)); 228 | if(nRetLen < ::GetWindowTextLength(hWndCtrl)) 229 | bSuccess = FALSE; 230 | } 231 | else 232 | { 233 | ATLASSERT(!bValidate || lstrlen(lpstrText) <= nLength); 234 | bSuccess = pT->SetDlgItemText(nID, lpstrText); 235 | } 236 | 237 | if(!bSuccess) 238 | { 239 | pT->OnDataExchangeError(nID, bSave); 240 | } 241 | else if(bSave && bValidate) // validation 242 | { 243 | ATLASSERT(nLength > 0); 244 | if(lstrlen(lpstrText) > nLength) 245 | { 246 | _XData data = { ddxDataText }; 247 | data.textData.nLength = lstrlen(lpstrText); 248 | data.textData.nMaxLength = nLength; 249 | pT->OnDataValidateError(nID, bSave, data); 250 | bSuccess = FALSE; 251 | } 252 | } 253 | return bSuccess; 254 | } 255 | 256 | BOOL DDX_Text(UINT nID, BSTR& bstrText, int /*cbSize*/, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0) 257 | { 258 | T* pT = static_cast(this); 259 | BOOL bSuccess = TRUE; 260 | 261 | if(bSave) 262 | { 263 | bSuccess = pT->GetDlgItemText(nID, bstrText); 264 | } 265 | else 266 | { 267 | USES_CONVERSION; 268 | LPTSTR lpstrText = OLE2T(bstrText); 269 | ATLASSERT(!bValidate || lstrlen(lpstrText) <= nLength); 270 | bSuccess = pT->SetDlgItemText(nID, lpstrText); 271 | } 272 | 273 | if(!bSuccess) 274 | { 275 | pT->OnDataExchangeError(nID, bSave); 276 | } 277 | else if(bSave && bValidate) // validation 278 | { 279 | ATLASSERT(nLength > 0); 280 | if((int)::SysStringLen(bstrText) > nLength) 281 | { 282 | _XData data = { ddxDataText }; 283 | data.textData.nLength = (int)::SysStringLen(bstrText); 284 | data.textData.nMaxLength = nLength; 285 | pT->OnDataValidateError(nID, bSave, data); 286 | bSuccess = FALSE; 287 | } 288 | } 289 | return bSuccess; 290 | } 291 | 292 | BOOL DDX_Text(UINT nID, ATL::CComBSTR& bstrText, int /*cbSize*/, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0) 293 | { 294 | T* pT = static_cast(this); 295 | BOOL bSuccess = TRUE; 296 | 297 | if(bSave) 298 | { 299 | bSuccess = pT->GetDlgItemText(nID, (BSTR&)bstrText); 300 | } 301 | else 302 | { 303 | USES_CONVERSION; 304 | LPTSTR lpstrText = OLE2T(bstrText); 305 | ATLASSERT(!bValidate || lstrlen(lpstrText) <= nLength); 306 | bSuccess = pT->SetDlgItemText(nID, lpstrText); 307 | } 308 | 309 | if(!bSuccess) 310 | { 311 | pT->OnDataExchangeError(nID, bSave); 312 | } 313 | else if(bSave && bValidate) // validation 314 | { 315 | ATLASSERT(nLength > 0); 316 | if((int)bstrText.Length() > nLength) 317 | { 318 | _XData data = { ddxDataText }; 319 | data.textData.nLength = (int)bstrText.Length(); 320 | data.textData.nMaxLength = nLength; 321 | pT->OnDataValidateError(nID, bSave, data); 322 | bSuccess = FALSE; 323 | } 324 | } 325 | return bSuccess; 326 | } 327 | 328 | #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) 329 | BOOL DDX_Text(UINT nID, _CSTRING_NS::CString& strText, int /*cbSize*/, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0) 330 | { 331 | T* pT = static_cast(this); 332 | BOOL bSuccess = TRUE; 333 | 334 | if(bSave) 335 | { 336 | HWND hWndCtrl = pT->GetDlgItem(nID); 337 | int nLen = ::GetWindowTextLength(hWndCtrl); 338 | int nRetLen = -1; 339 | LPTSTR lpstr = strText.GetBufferSetLength(nLen); 340 | if(lpstr != NULL) 341 | { 342 | nRetLen = ::GetWindowText(hWndCtrl, lpstr, nLen + 1); 343 | strText.ReleaseBuffer(); 344 | } 345 | if(nRetLen < nLen) 346 | bSuccess = FALSE; 347 | } 348 | else 349 | { 350 | bSuccess = pT->SetDlgItemText(nID, strText); 351 | } 352 | 353 | if(!bSuccess) 354 | { 355 | pT->OnDataExchangeError(nID, bSave); 356 | } 357 | else if(bSave && bValidate) // validation 358 | { 359 | ATLASSERT(nLength > 0); 360 | if(strText.GetLength() > nLength) 361 | { 362 | _XData data = { ddxDataText }; 363 | data.textData.nLength = strText.GetLength(); 364 | data.textData.nMaxLength = nLength; 365 | pT->OnDataValidateError(nID, bSave, data); 366 | bSuccess = FALSE; 367 | } 368 | } 369 | return bSuccess; 370 | } 371 | #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) 372 | 373 | // Numeric exchange 374 | template 375 | BOOL DDX_Int(UINT nID, Type& nVal, BOOL bSigned, BOOL bSave, BOOL bValidate = FALSE, Type nMin = 0, Type nMax = 0) 376 | { 377 | T* pT = static_cast(this); 378 | BOOL bSuccess = TRUE; 379 | 380 | if(bSave) 381 | { 382 | nVal = (Type)pT->GetDlgItemInt(nID, &bSuccess, bSigned); 383 | } 384 | else 385 | { 386 | ATLASSERT(!bValidate || nVal >= nMin && nVal <= nMax); 387 | bSuccess = pT->SetDlgItemInt(nID, nVal, bSigned); 388 | } 389 | 390 | if(!bSuccess) 391 | { 392 | pT->OnDataExchangeError(nID, bSave); 393 | } 394 | else if(bSave && bValidate) // validation 395 | { 396 | ATLASSERT(nMin != nMax); 397 | if(nVal < nMin || nVal > nMax) 398 | { 399 | _XData data = { ddxDataInt }; 400 | data.intData.nVal = (long)nVal; 401 | data.intData.nMin = (long)nMin; 402 | data.intData.nMax = (long)nMax; 403 | pT->OnDataValidateError(nID, bSave, data); 404 | bSuccess = FALSE; 405 | } 406 | } 407 | return bSuccess; 408 | } 409 | 410 | // Float exchange 411 | #ifdef _ATL_USE_DDX_FLOAT 412 | static BOOL _AtlSimpleFloatParse(LPCTSTR lpszText, double& d) 413 | { 414 | ATLASSERT(lpszText != NULL); 415 | while (*lpszText == _T(' ') || *lpszText == _T('\t')) 416 | lpszText++; 417 | 418 | TCHAR chFirst = lpszText[0]; 419 | d = _tcstod(lpszText, (LPTSTR*)&lpszText); 420 | if (d == 0.0 && chFirst != _T('0')) 421 | return FALSE; // could not convert 422 | while (*lpszText == _T(' ') || *lpszText == _T('\t')) 423 | lpszText++; 424 | 425 | if (*lpszText != _T('\0')) 426 | return FALSE; // not terminated properly 427 | 428 | return TRUE; 429 | } 430 | 431 | BOOL DDX_Float(UINT nID, float& nVal, BOOL bSave, BOOL bValidate = FALSE, float nMin = 0.F, float nMax = 0.F, int nPrecision = FLT_DIG) 432 | { 433 | T* pT = static_cast(this); 434 | BOOL bSuccess = TRUE; 435 | const int cchBuff = 32; 436 | TCHAR szBuff[cchBuff] = { 0 }; 437 | 438 | if(bSave) 439 | { 440 | pT->GetDlgItemText(nID, szBuff, cchBuff); 441 | double d = 0; 442 | if(_AtlSimpleFloatParse(szBuff, d)) 443 | nVal = (float)d; 444 | else 445 | bSuccess = FALSE; 446 | } 447 | else 448 | { 449 | ATLASSERT(!bValidate || nVal >= nMin && nVal <= nMax); 450 | SecureHelper::sprintf_x(szBuff, cchBuff, _T("%.*g"), nPrecision, nVal); 451 | bSuccess = pT->SetDlgItemText(nID, szBuff); 452 | } 453 | 454 | if(!bSuccess) 455 | { 456 | pT->OnDataExchangeError(nID, bSave); 457 | } 458 | else if(bSave && bValidate) // validation 459 | { 460 | ATLASSERT(nMin != nMax); 461 | if(nVal < nMin || nVal > nMax) 462 | { 463 | _XData data = { ddxDataFloat }; 464 | data.floatData.nVal = (double)nVal; 465 | data.floatData.nMin = (double)nMin; 466 | data.floatData.nMax = (double)nMax; 467 | pT->OnDataValidateError(nID, bSave, data); 468 | bSuccess = FALSE; 469 | } 470 | } 471 | return bSuccess; 472 | } 473 | 474 | BOOL DDX_Float(UINT nID, double& nVal, BOOL bSave, BOOL bValidate = FALSE, double nMin = 0., double nMax = 0., int nPrecision = DBL_DIG) 475 | { 476 | T* pT = static_cast(this); 477 | BOOL bSuccess = TRUE; 478 | const int cchBuff = 32; 479 | TCHAR szBuff[cchBuff] = { 0 }; 480 | 481 | if(bSave) 482 | { 483 | pT->GetDlgItemText(nID, szBuff, cchBuff); 484 | double d = 0; 485 | if(_AtlSimpleFloatParse(szBuff, d)) 486 | nVal = d; 487 | else 488 | bSuccess = FALSE; 489 | } 490 | else 491 | { 492 | ATLASSERT(!bValidate || nVal >= nMin && nVal <= nMax); 493 | SecureHelper::sprintf_x(szBuff, cchBuff, _T("%.*g"), nPrecision, nVal); 494 | bSuccess = pT->SetDlgItemText(nID, szBuff); 495 | } 496 | 497 | if(!bSuccess) 498 | { 499 | pT->OnDataExchangeError(nID, bSave); 500 | } 501 | else if(bSave && bValidate) // validation 502 | { 503 | ATLASSERT(nMin != nMax); 504 | if(nVal < nMin || nVal > nMax) 505 | { 506 | _XData data = { ddxDataFloat }; 507 | data.floatData.nVal = nVal; 508 | data.floatData.nMin = nMin; 509 | data.floatData.nMax = nMax; 510 | pT->OnDataValidateError(nID, bSave, data); 511 | bSuccess = FALSE; 512 | } 513 | } 514 | return bSuccess; 515 | } 516 | #endif // _ATL_USE_DDX_FLOAT 517 | 518 | // Full control subclassing (for CWindowImpl derived controls) 519 | template 520 | void DDX_Control(UINT nID, TControl& ctrl, BOOL bSave) 521 | { 522 | if(!bSave && ctrl.m_hWnd == NULL) 523 | { 524 | T* pT = static_cast(this); 525 | ctrl.SubclassWindow(pT->GetDlgItem(nID)); 526 | } 527 | } 528 | 529 | // Simple control attaching (for HWND wrapper controls) 530 | template 531 | void DDX_Control_Handle(UINT nID, TControl& ctrl, BOOL bSave) 532 | { 533 | if(!bSave && ctrl.m_hWnd == NULL) 534 | { 535 | T* pT = static_cast(this); 536 | ctrl = pT->GetDlgItem(nID); 537 | } 538 | } 539 | 540 | // Control state 541 | void DDX_Check(UINT nID, int& nValue, BOOL bSave) 542 | { 543 | T* pT = static_cast(this); 544 | HWND hWndCtrl = pT->GetDlgItem(nID); 545 | if(bSave) 546 | { 547 | nValue = (int)::SendMessage(hWndCtrl, BM_GETCHECK, 0, 0L); 548 | ATLASSERT(nValue >= 0 && nValue <= 2); 549 | } 550 | else 551 | { 552 | if(nValue < 0 || nValue > 2) 553 | { 554 | ATLTRACE2(atlTraceUI, 0, _T("ATL: Warning - dialog data checkbox value (%d) out of range.\n"), nValue); 555 | nValue = 0; // default to off 556 | } 557 | ::SendMessage(hWndCtrl, BM_SETCHECK, nValue, 0L); 558 | } 559 | } 560 | 561 | // variant that supports bool (checked/not-checked, no intermediate state) 562 | void DDX_Check(UINT nID, bool& bCheck, BOOL bSave) 563 | { 564 | int nValue = bCheck ? 1 : 0; 565 | DDX_Check(nID, nValue, bSave); 566 | 567 | if(bSave) 568 | { 569 | if(nValue == 2) 570 | ATLTRACE2(atlTraceUI, 0, _T("ATL: Warning - checkbox state (%d) out of supported range.\n"), nValue); 571 | bCheck = (nValue == 1); 572 | } 573 | } 574 | 575 | void DDX_Radio(UINT nID, int& nValue, BOOL bSave) 576 | { 577 | T* pT = static_cast(this); 578 | HWND hWndCtrl = pT->GetDlgItem(nID); 579 | ATLASSERT(hWndCtrl != NULL); 580 | 581 | // must be first in a group of auto radio buttons 582 | ATLASSERT(::GetWindowLong(hWndCtrl, GWL_STYLE) & WS_GROUP); 583 | ATLASSERT(::SendMessage(hWndCtrl, WM_GETDLGCODE, 0, 0L) & DLGC_RADIOBUTTON); 584 | 585 | if(bSave) 586 | nValue = -1; // value if none found 587 | 588 | // walk all children in group 589 | int nButton = 0; 590 | do 591 | { 592 | if(::SendMessage(hWndCtrl, WM_GETDLGCODE, 0, 0L) & DLGC_RADIOBUTTON) 593 | { 594 | // control in group is a radio button 595 | if(bSave) 596 | { 597 | if(::SendMessage(hWndCtrl, BM_GETCHECK, 0, 0L) != 0) 598 | { 599 | ATLASSERT(nValue == -1); // only set once 600 | nValue = nButton; 601 | } 602 | } 603 | else 604 | { 605 | // select button 606 | ::SendMessage(hWndCtrl, BM_SETCHECK, (nButton == nValue), 0L); 607 | } 608 | nButton++; 609 | } 610 | else 611 | { 612 | ATLTRACE2(atlTraceUI, 0, _T("ATL: Warning - skipping non-radio button in group.\n")); 613 | } 614 | hWndCtrl = ::GetWindow(hWndCtrl, GW_HWNDNEXT); 615 | } 616 | while (hWndCtrl != NULL && !(GetWindowLong(hWndCtrl, GWL_STYLE) & WS_GROUP)); 617 | } 618 | 619 | // DDX support for Tab, Combo, ListBox and ListView selection index 620 | #if (_MSC_VER >= 1300) 621 | template 622 | INT _getSel(TCtrl& tCtrl) 623 | { 624 | return tCtrl.GetCurSel(); 625 | } 626 | 627 | template 628 | void _setSel(TCtrl& tCtrl, INT iSel) 629 | { 630 | if(iSel < 0) 631 | tCtrl.SetCurSel(-1); 632 | else 633 | tCtrl.SetCurSel(iSel); 634 | } 635 | 636 | #ifdef __ATLCTRLS_H__ 637 | // ListViewCtrl specialization 638 | template <> 639 | INT _getSel(WTL::CListViewCtrl& tCtrl) 640 | { 641 | return tCtrl.GetSelectedIndex(); 642 | } 643 | 644 | template <> 645 | void _setSel(WTL::CListViewCtrl& tCtrl, INT iSel) 646 | { 647 | if(iSel < 0) 648 | tCtrl.SelectItem(-1); 649 | else 650 | tCtrl.SelectItem(iSel); 651 | } 652 | #endif // __ATLCTRLS_H__ 653 | 654 | template 655 | void DDX_Index(UINT nID, INT& nVal, BOOL bSave) 656 | { 657 | T* pT = static_cast(this); 658 | TCtrl ctrl(pT->GetDlgItem(nID)); 659 | 660 | if(bSave) 661 | nVal = _getSel(ctrl); 662 | else 663 | _setSel(ctrl, nVal); 664 | } 665 | #endif // (_MSC_VER >= 1300) 666 | 667 | // Overrideables 668 | void OnDataExchangeError(UINT nCtrlID, BOOL /*bSave*/) 669 | { 670 | // Override to display an error message 671 | ::MessageBeep((UINT)-1); 672 | T* pT = static_cast(this); 673 | ::SetFocus(pT->GetDlgItem(nCtrlID)); 674 | } 675 | 676 | void OnDataValidateError(UINT nCtrlID, BOOL /*bSave*/, _XData& /*data*/) 677 | { 678 | // Override to display an error message 679 | ::MessageBeep((UINT)-1); 680 | T* pT = static_cast(this); 681 | ::SetFocus(pT->GetDlgItem(nCtrlID)); 682 | } 683 | }; 684 | 685 | }; // namespace WTL 686 | 687 | #endif // __ATLDDX_H__ 688 | -------------------------------------------------------------------------------- /WTL/atlfind.h: -------------------------------------------------------------------------------- 1 | // Windows Template Library - WTL version 9.0 2 | // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved. 3 | // 4 | // This file is a part of the Windows Template Library. 5 | // The use and distribution terms for this software are covered by the 6 | // Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) 7 | // which can be found in the file CPL.TXT at the root of this distribution. 8 | // By using this software in any fashion, you are agreeing to be bound by 9 | // the terms of this license. You must not remove this notice, or 10 | // any other, from this software. 11 | 12 | #ifndef __ATLFIND_H__ 13 | #define __ATLFIND_H__ 14 | 15 | #pragma once 16 | 17 | #ifdef _WIN32_WCE 18 | #error atlfind.h is not supported on Windows CE 19 | #endif 20 | 21 | #ifndef __ATLCTRLS_H__ 22 | #error atlfind.h requires atlctrls.h to be included first 23 | #endif 24 | 25 | #ifndef __ATLDLGS_H__ 26 | #error atlfind.h requires atldlgs.h to be included first 27 | #endif 28 | 29 | #if !((defined(__ATLMISC_H__) && defined(_WTL_USE_CSTRING)) || defined(__ATLSTR_H__)) 30 | #error atlfind.h requires CString (either from ATL's atlstr.h or WTL's atlmisc.h with _WTL_USE_CSTRING) 31 | #endif 32 | 33 | 34 | /////////////////////////////////////////////////////////////////////////////// 35 | // Classes in this file: 36 | // 37 | // CEditFindReplaceImplBase 38 | // CEditFindReplaceImpl 39 | // CRichEditFindReplaceImpl 40 | 41 | 42 | namespace WTL 43 | { 44 | 45 | /////////////////////////////////////////////////////////////////////////////// 46 | // CEditFindReplaceImplBase - Base class for mixin classes that 47 | // help implement Find/Replace for CEdit or CRichEditCtrl based window classes. 48 | 49 | template 50 | class CEditFindReplaceImplBase 51 | { 52 | protected: 53 | // Typedefs 54 | typedef CEditFindReplaceImplBase thisClass; 55 | 56 | // Data members 57 | TFindReplaceDialog* m_pFindReplaceDialog; 58 | _CSTRING_NS::CString m_sFindNext, m_sReplaceWith; 59 | BOOL m_bFindOnly, m_bFirstSearch, m_bMatchCase, m_bWholeWord, m_bFindDown; 60 | LONG m_nInitialSearchPos; 61 | HCURSOR m_hOldCursor; 62 | 63 | // Enumerations 64 | enum TranslationTextItem 65 | { 66 | eText_OnReplaceAllMessage = 0, 67 | eText_OnReplaceAllTitle = 1, 68 | eText_OnTextNotFoundMessage = 2, 69 | eText_OnTextNotFoundTitle = 3 70 | }; 71 | 72 | public: 73 | // Constructors 74 | CEditFindReplaceImplBase() : 75 | m_pFindReplaceDialog(NULL), 76 | m_bFindOnly(TRUE), 77 | m_bFirstSearch(TRUE), 78 | m_bMatchCase(FALSE), 79 | m_bWholeWord(FALSE), 80 | m_bFindDown(TRUE), 81 | m_nInitialSearchPos(0), 82 | m_hOldCursor(NULL) 83 | { 84 | } 85 | 86 | // Message Handlers 87 | BEGIN_MSG_MAP(thisClass) 88 | ALT_MSG_MAP(1) 89 | MESSAGE_HANDLER(WM_DESTROY, OnDestroy) 90 | MESSAGE_HANDLER(TFindReplaceDialog::GetFindReplaceMsg(), OnFindReplaceCmd) 91 | COMMAND_ID_HANDLER(ID_EDIT_FIND, OnEditFind) 92 | COMMAND_ID_HANDLER(ID_EDIT_REPEAT, OnEditRepeat) 93 | COMMAND_ID_HANDLER(ID_EDIT_REPLACE, OnEditReplace) 94 | END_MSG_MAP() 95 | 96 | LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) 97 | { 98 | if(m_pFindReplaceDialog != NULL) 99 | { 100 | m_pFindReplaceDialog->SendMessage(WM_CLOSE); 101 | ATLASSERT(m_pFindReplaceDialog == NULL); 102 | } 103 | 104 | bHandled = FALSE; 105 | return 0; 106 | } 107 | 108 | LRESULT OnFindReplaceCmd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) 109 | { 110 | T* pT = static_cast(this); 111 | 112 | TFindReplaceDialog* pDialog = TFindReplaceDialog::GetNotifier(lParam); 113 | if(pDialog == NULL) 114 | { 115 | ATLASSERT(FALSE); 116 | ::MessageBeep(MB_ICONERROR); 117 | return 1; 118 | } 119 | ATLASSERT(pDialog == m_pFindReplaceDialog); 120 | 121 | LPFINDREPLACE findReplace = (LPFINDREPLACE)lParam; 122 | if((m_pFindReplaceDialog != NULL) && (findReplace != NULL)) 123 | { 124 | if(pDialog->FindNext()) 125 | { 126 | pT->OnFindNext(pDialog->GetFindString(), pDialog->SearchDown(), 127 | pDialog->MatchCase(), pDialog->MatchWholeWord()); 128 | } 129 | else if(pDialog->ReplaceCurrent()) 130 | { 131 | pT->OnReplaceSel(pDialog->GetFindString(), 132 | pDialog->SearchDown(), pDialog->MatchCase(), pDialog->MatchWholeWord(), 133 | pDialog->GetReplaceString()); 134 | } 135 | else if(pDialog->ReplaceAll()) 136 | { 137 | pT->OnReplaceAll(pDialog->GetFindString(), pDialog->GetReplaceString(), 138 | pDialog->MatchCase(), pDialog->MatchWholeWord()); 139 | } 140 | else if(pDialog->IsTerminating()) 141 | { 142 | // Dialog is going away (but hasn't gone away yet) 143 | // OnFinalMessage will "delete this" 144 | pT->OnTerminatingFindReplaceDialog(m_pFindReplaceDialog); 145 | m_pFindReplaceDialog = NULL; 146 | } 147 | } 148 | 149 | return 0; 150 | } 151 | 152 | LRESULT OnEditFind(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) 153 | { 154 | T* pT = static_cast(this); 155 | pT->FindReplace(TRUE); 156 | 157 | return 0; 158 | } 159 | 160 | LRESULT OnEditRepeat(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) 161 | { 162 | T* pT = static_cast(this); 163 | 164 | // If the user is holding down SHIFT when hitting F3, we'll 165 | // search in reverse. Otherwise, we'll search forward. 166 | // (be sure to have an accelerator mapped to ID_EDIT_REPEAT 167 | // for both F3 and Shift+F3) 168 | m_bFindDown = !((::GetKeyState(VK_SHIFT) & 0x8000) == 0x8000); 169 | 170 | if(m_sFindNext.IsEmpty()) 171 | { 172 | pT->FindReplace(TRUE); 173 | } 174 | else 175 | { 176 | if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown)) 177 | pT->TextNotFound(m_sFindNext); 178 | } 179 | 180 | return 0; 181 | } 182 | 183 | LRESULT OnEditReplace(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& bHandled) 184 | { 185 | T* pT = static_cast(this); 186 | 187 | DWORD style = pT->GetStyle(); 188 | if((style & ES_READONLY) != ES_READONLY) 189 | { 190 | pT->FindReplace(FALSE); 191 | } 192 | else 193 | { 194 | // Don't allow replace when the edit control is read only 195 | bHandled = FALSE; 196 | } 197 | 198 | return 0; 199 | } 200 | 201 | // Operations (overrideable) 202 | TFindReplaceDialog* CreateFindReplaceDialog(BOOL bFindOnly, // TRUE for Find, FALSE for FindReplace 203 | LPCTSTR lpszFindWhat, 204 | LPCTSTR lpszReplaceWith = NULL, 205 | DWORD dwFlags = FR_DOWN, 206 | HWND hWndParent = NULL) 207 | { 208 | // You can override all of this in a derived class 209 | 210 | TFindReplaceDialog* findReplaceDialog = new TFindReplaceDialog(); 211 | if(findReplaceDialog == NULL) 212 | { 213 | ::MessageBeep(MB_ICONHAND); 214 | } 215 | else 216 | { 217 | HWND hWndFindReplace = findReplaceDialog->Create(bFindOnly, 218 | lpszFindWhat, lpszReplaceWith, dwFlags, hWndParent); 219 | if(hWndFindReplace == NULL) 220 | { 221 | delete findReplaceDialog; 222 | findReplaceDialog = NULL; 223 | } 224 | else 225 | { 226 | findReplaceDialog->SetActiveWindow(); 227 | findReplaceDialog->ShowWindow(SW_SHOW); 228 | } 229 | } 230 | 231 | return findReplaceDialog; 232 | } 233 | 234 | void AdjustDialogPosition(HWND hWndDialog) 235 | { 236 | ATLASSERT((hWndDialog != NULL) && ::IsWindow(hWndDialog)); 237 | 238 | T* pT = static_cast(this); 239 | LONG nStartChar = 0, nEndChar = 0; 240 | // Send EM_GETSEL so we can use both Edit and RichEdit 241 | // (CEdit::GetSel uses int&, and CRichEditCtrlT::GetSel uses LONG&) 242 | ::SendMessage(pT->m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar); 243 | POINT point = pT->PosFromChar(nStartChar); 244 | ::ClientToScreen(pT->GetParent(), &point); 245 | CRect rect; 246 | ::GetWindowRect(hWndDialog, &rect); 247 | if(rect.PtInRect(point)) 248 | { 249 | if(point.y > rect.Height()) 250 | { 251 | rect.OffsetRect(0, point.y - rect.bottom - 20); 252 | } 253 | else 254 | { 255 | int nVertExt = GetSystemMetrics(SM_CYSCREEN); 256 | if(point.y + rect.Height() < nVertExt) 257 | rect.OffsetRect(0, 40 + point.y - rect.top); 258 | } 259 | 260 | ::MoveWindow(hWndDialog, rect.left, rect.top, rect.Width(), rect.Height(), TRUE); 261 | } 262 | } 263 | 264 | DWORD GetFindReplaceDialogFlags(void) const 265 | { 266 | DWORD dwFlags = 0; 267 | if(m_bFindDown) 268 | dwFlags |= FR_DOWN; 269 | if(m_bMatchCase) 270 | dwFlags |= FR_MATCHCASE; 271 | if(m_bWholeWord) 272 | dwFlags |= FR_WHOLEWORD; 273 | 274 | return dwFlags; 275 | } 276 | 277 | void FindReplace(BOOL bFindOnly) 278 | { 279 | T* pT = static_cast(this); 280 | m_bFirstSearch = TRUE; 281 | if(m_pFindReplaceDialog != NULL) 282 | { 283 | if(m_bFindOnly == bFindOnly) 284 | { 285 | m_pFindReplaceDialog->SetActiveWindow(); 286 | m_pFindReplaceDialog->ShowWindow(SW_SHOW); 287 | return; 288 | } 289 | else 290 | { 291 | m_pFindReplaceDialog->SendMessage(WM_CLOSE); 292 | ATLASSERT(m_pFindReplaceDialog == NULL); 293 | } 294 | } 295 | 296 | ATLASSERT(m_pFindReplaceDialog == NULL); 297 | 298 | _CSTRING_NS::CString findNext; 299 | pT->GetSelText(findNext); 300 | // if selection is empty or spans multiple lines use old find text 301 | if(findNext.IsEmpty() || (findNext.FindOneOf(_T("\n\r")) != -1)) 302 | findNext = m_sFindNext; 303 | _CSTRING_NS::CString replaceWith = m_sReplaceWith; 304 | DWORD dwFlags = pT->GetFindReplaceDialogFlags(); 305 | 306 | m_pFindReplaceDialog = pT->CreateFindReplaceDialog(bFindOnly, 307 | findNext, replaceWith, dwFlags, pT->operator HWND()); 308 | ATLASSERT(m_pFindReplaceDialog != NULL); 309 | if(m_pFindReplaceDialog != NULL) 310 | m_bFindOnly = bFindOnly; 311 | } 312 | 313 | BOOL SameAsSelected(LPCTSTR lpszCompare, BOOL bMatchCase, BOOL /*bWholeWord*/) 314 | { 315 | T* pT = static_cast(this); 316 | 317 | // check length first 318 | size_t nLen = lstrlen(lpszCompare); 319 | LONG nStartChar = 0, nEndChar = 0; 320 | // Send EM_GETSEL so we can use both Edit and RichEdit 321 | // (CEdit::GetSel uses int&, and CRichEditCtrlT::GetSel uses LONG&) 322 | ::SendMessage(pT->m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar); 323 | if(nLen != (size_t)(nEndChar - nStartChar)) 324 | return FALSE; 325 | 326 | // length is the same, check contents 327 | _CSTRING_NS::CString selectedText; 328 | pT->GetSelText(selectedText); 329 | 330 | return (bMatchCase && selectedText.Compare(lpszCompare) == 0) || 331 | (!bMatchCase && selectedText.CompareNoCase(lpszCompare) == 0); 332 | } 333 | 334 | void TextNotFound(LPCTSTR lpszFind) 335 | { 336 | T* pT = static_cast(this); 337 | m_bFirstSearch = TRUE; 338 | pT->OnTextNotFound(lpszFind); 339 | } 340 | 341 | _CSTRING_NS::CString GetTranslationText(enum TranslationTextItem eItem) const 342 | { 343 | _CSTRING_NS::CString text; 344 | switch(eItem) 345 | { 346 | case eText_OnReplaceAllMessage: 347 | text = _T("Replaced %d occurances of \"%s\" with \"%s\""); 348 | break; 349 | case eText_OnReplaceAllTitle: 350 | text = _T("Replace All"); 351 | break; 352 | case eText_OnTextNotFoundMessage: 353 | text = _T("Unable to find the text \"%s\""); 354 | break; 355 | case eText_OnTextNotFoundTitle: 356 | text = _T("Text not found"); 357 | break; 358 | } 359 | 360 | return text; 361 | } 362 | 363 | // Overrideable Handlers 364 | void OnFindNext(LPCTSTR lpszFind, BOOL bFindDown, BOOL bMatchCase, BOOL bWholeWord) 365 | { 366 | T* pT = static_cast(this); 367 | 368 | m_sFindNext = lpszFind; 369 | m_bMatchCase = bMatchCase; 370 | m_bWholeWord = bWholeWord; 371 | m_bFindDown = bFindDown; 372 | 373 | if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown)) 374 | pT->TextNotFound(m_sFindNext); 375 | else 376 | pT->AdjustDialogPosition(m_pFindReplaceDialog->operator HWND()); 377 | } 378 | 379 | void OnReplaceSel(LPCTSTR lpszFind, BOOL bFindDown, BOOL bMatchCase, BOOL bWholeWord, LPCTSTR lpszReplace) 380 | { 381 | T* pT = static_cast(this); 382 | 383 | m_sFindNext = lpszFind; 384 | m_sReplaceWith = lpszReplace; 385 | m_bMatchCase = bMatchCase; 386 | m_bWholeWord = bWholeWord; 387 | m_bFindDown = bFindDown; 388 | 389 | if(pT->SameAsSelected(m_sFindNext, m_bMatchCase, m_bWholeWord)) 390 | pT->ReplaceSel(m_sReplaceWith); 391 | 392 | if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown)) 393 | pT->TextNotFound(m_sFindNext); 394 | else 395 | pT->AdjustDialogPosition(m_pFindReplaceDialog->operator HWND()); 396 | } 397 | 398 | void OnReplaceAll(LPCTSTR lpszFind, LPCTSTR lpszReplace, BOOL bMatchCase, BOOL bWholeWord) 399 | { 400 | T* pT = static_cast(this); 401 | 402 | m_sFindNext = lpszFind; 403 | m_sReplaceWith = lpszReplace; 404 | m_bMatchCase = bMatchCase; 405 | m_bWholeWord = bWholeWord; 406 | m_bFindDown = TRUE; 407 | 408 | // no selection or different than what looking for 409 | if(!pT->SameAsSelected(m_sFindNext, m_bMatchCase, m_bWholeWord)) 410 | { 411 | if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown)) 412 | { 413 | pT->TextNotFound(m_sFindNext); 414 | return; 415 | } 416 | } 417 | 418 | pT->OnReplaceAllCoreBegin(); 419 | 420 | int replaceCount=0; 421 | do 422 | { 423 | ++replaceCount; 424 | pT->ReplaceSel(m_sReplaceWith); 425 | } while(pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown)); 426 | 427 | pT->OnReplaceAllCoreEnd(replaceCount); 428 | } 429 | 430 | void OnReplaceAllCoreBegin() 431 | { 432 | T* pT = static_cast(this); 433 | 434 | m_hOldCursor = ::SetCursor(::LoadCursor(NULL, IDC_WAIT)); 435 | 436 | pT->HideSelection(TRUE, FALSE); 437 | 438 | } 439 | 440 | void OnReplaceAllCoreEnd(int replaceCount) 441 | { 442 | T* pT = static_cast(this); 443 | pT->HideSelection(FALSE, FALSE); 444 | 445 | ::SetCursor(m_hOldCursor); 446 | 447 | _CSTRING_NS::CString message = pT->GetTranslationText(eText_OnReplaceAllMessage); 448 | if(message.GetLength() > 0) 449 | { 450 | _CSTRING_NS::CString formattedMessage; 451 | formattedMessage.Format(message, replaceCount, m_sFindNext, m_sReplaceWith); 452 | if(m_pFindReplaceDialog != NULL) 453 | { 454 | m_pFindReplaceDialog->MessageBox(formattedMessage, 455 | pT->GetTranslationText(eText_OnReplaceAllTitle), 456 | MB_OK | MB_ICONINFORMATION | MB_APPLMODAL); 457 | } 458 | else 459 | { 460 | pT->MessageBox(formattedMessage, 461 | pT->GetTranslationText(eText_OnReplaceAllTitle), 462 | MB_OK | MB_ICONINFORMATION | MB_APPLMODAL); 463 | } 464 | } 465 | } 466 | 467 | void OnTextNotFound(LPCTSTR lpszFind) 468 | { 469 | T* pT = static_cast(this); 470 | _CSTRING_NS::CString message = pT->GetTranslationText(eText_OnTextNotFoundMessage); 471 | if(message.GetLength() > 0) 472 | { 473 | _CSTRING_NS::CString formattedMessage; 474 | formattedMessage.Format(message, lpszFind); 475 | if(m_pFindReplaceDialog != NULL) 476 | { 477 | m_pFindReplaceDialog->MessageBox(formattedMessage, 478 | pT->GetTranslationText(eText_OnTextNotFoundTitle), 479 | MB_OK | MB_ICONINFORMATION | MB_APPLMODAL); 480 | } 481 | else 482 | { 483 | pT->MessageBox(formattedMessage, 484 | pT->GetTranslationText(eText_OnTextNotFoundTitle), 485 | MB_OK | MB_ICONINFORMATION | MB_APPLMODAL); 486 | } 487 | } 488 | else 489 | { 490 | ::MessageBeep(MB_ICONHAND); 491 | } 492 | } 493 | 494 | void OnTerminatingFindReplaceDialog(TFindReplaceDialog*& /*findReplaceDialog*/) 495 | { 496 | } 497 | }; 498 | 499 | 500 | /////////////////////////////////////////////////////////////////////////////// 501 | // CEditFindReplaceImpl - Mixin class for implementing Find/Replace for CEdit 502 | // based window classes. 503 | 504 | // Chain to CEditFindReplaceImpl message map. Your class must also derive from CEdit. 505 | // Example: 506 | // class CMyEdit : public CWindowImpl, 507 | // public CEditFindReplaceImpl 508 | // { 509 | // public: 510 | // BEGIN_MSG_MAP(CMyEdit) 511 | // // your handlers... 512 | // CHAIN_MSG_MAP_ALT(CEditFindReplaceImpl, 1) 513 | // END_MSG_MAP() 514 | // // other stuff... 515 | // }; 516 | 517 | template 518 | class CEditFindReplaceImpl : public CEditFindReplaceImplBase 519 | { 520 | protected: 521 | typedef CEditFindReplaceImpl thisClass; 522 | typedef CEditFindReplaceImplBase baseClass; 523 | 524 | // Data members 525 | LPTSTR m_pShadowBuffer; // Special shadow buffer only used in some cases. 526 | UINT m_nShadowSize; 527 | int m_bShadowBufferNeeded; // TRUE, FALSE, < 0 => Need to check 528 | 529 | public: 530 | // Constructors 531 | CEditFindReplaceImpl() : 532 | m_pShadowBuffer(NULL), 533 | m_nShadowSize(0), 534 | m_bShadowBufferNeeded(-1) 535 | { 536 | } 537 | 538 | virtual ~CEditFindReplaceImpl() 539 | { 540 | if(m_pShadowBuffer != NULL) 541 | { 542 | delete [] m_pShadowBuffer; 543 | m_pShadowBuffer = NULL; 544 | } 545 | } 546 | 547 | // Message Handlers 548 | BEGIN_MSG_MAP(thisClass) 549 | ALT_MSG_MAP(1) 550 | CHAIN_MSG_MAP_ALT(baseClass, 1) 551 | END_MSG_MAP() 552 | 553 | // Operations 554 | // Supported only for RichEdit, so this does nothing for Edit 555 | void HideSelection(BOOL /*bHide*/ = TRUE, BOOL /*bChangeStyle*/ = FALSE) 556 | { 557 | } 558 | 559 | // Operations (overrideable) 560 | BOOL FindTextSimple(LPCTSTR lpszFind, BOOL bMatchCase, BOOL bWholeWord, BOOL bFindDown = TRUE) 561 | { 562 | T* pT = static_cast(this); 563 | 564 | ATLASSERT(lpszFind != NULL); 565 | ATLASSERT(*lpszFind != _T('\0')); 566 | 567 | UINT nLen = pT->GetBufferLength(); 568 | int nStartChar = 0, nEndChar = 0; 569 | pT->GetSel(nStartChar, nEndChar); 570 | UINT nStart = nStartChar; 571 | int iDir = bFindDown ? +1 : -1; 572 | 573 | // can't find a match before the first character 574 | if((nStart == 0) && (iDir < 0)) 575 | return FALSE; 576 | 577 | LPCTSTR lpszText = pT->LockBuffer(); 578 | 579 | bool isDBCS = false; 580 | #ifdef _MBCS 581 | CPINFO info = { 0 }; 582 | ::GetCPInfo(::GetOEMCP(), &info); 583 | isDBCS = (info.MaxCharSize > 1); 584 | #endif 585 | 586 | if(iDir < 0) 587 | { 588 | // always go back one for search backwards 589 | nStart -= int((lpszText + nStart) - ::CharPrev(lpszText, lpszText + nStart)); 590 | } 591 | else if((nStartChar != nEndChar) && (pT->SameAsSelected(lpszFind, bMatchCase, bWholeWord))) 592 | { 593 | // easy to go backward/forward with SBCS 594 | #ifndef _UNICODE 595 | if(::IsDBCSLeadByte(lpszText[nStart])) 596 | nStart++; 597 | #endif 598 | nStart += iDir; 599 | } 600 | 601 | // handle search with nStart past end of buffer 602 | UINT nLenFind = ::lstrlen(lpszFind); 603 | if((nStart + nLenFind - 1) >= nLen) 604 | { 605 | if((iDir < 0) && (nLen >= nLenFind)) 606 | { 607 | if(isDBCS) 608 | { 609 | // walk back to previous character n times 610 | nStart = nLen; 611 | int n = nLenFind; 612 | while(n--) 613 | { 614 | nStart -= int((lpszText + nStart) - ::CharPrev(lpszText, lpszText + nStart)); 615 | } 616 | } 617 | else 618 | { 619 | // single-byte character set is easy and fast 620 | nStart = nLen - nLenFind; 621 | } 622 | ATLASSERT((nStart + nLenFind - 1) <= nLen); 623 | } 624 | else 625 | { 626 | pT->UnlockBuffer(); 627 | return FALSE; 628 | } 629 | } 630 | 631 | // start the search at nStart 632 | LPCTSTR lpsz = lpszText + nStart; 633 | typedef int (WINAPI* CompareProc)(LPCTSTR str1, LPCTSTR str2); 634 | CompareProc pfnCompare = bMatchCase ? lstrcmp : lstrcmpi; 635 | 636 | if(isDBCS) 637 | { 638 | // double-byte string search 639 | LPCTSTR lpszStop = NULL; 640 | if(iDir > 0) 641 | { 642 | // start at current and find _first_ occurrance 643 | lpszStop = lpszText + nLen - nLenFind + 1; 644 | } 645 | else 646 | { 647 | // start at top and find _last_ occurrance 648 | lpszStop = lpsz; 649 | lpsz = lpszText; 650 | } 651 | 652 | LPCTSTR lpszFound = NULL; 653 | while(lpsz <= lpszStop) 654 | { 655 | #ifndef _UNICODE 656 | if(!bMatchCase || (*lpsz == *lpszFind && (!::IsDBCSLeadByte(*lpsz) || lpsz[1] == lpszFind[1]))) 657 | #else 658 | if(!bMatchCase || (*lpsz == *lpszFind && lpsz[1] == lpszFind[1])) 659 | #endif 660 | { 661 | LPTSTR lpch = (LPTSTR)(lpsz + nLenFind); 662 | TCHAR chSave = *lpch; 663 | *lpch = _T('\0'); 664 | int nResult = (*pfnCompare)(lpsz, lpszFind); 665 | *lpch = chSave; 666 | if(nResult == 0) 667 | { 668 | lpszFound = lpsz; 669 | if(iDir > 0) 670 | break; 671 | } 672 | } 673 | lpsz = ::CharNext(lpsz); 674 | } 675 | pT->UnlockBuffer(); 676 | 677 | if(lpszFound != NULL) 678 | { 679 | int n = (int)(lpszFound - lpszText); 680 | pT->SetSel(n, n + nLenFind); 681 | return TRUE; 682 | } 683 | } 684 | else 685 | { 686 | // single-byte string search 687 | UINT nCompare = 0; 688 | if(iDir < 0) 689 | nCompare = (UINT)(lpsz - lpszText) + 1; 690 | else 691 | nCompare = nLen - (UINT)(lpsz - lpszText) - nLenFind + 1; 692 | 693 | while(nCompare > 0) 694 | { 695 | ATLASSERT(lpsz >= lpszText); 696 | ATLASSERT((lpsz + nLenFind - 1) <= (lpszText + nLen - 1)); 697 | 698 | LPSTR lpch = (LPSTR)(lpsz + nLenFind); 699 | char chSave = *lpch; 700 | *lpch = '\0'; 701 | int nResult = (*pfnCompare)(lpsz, lpszFind); 702 | *lpch = chSave; 703 | if(nResult == 0) 704 | { 705 | pT->UnlockBuffer(); 706 | int n = (int)(lpsz - lpszText); 707 | pT->SetSel(n, n + nLenFind); 708 | return TRUE; 709 | } 710 | 711 | // restore character at end of search 712 | *lpch = chSave; 713 | 714 | // move on to next substring 715 | nCompare--; 716 | lpsz += iDir; 717 | } 718 | pT->UnlockBuffer(); 719 | } 720 | 721 | return FALSE; 722 | } 723 | 724 | LPCTSTR LockBuffer() const 725 | { 726 | const T* pT = static_cast(this); 727 | ATLASSERT(pT->m_hWnd != NULL); 728 | 729 | BOOL useShadowBuffer = pT->UseShadowBuffer(); 730 | if(useShadowBuffer) 731 | { 732 | if((m_pShadowBuffer == NULL) || pT->GetModify()) 733 | { 734 | ATLASSERT((m_pShadowBuffer != NULL) || (m_nShadowSize == 0)); 735 | UINT nSize = pT->GetWindowTextLength() + 1; 736 | if(nSize > m_nShadowSize) 737 | { 738 | // need more room for shadow buffer 739 | T* pThisNoConst = const_cast(pT); 740 | delete[] m_pShadowBuffer; 741 | pThisNoConst->m_pShadowBuffer = NULL; 742 | pThisNoConst->m_nShadowSize = 0; 743 | pThisNoConst->m_pShadowBuffer = new TCHAR[nSize]; 744 | pThisNoConst->m_nShadowSize = nSize; 745 | } 746 | 747 | // update the shadow buffer with GetWindowText 748 | ATLASSERT(m_nShadowSize >= nSize); 749 | ATLASSERT(m_pShadowBuffer != NULL); 750 | pT->GetWindowText(m_pShadowBuffer, nSize); 751 | } 752 | 753 | return m_pShadowBuffer; 754 | } 755 | 756 | HLOCAL hLocal = pT->GetHandle(); 757 | ATLASSERT(hLocal != NULL); 758 | LPCTSTR lpszText = (LPCTSTR)::LocalLock(hLocal); 759 | ATLASSERT(lpszText != NULL); 760 | 761 | return lpszText; 762 | } 763 | 764 | void UnlockBuffer() const 765 | { 766 | const T* pT = static_cast(this); 767 | ATLASSERT(pT->m_hWnd != NULL); 768 | 769 | BOOL useShadowBuffer = pT->UseShadowBuffer(); 770 | if(!useShadowBuffer) 771 | { 772 | HLOCAL hLocal = pT->GetHandle(); 773 | ATLASSERT(hLocal != NULL); 774 | ::LocalUnlock(hLocal); 775 | } 776 | } 777 | 778 | UINT GetBufferLength() const 779 | { 780 | const T* pT = static_cast(this); 781 | ATLASSERT(pT->m_hWnd != NULL); 782 | 783 | UINT nLen = 0; 784 | LPCTSTR lpszText = pT->LockBuffer(); 785 | if(lpszText != NULL) 786 | nLen = ::lstrlen(lpszText); 787 | pT->UnlockBuffer(); 788 | 789 | return nLen; 790 | } 791 | 792 | LONG EndOfLine(LPCTSTR lpszText, UINT nLen, UINT nIndex) const 793 | { 794 | LPCTSTR lpsz = lpszText + nIndex; 795 | LPCTSTR lpszStop = lpszText + nLen; 796 | while(lpsz < lpszStop && *lpsz != _T('\r')) 797 | ++lpsz; 798 | return LONG(lpsz - lpszText); 799 | } 800 | 801 | LONG GetSelText(_CSTRING_NS::CString& strText) const 802 | { 803 | const T* pT = static_cast(this); 804 | 805 | int nStartChar = 0, nEndChar = 0; 806 | pT->GetSel(nStartChar, nEndChar); 807 | ATLASSERT((UINT)nEndChar <= pT->GetBufferLength()); 808 | LPCTSTR lpszText = pT->LockBuffer(); 809 | LONG nLen = pT->EndOfLine(lpszText, nEndChar, nStartChar) - nStartChar; 810 | SecureHelper::memcpy_x(strText.GetBuffer(nLen), nLen * sizeof(TCHAR), lpszText + nStartChar, nLen * sizeof(TCHAR)); 811 | strText.ReleaseBuffer(nLen); 812 | pT->UnlockBuffer(); 813 | 814 | return nLen; 815 | } 816 | 817 | BOOL UseShadowBuffer(void) const 818 | { 819 | const T* pT = static_cast(this); 820 | 821 | if(pT->m_bShadowBufferNeeded < 0) 822 | { 823 | T* pThisNoConst = const_cast(pT); 824 | 825 | #ifdef _versionhelpers_H_INCLUDED_ 826 | OSVERSIONINFOEX ovi = { sizeof(OSVERSIONINFOEX) }; 827 | ovi.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS; 828 | DWORDLONG const dwlConditionMask = ::VerSetConditionMask(0, VER_PLATFORMID, VER_EQUAL); 829 | bool bWin9x = (::VerifyVersionInfo(&ovi, VER_PLATFORMID, dwlConditionMask) != FALSE); 830 | #else // !_versionhelpers_H_INCLUDED_ 831 | OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) }; 832 | ::GetVersionEx(&ovi); 833 | 834 | bool bWin9x = (ovi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); 835 | #endif // _versionhelpers_H_INCLUDED_ 836 | if(bWin9x) 837 | { 838 | // Windows 95, 98, ME 839 | // Under Win9x, it is necessary to maintain a shadow buffer. 840 | // It is only updated when the control contents have been changed. 841 | pThisNoConst->m_bShadowBufferNeeded = TRUE; 842 | } 843 | else 844 | { 845 | // Windows NT, 2000, XP, etc. 846 | pThisNoConst->m_bShadowBufferNeeded = FALSE; 847 | 848 | #ifndef _UNICODE 849 | // On Windows XP (or later), if common controls version 6 is in use 850 | // (such as via theming), then EM_GETHANDLE will always return a UNICODE string. 851 | // If theming is enabled and Common Controls version 6 is in use, 852 | // you're really not suppose to superclass or subclass common controls 853 | // with an ANSI windows procedure (so its best to only theme if you use UNICODE). 854 | // Using a shadow buffer uses GetWindowText instead, so it solves 855 | // this problem for us (although it makes it a little less efficient). 856 | 857 | #ifdef _versionhelpers_H_INCLUDED_ 858 | if(::IsWindowsXPOrGreater()) 859 | #else // !_versionhelpers_H_INCLUDED_ 860 | if ((ovi.dwMajorVersion == 5 && ovi.dwMinorVersion >= 1) || (ovi.dwMajorVersion > 5)) 861 | #endif // _versionhelpers_H_INCLUDED_ 862 | { 863 | // We use DLLVERSIONINFO_private so we don't have to depend on shlwapi.h 864 | typedef struct _DLLVERSIONINFO_private 865 | { 866 | DWORD cbSize; 867 | DWORD dwMajorVersion; 868 | DWORD dwMinorVersion; 869 | DWORD dwBuildNumber; 870 | DWORD dwPlatformID; 871 | } DLLVERSIONINFO_private; 872 | 873 | HMODULE hModule = ::LoadLibrary("comctl32.dll"); 874 | if(hModule != NULL) 875 | { 876 | typedef HRESULT (CALLBACK *LPFN_DllGetVersion)(DLLVERSIONINFO_private *); 877 | LPFN_DllGetVersion fnDllGetVersion = (LPFN_DllGetVersion)::GetProcAddress(hModule, "DllGetVersion"); 878 | if(fnDllGetVersion != NULL) 879 | { 880 | DLLVERSIONINFO_private version = { sizeof(DLLVERSIONINFO_private) }; 881 | if(SUCCEEDED(fnDllGetVersion(&version))) 882 | { 883 | if(version.dwMajorVersion >= 6) 884 | { 885 | pThisNoConst->m_bShadowBufferNeeded = TRUE; 886 | 887 | 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")); 888 | ATLTRACE2(atlTraceUI, 0, _T("If you use common controls version 6 or later, you should only do so for UNICODE builds.\r\n")); 889 | } 890 | } 891 | } 892 | 893 | ::FreeLibrary(hModule); 894 | hModule = NULL; 895 | } 896 | } 897 | #endif // !_UNICODE 898 | } 899 | } 900 | 901 | return (pT->m_bShadowBufferNeeded != FALSE); 902 | } 903 | }; 904 | 905 | 906 | /////////////////////////////////////////////////////////////////////////////// 907 | // CRichEditFindReplaceImpl - Mixin class for implementing Find/Replace for CRichEditCtrl 908 | // based window classes. 909 | 910 | // Chain to CRichEditFindReplaceImpl message map. Your class must also derive from CRichEditCtrl. 911 | // Example: 912 | // class CMyRichEdit : public CWindowImpl, 913 | // public CRichEditFindReplaceImpl 914 | // { 915 | // public: 916 | // BEGIN_MSG_MAP(CMyRichEdit) 917 | // // your handlers... 918 | // CHAIN_MSG_MAP_ALT(CRichEditFindReplaceImpl, 1) 919 | // END_MSG_MAP() 920 | // // other stuff... 921 | // }; 922 | 923 | template 924 | class CRichEditFindReplaceImpl : public CEditFindReplaceImplBase 925 | { 926 | protected: 927 | typedef CRichEditFindReplaceImpl thisClass; 928 | typedef CEditFindReplaceImplBase baseClass; 929 | 930 | public: 931 | BEGIN_MSG_MAP(thisClass) 932 | ALT_MSG_MAP(1) 933 | CHAIN_MSG_MAP_ALT(baseClass, 1) 934 | END_MSG_MAP() 935 | 936 | // Operations (overrideable) 937 | BOOL FindTextSimple(LPCTSTR lpszFind, BOOL bMatchCase, BOOL bWholeWord, BOOL bFindDown = TRUE) 938 | { 939 | T* pT = static_cast(this); 940 | 941 | ATLASSERT(lpszFind != NULL); 942 | FINDTEXTEX ft = { 0 }; 943 | 944 | pT->GetSel(ft.chrg); 945 | if(m_bFirstSearch) 946 | { 947 | if(bFindDown) 948 | m_nInitialSearchPos = ft.chrg.cpMin; 949 | else 950 | m_nInitialSearchPos = ft.chrg.cpMax; 951 | m_bFirstSearch = FALSE; 952 | } 953 | 954 | #if (_RICHEDIT_VER >= 0x0200) 955 | ft.lpstrText = (LPTSTR)lpszFind; 956 | #else // !(_RICHEDIT_VER >= 0x0200) 957 | USES_CONVERSION; 958 | ft.lpstrText = T2A((LPTSTR)lpszFind); 959 | #endif // !(_RICHEDIT_VER >= 0x0200) 960 | 961 | if(ft.chrg.cpMin != ft.chrg.cpMax) // i.e. there is a selection 962 | { 963 | if(bFindDown) 964 | { 965 | ft.chrg.cpMin++; 966 | } 967 | else 968 | { 969 | // won't wraparound backwards 970 | ft.chrg.cpMin = __max(ft.chrg.cpMin, 0); 971 | } 972 | } 973 | 974 | DWORD dwFlags = bMatchCase ? FR_MATCHCASE : 0; 975 | dwFlags |= bWholeWord ? FR_WHOLEWORD : 0; 976 | 977 | ft.chrg.cpMax = pT->GetTextLength() + m_nInitialSearchPos; 978 | 979 | if(bFindDown) 980 | { 981 | if(m_nInitialSearchPos >= 0) 982 | ft.chrg.cpMax = pT->GetTextLength(); 983 | 984 | dwFlags |= FR_DOWN; 985 | ATLASSERT(ft.chrg.cpMax >= ft.chrg.cpMin); 986 | } 987 | else 988 | { 989 | if(m_nInitialSearchPos >= 0) 990 | ft.chrg.cpMax = 0; 991 | 992 | dwFlags &= ~FR_DOWN; 993 | ATLASSERT(ft.chrg.cpMax <= ft.chrg.cpMin); 994 | } 995 | 996 | BOOL bRet = FALSE; 997 | if(pT->FindAndSelect(dwFlags, ft) != -1) 998 | { 999 | bRet = TRUE; // we found the text 1000 | } 1001 | else if(m_nInitialSearchPos > 0) 1002 | { 1003 | // if the original starting point was not the beginning 1004 | // of the buffer and we haven't already been here 1005 | if(bFindDown) 1006 | { 1007 | ft.chrg.cpMin = 0; 1008 | ft.chrg.cpMax = m_nInitialSearchPos; 1009 | } 1010 | else 1011 | { 1012 | ft.chrg.cpMin = pT->GetTextLength(); 1013 | ft.chrg.cpMax = m_nInitialSearchPos; 1014 | } 1015 | m_nInitialSearchPos = m_nInitialSearchPos - pT->GetTextLength(); 1016 | 1017 | bRet = (pT->FindAndSelect(dwFlags, ft) != -1) ? TRUE : FALSE; 1018 | } 1019 | 1020 | return bRet; 1021 | } 1022 | 1023 | long FindAndSelect(DWORD dwFlags, FINDTEXTEX& ft) 1024 | { 1025 | T* pT = static_cast(this); 1026 | LONG index = pT->FindText(dwFlags, ft); 1027 | if(index != -1) // i.e. we found something 1028 | pT->SetSel(ft.chrgText); 1029 | 1030 | return index; 1031 | } 1032 | }; 1033 | 1034 | }; // namespace WTL 1035 | 1036 | #endif // __ATLFIND_H__ 1037 | --------------------------------------------------------------------------------