diff --git a/base/applications/ctfmon/ctfmon.cpp b/base/applications/ctfmon/ctfmon.cpp index 6c255f18b2e..331fd19cc37 100644 --- a/base/applications/ctfmon/ctfmon.cpp +++ b/base/applications/ctfmon/ctfmon.cpp @@ -194,9 +194,6 @@ InitApp( g_bOnWow64 = cicIsWow64(); // Is the current process on WoW64? cicGetOSInfo(&g_uACP, &g_dwOsInfo); // Get OS info - // Initialize Cicero - TFInitLib(); - // Create a mutex for Cicero g_hCicMutex = TF_CreateCicLoadMutex(&g_fWinLogon); if (!g_hCicMutex) @@ -251,9 +248,6 @@ UninitApp(VOID) // Close Tipbar Popup ClosePopupTipbar(); - // Release Cicero - TFUninitLib(); - // Close the mutex ::CloseHandle(g_hCicMutex); g_hCicMutex = NULL; diff --git a/base/setup/lib/utils/osdetect.c b/base/setup/lib/utils/osdetect.c index 0ee246c60b1..cc45fa907c2 100644 --- a/base/setup/lib/utils/osdetect.c +++ b/base/setup/lib/utils/osdetect.c @@ -806,12 +806,11 @@ CreateNTOSInstallationsList( ASSERT(PartEntry->DiskEntry == DiskEntry); - DPRINT(" Primary Partition #%d, index %d - Type 0x%02x, IsLogical = %s, IsPartitioned = %s, IsNew = %s, AutoCreate = %s, FormatState = %lu -- Should I check it? %s\n", + DPRINT(" Primary Partition #%d, index %d - Type 0x%02x, IsLogical = %s, IsPartitioned = %s, IsNew = %s, FormatState = %lu -- Should I check it? %s\n", PartEntry->PartitionNumber, PartEntry->PartitionIndex, PartEntry->PartitionType, PartEntry->LogicalPartition ? "TRUE" : "FALSE", PartEntry->IsPartitioned ? "TRUE" : "FALSE", PartEntry->New ? "Yes" : "No", - PartEntry->AutoCreate ? "Yes" : "No", PartEntry->FormatState, ShouldICheckThisPartition(PartEntry) ? "YES!" : "NO!"); @@ -828,12 +827,11 @@ CreateNTOSInstallationsList( ASSERT(PartEntry->DiskEntry == DiskEntry); - DPRINT(" Logical Partition #%d, index %d - Type 0x%02x, IsLogical = %s, IsPartitioned = %s, IsNew = %s, AutoCreate = %s, FormatState = %lu -- Should I check it? %s\n", + DPRINT(" Logical Partition #%d, index %d - Type 0x%02x, IsLogical = %s, IsPartitioned = %s, IsNew = %s, FormatState = %lu -- Should I check it? %s\n", PartEntry->PartitionNumber, PartEntry->PartitionIndex, PartEntry->PartitionType, PartEntry->LogicalPartition ? "TRUE" : "FALSE", PartEntry->IsPartitioned ? "TRUE" : "FALSE", PartEntry->New ? "Yes" : "No", - PartEntry->AutoCreate ? "Yes" : "No", PartEntry->FormatState, ShouldICheckThisPartition(PartEntry) ? "YES!" : "NO!"); diff --git a/base/setup/lib/utils/partlist.c b/base/setup/lib/utils/partlist.c index 49c15e9ffe2..6bb16fed9d4 100644 --- a/base/setup/lib/utils/partlist.c +++ b/base/setup/lib/utils/partlist.c @@ -552,7 +552,7 @@ IsSuperFloppy( } /* The partition lengths should agree */ - PartitionLengthEstimate = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; + PartitionLengthEstimate = GetDiskSizeInBytes(DiskEntry); if (PartitionInfo->PartitionLength.QuadPart != PartitionLengthEstimate) { DPRINT1("PartitionLength = %I64u is different from PartitionLengthEstimate = %I64u\n", @@ -676,26 +676,46 @@ CreateInsertBlankRegion( static BOOLEAN InitializePartitionEntry( - IN OUT PPARTENTRY PartEntry, - IN ULONGLONG SectorCount, - IN BOOLEAN AutoCreate) + _Inout_ PPARTENTRY PartEntry, + _In_opt_ ULONGLONG SizeBytes) { PDISKENTRY DiskEntry = PartEntry->DiskEntry; + ULONGLONG SectorCount; + + DPRINT1("Current entry sector count: %I64u\n", PartEntry->SectorCount.QuadPart); - DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart); + /* The entry must not be already partitioned and not be void */ + ASSERT(!PartEntry->IsPartitioned); + ASSERT(PartEntry->SectorCount.QuadPart); + + /* Convert the size in bytes to sector count. SizeBytes being + * zero means the caller wants to use all the empty space. */ + if ((SizeBytes == 0) || (SizeBytes == GetPartEntrySizeInBytes(PartEntry))) + { + /* Use all of the unpartitioned disk space */ + SectorCount = PartEntry->SectorCount.QuadPart; + } + else + { + SectorCount = SizeBytes / DiskEntry->BytesPerSector; + if (SectorCount == 0) + { + /* SizeBytes was certainly less than the minimal size, so fail */ + DPRINT1("Partition size %I64u too small\n", SizeBytes); + return FALSE; + } + } + DPRINT1(" New sector count: %I64u\n", SectorCount); - /* Fail if we try to initialize this partition entry with more sectors than what it actually contains */ + /* Fail if we request more sectors than what the entry actually contains */ if (SectorCount > PartEntry->SectorCount.QuadPart) return FALSE; - /* Fail if the partition is already in use */ - ASSERT(!PartEntry->IsPartitioned); - - if ((AutoCreate != FALSE) || + if ((SectorCount == 0) || (AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart)) { - PartEntry->AutoCreate = AutoCreate; + /* Reuse the whole current entry */ } else { @@ -703,7 +723,8 @@ InitializePartitionEntry( ULONGLONG SectorCount2; PPARTENTRY NewPartEntry; - /* Create a partition entry that represents the remaining space after the partition to be initialized */ + /* Create a partition entry that represents the remaining space + * after the partition to be initialized */ StartSector = AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment); SectorCount2 = PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - StartSector; @@ -735,7 +756,6 @@ InitializePartitionEntry( PartEntry->FormatState = Unformatted; PartEntry->FileSystem[0] = L'\0'; - // PartEntry->AutoCreate = AutoCreate; PartEntry->BootIndicator = FALSE; DPRINT1("First Sector : %I64u\n", PartEntry->StartSector.QuadPart); @@ -2390,37 +2410,24 @@ GetPrevPartition( return NULL; } -// static -FORCEINLINE +static inline BOOLEAN IsEmptyLayoutEntry( - IN PPARTITION_INFORMATION PartitionInfo) + _In_ PPARTITION_INFORMATION PartitionInfo) { - if (PartitionInfo->StartingOffset.QuadPart == 0 && - PartitionInfo->PartitionLength.QuadPart == 0) - { - return TRUE; - } - - return FALSE; + return (PartitionInfo->StartingOffset.QuadPart == 0 && + PartitionInfo->PartitionLength.QuadPart == 0); } -// static -FORCEINLINE +static inline BOOLEAN IsSamePrimaryLayoutEntry( - IN PPARTITION_INFORMATION PartitionInfo, - IN PDISKENTRY DiskEntry, - IN PPARTENTRY PartEntry) + _In_ PPARTITION_INFORMATION PartitionInfo, + _In_ PPARTENTRY PartEntry) { - if (PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector && - PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) + return ((PartitionInfo->StartingOffset.QuadPart == GetPartEntryOffsetInBytes(PartEntry)) && + (PartitionInfo->PartitionLength.QuadPart == GetPartEntrySizeInBytes(PartEntry))); // PartitionInfo->PartitionType == PartEntry->PartitionType - { - return TRUE; - } - - return FALSE; } static @@ -2578,12 +2585,12 @@ UpdateDiskLayout( PartEntry->OnDiskPartitionNumber = (!IsContainerPartition(PartEntry->PartitionType) ? PartitionNumber : 0); - if (!IsSamePrimaryLayoutEntry(PartitionInfo, DiskEntry, PartEntry)) + if (!IsSamePrimaryLayoutEntry(PartitionInfo, PartEntry)) { DPRINT1("Updating primary partition entry %lu\n", Index); - PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector; - PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; + PartitionInfo->StartingOffset.QuadPart = GetPartEntryOffsetInBytes(PartEntry); + PartitionInfo->PartitionLength.QuadPart = GetPartEntrySizeInBytes(PartEntry); PartitionInfo->HiddenSectors = PartEntry->StartSector.LowPart; PartitionInfo->PartitionNumber = PartEntry->PartitionNumber; PartitionInfo->PartitionType = PartEntry->PartitionType; @@ -2624,8 +2631,8 @@ UpdateDiskLayout( DPRINT1("Updating logical partition entry %lu\n", Index); - PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector; - PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; + PartitionInfo->StartingOffset.QuadPart = GetPartEntryOffsetInBytes(PartEntry); + PartitionInfo->PartitionLength.QuadPart = GetPartEntrySizeInBytes(PartEntry); PartitionInfo->HiddenSectors = DiskEntry->SectorAlignment; PartitionInfo->PartitionNumber = PartEntry->PartitionNumber; PartitionInfo->PartitionType = PartEntry->PartitionType; @@ -2862,12 +2869,11 @@ BOOLEAN CreatePartition( _In_ PPARTLIST List, _Inout_ PPARTENTRY PartEntry, - _In_ ULONGLONG SectorCount, - _In_ BOOLEAN AutoCreate) + _In_opt_ ULONGLONG SizeBytes) { ERROR_NUMBER Error; - DPRINT1("CreatePartition(%I64u)\n", SectorCount); + DPRINT1("CreatePartition(%I64u bytes)\n", SizeBytes); if (List == NULL || PartEntry == NULL || PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned) @@ -2883,7 +2889,7 @@ CreatePartition( } /* Initialize the partition entry, inserting a new blank region if needed */ - if (!InitializePartitionEntry(PartEntry, SectorCount, AutoCreate)) + if (!InitializePartitionEntry(PartEntry, SizeBytes)) return FALSE; UpdateDiskLayout(PartEntry->DiskEntry); @@ -2924,11 +2930,11 @@ BOOLEAN CreateExtendedPartition( _In_ PPARTLIST List, _Inout_ PPARTENTRY PartEntry, - _In_ ULONGLONG SectorCount) + _In_opt_ ULONGLONG SizeBytes) { ERROR_NUMBER Error; - DPRINT1("CreateExtendedPartition(%I64u)\n", SectorCount); + DPRINT1("CreateExtendedPartition(%I64u bytes)\n", SizeBytes); if (List == NULL || PartEntry == NULL || PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned) @@ -2944,7 +2950,7 @@ CreateExtendedPartition( } /* Initialize the partition entry, inserting a new blank region if needed */ - if (!InitializePartitionEntry(PartEntry, SectorCount, FALSE)) + if (!InitializePartitionEntry(PartEntry, SizeBytes)) return FALSE; ASSERT(PartEntry->LogicalPartition == FALSE); @@ -3933,7 +3939,7 @@ SetMountedDeviceValues( /* Assign a "\DosDevices\#:" mount point to this partition */ if (PartEntry->DriveLetter) { - StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector; + StartingOffset.QuadPart = GetPartEntryOffsetInBytes(PartEntry); if (!SetMountedDeviceValue(PartEntry->DriveLetter, DiskEntry->LayoutBuffer->Signature, StartingOffset)) @@ -3956,7 +3962,7 @@ SetMountedDeviceValues( /* Assign a "\DosDevices\#:" mount point to this partition */ if (PartEntry->DriveLetter) { - StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector; + StartingOffset.QuadPart = GetPartEntryOffsetInBytes(PartEntry); if (!SetMountedDeviceValue(PartEntry->DriveLetter, DiskEntry->LayoutBuffer->Signature, StartingOffset)) diff --git a/base/setup/lib/utils/partlist.h b/base/setup/lib/utils/partlist.h index c59b5e1f4b7..d5b20615455 100644 --- a/base/setup/lib/utils/partlist.h +++ b/base/setup/lib/utils/partlist.h @@ -70,9 +70,6 @@ typedef struct _PARTENTRY /* Partition is new, table does not exist on disk yet */ BOOLEAN New; - /* Partition was created automatically */ - BOOLEAN AutoCreate; - /* Partition must be checked */ BOOLEAN NeedsCheck; @@ -227,6 +224,16 @@ RoundingDivide( IN ULONGLONG Divisor); +#define GetPartEntryOffsetInBytes(PartEntry) \ + ((PartEntry)->StartSector.QuadPart * (PartEntry)->DiskEntry->BytesPerSector) + +#define GetPartEntrySizeInBytes(PartEntry) \ + ((PartEntry)->SectorCount.QuadPart * (PartEntry)->DiskEntry->BytesPerSector) + +#define GetDiskSizeInBytes(DiskEntry) \ + ((DiskEntry)->SectorCount.QuadPart * (DiskEntry)->BytesPerSector) + + BOOLEAN IsSuperFloppy( IN PDISKENTRY DiskEntry); @@ -306,14 +313,13 @@ BOOLEAN CreatePartition( _In_ PPARTLIST List, _Inout_ PPARTENTRY PartEntry, - _In_ ULONGLONG SectorCount, - _In_ BOOLEAN AutoCreate); + _In_opt_ ULONGLONG SizeBytes); BOOLEAN CreateExtendedPartition( _In_ PPARTLIST List, _Inout_ PPARTENTRY PartEntry, - _In_ ULONGLONG SectorCount); + _In_opt_ ULONGLONG SizeBytes); NTSTATUS DismountVolume( diff --git a/base/setup/usetup/partlist.c b/base/setup/usetup/partlist.c index 76988b0606c..2420ea3a3ea 100644 --- a/base/setup/usetup/partlist.c +++ b/base/setup/usetup/partlist.c @@ -156,7 +156,7 @@ PartitionDescription( PCSTR Unit; /* Get the partition size */ - PartSize = PartEntry->SectorCount.QuadPart * PartEntry->DiskEntry->BytesPerSector; + PartSize = GetPartEntrySizeInBytes(PartEntry); PrettifySize2(&PartSize, &Unit); if (PartEntry->IsPartitioned == FALSE) @@ -307,7 +307,7 @@ DiskDescription( PCSTR Unit; /* Get the disk size */ - DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; + DiskSize = GetDiskSizeInBytes(DiskEntry); PrettifySize1(&DiskSize, &Unit); // diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c index 1b23cf7d220..0389a641a9f 100644 --- a/base/setup/usetup/usetup.c +++ b/base/setup/usetup/usetup.c @@ -79,6 +79,9 @@ static enum { PartTypeExtended // MBR-disk container } PartCreateType = PartTypeData; +/* Flag set in PARTENTRY::New when a partition is created automatically */ +#define PARTITION_NEW_AUTOCREATE 0x80 + /* List of supported file systems for the partition to be formatted */ static PFILE_SYSTEM_LIST FileSystemList = NULL; @@ -1535,18 +1538,18 @@ LayoutSettingsPage(PINPUT_RECORD Ir) } -static BOOL -IsDiskSizeValid(PPARTENTRY PartEntry) +static BOOLEAN +IsPartitionLargeEnough( + _In_ PPARTENTRY PartEntry) { - ULONGLONG size; + /* Retrieve the maximum size in MB (rounded up) */ + ULONGLONG PartSize = RoundingDivide(GetPartEntrySizeInBytes(PartEntry), MB); - size = PartEntry->SectorCount.QuadPart * PartEntry->DiskEntry->BytesPerSector; - size = (size + (512 * KB)) / MB; /* in MBytes */ - - if (size < USetupData.RequiredPartitionDiskSpace) + if (PartSize < USetupData.RequiredPartitionDiskSpace) { /* Partition is too small so ask for another one */ - DPRINT1("Partition is too small (size: %I64u MB), required disk space is %lu MB\n", size, USetupData.RequiredPartitionDiskSpace); + DPRINT1("Partition is too small (size: %I64u MB), required disk space is %lu MB\n", + PartSize, USetupData.RequiredPartitionDiskSpace); return FALSE; } else @@ -1640,13 +1643,15 @@ SelectPartitionPage(PINPUT_RECORD Ir) ASSERT(CurrentPartition != NULL); ASSERT(!IsContainerPartition(CurrentPartition->PartitionType)); + /* Automatically create the partition on the whole empty space; + * it will be formatted later with default parameters */ CreatePartition(PartitionList, CurrentPartition, - CurrentPartition->SectorCount.QuadPart, - TRUE); + 0ULL); + CurrentPartition->New |= PARTITION_NEW_AUTOCREATE; // FIXME?? Aren't we going to enter an infinite loop, if this test fails?? - if (!IsDiskSizeValid(CurrentPartition)) + if (!IsPartitionLargeEnough(CurrentPartition)) { MUIDisplayError(ERROR_INSUFFICIENT_PARTITION_SIZE, Ir, POPUP_WAIT_ANY_KEY, USetupData.RequiredPartitionDiskSpace); @@ -1664,7 +1669,7 @@ SelectPartitionPage(PINPUT_RECORD Ir) DrawPartitionList(&ListUi); // FIXME: Doesn't make much sense... // FIXME?? Aren't we going to enter an infinite loop, if this test fails?? - if (!IsDiskSizeValid(InstallPartition)) + if (!IsPartitionLargeEnough(InstallPartition)) { MUIDisplayError(ERROR_INSUFFICIENT_PARTITION_SIZE, Ir, POPUP_WAIT_ANY_KEY, USetupData.RequiredPartitionDiskSpace); @@ -1769,13 +1774,15 @@ SelectPartitionPage(PINPUT_RECORD Ir) return SELECT_PARTITION_PAGE; } + /* Automatically create the partition on the whole empty space; + * it will be formatted later with default parameters */ CreatePartition(PartitionList, CurrentPartition, - 0ULL, - TRUE); + 0ULL); + CurrentPartition->New |= PARTITION_NEW_AUTOCREATE; } - if (!IsDiskSizeValid(CurrentPartition)) + if (!IsPartitionLargeEnough(CurrentPartition)) { MUIDisplayError(ERROR_INSUFFICIENT_PARTITION_SIZE, Ir, POPUP_WAIT_ANY_KEY, USetupData.RequiredPartitionDiskSpace); @@ -2072,11 +2079,9 @@ CreatePartitionPage(PINPUT_RECORD Ir) PPARTENTRY PartEntry; PDISKENTRY DiskEntry; ULONG uID; - BOOLEAN Quit; - BOOLEAN Cancel; ULONG MaxSize; - ULONGLONG PartSize; - ULONGLONG SectorCount; + ULONGLONG MaxPartSize, PartSize; + BOOLEAN Quit, Cancel; WCHAR InputBuffer[50]; CHAR LineBuffer[100]; @@ -2110,15 +2115,17 @@ CreatePartitionPage(PINPUT_RECORD Ir) CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION)); + MaxPartSize = GetPartEntrySizeInBytes(PartEntry); + while (TRUE) { - MaxSize = (PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) / MB; /* in MBytes (rounded) */ - if (MaxSize > PARTITION_MAXSIZE) - MaxSize = PARTITION_MAXSIZE; + /* Retrieve the maximum size in MB (rounded up) + * and cap it with what the user can enter */ + MaxSize = (ULONG)RoundingDivide(MaxPartSize, MB); + MaxSize = min(MaxSize, PARTITION_MAXSIZE); - ShowPartitionSizeInputBox(12, 14, xScreen - 12, 17, /* left, top, right, bottom */ + ShowPartitionSizeInputBox(12, 14, xScreen - 12, 17, MaxSize, InputBuffer, &Quit, &Cancel); - if (Quit) { if (ConfirmQuit(Ir)) @@ -2129,50 +2136,41 @@ CreatePartitionPage(PINPUT_RECORD Ir) { return SELECT_PARTITION_PAGE; } - else - { - PartSize = _wcstoui64(InputBuffer, NULL, 10); - /* Retry if too small or too large */ - if (PartSize < 1) - continue; - if (PartSize > MaxSize) - continue; - - /* Convert to bytes */ - if (PartSize == MaxSize) - { - /* Use all of the unpartitioned disk space */ - SectorCount = PartEntry->SectorCount.QuadPart; - } - else - { - /* Calculate the sector count from the size in MB */ - SectorCount = PartSize * MB / DiskEntry->BytesPerSector; + PartSize = _wcstoui64(InputBuffer, NULL, 10); - /* But never get larger than the unpartitioned disk space */ - if (SectorCount > PartEntry->SectorCount.QuadPart) - SectorCount = PartEntry->SectorCount.QuadPart; - } + /* Retry if too small or too large */ + if ((PartSize < 1) || (PartSize > MaxSize)) + continue; - DPRINT("Partition size: %I64u bytes\n", PartSize); + /* + * If the input size, given in MB, specifies the maximum partition + * size, it may slightly under- or over-estimate it due to rounding + * error. In this case, use all of the unpartitioned disk space. + * Otherwise, directly convert the size to bytes. + */ + if (PartSize == MaxSize) + PartSize = MaxPartSize; + else // if (PartSize < MaxSize) + PartSize *= MB; + DPRINT("Partition size: %I64u bytes\n", PartSize); - if (PartCreateType == PartTypeData) - { - CreatePartition(PartitionList, - CurrentPartition, - SectorCount, - FALSE); - } - else // if (PartCreateType == PartTypeExtended) - { - CreateExtendedPartition(PartitionList, - CurrentPartition, - SectorCount); - } + ASSERT(PartSize <= MaxPartSize); - return SELECT_PARTITION_PAGE; + if (PartCreateType == PartTypeData) + { + CreatePartition(PartitionList, + CurrentPartition, + PartSize); } + else // if (PartCreateType == PartTypeExtended) + { + CreateExtendedPartition(PartitionList, + CurrentPartition, + PartSize); + } + + return SELECT_PARTITION_PAGE; } return CREATE_PARTITION_PAGE; @@ -2424,10 +2422,14 @@ SelectFileSystemPage(PINPUT_RECORD Ir) */ if (!SystemPartition->IsPartitioned) { + /* Automatically create the partition; it will be + * formatted later with default parameters */ + // FIXME: Don't use the whole empty space, but a minimal size + // specified from the TXTSETUP.SIF or unattended setup. CreatePartition(PartitionList, SystemPartition, - 0LL, // SystemPartition->SectorCount.QuadPart, - TRUE); + 0ULL); + SystemPartition->New |= PARTITION_NEW_AUTOCREATE; ASSERT(SystemPartition->IsPartitioned); } @@ -2580,9 +2582,9 @@ SelectFileSystemPage(PINPUT_RECORD Ir) MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE); - if (PartEntry->AutoCreate) + if (PartEntry->New & PARTITION_NEW_AUTOCREATE) { - PartEntry->AutoCreate = FALSE; + PartEntry->New &= ~PARTITION_NEW_AUTOCREATE; CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NEWPARTITION)); } diff --git a/dll/ime/msctfime/CMakeLists.txt b/dll/ime/msctfime/CMakeLists.txt index 5a034398964..288c14afc7f 100644 --- a/dll/ime/msctfime/CMakeLists.txt +++ b/dll/ime/msctfime/CMakeLists.txt @@ -5,7 +5,15 @@ include_directories( spec2def(msctfime.ime msctfime.spec) list(APPEND SOURCE - msctfime.cpp) + bridge.cpp + compartment.cpp + functions.cpp + inputcontext.cpp + msctfime.cpp + profile.cpp + sinks.cpp + tls.cpp + ui.cpp) file(GLOB msctfime_rc_deps res/*.*) add_rc_deps(msctfime.rc ${msctfime_rc_deps}) diff --git a/dll/ime/msctfime/bridge.cpp b/dll/ime/msctfime/bridge.cpp new file mode 100644 index 00000000000..de9e6ba10ef --- /dev/null +++ b/dll/ime/msctfime/bridge.cpp @@ -0,0 +1,608 @@ +/* + * PROJECT: ReactOS msctfime.ime + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Bridge + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#include "msctfime.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msctfime); + +/// @implemented +CicBridge::CicBridge() +{ + m_bImmxInited = FALSE; + m_bUnknown1 = FALSE; + m_bDeactivating = FALSE; + m_bUnknown2 = FALSE; + m_pKeystrokeMgr = NULL; + m_pDocMgr = NULL; + m_pThreadMgrEventSink = NULL; + m_cliendId = 0; + m_cRefs = 1; +} + +/// @implemented +STDMETHODIMP CicBridge::QueryInterface(REFIID riid, LPVOID* ppvObj) +{ + *ppvObj = NULL; + + if (!IsEqualIID(riid, IID_ITfSysHookSink)) + return E_NOINTERFACE; + + *ppvObj = this; + AddRef(); + + return S_OK; +} + +/// @implemented +STDMETHODIMP_(ULONG) CicBridge::AddRef() +{ + return ::InterlockedIncrement(&m_cRefs); +} + +/// @implemented +STDMETHODIMP_(ULONG) CicBridge::Release() +{ + if (::InterlockedDecrement(&m_cRefs) == 0) + { + delete this; + return 0; + } + return m_cRefs; +} + +/// @implemented +CicBridge::~CicBridge() +{ + TLS *pTLS = TLS::PeekTLS(); + if (!pTLS || !pTLS->m_pThreadMgr) + return; + + if (SUCCEEDED(DeactivateIMMX(pTLS, pTLS->m_pThreadMgr))) + UnInitIMMX(pTLS); +} + +void CicBridge::GetDocumentManager(_Inout_ CicIMCCLock& imeContext) +{ + CicInputContext *pCicIC = imeContext.get().m_pCicIC; + if (pCicIC) + { + m_pDocMgr = pCicIC->m_pDocumentMgr; + m_pDocMgr->AddRef(); + } + else + { + m_pDocMgr->Release(); + m_pDocMgr = NULL; + } +} + +/// @unimplemented +HRESULT +CicBridge::CreateInputContext( + _Inout_ TLS *pTLS, + _In_ HIMC hIMC) +{ + CicIMCLock imcLock(hIMC); + HRESULT hr = imcLock.m_hr; + if (!imcLock) + hr = E_FAIL; + if (FAILED(hr)) + return hr; + + if (!imcLock.get().hCtfImeContext) + { + HIMCC hCtfImeContext = ImmCreateIMCC(sizeof(CTFIMECONTEXT)); + if (!hCtfImeContext) + return E_OUTOFMEMORY; + imcLock.get().hCtfImeContext = hCtfImeContext; + } + + CicIMCCLock imeContext(imcLock.get().hCtfImeContext); + CicInputContext *pCicIC = imeContext.get().m_pCicIC; + if (!pCicIC) + { + pCicIC = new(cicNoThrow) CicInputContext(m_cliendId, &m_LibThread, hIMC); + if (!pCicIC) + { + imeContext.unlock(); + imcLock.unlock(); + DestroyInputContext(pTLS, hIMC); + return E_OUTOFMEMORY; + } + + if (!pTLS->m_pThreadMgr) + { + pCicIC->Release(); + imeContext.unlock(); + imcLock.unlock(); + DestroyInputContext(pTLS, hIMC); + return E_NOINTERFACE; + } + + imeContext.get().m_pCicIC = pCicIC; + } + + hr = pCicIC->CreateInputContext(pTLS->m_pThreadMgr, imcLock); + if (FAILED(hr)) + { + pCicIC->Release(); + imeContext.get().m_pCicIC = NULL; + } + else + { + if (imcLock.get().hWnd && imcLock.get().hWnd == ::GetFocus()) + { + GetDocumentManager(imeContext); + //FIXME + } + } + + return E_NOTIMPL; +} + +/// @implemented +HRESULT CicBridge::DestroyInputContext(TLS *pTLS, HIMC hIMC) +{ + CicIMCLock imcLock(hIMC); + HRESULT hr = imcLock.m_hr; + if (!imcLock) + hr = E_FAIL; + if (FAILED(hr)) + return hr; + + hr = E_FAIL; + CicIMCCLock imeContext(imcLock.get().hCtfImeContext); + if (imeContext) + hr = imeContext.m_hr; + + if (SUCCEEDED(hr) && !(imeContext.get().m_dwCicFlags & 1)) + { + imeContext.get().m_dwCicFlags |= 1; + + CicInputContext *pCicIC = imeContext.get().m_pCicIC; + if (pCicIC) + { + imeContext.get().m_pCicIC = NULL; + hr = pCicIC->DestroyInputContext(); + pCicIC->Release(); + imeContext.get().m_pCicIC = NULL; + } + } + + if (imcLock.get().hCtfImeContext) + { + ImmDestroyIMCC(imcLock.get().hCtfImeContext); + imcLock.get().hCtfImeContext = NULL; + hr = S_OK; + } + + return hr; +} + +ITfContext * +CicBridge::GetInputContext(CicIMCCLock& imeContext) +{ + CicInputContext *pCicIC = imeContext.get().m_pCicIC; + if (!pCicIC) + return NULL; + return pCicIC->m_pContext; +} + +/// @unimplemented +HRESULT CicBridge::OnSetOpenStatus( + TLS *pTLS, + ITfThreadMgr_P *pThreadMgr, + CicIMCLock& imcLock, + CicInputContext *pCicIC) +{ + return E_NOTIMPL; +} + +/// Selects the IME context. +/// @implemented +HRESULT +CicBridge::SelectEx( + _Inout_ TLS *pTLS, + _Inout_ ITfThreadMgr_P *pThreadMgr, + _In_ HIMC hIMC, + _In_ BOOL fSelect, + _In_ HKL hKL) +{ + CicIMCLock imcLock(hIMC); + if (FAILED(imcLock.m_hr)) + return imcLock.m_hr; + + CicIMCCLock imeContext(imcLock.get().hCtfImeContext); + if (!imeContext) + imeContext.m_hr = E_FAIL; + if (FAILED(imeContext.m_hr)) + return imeContext.m_hr; + + CicInputContext *pCicIC = imeContext.get().m_pCicIC; + if (pCicIC) + pCicIC->m_bSelecting = TRUE; + + if (fSelect) + { + if (pCicIC) + pCicIC->m_dwUnknown6[1] &= ~1; + if (imcLock.get().fOpen) + OnSetOpenStatus(pTLS, pThreadMgr, imcLock, pCicIC); + } + else + { + ITfContext *pContext = GetInputContext(imeContext); + pThreadMgr->RequestPostponedLock(pContext); + if (pCicIC) + pCicIC->m_bSelecting = FALSE; + if (pContext) + pContext->Release(); + } + + return imeContext.m_hr; +} + +/// Used in CicBridge::EnumCreateInputContextCallback and +/// CicBridge::EnumDestroyInputContextCallback. +typedef struct ENUM_CREATE_DESTROY_IC +{ + TLS *m_pTLS; + CicBridge *m_pBridge; +} ENUM_CREATE_DESTROY_IC, *PENUM_CREATE_DESTROY_IC; + +/// Creates input context for the current thread. +/// @implemented +BOOL CALLBACK CicBridge::EnumCreateInputContextCallback(HIMC hIMC, LPARAM lParam) +{ + PENUM_CREATE_DESTROY_IC pData = (PENUM_CREATE_DESTROY_IC)lParam; + pData->m_pBridge->CreateInputContext(pData->m_pTLS, hIMC); + return TRUE; +} + +/// Destroys input context for the current thread. +/// @implemented +BOOL CALLBACK CicBridge::EnumDestroyInputContextCallback(HIMC hIMC, LPARAM lParam) +{ + PENUM_CREATE_DESTROY_IC pData = (PENUM_CREATE_DESTROY_IC)lParam; + pData->m_pBridge->DestroyInputContext(pData->m_pTLS, hIMC); + return TRUE; +} + +/// @implemented +HRESULT +CicBridge::ActivateIMMX( + _Inout_ TLS *pTLS, + _Inout_ ITfThreadMgr_P *pThreadMgr) +{ + HRESULT hr = pThreadMgr->ActivateEx(&m_cliendId, 1); + if (hr != S_OK) + { + m_cliendId = 0; + return E_FAIL; + } + + if (m_cActivateLocks++ != 0) + return S_OK; + + ITfSourceSingle *pSource = NULL; + hr = pThreadMgr->QueryInterface(IID_ITfSourceSingle, (void**)&pSource); + if (FAILED(hr)) + { + DeactivateIMMX(pTLS, pThreadMgr); + return hr; + } + + CFunctionProvider *pProvider = new(cicNoThrow) CFunctionProvider(m_cliendId); + if (!pProvider) + { + hr = E_FAIL; + goto Finish; + } + + pSource->AdviseSingleSink(m_cliendId, IID_ITfFunctionProvider, pProvider); + pProvider->Release(); + + if (!m_pDocMgr) + { + hr = pThreadMgr->CreateDocumentMgr(&m_pDocMgr); + if (FAILED(hr)) + { + hr = E_FAIL; + goto Finish; + } + + SetCompartmentDWORD(m_cliendId, m_pDocMgr, GUID_COMPARTMENT_CTFIME_DIMFLAGS, TRUE, FALSE); + } + + pThreadMgr->SetSysHookSink(this); + + hr = S_OK; + if (pTLS->m_bDestroyed) + { + ENUM_CREATE_DESTROY_IC Data = { pTLS, this }; + ImmEnumInputContext(0, CicBridge::EnumCreateInputContextCallback, (LPARAM)&Data); + } + +Finish: + if (FAILED(hr)) + DeactivateIMMX(pTLS, pThreadMgr); + if (pSource) + pSource->Release(); + return hr; +} + +/// @implemented +HRESULT +CicBridge::DeactivateIMMX( + _Inout_ TLS *pTLS, + _Inout_ ITfThreadMgr_P *pThreadMgr) +{ + if (m_bDeactivating) + return TRUE; + + m_bDeactivating = TRUE; + + if (m_cliendId) + { + ENUM_CREATE_DESTROY_IC Data = { pTLS, this }; + ImmEnumInputContext(0, CicBridge::EnumDestroyInputContextCallback, (LPARAM)&Data); + pTLS->m_bDestroyed = TRUE; + + ITfSourceSingle *pSource = NULL; + if (pThreadMgr->QueryInterface(IID_ITfSourceSingle, (void **)&pSource) == S_OK) + pSource->UnadviseSingleSink(m_cliendId, IID_ITfFunctionProvider); + + m_cliendId = 0; + + while (m_cActivateLocks > 0) + { + --m_cActivateLocks; + pThreadMgr->Deactivate(); + } + + if (pSource) + pSource->Release(); + } + + if (m_pDocMgr) + { + m_pDocMgr->Release(); + m_pDocMgr = NULL; + } + + pThreadMgr->SetSysHookSink(NULL); + + m_bDeactivating = FALSE; + + return S_OK; +} + +/// @implemented +HRESULT +CicBridge::InitIMMX(_Inout_ TLS *pTLS) +{ + if (m_bImmxInited) + return S_OK; + + HRESULT hr = S_OK; + if (!pTLS->m_pThreadMgr) + { + ITfThreadMgr *pThreadMgr = NULL; + hr = TF_CreateThreadMgr(&pThreadMgr); + if (FAILED(hr)) + return E_FAIL; + + hr = pThreadMgr->QueryInterface(IID_ITfThreadMgr_P, (void **)&pTLS->m_pThreadMgr); + if (pThreadMgr) + pThreadMgr->Release(); + if (FAILED(hr)) + return E_FAIL; + } + + if (!m_pThreadMgrEventSink) + { + m_pThreadMgrEventSink = + new(cicNoThrow) CThreadMgrEventSink(CThreadMgrEventSink::DIMCallback, NULL, NULL); + if (!m_pThreadMgrEventSink) + { + UnInitIMMX(pTLS); + return E_FAIL; + } + } + + m_pThreadMgrEventSink->SetCallbackPV(m_pThreadMgrEventSink); + m_pThreadMgrEventSink->_Advise(pTLS->m_pThreadMgr); + + if (!pTLS->m_pProfile) + { + pTLS->m_pProfile = new(cicNoThrow) CicProfile(); + if (!pTLS->m_pProfile) + return E_OUTOFMEMORY; + + hr = pTLS->m_pProfile->InitProfileInstance(pTLS); + if (FAILED(hr)) + { + UnInitIMMX(pTLS); + return E_FAIL; + } + } + + hr = pTLS->m_pThreadMgr->QueryInterface(IID_ITfKeystrokeMgr_P, (void **)&m_pKeystrokeMgr); + if (FAILED(hr)) + { + UnInitIMMX(pTLS); + return E_FAIL; + } + + hr = InitDisplayAttrbuteLib(&m_LibThread); + if (FAILED(hr)) + { + UnInitIMMX(pTLS); + return E_FAIL; + } + + m_bImmxInited = TRUE; + return S_OK; +} + +/// @implemented +BOOL CicBridge::UnInitIMMX(_Inout_ TLS *pTLS) +{ + UninitDisplayAttrbuteLib(&m_LibThread); + TFUninitLib_Thread(&m_LibThread); + + if (m_pKeystrokeMgr) + { + m_pKeystrokeMgr->Release(); + m_pKeystrokeMgr = NULL; + } + + if (pTLS->m_pProfile) + { + pTLS->m_pProfile->Release(); + pTLS->m_pProfile = NULL; + } + + if (m_pThreadMgrEventSink) + { + m_pThreadMgrEventSink->_Unadvise(); + m_pThreadMgrEventSink->Release(); + m_pThreadMgrEventSink = NULL; + } + + if (pTLS->m_pThreadMgr) + { + pTLS->m_pThreadMgr->Release(); + pTLS->m_pThreadMgr = NULL; + } + + m_bImmxInited = FALSE; + return TRUE; +} + +/// @implemented +STDMETHODIMP CicBridge::OnPreFocusDIM(HWND hwnd) +{ + return S_OK; +} + +/// @unimplemented +STDMETHODIMP CicBridge::OnSysKeyboardProc(UINT, LONG) +{ + return E_NOTIMPL; +} + +/// @implemented +STDMETHODIMP CicBridge::OnSysShellProc(INT, UINT, LONG) +{ + return S_OK; +} + +/// @implemented +void +CicBridge::PostTransMsg( + _In_ HWND hWnd, + _In_ INT cTransMsgs, + _In_ const TRANSMSG *pTransMsgs) +{ + for (INT i = 0; i < cTransMsgs; ++i, ++pTransMsgs) + { + ::PostMessageW(hWnd, pTransMsgs->message, pTransMsgs->wParam, pTransMsgs->lParam); + } +} + +/// @implemented +HRESULT +CicBridge::ConfigureGeneral( + _Inout_ TLS* pTLS, + _In_ ITfThreadMgr *pThreadMgr, + _In_ HKL hKL, + _In_ HWND hWnd) +{ + CicProfile *pProfile = pTLS->m_pProfile; + if (!pProfile) + return E_OUTOFMEMORY; + + TF_LANGUAGEPROFILE profile; + HRESULT hr = pProfile->GetActiveLanguageProfile(hKL, GUID_TFCAT_TIP_KEYBOARD, &profile); + if (FAILED(hr)) + return hr; + + ITfFunctionProvider *pProvider = NULL; + hr = pThreadMgr->GetFunctionProvider(profile.clsid, &pProvider); + if (FAILED(hr)) + return hr; + + ITfFnConfigure *pFnConfigure = NULL; + hr = pProvider->GetFunction(GUID_NULL, IID_ITfFnConfigure, (IUnknown**)&pFnConfigure); + if (FAILED(hr)) + { + pProvider->Release(); + return hr; + } + + hr = pFnConfigure->Show(hWnd, profile.langid, profile.guidProfile); + + pFnConfigure->Release(); + pProvider->Release(); + return hr; +} + +/// @implemented +HRESULT +CicBridge::ConfigureRegisterWord( + _Inout_ TLS* pTLS, + _In_ ITfThreadMgr *pThreadMgr, + _In_ HKL hKL, + _In_ HWND hWnd, + _Inout_opt_ LPVOID lpData) +{ + CicProfile *pProfile = pTLS->m_pProfile; + if (!pProfile) + return E_OUTOFMEMORY; + + TF_LANGUAGEPROFILE profile; + HRESULT hr = pProfile->GetActiveLanguageProfile(hKL, GUID_TFCAT_TIP_KEYBOARD, &profile); + if (FAILED(hr)) + return hr; + + ITfFunctionProvider *pProvider = NULL; + hr = pThreadMgr->GetFunctionProvider(profile.clsid, &pProvider); + if (FAILED(hr)) + return hr; + + ITfFnConfigureRegisterWord *pFunction = NULL; + hr = pProvider->GetFunction(GUID_NULL, IID_ITfFnConfigureRegisterWord, (IUnknown**)&pFunction); + if (FAILED(hr)) + { + pProvider->Release(); + return hr; + } + + REGISTERWORDW* pRegWord = (REGISTERWORDW*)lpData; + if (pRegWord) + { + if (pRegWord->lpWord) + { + hr = E_OUTOFMEMORY; + BSTR bstrWord = SysAllocString(pRegWord->lpWord); + if (bstrWord) + { + hr = pFunction->Show(hWnd, profile.langid, profile.guidProfile, bstrWord); + SysFreeString(bstrWord); + } + } + else + { + hr = pFunction->Show(hWnd, profile.langid, profile.guidProfile, NULL); + } + } + + pProvider->Release(); + pFunction->Release(); + return hr; +} diff --git a/dll/ime/msctfime/bridge.h b/dll/ime/msctfime/bridge.h new file mode 100644 index 00000000000..c8b8441203d --- /dev/null +++ b/dll/ime/msctfime/bridge.h @@ -0,0 +1,80 @@ +/* + * PROJECT: ReactOS msctfime.ime + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Bridge + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#pragma once + +#include "sinks.h" +#include "tls.h" + +class CicBridge : public ITfSysHookSink +{ +protected: + LONG m_cRefs; + BOOL m_bImmxInited; + BOOL m_bUnknown1; + BOOL m_bDeactivating; + DWORD m_cActivateLocks; + ITfKeystrokeMgr *m_pKeystrokeMgr; + ITfDocumentMgr *m_pDocMgr; + CThreadMgrEventSink *m_pThreadMgrEventSink; + TfClientId m_cliendId; + CIC_LIBTHREAD m_LibThread; + BOOL m_bUnknown2; + + static BOOL CALLBACK EnumCreateInputContextCallback(HIMC hIMC, LPARAM lParam); + static BOOL CALLBACK EnumDestroyInputContextCallback(HIMC hIMC, LPARAM lParam); + +public: + CicBridge(); + virtual ~CicBridge(); + + // IUnknown interface + STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + + // ITfSysHookSink interface + STDMETHODIMP OnPreFocusDIM(HWND hwnd) override; + STDMETHODIMP OnSysKeyboardProc(UINT, LONG) override; + STDMETHODIMP OnSysShellProc(INT, UINT, LONG) override; + + HRESULT InitIMMX(_Inout_ TLS *pTLS); + BOOL UnInitIMMX(_Inout_ TLS *pTLS); + HRESULT ActivateIMMX(_Inout_ TLS *pTLS, _Inout_ ITfThreadMgr_P *pThreadMgr); + HRESULT DeactivateIMMX(_Inout_ TLS *pTLS, _Inout_ ITfThreadMgr_P *pThreadMgr); + + HRESULT CreateInputContext(TLS *pTLS, HIMC hIMC); + HRESULT DestroyInputContext(TLS *pTLS, HIMC hIMC); + ITfContext *GetInputContext(CicIMCCLock& imeContext); + + HRESULT SelectEx( + _Inout_ TLS *pTLS, + _Inout_ ITfThreadMgr_P *pThreadMgr, + _In_ HIMC hIMC, + _In_ BOOL fSelect, + _In_ HKL hKL); + HRESULT OnSetOpenStatus( + TLS *pTLS, + ITfThreadMgr_P *pThreadMgr, + CicIMCLock& imcLock, + CicInputContext *pCicIC); + + void PostTransMsg(_In_ HWND hWnd, _In_ INT cTransMsgs, _In_ const TRANSMSG *pTransMsgs); + void GetDocumentManager(_Inout_ CicIMCCLock& imeContext); + + HRESULT + ConfigureGeneral(_Inout_ TLS* pTLS, + _In_ ITfThreadMgr *pThreadMgr, + _In_ HKL hKL, + _In_ HWND hWnd); + HRESULT ConfigureRegisterWord( + _Inout_ TLS* pTLS, + _In_ ITfThreadMgr *pThreadMgr, + _In_ HKL hKL, + _In_ HWND hWnd, + _Inout_opt_ LPVOID lpData); +}; diff --git a/dll/ime/msctfime/compartment.cpp b/dll/ime/msctfime/compartment.cpp new file mode 100644 index 00000000000..d92b1b526f4 --- /dev/null +++ b/dll/ime/msctfime/compartment.cpp @@ -0,0 +1,163 @@ +/* + * PROJECT: ReactOS msctfime.ime + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Supporting compartments + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#include "msctfime.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msctfime); + +/// @implemented +HRESULT +GetCompartment( + IUnknown *pUnknown, + REFGUID rguid, + ITfCompartment **ppComp, + BOOL bThread) +{ + *ppComp = NULL; + + ITfThreadMgr *pThreadMgr = NULL; + ITfCompartmentMgr *pCompMgr = NULL; + + HRESULT hr; + if (bThread) + { + hr = pUnknown->QueryInterface(IID_ITfThreadMgr, (void **)&pThreadMgr); + if (FAILED(hr)) + return hr; + + hr = pThreadMgr->GetGlobalCompartment(&pCompMgr); + } + else + { + hr = pUnknown->QueryInterface(IID_ITfCompartmentMgr, (void **)&pCompMgr); + } + + if (SUCCEEDED(hr)) + { + hr = E_FAIL; + if (pCompMgr) + { + hr = pCompMgr->GetCompartment(rguid, ppComp); + pCompMgr->Release(); + } + } + + if (pThreadMgr) + pThreadMgr->Release(); + + return hr; +} + +/// @implemented +HRESULT +SetCompartmentDWORD( + TfEditCookie cookie, + IUnknown *pUnknown, + REFGUID rguid, + DWORD dwValue, + BOOL bThread) +{ + ITfCompartment *pComp = NULL; + HRESULT hr = GetCompartment(pUnknown, rguid, &pComp, bThread); + if (FAILED(hr)) + return hr; + + VARIANT vari; + V_I4(&vari) = dwValue; + V_VT(&vari) = VT_I4; + hr = pComp->SetValue(cookie, &vari); + + pComp->Release(); + return hr; +} + +/// @implemented +HRESULT +GetCompartmentDWORD( + IUnknown *pUnknown, + REFGUID rguid, + LPDWORD pdwValue, + BOOL bThread) +{ + *pdwValue = 0; + + ITfCompartment *pComp = NULL; + HRESULT hr = GetCompartment(pUnknown, rguid, &pComp, bThread); + if (FAILED(hr)) + return hr; + + VARIANT vari; + hr = pComp->GetValue(&vari); + if (hr == S_OK) + *pdwValue = V_I4(&vari); + + pComp->Release(); + return hr; +} + +/// @implemented +HRESULT +SetCompartmentUnknown( + TfEditCookie cookie, + IUnknown *pUnknown, + REFGUID rguid, + IUnknown *punkValue) +{ + ITfCompartment *pComp = NULL; + HRESULT hr = GetCompartment(pUnknown, rguid, &pComp, FALSE); + if (FAILED(hr)) + return hr; + + VARIANT vari; + V_UNKNOWN(&vari) = punkValue; + V_VT(&vari) = VT_UNKNOWN; + hr = pComp->SetValue(cookie, &vari); + + pComp->Release(); + return hr; +} + +/// @implemented +HRESULT +ClearCompartment( + TfClientId tid, + IUnknown *pUnknown, + REFGUID rguid, + BOOL bThread) +{ + ITfCompartmentMgr *pCompMgr = NULL; + ITfThreadMgr *pThreadMgr = NULL; + + HRESULT hr; + if (bThread) + { + hr = pUnknown->QueryInterface(IID_ITfThreadMgr, (void **)&pThreadMgr); + if (FAILED(hr)) + return hr; + + hr = pThreadMgr->GetGlobalCompartment(&pCompMgr); + } + else + { + hr = pUnknown->QueryInterface(IID_ITfCompartmentMgr, (void **)&pCompMgr); + } + + if (SUCCEEDED(hr)) + { + hr = E_FAIL; + if (pCompMgr) + { + hr = pCompMgr->ClearCompartment(tid, rguid); + pCompMgr->Release(); + } + } + + if (pThreadMgr) + pThreadMgr->Release(); + + return hr; +} diff --git a/dll/ime/msctfime/compartment.h b/dll/ime/msctfime/compartment.h new file mode 100644 index 00000000000..88805566832 --- /dev/null +++ b/dll/ime/msctfime/compartment.h @@ -0,0 +1,44 @@ +/* + * PROJECT: ReactOS msctfime.ime + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Supporting compartments + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#pragma once + +HRESULT +GetCompartment( + IUnknown *pUnknown, + REFGUID rguid, + ITfCompartment **ppComp, + BOOL bThread); + +HRESULT +SetCompartmentDWORD( + TfEditCookie cookie, + IUnknown *pUnknown, + REFGUID rguid, + DWORD dwValue, + BOOL bThread); + +HRESULT +GetCompartmentDWORD( + IUnknown *pUnknown, + REFGUID rguid, + LPDWORD pdwValue, + BOOL bThread); + +HRESULT +SetCompartmentUnknown( + TfEditCookie cookie, + IUnknown *pUnknown, + REFGUID rguid, + IUnknown *punkValue); + +HRESULT +ClearCompartment( + TfClientId tid, + IUnknown *pUnknown, + REFGUID rguid, + BOOL bThread); diff --git a/dll/ime/msctfime/functions.cpp b/dll/ime/msctfime/functions.cpp new file mode 100644 index 00000000000..c9832f90cff --- /dev/null +++ b/dll/ime/msctfime/functions.cpp @@ -0,0 +1,175 @@ +/* + * PROJECT: ReactOS msctfime.ime + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: The functions of msctfime.ime + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#include "msctfime.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msctfime); + +/// @implemented +CFunctionProviderBase::CFunctionProviderBase(_In_ TfClientId clientId) +{ + m_clientId = clientId; + m_guid = GUID_NULL; + m_bstr = NULL; + m_cRefs = 1; +} + +/// @implemented +CFunctionProviderBase::~CFunctionProviderBase() +{ + if (!DllShutdownInProgress()) + ::SysFreeString(m_bstr); +} + +/// @implemented +BOOL +CFunctionProviderBase::Init( + _In_ REFGUID rguid, + _In_ LPCWSTR psz) +{ + m_bstr = ::SysAllocString(psz); + m_guid = rguid; + return (m_bstr != NULL); +} + +/// @implemented +STDMETHODIMP +CFunctionProviderBase::QueryInterface( + _In_ REFIID riid, + _Out_ LPVOID* ppvObj) +{ + if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfFunctionProvider)) + { + *ppvObj = this; + AddRef(); + return S_OK; + } + return E_NOINTERFACE; +} + +/// @implemented +STDMETHODIMP_(ULONG) CFunctionProviderBase::AddRef() +{ + return ::InterlockedIncrement(&m_cRefs); +} + +/// @implemented +STDMETHODIMP_(ULONG) CFunctionProviderBase::Release() +{ + if (::InterlockedDecrement(&m_cRefs) == 0) + { + delete this; + return 0; + } + return m_cRefs; +} + +/// @implemented +STDMETHODIMP CFunctionProviderBase::GetType(_Out_ GUID *guid) +{ + *guid = m_guid; + return S_OK; +} + +/// @implemented +STDMETHODIMP CFunctionProviderBase::GetDescription(_Out_ BSTR *desc) +{ + *desc = ::SysAllocString(m_bstr); + return (*desc ? S_OK : E_OUTOFMEMORY); +} + +/***********************************************************************/ + +/// @implemented +CFunctionProvider::CFunctionProvider(_In_ TfClientId clientId) : CFunctionProviderBase(clientId) +{ + Init(CLSID_CAImmLayer, L"MSCTFIME::Function Provider"); +} + +/// @implemented +STDMETHODIMP +CFunctionProvider::GetFunction( + _In_ REFGUID guid, + _In_ REFIID riid, + _Out_ IUnknown **func) +{ + *func = NULL; + + if (IsEqualGUID(guid, GUID_NULL) && + IsEqualIID(riid, IID_IAImmFnDocFeed)) + { + *func = new(cicNoThrow) CFnDocFeed(); + if (*func) + return S_OK; + } + + return E_NOINTERFACE; +} + +/***********************************************************************/ + +CFnDocFeed::CFnDocFeed() +{ + m_cRefs = 1; +} + +CFnDocFeed::~CFnDocFeed() +{ +} + +/// @implemented +STDMETHODIMP CFnDocFeed::QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) +{ + if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IAImmFnDocFeed)) + { + *ppvObj = this; + AddRef(); + return S_OK; + } + return E_NOINTERFACE; +} + +/// @implemented +STDMETHODIMP_(ULONG) CFnDocFeed::AddRef() +{ + return ::InterlockedIncrement(&m_cRefs); +} + +/// @implemented +STDMETHODIMP_(ULONG) CFnDocFeed::Release() +{ + if (::InterlockedDecrement(&m_cRefs) == 0) + { + delete this; + return 0; + } + return m_cRefs; +} + +/// @unimplemented +STDMETHODIMP CFnDocFeed::DocFeed() +{ + return E_NOTIMPL; +} + +/// @unimplemented +STDMETHODIMP CFnDocFeed::ClearDocFeedBuffer() +{ + return E_NOTIMPL; +} + +/// @unimplemented +STDMETHODIMP CFnDocFeed::StartReconvert() +{ + return E_NOTIMPL; +} + +/// @unimplemented +STDMETHODIMP CFnDocFeed::StartUndoCompositionString() +{ + return E_NOTIMPL; +} diff --git a/dll/ime/msctfime/functions.h b/dll/ime/msctfime/functions.h new file mode 100644 index 00000000000..6938162a6e5 --- /dev/null +++ b/dll/ime/msctfime/functions.h @@ -0,0 +1,63 @@ +/* + * PROJECT: ReactOS msctfime.ime + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: The functions of msctfime.ime + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +class CFunctionProviderBase : public ITfFunctionProvider +{ +protected: + TfClientId m_clientId; + GUID m_guid; + BSTR m_bstr; + LONG m_cRefs; + +public: + CFunctionProviderBase(_In_ TfClientId clientId); + virtual ~CFunctionProviderBase(); + + // IUnknown interface + STDMETHODIMP QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + + // ITfFunctionProvider interface + STDMETHODIMP GetType(_Out_ GUID *guid) override; + STDMETHODIMP GetDescription(_Out_ BSTR *desc) override; + //STDMETHODIMP GetFunction(_In_ REFGUID guid, _In_ REFIID riid, _Out_ IUnknown **func) = 0; + + BOOL Init(_In_ REFGUID rguid, _In_ LPCWSTR psz); +}; + +/***********************************************************************/ + +class CFunctionProvider : public CFunctionProviderBase +{ +public: + CFunctionProvider(_In_ TfClientId clientId); + + STDMETHODIMP GetFunction(_In_ REFGUID guid, _In_ REFIID riid, _Out_ IUnknown **func) override; +}; + +/***********************************************************************/ + +class CFnDocFeed : public IAImmFnDocFeed +{ + LONG m_cRefs; + +public: + CFnDocFeed(); + virtual ~CFnDocFeed(); + + // IUnknown interface + STDMETHODIMP QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + + // IAImmFnDocFeed interface + STDMETHODIMP DocFeed() override; + STDMETHODIMP ClearDocFeedBuffer() override; + STDMETHODIMP StartReconvert() override; + STDMETHODIMP StartUndoCompositionString() override; +}; diff --git a/dll/ime/msctfime/inputcontext.cpp b/dll/ime/msctfime/inputcontext.cpp new file mode 100644 index 00000000000..1bdf64cb62e --- /dev/null +++ b/dll/ime/msctfime/inputcontext.cpp @@ -0,0 +1,323 @@ +/* + * PROJECT: ReactOS msctfime.ime + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Input Context of msctfime.ime + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#include "msctfime.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msctfime); + +/// @unimplemented +CicInputContext::CicInputContext( + _In_ TfClientId cliendId, + _Inout_ PCIC_LIBTHREAD pLibThread, + _In_ HIMC hIMC) +{ + m_hIMC = hIMC; + m_guid = GUID_NULL; + m_dwQueryPos = 0; + m_cRefs = 1; +} + +/// @implemented +STDMETHODIMP CicInputContext::QueryInterface(REFIID riid, LPVOID* ppvObj) +{ + *ppvObj = NULL; + + if (IsEqualIID(riid, IID_ITfContextOwnerCompositionSink)) + { + *ppvObj = static_cast(this); + AddRef(); + return S_OK; + } + if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfCleanupContextSink)) + { + *ppvObj = this; + AddRef(); + return S_OK; + } + + return E_NOINTERFACE; +} + +/// @implemented +STDMETHODIMP_(ULONG) CicInputContext::AddRef() +{ + return ::InterlockedIncrement(&m_cRefs); +} + +/// @implemented +STDMETHODIMP_(ULONG) CicInputContext::Release() +{ + if (::InterlockedDecrement(&m_cRefs) == 0) + { + delete this; + return 0; + } + return m_cRefs; +} + +/// @implemented +STDMETHODIMP +CicInputContext::OnStartComposition( + ITfCompositionView *pComposition, + BOOL *pfOk) +{ + if ((m_cCompLocks <= 0) || m_dwUnknown6_5) + { + *pfOk = TRUE; + ++m_cCompLocks; + } + else + { + *pfOk = FALSE; + } + return S_OK; +} + +/// @implemented +STDMETHODIMP +CicInputContext::OnUpdateComposition( + ITfCompositionView *pComposition, + ITfRange *pRangeNew) +{ + return S_OK; +} + +/// @implemented +STDMETHODIMP +CicInputContext::OnEndComposition( + ITfCompositionView *pComposition) +{ + --m_cCompLocks; + return S_OK; +} + +/// @implemented +HRESULT +CicInputContext::GetGuidAtom( + _Inout_ CicIMCLock& imcLock, + _In_ BYTE iAtom, + _Out_opt_ LPDWORD pdwGuidAtom) +{ + CicIMCCLock imeContext(imcLock.get().hCompStr); + HRESULT hr = imeContext.m_hr; + if (!imeContext) + hr = E_FAIL; + if (FAILED(hr)) + return hr; + + hr = E_FAIL; + if (iAtom < m_cGuidAtoms) + { + *pdwGuidAtom = m_adwGuidAtoms[iAtom]; + hr = S_OK; + } + + return hr; +} + +/// @unimplemented +HRESULT +CicInputContext::CreateInputContext( + _Inout_ ITfThreadMgr *pThreadMgr, + _Inout_ CicIMCLock& imcLock) +{ + //FIXME + return E_NOTIMPL; +} + +/// @unimplemented +HRESULT +CicInputContext::DestroyInputContext() +{ + ITfSourceSingle *pSource = NULL; + + if (m_pContext && m_pContext->QueryInterface(IID_ITfSourceSingle, (void **)&pSource) == S_OK) + pSource->UnadviseSingleSink(m_clientId, IID_ITfCleanupContextSink); + + //FIXME: m_dwUnknown5 + + if (m_pTextEventSink) + { + m_pTextEventSink->_Unadvise(); + m_pTextEventSink->Release(); + m_pTextEventSink = NULL; + } + + if (m_pCompEventSink2) + { + m_pCompEventSink2->_Unadvise(); + m_pCompEventSink2->Release(); + m_pCompEventSink2 = NULL; + } + + if (m_pCompEventSink1) + { + m_pCompEventSink1->_Unadvise(); + m_pCompEventSink1->Release(); + m_pCompEventSink1 = NULL; + } + + //FIXME: m_pInputContextOwner + + if (m_pDocumentMgr) + m_pDocumentMgr->Pop(1); + + if (m_pContext) + { + ClearCompartment(m_clientId, m_pContext, GUID_COMPARTMENT_CTFIME_CICINPUTCONTEXT, 0); + m_pContext->Release(); + m_pContext = NULL; + } + + if (m_pContextOwnerServices) + { + m_pContextOwnerServices->Release(); + m_pContextOwnerServices = NULL; + } + + // FIXME: m_pICOwnerCallback + + if (m_pDocumentMgr) + { + m_pDocumentMgr->Release(); + m_pDocumentMgr = NULL; + } + + if (pSource) + pSource->Release(); + + return S_OK; +} + +/// @implemented +STDMETHODIMP +CicInputContext::OnCompositionTerminated(TfEditCookie ecWrite, ITfComposition *pComposition) +{ + return S_OK; +} + +/// @implemented +STDMETHODIMP +CicInputContext::OnCleanupContext( + _In_ TfEditCookie ecWrite, + _Inout_ ITfContext *pic) +{ + TLS *pTLS = TLS::PeekTLS(); + if (!pTLS || !pTLS->m_pProfile) + return E_OUTOFMEMORY; + + LANGID LangID; + pTLS->m_pProfile->GetLangId(&LangID); + + IMEINFO IMEInfo; + WCHAR szPath[MAX_PATH]; + if (Inquire(&IMEInfo, szPath, 0, (HKL)UlongToHandle(LangID)) != S_OK) + return E_FAIL; + + ITfProperty *pProp = NULL; + if (!(IMEInfo.fdwProperty & IME_PROP_COMPLETE_ON_UNSELECT)) + return S_OK; + + HRESULT hr = pic->GetProperty(GUID_PROP_COMPOSING, &pProp); + if (FAILED(hr)) + return S_OK; + + IEnumTfRanges *pRanges = NULL; + hr = pProp->EnumRanges(ecWrite, &pRanges, NULL); + if (SUCCEEDED(hr)) + { + ITfRange *pRange = NULL; + while (pRanges->Next(1, &pRange, 0) == S_OK) + { + VARIANT vari; + V_VT(&vari) = VT_EMPTY; + pProp->GetValue(ecWrite, pRange, &vari); + if (V_VT(&vari) == VT_I4) + { + if (V_I4(&vari)) + pProp->Clear(ecWrite, pRange); + } + pRange->Release(); + pRange = NULL; + } + pRanges->Release(); + } + pProp->Release(); + + return S_OK; +} + +/// Retrieves the IME information. +/// @implemented +HRESULT +Inquire( + _Out_ LPIMEINFO lpIMEInfo, + _Out_ LPWSTR lpszWndClass, + _In_ DWORD dwSystemInfoFlags, + _In_ HKL hKL) +{ + if (!lpIMEInfo) + return E_OUTOFMEMORY; + + StringCchCopyW(lpszWndClass, 64, L"MSCTFIME UI"); + lpIMEInfo->dwPrivateDataSize = 0; + + switch (LOWORD(hKL)) // Language ID + { + case MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT): // Japanese + { + lpIMEInfo->fdwProperty = IME_PROP_COMPLETE_ON_UNSELECT | IME_PROP_SPECIAL_UI | + IME_PROP_AT_CARET | IME_PROP_NEED_ALTKEY | + IME_PROP_KBD_CHAR_FIRST; + lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE | IME_CMODE_KATAKANA | + IME_CMODE_NATIVE; + lpIMEInfo->fdwSentenceCaps = IME_SMODE_CONVERSATION | IME_SMODE_PLAURALCLAUSE; + lpIMEInfo->fdwSelectCaps = SELECT_CAP_SENTENCE | SELECT_CAP_CONVERSION; + lpIMEInfo->fdwSCSCaps = SCS_CAP_SETRECONVERTSTRING | SCS_CAP_MAKEREAD | + SCS_CAP_COMPSTR; + lpIMEInfo->fdwUICaps = UI_CAP_ROT90; + break; + } + case MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT): // Korean + { + lpIMEInfo->fdwProperty = IME_PROP_COMPLETE_ON_UNSELECT | IME_PROP_SPECIAL_UI | + IME_PROP_AT_CARET | IME_PROP_NEED_ALTKEY | + IME_PROP_KBD_CHAR_FIRST; + lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE; + lpIMEInfo->fdwSentenceCaps = 0; + lpIMEInfo->fdwSCSCaps = SCS_CAP_SETRECONVERTSTRING | SCS_CAP_COMPSTR; + lpIMEInfo->fdwSelectCaps = SELECT_CAP_CONVERSION; + lpIMEInfo->fdwUICaps = UI_CAP_ROT90; + break; + } + case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED): // Simplified Chinese + case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL): // Traditional Chinese + { + lpIMEInfo->fdwProperty = IME_PROP_SPECIAL_UI | IME_PROP_AT_CARET | + IME_PROP_NEED_ALTKEY | IME_PROP_KBD_CHAR_FIRST; + lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE; + lpIMEInfo->fdwSentenceCaps = SELECT_CAP_CONVERSION; + lpIMEInfo->fdwSelectCaps = 0; + lpIMEInfo->fdwSCSCaps = SCS_CAP_SETRECONVERTSTRING | SCS_CAP_MAKEREAD | + SCS_CAP_COMPSTR; + lpIMEInfo->fdwUICaps = UI_CAP_ROT90; + break; + } + default: // Otherwise + { + lpIMEInfo->fdwProperty = IME_PROP_UNICODE | IME_PROP_AT_CARET; + lpIMEInfo->fdwConversionCaps = 0; + lpIMEInfo->fdwSentenceCaps = 0; + lpIMEInfo->fdwSCSCaps = 0; + lpIMEInfo->fdwUICaps = 0; + lpIMEInfo->fdwSelectCaps = 0; + break; + } + } + + return S_OK; +} diff --git a/dll/ime/msctfime/inputcontext.h b/dll/ime/msctfime/inputcontext.h new file mode 100644 index 00000000000..2273161926e --- /dev/null +++ b/dll/ime/msctfime/inputcontext.h @@ -0,0 +1,91 @@ +/* + * PROJECT: ReactOS msctfime.ime + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Input Context of msctfime.ime + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#pragma once + +#include "sinks.h" + +class CInputContextOwnerCallBack; +class CInputContextOwner; + +HRESULT +Inquire( + _Out_ LPIMEINFO lpIMEInfo, + _Out_ LPWSTR lpszWndClass, + _In_ DWORD dwSystemInfoFlags, + _In_ HKL hKL); + +/*********************************************************************** + * CicInputContext + * + * The msctfime.ime's input context. + */ +class CicInputContext + : public ITfCleanupContextSink + , public ITfContextOwnerCompositionSink + , public ITfCompositionSink +{ +public: + LONG m_cRefs; + HIMC m_hIMC; + ITfDocumentMgr *m_pDocumentMgr; + ITfContext *m_pContext; + ITfContextOwnerServices *m_pContextOwnerServices; + CInputContextOwnerCallBack *m_pICOwnerCallback; + CTextEventSink *m_pTextEventSink; + CCompartmentEventSink *m_pCompEventSink1; + CCompartmentEventSink *m_pCompEventSink2; + CInputContextOwner *m_pInputContextOwner; + DWORD m_dwUnknown3[3]; + DWORD m_dwUnknown4[2]; + DWORD m_dwQueryPos; + DWORD m_dwUnknown5; + GUID m_guid; + DWORD m_dwUnknown6[11]; + BOOL m_bSelecting; + DWORD m_dwUnknown6_5; + LONG m_cCompLocks; + DWORD m_dwUnknown7[5]; + WORD m_cGuidAtoms; + WORD m_padding; + DWORD m_adwGuidAtoms[256]; + DWORD m_dwUnknown8[17]; + TfClientId m_clientId; + DWORD m_dwUnknown9; + +public: + CicInputContext( + _In_ TfClientId cliendId, + _Inout_ PCIC_LIBTHREAD pLibThread, + _In_ HIMC hIMC); + virtual ~CicInputContext() { } + + // IUnknown interface + STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + + // ITfCleanupContextSink interface + STDMETHODIMP OnCleanupContext(_In_ TfEditCookie ecWrite, _Inout_ ITfContext *pic) override; + + // ITfContextOwnerCompositionSink interface + STDMETHODIMP OnStartComposition(ITfCompositionView *pComposition, BOOL *pfOk) override; + STDMETHODIMP OnUpdateComposition(ITfCompositionView *pComposition, ITfRange *pRangeNew) override; + STDMETHODIMP OnEndComposition(ITfCompositionView *pComposition) override; + + // ITfCompositionSink interface + STDMETHODIMP OnCompositionTerminated(TfEditCookie ecWrite, ITfComposition *pComposition) override; + + HRESULT + GetGuidAtom( + _Inout_ CicIMCLock& imcLock, + _In_ BYTE iAtom, + _Out_opt_ LPDWORD pdwGuidAtom); + + HRESULT CreateInputContext(_Inout_ ITfThreadMgr *pThreadMgr, _Inout_ CicIMCLock& imcLock); + HRESULT DestroyInputContext(); +}; diff --git a/dll/ime/msctfime/msctfime.cpp b/dll/ime/msctfime/msctfime.cpp index c1353076be1..445998d6a9c 100644 --- a/dll/ime/msctfime/msctfime.cpp +++ b/dll/ime/msctfime/msctfime.cpp @@ -10,94 +10,41 @@ WINE_DEFAULT_DEBUG_CHANNEL(msctfime); +typedef CicArray CDispAttrPropCache; + HINSTANCE g_hInst = NULL; /* The instance of this module */ BOOL g_bWinLogon = FALSE; UINT g_uACP = CP_ACP; DWORD g_dwOSInfo = 0; BOOL gfTFInitLib = FALSE; CRITICAL_SECTION g_csLock; - -DEFINE_GUID(GUID_COMPARTMENT_CTFIME_DIMFLAGS, 0xA94C5FD2, 0xC471, 0x4031, 0x95, 0x46, 0x70, 0x9C, 0x17, 0x30, 0x0C, 0xB9); -DEFINE_GUID(GUID_COMPARTMENT_CTFIME_CICINPUTCONTEXT, 0x85A688F7, 0x6DC8, 0x4F17, 0xA8, 0x3A, 0xB1, 0x1C, 0x09, 0xCD, 0xD7, 0xBF); +CDispAttrPropCache *g_pPropCache = NULL; EXTERN_C void __cxa_pure_virtual(void) { ERR("__cxa_pure_virtual\n"); } -UINT WM_MSIME_SERVICE = 0; -UINT WM_MSIME_UIREADY = 0; -UINT WM_MSIME_RECONVERTREQUEST = 0; -UINT WM_MSIME_RECONVERT = 0; -UINT WM_MSIME_DOCUMENTFEED = 0; -UINT WM_MSIME_QUERYPOSITION = 0; -UINT WM_MSIME_MODEBIAS = 0; -UINT WM_MSIME_SHOWIMEPAD = 0; -UINT WM_MSIME_MOUSE = 0; -UINT WM_MSIME_KEYMAP = 0; - -/// @implemented -BOOL IsMsImeMessage(_In_ UINT uMsg) -{ - return (uMsg == WM_MSIME_SERVICE || - uMsg == WM_MSIME_UIREADY || - uMsg == WM_MSIME_RECONVERTREQUEST || - uMsg == WM_MSIME_RECONVERT || - uMsg == WM_MSIME_DOCUMENTFEED || - uMsg == WM_MSIME_QUERYPOSITION || - uMsg == WM_MSIME_MODEBIAS || - uMsg == WM_MSIME_SHOWIMEPAD || - uMsg == WM_MSIME_MOUSE || - uMsg == WM_MSIME_KEYMAP); -} - -/// @implemented -BOOL RegisterMSIMEMessage(VOID) -{ - // Using ANSI (A) version here can reduce binary size. - WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService"); - WM_MSIME_UIREADY = RegisterWindowMessageA("MSIMEUIReady"); - WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest"); - WM_MSIME_RECONVERT = RegisterWindowMessageA("MSIMEReconvert"); - WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed"); - WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition"); - WM_MSIME_MODEBIAS = RegisterWindowMessageA("MSIMEModeBias"); - WM_MSIME_SHOWIMEPAD = RegisterWindowMessageA("MSIMEShowImePad"); - WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation"); - WM_MSIME_KEYMAP = RegisterWindowMessageA("MSIMEKeyMap"); - return (WM_MSIME_SERVICE && - WM_MSIME_UIREADY && - WM_MSIME_RECONVERTREQUEST && - WM_MSIME_RECONVERT && - WM_MSIME_DOCUMENTFEED && - WM_MSIME_QUERYPOSITION && - WM_MSIME_MODEBIAS && - WM_MSIME_SHOWIMEPAD && - WM_MSIME_MOUSE && - WM_MSIME_KEYMAP); -} - -typedef BOOLEAN (WINAPI *FN_DllShutDownInProgress)(VOID); +typedef BOOLEAN (WINAPI *FN_DllShutdownInProgress)(VOID); /// This function calls ntdll!RtlDllShutdownInProgress. /// It can detect the system is shutting down or not. /// @implemented -EXTERN_C BOOLEAN WINAPI -DllShutDownInProgress(VOID) +EXTERN_C BOOLEAN WINAPI DllShutdownInProgress(VOID) { HMODULE hNTDLL; - static FN_DllShutDownInProgress s_fnDllShutDownInProgress = NULL; + static FN_DllShutdownInProgress s_fnDllShutdownInProgress = NULL; - if (s_fnDllShutDownInProgress) - return s_fnDllShutDownInProgress(); + if (s_fnDllShutdownInProgress) + return s_fnDllShutdownInProgress(); hNTDLL = cicGetSystemModuleHandle(L"ntdll.dll", FALSE); - s_fnDllShutDownInProgress = - (FN_DllShutDownInProgress)GetProcAddress(hNTDLL, "RtlDllShutdownInProgress"); - if (!s_fnDllShutDownInProgress) + s_fnDllShutdownInProgress = + (FN_DllShutdownInProgress)GetProcAddress(hNTDLL, "RtlDllShutdownInProgress"); + if (!s_fnDllShutdownInProgress) return FALSE; - return s_fnDllShutDownInProgress(); + return s_fnDllShutdownInProgress(); } /// This function checks if the current user logon session is interactive. @@ -124,31 +71,34 @@ IsInteractiveUserLogon(VOID) return bOK && IsMember; } -HRESULT InitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread) +/// @implemented +ITfCategoryMgr *GetUIMCat(PCIC_LIBTHREAD pLibThread) { if (!pLibThread) - return E_FAIL; + return NULL; - if (pLibThread->m_pDisplayAttrMgr) + if (pLibThread->m_pCategoryMgr) + return pLibThread->m_pCategoryMgr; + + if (FAILED(cicCoCreateInstance(CLSID_TF_CategoryMgr, NULL, CLSCTX_INPROC_SERVER, + IID_ITfCategoryMgr, (void **)&pLibThread->m_pCategoryMgr))) { - pLibThread->m_pDisplayAttrMgr->Release(); - pLibThread->m_pDisplayAttrMgr = NULL; + return NULL; } - - //FIXME - return E_NOTIMPL; + return pLibThread->m_pCategoryMgr; } -HIMC GetActiveContext(VOID) +/// @implemented +HRESULT LibEnumItemsInCategory(PCIC_LIBTHREAD pLibThread, REFGUID rguid, IEnumGUID **ppEnum) { - HWND hwndFocus = ::GetFocus(); - if (!hwndFocus) - hwndFocus = ::GetActiveWindow(); - return ::ImmGetContext(hwndFocus); + ITfCategoryMgr *pCat = GetUIMCat(pLibThread); + if (!pCat) + return E_FAIL; + return pCat->EnumItemsInCategory(rguid, ppEnum); } /// @implemented -HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread) +HRESULT InitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread) { if (!pLibThread) return E_FAIL; @@ -159,2510 +109,145 @@ HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread) pLibThread->m_pDisplayAttrMgr = NULL; } - return S_OK; -} - -/// Gets the charset from a language ID. -/// @implemented -BYTE GetCharsetFromLangId(_In_ DWORD dwValue) -{ - CHARSETINFO info; - if (!::TranslateCharsetInfo((DWORD*)(DWORD_PTR)dwValue, &info, TCI_SRCLOCALE)) - return 0; - return info.ciCharset; -} - -/// Selects or unselects the input context. -/// @implemented -HRESULT -InternalSelectEx( - _In_ HIMC hIMC, - _In_ BOOL fSelect, - _In_ LANGID LangID) -{ - CicIMCLock imcLock(hIMC); - if (!imcLock) - imcLock.m_hr = E_FAIL; - if (FAILED(imcLock.m_hr)) - return imcLock.m_hr; - - if (PRIMARYLANGID(LangID) == LANG_CHINESE) - { - imcLock.get().cfCandForm[0].dwStyle = 0; - imcLock.get().cfCandForm[0].dwIndex = (DWORD)-1; - } - - if (!fSelect) - { - imcLock.get().fdwInit &= ~INIT_GUIDMAP; - return imcLock.m_hr; - } - - if (!imcLock.ClearCand()) - return imcLock.m_hr; - - // Populate conversion mode - if (!(imcLock.get().fdwInit & INIT_CONVERSION)) - { - DWORD dwConv = (imcLock.get().fdwConversion & IME_CMODE_SOFTKBD); - if (LangID) - { - if (PRIMARYLANGID(LangID) == LANG_JAPANESE) - { - dwConv |= IME_CMODE_ROMAN | IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE; - } - else if (PRIMARYLANGID(LangID) != LANG_KOREAN) - { - dwConv |= IME_CMODE_NATIVE; - } - } - imcLock.get().fdwConversion |= dwConv; - imcLock.get().fdwInit |= INIT_CONVERSION; - } - - // Populate sentence mode - imcLock.get().fdwSentence |= IME_SMODE_PHRASEPREDICT; - - // Populate LOGFONT - if (!(imcLock.get().fdwInit & INIT_LOGFONT)) - { - // Get logical font - LOGFONTW lf; - HDC hDC = ::GetDC(imcLock.get().hWnd); - HGDIOBJ hFont = GetCurrentObject(hDC, OBJ_FONT); - ::GetObjectW(hFont, sizeof(LOGFONTW), &lf); - ::ReleaseDC(imcLock.get().hWnd, hDC); - - imcLock.get().lfFont.W = lf; - imcLock.get().fdwInit |= INIT_LOGFONT; - } - imcLock.get().lfFont.W.lfCharSet = GetCharsetFromLangId(LangID); - - imcLock.InitContext(); - - return imcLock.m_hr; -} - -/*********************************************************************** - * Compartment - */ - -/// @implemented -HRESULT -GetCompartment( - IUnknown *pUnknown, - REFGUID rguid, - ITfCompartment **ppComp, - BOOL bThread) -{ - *ppComp = NULL; - - ITfThreadMgr *pThreadMgr = NULL; - ITfCompartmentMgr *pCompMgr = NULL; - - HRESULT hr; - if (bThread) - { - hr = pUnknown->QueryInterface(IID_ITfThreadMgr, (void **)&pThreadMgr); - if (FAILED(hr)) - return hr; - - hr = pThreadMgr->GetGlobalCompartment(&pCompMgr); - } - else - { - hr = pUnknown->QueryInterface(IID_ITfCompartmentMgr, (void **)&pCompMgr); - } - - if (SUCCEEDED(hr)) - { - hr = E_FAIL; - if (pCompMgr) - { - hr = pCompMgr->GetCompartment(rguid, ppComp); - pCompMgr->Release(); - } - } - - if (pThreadMgr) - pThreadMgr->Release(); - - return hr; -} - -/// @implemented -HRESULT -SetCompartmentDWORD( - TfEditCookie cookie, - IUnknown *pUnknown, - REFGUID rguid, - DWORD dwValue, - BOOL bThread) -{ - ITfCompartment *pComp = NULL; - HRESULT hr = GetCompartment(pUnknown, rguid, &pComp, bThread); - if (FAILED(hr)) - return hr; - - VARIANT vari; - V_I4(&vari) = dwValue; - V_VT(&vari) = VT_I4; - hr = pComp->SetValue(cookie, &vari); - - pComp->Release(); - return hr; -} - -/// @implemented -HRESULT -GetCompartmentDWORD( - IUnknown *pUnknown, - REFGUID rguid, - LPDWORD pdwValue, - BOOL bThread) -{ - *pdwValue = 0; - - ITfCompartment *pComp = NULL; - HRESULT hr = GetCompartment(pUnknown, rguid, &pComp, bThread); - if (FAILED(hr)) - return hr; - - VARIANT vari; - hr = pComp->GetValue(&vari); - if (hr == S_OK) - *pdwValue = V_I4(&vari); - - pComp->Release(); - return hr; -} - -/// @implemented -HRESULT -SetCompartmentUnknown( - TfEditCookie cookie, - IUnknown *pUnknown, - REFGUID rguid, - IUnknown *punkValue) -{ - ITfCompartment *pComp = NULL; - HRESULT hr = GetCompartment(pUnknown, rguid, &pComp, FALSE); - if (FAILED(hr)) - return hr; - - VARIANT vari; - V_UNKNOWN(&vari) = punkValue; - V_VT(&vari) = VT_UNKNOWN; - hr = pComp->SetValue(cookie, &vari); - - pComp->Release(); - return hr; -} - -/// @implemented -HRESULT -ClearCompartment( - TfClientId tid, - IUnknown *pUnknown, - REFGUID rguid, - BOOL bThread) -{ - ITfCompartmentMgr *pCompMgr = NULL; - ITfThreadMgr *pThreadMgr = NULL; - - HRESULT hr; - if (bThread) - { - hr = pUnknown->QueryInterface(IID_ITfThreadMgr, (void **)&pThreadMgr); - if (FAILED(hr)) - return hr; - - hr = pThreadMgr->GetGlobalCompartment(&pCompMgr); - } - else - { - hr = pUnknown->QueryInterface(IID_ITfCompartmentMgr, (void **)&pCompMgr); - } - - if (SUCCEEDED(hr)) - { - hr = E_FAIL; - if (pCompMgr) - { - hr = pCompMgr->ClearCompartment(tid, rguid); - pCompMgr->Release(); - } - } - - if (pThreadMgr) - pThreadMgr->Release(); - - return hr; -} - -typedef struct CESMAP -{ - ITfCompartment *m_pComp; - DWORD m_dwCookie; -} CESMAP, *PCESMAP; - -typedef INT (CALLBACK *FN_EVENTSINK)(LPVOID, REFGUID); - -class CCompartmentEventSink : public ITfCompartmentEventSink -{ - CicArray m_array; - LONG m_cRefs; - FN_EVENTSINK m_fnEventSink; - LPVOID m_pUserData; - -public: - CCompartmentEventSink(FN_EVENTSINK fnEventSink, LPVOID pUserData); - virtual ~CCompartmentEventSink(); - - HRESULT _Advise(IUnknown *pUnknown, REFGUID rguid, BOOL bThread); - HRESULT _Unadvise(); - - // IUnknown interface - STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override; - STDMETHODIMP_(ULONG) AddRef() override; - STDMETHODIMP_(ULONG) Release() override; - - // ITfCompartmentEventSink interface - STDMETHODIMP OnChange(REFGUID rguid) override; -}; - -/// @implemented -CCompartmentEventSink::CCompartmentEventSink(FN_EVENTSINK fnEventSink, LPVOID pUserData) - : m_array() - , m_cRefs(1) - , m_fnEventSink(fnEventSink) - , m_pUserData(pUserData) -{ -} - -/// @implemented -CCompartmentEventSink::~CCompartmentEventSink() -{ -} - -/// @implemented -STDMETHODIMP CCompartmentEventSink::QueryInterface(REFIID riid, LPVOID* ppvObj) -{ - if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfCompartmentEventSink)) - { - *ppvObj = this; - AddRef(); - return S_OK; - } - - *ppvObj = NULL; - return E_NOINTERFACE; -} - -/// @implemented -STDMETHODIMP_(ULONG) CCompartmentEventSink::AddRef() -{ - return ::InterlockedIncrement(&m_cRefs); -} - -/// @implemented -STDMETHODIMP_(ULONG) CCompartmentEventSink::Release() -{ - if (::InterlockedDecrement(&m_cRefs) == 0) + if (FAILED(cicCoCreateInstance(CLSID_TF_DisplayAttributeMgr, NULL, CLSCTX_INPROC_SERVER, + IID_ITfDisplayAttributeMgr, + (void **)&pLibThread->m_pDisplayAttrMgr))) { - delete this; - return 0; + return E_FAIL; } - return m_cRefs; -} - -/// @implemented -STDMETHODIMP CCompartmentEventSink::OnChange(REFGUID rguid) -{ - return m_fnEventSink(m_pUserData, rguid); -} -/// @implemented -HRESULT -CCompartmentEventSink::_Advise(IUnknown *pUnknown, REFGUID rguid, BOOL bThread) -{ - CESMAP *pCesMap = m_array.Append(1); - if (!pCesMap) - return E_OUTOFMEMORY; + IEnumGUID *pEnumGuid; + LibEnumItemsInCategory(pLibThread, GUID_TFCAT_DISPLAYATTRIBUTEPROPERTY, &pEnumGuid); - ITfSource *pSource = NULL; + HRESULT hr = E_OUTOFMEMORY; - HRESULT hr = GetCompartment(pUnknown, rguid, &pCesMap->m_pComp, bThread); - if (FAILED(hr)) + ::EnterCriticalSection(&g_csLock); + if (pEnumGuid && !g_pPropCache) { - hr = pCesMap->m_pComp->QueryInterface(IID_ITfSource, (void **)&pSource); - if (FAILED(hr)) + g_pPropCache = new(cicNoThrow) CDispAttrPropCache(); + if (g_pPropCache) { - hr = pSource->AdviseSink(IID_ITfCompartmentEventSink, this, &pCesMap->m_dwCookie); - if (FAILED(hr)) - { - if (pCesMap->m_pComp) - { - pCesMap->m_pComp->Release(); - pCesMap->m_pComp = NULL; - } - m_array.Remove(m_array.size() - 1, 1); - } - else + g_pPropCache->Add(GUID_PROP_ATTRIBUTE); + GUID guid; + while (pEnumGuid->Next(1, &guid, NULL) == S_OK) { - hr = S_OK; + if (!IsEqualGUID(guid, GUID_PROP_ATTRIBUTE)) + g_pPropCache->Add(guid); } + hr = S_OK; } } + ::LeaveCriticalSection(&g_csLock); - if (pSource) - pSource->Release(); - - return hr; -} - -/// @implemented -HRESULT CCompartmentEventSink::_Unadvise() -{ - CESMAP *pCesMap = m_array.data(); - size_t cItems = m_array.size(); - if (!cItems) - return S_OK; - - do - { - ITfSource *pSource = NULL; - HRESULT hr = pCesMap->m_pComp->QueryInterface(IID_ITfSource, (void **)&pSource); - if (SUCCEEDED(hr)) - pSource->UnadviseSink(pCesMap->m_dwCookie); - - if (pCesMap->m_pComp) - { - pCesMap->m_pComp->Release(); - pCesMap->m_pComp = NULL; - } - - if (pSource) - pSource->Release(); - - ++pCesMap; - --cItems; - } while (cItems); - - return S_OK; -} - -class CInputContextOwnerCallBack; -class CInputContextOwner; - -typedef INT (CALLBACK *FN_ENDEDIT)(INT, LPVOID, LPVOID); -typedef INT (CALLBACK *FN_LAYOUTCHANGE)(UINT nType, FN_ENDEDIT fnEndEdit, ITfContextView *pView); - -class CTextEventSink : public ITfTextEditSink, ITfTextLayoutSink -{ -protected: - LONG m_cRefs; - IUnknown *m_pUnknown; - DWORD m_dwEditSinkCookie; - DWORD m_dwLayoutSinkCookie; - union - { - UINT m_uFlags; - FN_LAYOUTCHANGE m_fnLayoutChange; - }; - FN_ENDEDIT m_fnEndEdit; - LPVOID m_pCallbackPV; - -public: - CTextEventSink(FN_ENDEDIT fnEndEdit, LPVOID pCallbackPV); - virtual ~CTextEventSink(); - - HRESULT _Advise(IUnknown *pUnknown, UINT uFlags); - HRESULT _Unadvise(); - - // IUnknown interface - STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override; - STDMETHODIMP_(ULONG) AddRef() override; - STDMETHODIMP_(ULONG) Release() override; - - // ITfTextEditSink interface - STDMETHODIMP OnEndEdit( - ITfContext *pic, - TfEditCookie ecReadOnly, - ITfEditRecord *pEditRecord) override; - - // ITfTextLayoutSink interface - STDMETHODIMP - OnLayoutChange( - ITfContext *pContext, - TfLayoutCode lcode, - ITfContextView *pContextView) override; -}; - -/// @implemented -CTextEventSink::CTextEventSink(FN_ENDEDIT fnEndEdit, LPVOID pCallbackPV) -{ - m_cRefs = 1; - m_pUnknown = NULL; - m_dwEditSinkCookie = (DWORD)-1; - m_dwLayoutSinkCookie = (DWORD)-1; - m_fnLayoutChange = NULL; - m_fnEndEdit = fnEndEdit; - m_pCallbackPV = pCallbackPV; -} - -/// @implemented -CTextEventSink::~CTextEventSink() -{ -} - -/// @implemented -STDMETHODIMP CTextEventSink::QueryInterface(REFIID riid, LPVOID* ppvObj) -{ - if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfTextEditSink)) - { - *ppvObj = this; - AddRef(); - return S_OK; - } - if (IsEqualIID(riid, IID_ITfTextLayoutSink)) - { - *ppvObj = static_cast(this); - AddRef(); - return S_OK; - } - return E_NOINTERFACE; -} - -/// @implemented -STDMETHODIMP_(ULONG) CTextEventSink::AddRef() -{ - return ::InterlockedIncrement(&m_cRefs); -} - -/// @implemented -STDMETHODIMP_(ULONG) CTextEventSink::Release() -{ - if (::InterlockedDecrement(&m_cRefs) == 0) - { - delete this; - return 0; - } - return m_cRefs; -} - -struct TEXT_EVENT_SINK_END_EDIT -{ - TfEditCookie m_ecReadOnly; - ITfEditRecord *m_pEditRecord; - ITfContext *m_pContext; -}; - -/// @implemented -STDMETHODIMP CTextEventSink::OnEndEdit( - ITfContext *pic, - TfEditCookie ecReadOnly, - ITfEditRecord *pEditRecord) -{ - TEXT_EVENT_SINK_END_EDIT Data = { ecReadOnly, pEditRecord, pic }; - return m_fnEndEdit(1, m_pCallbackPV, (LPVOID)&Data); -} - -/// @implemented -STDMETHODIMP CTextEventSink::OnLayoutChange( - ITfContext *pContext, - TfLayoutCode lcode, - ITfContextView *pContextView) -{ - switch (lcode) - { - case TF_LC_CREATE: - return m_fnLayoutChange(3, m_fnEndEdit, pContextView); - case TF_LC_CHANGE: - return m_fnLayoutChange(2, m_fnEndEdit, pContextView); - case TF_LC_DESTROY: - return m_fnLayoutChange(4, m_fnEndEdit, pContextView); - default: - return E_INVALIDARG; - } -} - -/// @implemented -HRESULT CTextEventSink::_Advise(IUnknown *pUnknown, UINT uFlags) -{ - m_pUnknown = NULL; - m_uFlags = uFlags; - - ITfSource *pSource = NULL; - HRESULT hr = pUnknown->QueryInterface(IID_ITfSource, (void**)&pSource); - if (SUCCEEDED(hr)) - { - ITfTextEditSink *pSink = static_cast(this); - if (uFlags & 1) - hr = pSource->AdviseSink(IID_ITfTextEditSink, pSink, &m_dwEditSinkCookie); - if (SUCCEEDED(hr) && (uFlags & 2)) - hr = pSource->AdviseSink(IID_ITfTextLayoutSink, pSink, &m_dwLayoutSinkCookie); - - if (SUCCEEDED(hr)) - { - m_pUnknown = pUnknown; - pUnknown->AddRef(); - } - else - { - pSource->UnadviseSink(m_dwEditSinkCookie); - } - } - - if (pSource) - pSource->Release(); - - return hr; -} - -/// @implemented -HRESULT CTextEventSink::_Unadvise() -{ - if (!m_pUnknown) - return E_FAIL; - - ITfSource *pSource = NULL; - HRESULT hr = m_pUnknown->QueryInterface(IID_ITfSource, (void**)&pSource); - if (SUCCEEDED(hr)) - { - if (m_uFlags & 1) - hr = pSource->UnadviseSink(m_dwEditSinkCookie); - if (m_uFlags & 2) - hr = pSource->UnadviseSink(m_dwLayoutSinkCookie); - - pSource->Release(); - } - - m_pUnknown->Release(); - m_pUnknown = NULL; - - return E_NOTIMPL; -} - -/*********************************************************************** - * CicInputContext - * - * The msctfime.ime's input context. - */ -class CicInputContext - : public ITfCleanupContextSink - , public ITfContextOwnerCompositionSink - , public ITfCompositionSink -{ -public: - LONG m_cRefs; - HIMC m_hIMC; - ITfDocumentMgr *m_pDocumentMgr; - ITfContext *m_pContext; - ITfContextOwnerServices *m_pContextOwnerServices; - CInputContextOwnerCallBack *m_pICOwnerCallback; - CTextEventSink *m_pTextEventSink; - CCompartmentEventSink *m_pCompEventSink1; - CCompartmentEventSink *m_pCompEventSink2; - CInputContextOwner *m_pInputContextOwner; - DWORD m_dwUnknown3[3]; - DWORD m_dwUnknown4[2]; - DWORD m_dwQueryPos; - DWORD m_dwUnknown5; - GUID m_guid; - DWORD m_dwUnknown6[11]; - BOOL m_bSelecting; - DWORD m_dwUnknown6_5; - LONG m_cCompLocks; - DWORD m_dwUnknown7[5]; - WORD m_cGuidAtoms; - WORD m_padding; - DWORD m_adwGuidAtoms[256]; - DWORD m_dwUnknown8[17]; - TfClientId m_clientId; - DWORD m_dwUnknown9; - -public: - CicInputContext( - _In_ TfClientId cliendId, - _Inout_ PCIC_LIBTHREAD pLibThread, - _In_ HIMC hIMC); - virtual ~CicInputContext() { } - - // IUnknown interface - STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override; - STDMETHODIMP_(ULONG) AddRef() override; - STDMETHODIMP_(ULONG) Release() override; - - // ITfCleanupContextSink interface - STDMETHODIMP OnCleanupContext(_In_ TfEditCookie ecWrite, _Inout_ ITfContext *pic) override; - - // ITfContextOwnerCompositionSink interface - STDMETHODIMP OnStartComposition(ITfCompositionView *pComposition, BOOL *pfOk) override; - STDMETHODIMP OnUpdateComposition(ITfCompositionView *pComposition, ITfRange *pRangeNew) override; - STDMETHODIMP OnEndComposition(ITfCompositionView *pComposition) override; - - // ITfCompositionSink interface - STDMETHODIMP OnCompositionTerminated(TfEditCookie ecWrite, ITfComposition *pComposition) override; - - HRESULT - GetGuidAtom( - _Inout_ CicIMCLock& imcLock, - _In_ BYTE iAtom, - _Out_opt_ LPDWORD pdwGuidAtom); - - HRESULT CreateInputContext(_Inout_ ITfThreadMgr *pThreadMgr, _Inout_ CicIMCLock& imcLock); - HRESULT DestroyInputContext(); -}; - -/// @unimplemented -CicInputContext::CicInputContext( - _In_ TfClientId cliendId, - _Inout_ PCIC_LIBTHREAD pLibThread, - _In_ HIMC hIMC) -{ - m_hIMC = hIMC; - m_guid = GUID_NULL; - m_dwQueryPos = 0; - m_cRefs = 1; -} - -/// @implemented -STDMETHODIMP CicInputContext::QueryInterface(REFIID riid, LPVOID* ppvObj) -{ - *ppvObj = NULL; - - if (IsEqualIID(riid, IID_ITfContextOwnerCompositionSink)) - { - *ppvObj = static_cast(this); - AddRef(); - return S_OK; - } - if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfCleanupContextSink)) - { - *ppvObj = this; - AddRef(); - return S_OK; - } - - return E_NOINTERFACE; -} - -/// @implemented -STDMETHODIMP_(ULONG) CicInputContext::AddRef() -{ - return ::InterlockedIncrement(&m_cRefs); -} - -/// @implemented -STDMETHODIMP_(ULONG) CicInputContext::Release() -{ - if (::InterlockedDecrement(&m_cRefs) == 0) - { - delete this; - return 0; - } - return m_cRefs; -} - -/// @implemented -STDMETHODIMP -CicInputContext::OnStartComposition( - ITfCompositionView *pComposition, - BOOL *pfOk) -{ - if ((m_cCompLocks <= 0) || m_dwUnknown6_5) - { - *pfOk = TRUE; - ++m_cCompLocks; - } - else - { - *pfOk = FALSE; - } - return S_OK; -} - -/// @implemented -STDMETHODIMP -CicInputContext::OnUpdateComposition( - ITfCompositionView *pComposition, - ITfRange *pRangeNew) -{ - return S_OK; -} - -/// @implemented -STDMETHODIMP -CicInputContext::OnEndComposition( - ITfCompositionView *pComposition) -{ - --m_cCompLocks; - return S_OK; -} - -/// @implemented -HRESULT -CicInputContext::GetGuidAtom( - _Inout_ CicIMCLock& imcLock, - _In_ BYTE iAtom, - _Out_opt_ LPDWORD pdwGuidAtom) -{ - CicIMCCLock imeContext(imcLock.get().hCompStr); - HRESULT hr = imeContext.m_hr; - if (!imeContext) - hr = E_FAIL; - if (FAILED(hr)) - return hr; - - hr = E_FAIL; - if (iAtom < m_cGuidAtoms) - { - *pdwGuidAtom = m_adwGuidAtoms[iAtom]; - hr = S_OK; - } - - return hr; -} - -/// @unimplemented -HRESULT -CicInputContext::CreateInputContext( - _Inout_ ITfThreadMgr *pThreadMgr, - _Inout_ CicIMCLock& imcLock) -{ - //FIXME - return E_NOTIMPL; -} - -/// @unimplemented -HRESULT -CicInputContext::DestroyInputContext() -{ - ITfSourceSingle *pSource = NULL; - - if (m_pContext && m_pContext->QueryInterface(IID_ITfSourceSingle, (void **)&pSource) == S_OK) - pSource->UnadviseSingleSink(m_clientId, IID_ITfCleanupContextSink); - - //FIXME: m_dwUnknown5 - - if (m_pTextEventSink) - { - m_pTextEventSink->_Unadvise(); - m_pTextEventSink->Release(); - m_pTextEventSink = NULL; - } - - if (m_pCompEventSink2) - { - m_pCompEventSink2->_Unadvise(); - m_pCompEventSink2->Release(); - m_pCompEventSink2 = NULL; - } - - if (m_pCompEventSink1) - { - m_pCompEventSink1->_Unadvise(); - m_pCompEventSink1->Release(); - m_pCompEventSink1 = NULL; - } - - //FIXME: m_pInputContextOwner - - if (m_pDocumentMgr) - m_pDocumentMgr->Pop(1); - - if (m_pContext) - { - ClearCompartment(m_clientId, m_pContext, GUID_COMPARTMENT_CTFIME_CICINPUTCONTEXT, 0); - m_pContext->Release(); - m_pContext = NULL; - } - - if (m_pContextOwnerServices) - { - m_pContextOwnerServices->Release(); - m_pContextOwnerServices = NULL; - } - - // FIXME: m_pICOwnerCallback - - if (m_pDocumentMgr) - { - m_pDocumentMgr->Release(); - m_pDocumentMgr = NULL; - } - - if (pSource) - pSource->Release(); - - return S_OK; -} - -/// @implemented -STDMETHODIMP -CicInputContext::OnCompositionTerminated(TfEditCookie ecWrite, ITfComposition *pComposition) -{ - return S_OK; -} - -/// Retrieves the IME information. -/// @implemented -HRESULT -Inquire( - _Out_ LPIMEINFO lpIMEInfo, - _Out_ LPWSTR lpszWndClass, - _In_ DWORD dwSystemInfoFlags, - _In_ HKL hKL) -{ - if (!lpIMEInfo) - return E_OUTOFMEMORY; - - StringCchCopyW(lpszWndClass, 64, L"MSCTFIME UI"); - lpIMEInfo->dwPrivateDataSize = 0; - - switch (LOWORD(hKL)) // Language ID - { - case MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT): // Japanese - { - lpIMEInfo->fdwProperty = IME_PROP_COMPLETE_ON_UNSELECT | IME_PROP_SPECIAL_UI | - IME_PROP_AT_CARET | IME_PROP_NEED_ALTKEY | - IME_PROP_KBD_CHAR_FIRST; - lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE | IME_CMODE_KATAKANA | - IME_CMODE_NATIVE; - lpIMEInfo->fdwSentenceCaps = IME_SMODE_CONVERSATION | IME_SMODE_PLAURALCLAUSE; - lpIMEInfo->fdwSelectCaps = SELECT_CAP_SENTENCE | SELECT_CAP_CONVERSION; - lpIMEInfo->fdwSCSCaps = SCS_CAP_SETRECONVERTSTRING | SCS_CAP_MAKEREAD | - SCS_CAP_COMPSTR; - lpIMEInfo->fdwUICaps = UI_CAP_ROT90; - break; - } - case MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT): // Korean - { - lpIMEInfo->fdwProperty = IME_PROP_COMPLETE_ON_UNSELECT | IME_PROP_SPECIAL_UI | - IME_PROP_AT_CARET | IME_PROP_NEED_ALTKEY | - IME_PROP_KBD_CHAR_FIRST; - lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE; - lpIMEInfo->fdwSentenceCaps = 0; - lpIMEInfo->fdwSCSCaps = SCS_CAP_SETRECONVERTSTRING | SCS_CAP_COMPSTR; - lpIMEInfo->fdwSelectCaps = SELECT_CAP_CONVERSION; - lpIMEInfo->fdwUICaps = UI_CAP_ROT90; - break; - } - case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED): // Simplified Chinese - case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL): // Traditional Chinese - { - lpIMEInfo->fdwProperty = IME_PROP_SPECIAL_UI | IME_PROP_AT_CARET | - IME_PROP_NEED_ALTKEY | IME_PROP_KBD_CHAR_FIRST; - lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE; - lpIMEInfo->fdwSentenceCaps = SELECT_CAP_CONVERSION; - lpIMEInfo->fdwSelectCaps = 0; - lpIMEInfo->fdwSCSCaps = SCS_CAP_SETRECONVERTSTRING | SCS_CAP_MAKEREAD | - SCS_CAP_COMPSTR; - lpIMEInfo->fdwUICaps = UI_CAP_ROT90; - break; - } - default: // Otherwise - { - lpIMEInfo->fdwProperty = IME_PROP_UNICODE | IME_PROP_AT_CARET; - lpIMEInfo->fdwConversionCaps = 0; - lpIMEInfo->fdwSentenceCaps = 0; - lpIMEInfo->fdwSCSCaps = 0; - lpIMEInfo->fdwUICaps = 0; - lpIMEInfo->fdwSelectCaps = 0; - break; - } - } - - return S_OK; -} - -class TLS; - -typedef INT (CALLBACK *FN_INITDOCMGR)(UINT, ITfDocumentMgr *, ITfDocumentMgr *, LPVOID); -typedef INT (CALLBACK *FN_PUSHPOP)(UINT, ITfContext *, LPVOID); - -class CThreadMgrEventSink : public ITfThreadMgrEventSink -{ -protected: - ITfThreadMgr *m_pThreadMgr; - DWORD m_dwCookie; - FN_INITDOCMGR m_fnInit; - FN_PUSHPOP m_fnPushPop; - DWORD m_dw; - LPVOID m_pCallbackPV; - LONG m_cRefs; - -public: - CThreadMgrEventSink( - _In_ FN_INITDOCMGR fnInit, - _In_ FN_PUSHPOP fnPushPop = NULL, - _Inout_ LPVOID pvCallbackPV = NULL); - virtual ~CThreadMgrEventSink() { } - - void SetCallbackPV(_Inout_ LPVOID pv); - HRESULT _Advise(ITfThreadMgr *pThreadMgr); - HRESULT _Unadvise(); - - // IUnknown interface - STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override; - STDMETHODIMP_(ULONG) AddRef() override; - STDMETHODIMP_(ULONG) Release() override; - - // ITfThreadMgrEventSink interface - STDMETHODIMP OnInitDocumentMgr(ITfDocumentMgr *pdim) override; - STDMETHODIMP OnUninitDocumentMgr(ITfDocumentMgr *pdim) override; - STDMETHODIMP OnSetFocus(ITfDocumentMgr *pdimFocus, ITfDocumentMgr *pdimPrevFocus) override; - STDMETHODIMP OnPushContext(ITfContext *pic) override; - STDMETHODIMP OnPopContext(ITfContext *pic) override; - - static INT CALLBACK DIMCallback( - UINT nCode, - ITfDocumentMgr *pDocMgr1, - ITfDocumentMgr *pDocMgr2, - LPVOID pUserData); -}; - -/// @implemented -CThreadMgrEventSink::CThreadMgrEventSink( - _In_ FN_INITDOCMGR fnInit, - _In_ FN_PUSHPOP fnPushPop, - _Inout_ LPVOID pvCallbackPV) -{ - m_fnInit = fnInit; - m_fnPushPop = fnPushPop; - m_pCallbackPV = pvCallbackPV; - m_cRefs = 1; -} - -/// @implemented -STDMETHODIMP CThreadMgrEventSink::QueryInterface(REFIID riid, LPVOID* ppvObj) -{ - if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfThreadMgrEventSink)) - { - *ppvObj = this; - AddRef(); - return S_OK; - } - *ppvObj = NULL; - return E_NOINTERFACE; -} - -/// @implemented -STDMETHODIMP_(ULONG) CThreadMgrEventSink::AddRef() -{ - return ::InterlockedIncrement(&m_cRefs); -} - -/// @implemented -STDMETHODIMP_(ULONG) CThreadMgrEventSink::Release() -{ - if (::InterlockedDecrement(&m_cRefs) == 0) - { - delete this; - return 0; - } - return m_cRefs; -} - -INT CALLBACK -CThreadMgrEventSink::DIMCallback( - UINT nCode, - ITfDocumentMgr *pDocMgr1, - ITfDocumentMgr *pDocMgr2, - LPVOID pUserData) -{ - return E_NOTIMPL; -} - -STDMETHODIMP CThreadMgrEventSink::OnInitDocumentMgr(ITfDocumentMgr *pdim) -{ - if (!m_fnInit) - return S_OK; - return m_fnInit(0, pdim, NULL, m_pCallbackPV); -} - -STDMETHODIMP CThreadMgrEventSink::OnUninitDocumentMgr(ITfDocumentMgr *pdim) -{ - if (!m_fnInit) - return S_OK; - return m_fnInit(1, pdim, NULL, m_pCallbackPV); -} - -STDMETHODIMP -CThreadMgrEventSink::OnSetFocus(ITfDocumentMgr *pdimFocus, ITfDocumentMgr *pdimPrevFocus) -{ - if (!m_fnInit) - return S_OK; - return m_fnInit(2, pdimFocus, pdimPrevFocus, m_pCallbackPV); -} - -STDMETHODIMP CThreadMgrEventSink::OnPushContext(ITfContext *pic) -{ - if (!m_fnPushPop) - return S_OK; - return m_fnPushPop(3, pic, m_pCallbackPV); -} - -STDMETHODIMP CThreadMgrEventSink::OnPopContext(ITfContext *pic) -{ - if (!m_fnPushPop) - return S_OK; - return m_fnPushPop(4, pic, m_pCallbackPV); -} - -void CThreadMgrEventSink::SetCallbackPV(_Inout_ LPVOID pv) -{ - if (!m_pCallbackPV) - m_pCallbackPV = pv; -} - -HRESULT CThreadMgrEventSink::_Advise(ITfThreadMgr *pThreadMgr) -{ - m_pThreadMgr = NULL; - - HRESULT hr = E_FAIL; - ITfSource *pSource = NULL; - if (pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource) == S_OK && - pSource->AdviseSink(IID_ITfThreadMgrEventSink, this, &m_dwCookie) == S_OK) - { - m_pThreadMgr = pThreadMgr; - pThreadMgr->AddRef(); - hr = S_OK; - } - - if (pSource) - pSource->Release(); - - return hr; -} - -HRESULT CThreadMgrEventSink::_Unadvise() -{ - HRESULT hr = E_FAIL; - ITfSource *pSource = NULL; - - if (m_pThreadMgr) - { - if (m_pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource) == S_OK && - pSource->UnadviseSink(m_dwCookie) == S_OK) - { - hr = S_OK; - } - - if (pSource) - pSource->Release(); - } - - if (m_pThreadMgr) - { - m_pThreadMgr->Release(); - m_pThreadMgr = NULL; - } - - return hr; -} - -class CFunctionProviderBase : public ITfFunctionProvider -{ -protected: - TfClientId m_clientId; - GUID m_guid; - BSTR m_bstr; - LONG m_cRefs; - -public: - CFunctionProviderBase(_In_ TfClientId clientId); - virtual ~CFunctionProviderBase(); - - // IUnknown interface - STDMETHODIMP QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) override; - STDMETHODIMP_(ULONG) AddRef() override; - STDMETHODIMP_(ULONG) Release() override; - - // ITfFunctionProvider interface - STDMETHODIMP GetType(_Out_ GUID *guid) override; - STDMETHODIMP GetDescription(_Out_ BSTR *desc) override; - //STDMETHODIMP GetFunction(_In_ REFGUID guid, _In_ REFIID riid, _Out_ IUnknown **func) = 0; - - BOOL Init(_In_ REFGUID rguid, _In_ LPCWSTR psz); -}; - -/// @implemented -CFunctionProviderBase::CFunctionProviderBase(_In_ TfClientId clientId) -{ - m_clientId = clientId; - m_guid = GUID_NULL; - m_bstr = NULL; - m_cRefs = 1; -} - -/// @implemented -CFunctionProviderBase::~CFunctionProviderBase() -{ - if (!RtlDllShutdownInProgress()) - ::SysFreeString(m_bstr); -} - -/// @implemented -BOOL -CFunctionProviderBase::Init( - _In_ REFGUID rguid, - _In_ LPCWSTR psz) -{ - m_bstr = ::SysAllocString(psz); - m_guid = rguid; - return (m_bstr != NULL); -} - -class CFnDocFeed : public IAImmFnDocFeed -{ - LONG m_cRefs; - -public: - CFnDocFeed(); - virtual ~CFnDocFeed(); - - // IUnknown interface - STDMETHODIMP QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) override; - STDMETHODIMP_(ULONG) AddRef() override; - STDMETHODIMP_(ULONG) Release() override; - - // IAImmFnDocFeed interface - STDMETHODIMP DocFeed() override; - STDMETHODIMP ClearDocFeedBuffer() override; - STDMETHODIMP StartReconvert() override; - STDMETHODIMP StartUndoCompositionString() override; -}; - -CFnDocFeed::CFnDocFeed() -{ - m_cRefs = 1; -} - -CFnDocFeed::~CFnDocFeed() -{ -} - -/// @implemented -STDMETHODIMP CFnDocFeed::QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) -{ - if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IAImmFnDocFeed)) - { - *ppvObj = this; - AddRef(); - return S_OK; - } - return E_NOINTERFACE; -} - -/// @implemented -STDMETHODIMP_(ULONG) CFnDocFeed::AddRef() -{ - return ::InterlockedIncrement(&m_cRefs); -} - -/// @implemented -STDMETHODIMP_(ULONG) CFnDocFeed::Release() -{ - if (::InterlockedDecrement(&m_cRefs) == 0) - { - delete this; - return 0; - } - return m_cRefs; -} - -/// @unimplemented -STDMETHODIMP CFnDocFeed::DocFeed() -{ - return E_NOTIMPL; -} - -/// @unimplemented -STDMETHODIMP CFnDocFeed::ClearDocFeedBuffer() -{ - return E_NOTIMPL; -} - -/// @unimplemented -STDMETHODIMP CFnDocFeed::StartReconvert() -{ - return E_NOTIMPL; -} - -/// @unimplemented -STDMETHODIMP CFnDocFeed::StartUndoCompositionString() -{ - return E_NOTIMPL; -} - -/// @implemented -STDMETHODIMP -CFunctionProviderBase::QueryInterface( - _In_ REFIID riid, - _Out_ LPVOID* ppvObj) -{ - if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfFunctionProvider)) - { - *ppvObj = this; - AddRef(); - return S_OK; - } - return E_NOINTERFACE; -} - -/// @implemented -STDMETHODIMP_(ULONG) CFunctionProviderBase::AddRef() -{ - return ::InterlockedIncrement(&m_cRefs); -} - -/// @implemented -STDMETHODIMP_(ULONG) CFunctionProviderBase::Release() -{ - if (::InterlockedDecrement(&m_cRefs) == 0) - { - delete this; - return 0; - } - return m_cRefs; -} - -/// @implemented -STDMETHODIMP CFunctionProviderBase::GetType(_Out_ GUID *guid) -{ - *guid = m_guid; - return S_OK; -} - -/// @implemented -STDMETHODIMP CFunctionProviderBase::GetDescription(_Out_ BSTR *desc) -{ - *desc = ::SysAllocString(m_bstr); - return (*desc ? S_OK : E_OUTOFMEMORY); -} - -class CFunctionProvider : public CFunctionProviderBase -{ -public: - CFunctionProvider(_In_ TfClientId clientId); - - STDMETHODIMP GetFunction(_In_ REFGUID guid, _In_ REFIID riid, _Out_ IUnknown **func) override; -}; - -/// @implemented -CFunctionProvider::CFunctionProvider(_In_ TfClientId clientId) : CFunctionProviderBase(clientId) -{ - Init(CLSID_CAImmLayer, L"MSCTFIME::Function Provider"); -} - -/// @implemented -STDMETHODIMP -CFunctionProvider::GetFunction( - _In_ REFGUID guid, - _In_ REFIID riid, - _Out_ IUnknown **func) -{ - *func = NULL; - - if (IsEqualGUID(guid, GUID_NULL) && - IsEqualIID(riid, IID_IAImmFnDocFeed)) - { - *func = new(cicNoThrow) CFnDocFeed(); - if (*func) - return S_OK; - } - - return E_NOINTERFACE; -} - -/* FIXME */ -class CicBridge : public ITfSysHookSink -{ -protected: - LONG m_cRefs; - BOOL m_bImmxInited; - BOOL m_bUnknown1; - BOOL m_bDeactivating; - DWORD m_cActivateLocks; - ITfKeystrokeMgr *m_pKeystrokeMgr; - ITfDocumentMgr *m_pDocMgr; - CThreadMgrEventSink *m_pThreadMgrEventSink; - TfClientId m_cliendId; - CIC_LIBTHREAD m_LibThread; - BOOL m_bUnknown2; - - static BOOL CALLBACK EnumCreateInputContextCallback(HIMC hIMC, LPARAM lParam); - static BOOL CALLBACK EnumDestroyInputContextCallback(HIMC hIMC, LPARAM lParam); - -public: - CicBridge(); - virtual ~CicBridge(); - - // IUnknown interface - STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override; - STDMETHODIMP_(ULONG) AddRef() override; - STDMETHODIMP_(ULONG) Release() override; - - // ITfSysHookSink interface - STDMETHODIMP OnPreFocusDIM(HWND hwnd) override; - STDMETHODIMP OnSysKeyboardProc(UINT, LONG) override; - STDMETHODIMP OnSysShellProc(INT, UINT, LONG) override; - - HRESULT InitIMMX(_Inout_ TLS *pTLS); - BOOL UnInitIMMX(_Inout_ TLS *pTLS); - HRESULT ActivateIMMX(_Inout_ TLS *pTLS, _Inout_ ITfThreadMgr_P *pThreadMgr); - HRESULT DeactivateIMMX(_Inout_ TLS *pTLS, _Inout_ ITfThreadMgr_P *pThreadMgr); - - HRESULT CreateInputContext(TLS *pTLS, HIMC hIMC); - HRESULT DestroyInputContext(TLS *pTLS, HIMC hIMC); - ITfContext *GetInputContext(CicIMCCLock& imeContext); - - HRESULT SelectEx( - _Inout_ TLS *pTLS, - _Inout_ ITfThreadMgr_P *pThreadMgr, - _In_ HIMC hIMC, - _In_ BOOL fSelect, - _In_ HKL hKL); - HRESULT OnSetOpenStatus( - TLS *pTLS, - ITfThreadMgr_P *pThreadMgr, - CicIMCLock& imcLock, - CicInputContext *pCicIC); - - void PostTransMsg(_In_ HWND hWnd, _In_ INT cTransMsgs, _In_ const TRANSMSG *pTransMsgs); - void GetDocumentManager(_Inout_ CicIMCCLock& imeContext); - - HRESULT - ConfigureGeneral(_Inout_ TLS* pTLS, - _In_ ITfThreadMgr *pThreadMgr, - _In_ HKL hKL, - _In_ HWND hWnd); - HRESULT ConfigureRegisterWord( - _Inout_ TLS* pTLS, - _In_ ITfThreadMgr *pThreadMgr, - _In_ HKL hKL, - _In_ HWND hWnd, - _Inout_opt_ LPVOID lpData); -}; - -class CActiveLanguageProfileNotifySink : public ITfActiveLanguageProfileNotifySink -{ -protected: - typedef INT (CALLBACK *FN_COMPARE)(REFGUID rguid1, REFGUID rguid2, BOOL fActivated, LPVOID pUserData); - LONG m_cRefs; - ITfThreadMgr *m_pThreadMgr; - DWORD m_dwConnection; - FN_COMPARE m_fnCompare; - LPVOID m_pUserData; - -public: - CActiveLanguageProfileNotifySink(_In_ FN_COMPARE fnCompare, _Inout_opt_ void *pUserData); - virtual ~CActiveLanguageProfileNotifySink(); - - HRESULT _Advise(ITfThreadMgr *pThreadMgr); - HRESULT _Unadvise(); - - // IUnknown interface - STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override; - STDMETHODIMP_(ULONG) AddRef() override; - STDMETHODIMP_(ULONG) Release() override; - - // ITfActiveLanguageProfileNotifySink interface - STDMETHODIMP - OnActivated( - REFCLSID clsid, - REFGUID guidProfile, - BOOL fActivated) override; -}; - -/// @implemented -CActiveLanguageProfileNotifySink::CActiveLanguageProfileNotifySink( - _In_ FN_COMPARE fnCompare, - _Inout_opt_ void *pUserData) -{ - m_dwConnection = (DWORD)-1; - m_fnCompare = fnCompare; - m_cRefs = 1; - m_pUserData = pUserData; -} - -/// @implemented -CActiveLanguageProfileNotifySink::~CActiveLanguageProfileNotifySink() -{ -} - -/// @implemented -STDMETHODIMP CActiveLanguageProfileNotifySink::QueryInterface(REFIID riid, LPVOID* ppvObj) -{ - if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfActiveLanguageProfileNotifySink)) - { - *ppvObj = this; - AddRef(); - return S_OK; - } - *ppvObj = NULL; - return E_NOINTERFACE; -} - -/// @implemented -STDMETHODIMP_(ULONG) CActiveLanguageProfileNotifySink::AddRef() -{ - return ::InterlockedIncrement(&m_cRefs); -} - -/// @implemented -STDMETHODIMP_(ULONG) CActiveLanguageProfileNotifySink::Release() -{ - if (::InterlockedDecrement(&m_cRefs) == 0) - { - delete this; - return 0; - } - return m_cRefs; -} - -/// @implemented -STDMETHODIMP -CActiveLanguageProfileNotifySink::OnActivated( - REFCLSID clsid, - REFGUID guidProfile, - BOOL fActivated) -{ - if (!m_fnCompare) - return 0; - - return m_fnCompare(clsid, guidProfile, fActivated, m_pUserData); -} - -/// @implemented -HRESULT -CActiveLanguageProfileNotifySink::_Advise( - ITfThreadMgr *pThreadMgr) -{ - m_pThreadMgr = NULL; - - ITfSource *pSource = NULL; - HRESULT hr = pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource); - if (FAILED(hr)) - return E_FAIL; - - hr = pSource->AdviseSink(IID_ITfActiveLanguageProfileNotifySink, this, &m_dwConnection); - if (SUCCEEDED(hr)) - { - m_pThreadMgr = pThreadMgr; - pThreadMgr->AddRef(); - hr = S_OK; - } - else - { - hr = E_FAIL; - } - - if (pSource) - pSource->Release(); - - return hr; -} - -/// @implemented -HRESULT -CActiveLanguageProfileNotifySink::_Unadvise() -{ - if (!m_pThreadMgr) - return E_FAIL; - - ITfSource *pSource = NULL; - HRESULT hr = m_pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource); - if (SUCCEEDED(hr)) - { - hr = pSource->UnadviseSink(m_dwConnection); - if (SUCCEEDED(hr)) - hr = S_OK; - } - - if (pSource) - pSource->Release(); - - if (m_pThreadMgr) - { - m_pThreadMgr->Release(); - m_pThreadMgr = NULL; - } - - return hr; -} - -/* FIXME */ -class CicProfile : public IUnknown -{ -protected: - ITfInputProcessorProfiles *m_pIPProfiles; - CActiveLanguageProfileNotifySink *m_pActiveLanguageProfileNotifySink; - LANGID m_LangID1; - WORD m_padding1; - DWORD m_dwFlags; - UINT m_nCodePage; - LANGID m_LangID2; - WORD m_padding2; - DWORD m_dwUnknown1; - LONG m_cRefs; - - static INT CALLBACK - ActiveLanguageProfileNotifySinkCallback( - REFGUID rguid1, - REFGUID rguid2, - BOOL fActivated, - LPVOID pUserData); - -public: - CicProfile(); - virtual ~CicProfile(); - - // IUnknown interface - STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override; - STDMETHODIMP_(ULONG) AddRef() override; - STDMETHODIMP_(ULONG) Release() override; - - HRESULT - GetActiveLanguageProfile( - _In_ HKL hKL, - _In_ REFGUID rguid, - _Out_ TF_LANGUAGEPROFILE *pProfile); - HRESULT GetLangId(_Out_ LANGID *pLangID); - HRESULT GetCodePageA(_Out_ UINT *puCodePage); - - HRESULT InitProfileInstance(_Inout_ TLS *pTLS); -}; - -/// @implemented -CicProfile::CicProfile() -{ - m_dwFlags &= 0xFFFFFFF0; - m_cRefs = 1; - m_pIPProfiles = NULL; - m_pActiveLanguageProfileNotifySink = NULL; - m_LangID1 = 0; - m_nCodePage = CP_ACP; - m_LangID2 = 0; - m_dwUnknown1 = 0; -} - -/// @implemented -CicProfile::~CicProfile() -{ - if (m_pIPProfiles) - { - if (m_LangID1) - m_pIPProfiles->ChangeCurrentLanguage(m_LangID1); - - m_pIPProfiles->Release(); - m_pIPProfiles = NULL; - } - - if (m_pActiveLanguageProfileNotifySink) - { - m_pActiveLanguageProfileNotifySink->_Unadvise(); - m_pActiveLanguageProfileNotifySink->Release(); - m_pActiveLanguageProfileNotifySink = NULL; - } -} - -/// @implemented -STDMETHODIMP CicProfile::QueryInterface(REFIID riid, LPVOID* ppvObj) -{ - *ppvObj = NULL; - return E_NOINTERFACE; -} - -/// @implemented -STDMETHODIMP_(ULONG) CicProfile::AddRef() -{ - return ::InterlockedIncrement(&m_cRefs); -} - -/// @implemented -STDMETHODIMP_(ULONG) CicProfile::Release() -{ - if (::InterlockedDecrement(&m_cRefs) == 0) - { - delete this; - return 0; - } - return m_cRefs; -} - -/// @implemented -INT CALLBACK -CicProfile::ActiveLanguageProfileNotifySinkCallback( - REFGUID rguid1, - REFGUID rguid2, - BOOL fActivated, - LPVOID pUserData) -{ - CicProfile *pThis = (CicProfile *)pUserData; - pThis->m_dwFlags &= ~0xE; - return 0; -} - -/// @implemented -HRESULT CicProfile::GetCodePageA(_Out_ UINT *puCodePage) -{ - if (!puCodePage) - return E_INVALIDARG; - - if (m_dwFlags & 2) - { - *puCodePage = m_nCodePage; - return S_OK; - } - - *puCodePage = 0; - - LANGID LangID; - HRESULT hr = GetLangId(&LangID); - if (FAILED(hr)) - return E_FAIL; - - WCHAR szBuff[12]; - INT cch = ::GetLocaleInfoW(LangID, LOCALE_IDEFAULTANSICODEPAGE, szBuff, _countof(szBuff)); - if (cch) - { - szBuff[cch] = 0; - m_nCodePage = *puCodePage = wcstoul(szBuff, NULL, 10); - m_dwFlags |= 2; - } - - return S_OK; -} - -/// @implemented -HRESULT CicProfile::GetLangId(_Out_ LANGID *pLangID) -{ - *pLangID = 0; - - if (!m_pIPProfiles) - return E_FAIL; - - if (m_dwFlags & 4) - { - *pLangID = m_LangID2; - return S_OK; - } - - HRESULT hr = m_pIPProfiles->GetCurrentLanguage(pLangID); - if (SUCCEEDED(hr)) - { - m_dwFlags |= 4; - m_LangID2 = *pLangID; - } - - return hr; -} - -class TLS -{ -public: - static DWORD s_dwTlsIndex; - - DWORD m_dwSystemInfoFlags; - CicBridge *m_pBridge; - CicProfile *m_pProfile; - ITfThreadMgr_P *m_pThreadMgr; - DWORD m_dwFlags1; - DWORD m_dwFlags2; - DWORD m_dwUnknown2; - BOOL m_bDestroyed; - DWORD m_dwNowOpening; - DWORD m_NonEAComposition; - DWORD m_cWnds; - - /** - * @implemented - */ - static BOOL Initialize() - { - s_dwTlsIndex = ::TlsAlloc(); - return s_dwTlsIndex != (DWORD)-1; - } - - /** - * @implemented - */ - static VOID Uninitialize() - { - if (s_dwTlsIndex != (DWORD)-1) - { - ::TlsFree(s_dwTlsIndex); - s_dwTlsIndex = (DWORD)-1; - } - } - - /** - * @implemented - */ - static TLS* GetTLS() - { - if (s_dwTlsIndex == (DWORD)-1) - return NULL; - - return InternalAllocateTLS(); - } - - /** - * @implemented - */ - static TLS* PeekTLS() - { - return (TLS*)::TlsGetValue(TLS::s_dwTlsIndex); - } - - static TLS* InternalAllocateTLS(); - static BOOL InternalDestroyTLS(); - -}; - -DWORD TLS::s_dwTlsIndex = (DWORD)-1; - -/// @implemented -TLS* TLS::InternalAllocateTLS() -{ - TLS *pTLS = TLS::PeekTLS(); - if (pTLS) - return pTLS; - - if (DllShutDownInProgress()) - return NULL; - - pTLS = (TLS *)cicMemAllocClear(sizeof(TLS)); - if (!pTLS) - return NULL; - - if (!::TlsSetValue(s_dwTlsIndex, pTLS)) - { - cicMemFree(pTLS); - return NULL; - } - - pTLS->m_dwFlags1 |= 1; - pTLS->m_dwUnknown2 |= 1; - return pTLS; -} - -/// @implemented -BOOL TLS::InternalDestroyTLS() -{ - TLS *pTLS = TLS::PeekTLS(); - if (!pTLS) - return FALSE; - - if (pTLS->m_pBridge) - pTLS->m_pBridge->Release(); - if (pTLS->m_pProfile) - pTLS->m_pProfile->Release(); - if (pTLS->m_pThreadMgr) - pTLS->m_pThreadMgr->Release(); - - cicMemFree(pTLS); - ::TlsSetValue(s_dwTlsIndex, NULL); - return TRUE; -} - -/// @implemented -HRESULT -CicProfile::InitProfileInstance(_Inout_ TLS *pTLS) -{ - HRESULT hr = TF_CreateInputProcessorProfiles(&m_pIPProfiles); - if (FAILED(hr)) - return hr; - - if (!m_pActiveLanguageProfileNotifySink) - { - CActiveLanguageProfileNotifySink *pSink = - new(cicNoThrow) CActiveLanguageProfileNotifySink( - CicProfile::ActiveLanguageProfileNotifySinkCallback, this); - if (!pSink) - { - m_pIPProfiles->Release(); - m_pIPProfiles = NULL; - return E_FAIL; - } - m_pActiveLanguageProfileNotifySink = pSink; - } - - if (pTLS->m_pThreadMgr) - m_pActiveLanguageProfileNotifySink->_Advise(pTLS->m_pThreadMgr); - - return hr; -} - -/// @implemented -STDMETHODIMP -CicInputContext::OnCleanupContext( - _In_ TfEditCookie ecWrite, - _Inout_ ITfContext *pic) -{ - TLS *pTLS = TLS::PeekTLS(); - if (!pTLS || !pTLS->m_pProfile) - return E_OUTOFMEMORY; - - LANGID LangID; - pTLS->m_pProfile->GetLangId(&LangID); - - IMEINFO IMEInfo; - WCHAR szPath[MAX_PATH]; - if (Inquire(&IMEInfo, szPath, 0, (HKL)UlongToHandle(LangID)) != S_OK) - return E_FAIL; - - ITfProperty *pProp = NULL; - if (!(IMEInfo.fdwProperty & IME_PROP_COMPLETE_ON_UNSELECT)) - return S_OK; - - HRESULT hr = pic->GetProperty(GUID_PROP_COMPOSING, &pProp); - if (FAILED(hr)) - return S_OK; - - IEnumTfRanges *pRanges = NULL; - hr = pProp->EnumRanges(ecWrite, &pRanges, NULL); - if (SUCCEEDED(hr)) - { - ITfRange *pRange = NULL; - while (pRanges->Next(1, &pRange, 0) == S_OK) - { - VARIANT vari; - V_VT(&vari) = VT_EMPTY; - pProp->GetValue(ecWrite, pRange, &vari); - if (V_VT(&vari) == VT_I4) - { - if (V_I4(&vari)) - pProp->Clear(ecWrite, pRange); - } - pRange->Release(); - pRange = NULL; - } - pRanges->Release(); - } - pProp->Release(); - - return S_OK; -} - -/*********************************************************************** - * CicBridge - */ - -CicBridge::CicBridge() -{ - m_bImmxInited = FALSE; - m_bUnknown1 = FALSE; - m_bDeactivating = FALSE; - m_bUnknown2 = FALSE; - m_pKeystrokeMgr = NULL; - m_pDocMgr = NULL; - m_pThreadMgrEventSink = NULL; - m_cliendId = 0; - m_cRefs = 1; -} - -/// @implemented -STDMETHODIMP CicBridge::QueryInterface(REFIID riid, LPVOID* ppvObj) -{ - *ppvObj = NULL; - - if (!IsEqualIID(riid, IID_ITfSysHookSink)) - return E_NOINTERFACE; - - *ppvObj = this; - AddRef(); - - return S_OK; -} - -/// @implemented -STDMETHODIMP_(ULONG) CicBridge::AddRef() -{ - return ::InterlockedIncrement(&m_cRefs); -} - -/// @implemented -STDMETHODIMP_(ULONG) CicBridge::Release() -{ - if (::InterlockedDecrement(&m_cRefs) == 0) - { - delete this; - return 0; - } - return m_cRefs; -} - -/// @implemented -CicBridge::~CicBridge() -{ - TLS *pTLS = TLS::PeekTLS(); - if (!pTLS || !pTLS->m_pThreadMgr) - return; - - if (SUCCEEDED(DeactivateIMMX(pTLS, pTLS->m_pThreadMgr))) - UnInitIMMX(pTLS); -} - -void CicBridge::GetDocumentManager(_Inout_ CicIMCCLock& imeContext) -{ - CicInputContext *pCicIC = imeContext.get().m_pCicIC; - if (pCicIC) - { - m_pDocMgr = pCicIC->m_pDocumentMgr; - m_pDocMgr->AddRef(); - } - else - { - m_pDocMgr->Release(); - m_pDocMgr = NULL; - } -} - -/// @unimplemented -HRESULT -CicBridge::CreateInputContext( - _Inout_ TLS *pTLS, - _In_ HIMC hIMC) -{ - CicIMCLock imcLock(hIMC); - HRESULT hr = imcLock.m_hr; - if (!imcLock) - hr = E_FAIL; - if (FAILED(hr)) - return hr; - - if (!imcLock.get().hCtfImeContext) - { - HIMCC hCtfImeContext = ImmCreateIMCC(sizeof(CTFIMECONTEXT)); - if (!hCtfImeContext) - return E_OUTOFMEMORY; - imcLock.get().hCtfImeContext = hCtfImeContext; - } - - CicIMCCLock imeContext(imcLock.get().hCtfImeContext); - CicInputContext *pCicIC = imeContext.get().m_pCicIC; - if (!pCicIC) - { - pCicIC = new(cicNoThrow) CicInputContext(m_cliendId, &m_LibThread, hIMC); - if (!pCicIC) - { - imeContext.unlock(); - imcLock.unlock(); - DestroyInputContext(pTLS, hIMC); - return E_OUTOFMEMORY; - } - - if (!pTLS->m_pThreadMgr) - { - pCicIC->Release(); - imeContext.unlock(); - imcLock.unlock(); - DestroyInputContext(pTLS, hIMC); - return E_NOINTERFACE; - } - - imeContext.get().m_pCicIC = pCicIC; - } - - hr = pCicIC->CreateInputContext(pTLS->m_pThreadMgr, imcLock); - if (FAILED(hr)) - { - pCicIC->Release(); - imeContext.get().m_pCicIC = NULL; - } - else - { - if (imcLock.get().hWnd && imcLock.get().hWnd == ::GetFocus()) - { - GetDocumentManager(imeContext); - //FIXME - } - } - - return E_NOTIMPL; -} - -/// @implemented -HRESULT CicBridge::DestroyInputContext(TLS *pTLS, HIMC hIMC) -{ - CicIMCLock imcLock(hIMC); - HRESULT hr = imcLock.m_hr; - if (!imcLock) - hr = E_FAIL; - if (FAILED(hr)) - return hr; - - hr = E_FAIL; - CicIMCCLock imeContext(imcLock.get().hCtfImeContext); - if (imeContext) - hr = imeContext.m_hr; - - if (SUCCEEDED(hr) && !(imeContext.get().m_dwCicFlags & 1)) - { - imeContext.get().m_dwCicFlags |= 1; - - CicInputContext *pCicIC = imeContext.get().m_pCicIC; - if (pCicIC) - { - imeContext.get().m_pCicIC = NULL; - hr = pCicIC->DestroyInputContext(); - pCicIC->Release(); - imeContext.get().m_pCicIC = NULL; - } - } - - if (imcLock.get().hCtfImeContext) - { - ImmDestroyIMCC(imcLock.get().hCtfImeContext); - imcLock.get().hCtfImeContext = NULL; - hr = S_OK; - } - - return hr; -} - -ITfContext * -CicBridge::GetInputContext(CicIMCCLock& imeContext) -{ - CicInputContext *pCicIC = imeContext.get().m_pCicIC; - if (!pCicIC) - return NULL; - return pCicIC->m_pContext; -} - -/// @unimplemented -HRESULT CicBridge::OnSetOpenStatus( - TLS *pTLS, - ITfThreadMgr_P *pThreadMgr, - CicIMCLock& imcLock, - CicInputContext *pCicIC) -{ - return E_NOTIMPL; -} - -/// Selects the IME context. -/// @implemented -HRESULT -CicBridge::SelectEx( - _Inout_ TLS *pTLS, - _Inout_ ITfThreadMgr_P *pThreadMgr, - _In_ HIMC hIMC, - _In_ BOOL fSelect, - _In_ HKL hKL) -{ - CicIMCLock imcLock(hIMC); - if (FAILED(imcLock.m_hr)) - return imcLock.m_hr; - - CicIMCCLock imeContext(imcLock.get().hCtfImeContext); - if (!imeContext) - imeContext.m_hr = E_FAIL; - if (FAILED(imeContext.m_hr)) - return imeContext.m_hr; - - CicInputContext *pCicIC = imeContext.get().m_pCicIC; - if (pCicIC) - pCicIC->m_bSelecting = TRUE; - - if (fSelect) - { - if (pCicIC) - pCicIC->m_dwUnknown6[1] &= ~1; - if (imcLock.get().fOpen) - OnSetOpenStatus(pTLS, pThreadMgr, imcLock, pCicIC); - } - else - { - ITfContext *pContext = GetInputContext(imeContext); - pThreadMgr->RequestPostponedLock(pContext); - if (pCicIC) - pCicIC->m_bSelecting = FALSE; - if (pContext) - pContext->Release(); - } - - return imeContext.m_hr; -} - -/// Used in CicBridge::EnumCreateInputContextCallback and -/// CicBridge::EnumDestroyInputContextCallback. -typedef struct ENUM_CREATE_DESTROY_IC -{ - TLS *m_pTLS; - CicBridge *m_pBridge; -} ENUM_CREATE_DESTROY_IC, *PENUM_CREATE_DESTROY_IC; - -/// Creates input context for the current thread. -/// @implemented -BOOL CALLBACK CicBridge::EnumCreateInputContextCallback(HIMC hIMC, LPARAM lParam) -{ - PENUM_CREATE_DESTROY_IC pData = (PENUM_CREATE_DESTROY_IC)lParam; - pData->m_pBridge->CreateInputContext(pData->m_pTLS, hIMC); - return TRUE; -} - -/// Destroys input context for the current thread. -/// @implemented -BOOL CALLBACK CicBridge::EnumDestroyInputContextCallback(HIMC hIMC, LPARAM lParam) -{ - PENUM_CREATE_DESTROY_IC pData = (PENUM_CREATE_DESTROY_IC)lParam; - pData->m_pBridge->DestroyInputContext(pData->m_pTLS, hIMC); - return TRUE; -} - -/// @implemented -HRESULT -CicBridge::ActivateIMMX( - _Inout_ TLS *pTLS, - _Inout_ ITfThreadMgr_P *pThreadMgr) -{ - HRESULT hr = pThreadMgr->ActivateEx(&m_cliendId, 1); - if (hr != S_OK) - { - m_cliendId = 0; - return E_FAIL; - } - - if (m_cActivateLocks++ != 0) - return S_OK; - - ITfSourceSingle *pSource = NULL; - hr = pThreadMgr->QueryInterface(IID_ITfSourceSingle, (void**)&pSource); - if (FAILED(hr)) - { - DeactivateIMMX(pTLS, pThreadMgr); - return hr; - } - - CFunctionProvider *pProvider = new(cicNoThrow) CFunctionProvider(m_cliendId); - if (!pProvider) - { - hr = E_FAIL; - goto Finish; - } - - pSource->AdviseSingleSink(m_cliendId, IID_ITfFunctionProvider, pProvider); - pProvider->Release(); - - if (!m_pDocMgr) - { - hr = pThreadMgr->CreateDocumentMgr(&m_pDocMgr); - if (FAILED(hr)) - { - hr = E_FAIL; - goto Finish; - } - - SetCompartmentDWORD(m_cliendId, m_pDocMgr, GUID_COMPARTMENT_CTFIME_DIMFLAGS, TRUE, FALSE); - } - - pThreadMgr->SetSysHookSink(this); - - hr = S_OK; - if (pTLS->m_bDestroyed) - { - ENUM_CREATE_DESTROY_IC Data = { pTLS, this }; - ImmEnumInputContext(0, CicBridge::EnumCreateInputContextCallback, (LPARAM)&Data); - } - -Finish: - if (FAILED(hr)) - DeactivateIMMX(pTLS, pThreadMgr); - if (pSource) - pSource->Release(); - return hr; -} - -/// @implemented -HRESULT -CicBridge::DeactivateIMMX( - _Inout_ TLS *pTLS, - _Inout_ ITfThreadMgr_P *pThreadMgr) -{ - if (m_bDeactivating) - return TRUE; - - m_bDeactivating = TRUE; - - if (m_cliendId) - { - ENUM_CREATE_DESTROY_IC Data = { pTLS, this }; - ImmEnumInputContext(0, CicBridge::EnumDestroyInputContextCallback, (LPARAM)&Data); - pTLS->m_bDestroyed = TRUE; - - ITfSourceSingle *pSource = NULL; - if (pThreadMgr->QueryInterface(IID_ITfSourceSingle, (void **)&pSource) == S_OK) - pSource->UnadviseSingleSink(m_cliendId, IID_ITfFunctionProvider); - - m_cliendId = 0; - - while (m_cActivateLocks > 0) - { - --m_cActivateLocks; - pThreadMgr->Deactivate(); - } - - if (pSource) - pSource->Release(); - } - - if (m_pDocMgr) - { - m_pDocMgr->Release(); - m_pDocMgr = NULL; - } - - pThreadMgr->SetSysHookSink(NULL); - - m_bDeactivating = FALSE; - - return S_OK; -} - -/// @implemented -HRESULT -CicBridge::InitIMMX(_Inout_ TLS *pTLS) -{ - if (m_bImmxInited) - return S_OK; - - HRESULT hr = S_OK; - if (!pTLS->m_pThreadMgr) - { - ITfThreadMgr *pThreadMgr = NULL; - hr = TF_CreateThreadMgr(&pThreadMgr); - if (FAILED(hr)) - return E_FAIL; - - hr = pThreadMgr->QueryInterface(IID_ITfThreadMgr_P, (void **)&pTLS->m_pThreadMgr); - if (pThreadMgr) - pThreadMgr->Release(); - if (FAILED(hr)) - return E_FAIL; - } - - if (!m_pThreadMgrEventSink) - { - m_pThreadMgrEventSink = - new(cicNoThrow) CThreadMgrEventSink(CThreadMgrEventSink::DIMCallback, NULL, NULL); - if (!m_pThreadMgrEventSink) - { - UnInitIMMX(pTLS); - return E_FAIL; - } - } - - m_pThreadMgrEventSink->SetCallbackPV(m_pThreadMgrEventSink); - m_pThreadMgrEventSink->_Advise(pTLS->m_pThreadMgr); - - if (!pTLS->m_pProfile) - { - pTLS->m_pProfile = new(cicNoThrow) CicProfile(); - if (!pTLS->m_pProfile) - return E_OUTOFMEMORY; - - hr = pTLS->m_pProfile->InitProfileInstance(pTLS); - if (FAILED(hr)) - { - UnInitIMMX(pTLS); - return E_FAIL; - } - } - - hr = pTLS->m_pThreadMgr->QueryInterface(IID_ITfKeystrokeMgr_P, (void **)&m_pKeystrokeMgr); - if (FAILED(hr)) - { - UnInitIMMX(pTLS); - return E_FAIL; - } - - hr = InitDisplayAttrbuteLib(&m_LibThread); - if (FAILED(hr)) - { - UnInitIMMX(pTLS); - return E_FAIL; - } - - m_bImmxInited = TRUE; - return S_OK; -} - -/// @implemented -BOOL CicBridge::UnInitIMMX(_Inout_ TLS *pTLS) -{ - UninitDisplayAttrbuteLib(&m_LibThread); - TFUninitLib_Thread(&m_LibThread); - - if (m_pKeystrokeMgr) - { - m_pKeystrokeMgr->Release(); - m_pKeystrokeMgr = NULL; - } - - if (pTLS->m_pProfile) - { - pTLS->m_pProfile->Release(); - pTLS->m_pProfile = NULL; - } - - if (m_pThreadMgrEventSink) - { - m_pThreadMgrEventSink->_Unadvise(); - m_pThreadMgrEventSink->Release(); - m_pThreadMgrEventSink = NULL; - } - - if (pTLS->m_pThreadMgr) - { - pTLS->m_pThreadMgr->Release(); - pTLS->m_pThreadMgr = NULL; - } - - m_bImmxInited = FALSE; - return TRUE; -} - -/// @implemented -STDMETHODIMP CicBridge::OnPreFocusDIM(HWND hwnd) -{ - return S_OK; -} - -/// @unimplemented -STDMETHODIMP CicBridge::OnSysKeyboardProc(UINT, LONG) -{ - return E_NOTIMPL; -} - -/// @implemented -STDMETHODIMP CicBridge::OnSysShellProc(INT, UINT, LONG) -{ - return S_OK; + return hr; } -/// @implemented -void -CicBridge::PostTransMsg( - _In_ HWND hWnd, - _In_ INT cTransMsgs, - _In_ const TRANSMSG *pTransMsgs) +HIMC GetActiveContext(VOID) { - for (INT i = 0; i < cTransMsgs; ++i, ++pTransMsgs) - { - ::PostMessageW(hWnd, pTransMsgs->message, pTransMsgs->wParam, pTransMsgs->lParam); - } + HWND hwndFocus = ::GetFocus(); + if (!hwndFocus) + hwndFocus = ::GetActiveWindow(); + return ::ImmGetContext(hwndFocus); } /// @implemented -HRESULT -CicBridge::ConfigureGeneral( - _Inout_ TLS* pTLS, - _In_ ITfThreadMgr *pThreadMgr, - _In_ HKL hKL, - _In_ HWND hWnd) +HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread) { - CicProfile *pProfile = pTLS->m_pProfile; - if (!pProfile) - return E_OUTOFMEMORY; - - TF_LANGUAGEPROFILE profile; - HRESULT hr = pProfile->GetActiveLanguageProfile(hKL, GUID_TFCAT_TIP_KEYBOARD, &profile); - if (FAILED(hr)) - return hr; - - ITfFunctionProvider *pProvider = NULL; - hr = pThreadMgr->GetFunctionProvider(profile.clsid, &pProvider); - if (FAILED(hr)) - return hr; + if (!pLibThread) + return E_FAIL; - ITfFnConfigure *pFnConfigure = NULL; - hr = pProvider->GetFunction(GUID_NULL, IID_ITfFnConfigure, (IUnknown**)&pFnConfigure); - if (FAILED(hr)) + if (pLibThread->m_pDisplayAttrMgr) { - pProvider->Release(); - return hr; + pLibThread->m_pDisplayAttrMgr->Release(); + pLibThread->m_pDisplayAttrMgr = NULL; } - hr = pFnConfigure->Show(hWnd, profile.langid, profile.guidProfile); + return S_OK; +} - pFnConfigure->Release(); - pProvider->Release(); - return hr; +/// Gets the charset from a language ID. +/// @implemented +BYTE GetCharsetFromLangId(_In_ DWORD dwValue) +{ + CHARSETINFO info; + if (!::TranslateCharsetInfo((DWORD*)(DWORD_PTR)dwValue, &info, TCI_SRCLOCALE)) + return 0; + return info.ciCharset; } +/// Selects or unselects the input context. /// @implemented HRESULT -CicBridge::ConfigureRegisterWord( - _Inout_ TLS* pTLS, - _In_ ITfThreadMgr *pThreadMgr, - _In_ HKL hKL, - _In_ HWND hWnd, - _Inout_opt_ LPVOID lpData) +InternalSelectEx( + _In_ HIMC hIMC, + _In_ BOOL fSelect, + _In_ LANGID LangID) { - CicProfile *pProfile = pTLS->m_pProfile; - if (!pProfile) - return E_OUTOFMEMORY; - - TF_LANGUAGEPROFILE profile; - HRESULT hr = pProfile->GetActiveLanguageProfile(hKL, GUID_TFCAT_TIP_KEYBOARD, &profile); - if (FAILED(hr)) - return hr; + CicIMCLock imcLock(hIMC); + if (!imcLock) + imcLock.m_hr = E_FAIL; + if (FAILED(imcLock.m_hr)) + return imcLock.m_hr; - ITfFunctionProvider *pProvider = NULL; - hr = pThreadMgr->GetFunctionProvider(profile.clsid, &pProvider); - if (FAILED(hr)) - return hr; + if (PRIMARYLANGID(LangID) == LANG_CHINESE) + { + imcLock.get().cfCandForm[0].dwStyle = 0; + imcLock.get().cfCandForm[0].dwIndex = (DWORD)-1; + } - ITfFnConfigureRegisterWord *pFunction = NULL; - hr = pProvider->GetFunction(GUID_NULL, IID_ITfFnConfigureRegisterWord, (IUnknown**)&pFunction); - if (FAILED(hr)) + if (!fSelect) { - pProvider->Release(); - return hr; + imcLock.get().fdwInit &= ~INIT_GUIDMAP; + return imcLock.m_hr; } - REGISTERWORDW* pRegWord = (REGISTERWORDW*)lpData; - if (pRegWord) + if (!imcLock.ClearCand()) + return imcLock.m_hr; + + // Populate conversion mode + if (!(imcLock.get().fdwInit & INIT_CONVERSION)) { - if (pRegWord->lpWord) + DWORD dwConv = (imcLock.get().fdwConversion & IME_CMODE_SOFTKBD); + if (LangID) { - hr = E_OUTOFMEMORY; - BSTR bstrWord = SysAllocString(pRegWord->lpWord); - if (bstrWord) + if (PRIMARYLANGID(LangID) == LANG_JAPANESE) { - hr = pFunction->Show(hWnd, profile.langid, profile.guidProfile, bstrWord); - SysFreeString(bstrWord); + dwConv |= IME_CMODE_ROMAN | IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE; + } + else if (PRIMARYLANGID(LangID) != LANG_KOREAN) + { + dwConv |= IME_CMODE_NATIVE; } } - else - { - hr = pFunction->Show(hWnd, profile.langid, profile.guidProfile, NULL); - } + imcLock.get().fdwConversion |= dwConv; + imcLock.get().fdwInit |= INIT_CONVERSION; } - pProvider->Release(); - pFunction->Release(); - return hr; -} + // Populate sentence mode + imcLock.get().fdwSentence |= IME_SMODE_PHRASEPREDICT; -/*********************************************************************** - * CicProfile - */ + // Populate LOGFONT + if (!(imcLock.get().fdwInit & INIT_LOGFONT)) + { + // Get logical font + LOGFONTW lf; + HDC hDC = ::GetDC(imcLock.get().hWnd); + HGDIOBJ hFont = GetCurrentObject(hDC, OBJ_FONT); + ::GetObjectW(hFont, sizeof(LOGFONTW), &lf); + ::ReleaseDC(imcLock.get().hWnd, hDC); -/// @unimplemented -HRESULT -CicProfile::GetActiveLanguageProfile( - _In_ HKL hKL, - _In_ REFGUID rguid, - _Out_ TF_LANGUAGEPROFILE *pProfile) -{ - return E_NOTIMPL; + imcLock.get().lfFont.W = lf; + imcLock.get().fdwInit |= INIT_LOGFONT; + } + imcLock.get().lfFont.W.lfCharSet = GetCharsetFromLangId(LangID); + + imcLock.InitContext(); + + return imcLock.m_hr; } +class TLS; + /*********************************************************************** * ImeInquire (MSCTFIME.@) * @@ -3273,377 +858,25 @@ CtfImeThreadDetach(VOID) return S_OK; } -/*********************************************************************** - * UIComposition - */ -struct UIComposition -{ - void OnImeStartComposition(CicIMCLock& imcLock, HWND hUIWnd); - void OnImeCompositionUpdate(CicIMCLock& imcLock); - void OnImeEndComposition(); - void OnImeSetContext(CicIMCLock& imcLock, HWND hUIWnd, WPARAM wParam, LPARAM lParam); - void OnPaintTheme(WPARAM wParam); - void OnDestroy(); - - static LRESULT CALLBACK CompWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -}; - -/// @unimplemented -void UIComposition::OnImeStartComposition(CicIMCLock& imcLock, HWND hUIWnd) -{ - //FIXME -} - -/// @unimplemented -void UIComposition::OnImeCompositionUpdate(CicIMCLock& imcLock) -{ - //FIXME -} - -/// @unimplemented -void UIComposition::OnImeEndComposition() -{ - //FIXME -} - -/// @unimplemented -void UIComposition::OnImeSetContext(CicIMCLock& imcLock, HWND hUIWnd, WPARAM wParam, LPARAM lParam) -{ - //FIXME -} - -/// @unimplemented -void UIComposition::OnPaintTheme(WPARAM wParam) -{ - //FIXME -} - -/// @unimplemented -void UIComposition::OnDestroy() -{ - //FIXME -} - -/// @unimplemented -LRESULT CALLBACK -UIComposition::CompWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (uMsg == WM_CREATE) - return -1; // FIXME - return 0; -} - -/*********************************************************************** - * UI - */ -struct UI -{ - HWND m_hWnd; - UIComposition *m_pComp; - - UI(HWND hWnd); - virtual ~UI(); - - HRESULT _Create(); - void _Destroy(); - - static void OnCreate(HWND hWnd); - static void OnDestroy(HWND hWnd); - void OnImeSetContext(CicIMCLock& imcLock, WPARAM wParam, LPARAM lParam); -}; - -// For GetWindowLongPtr/SetWindowLongPtr -#define UIGWLP_HIMC 0 -#define UIGWLP_UI sizeof(HIMC) -#define UIGWLP_SIZE (UIGWLP_UI + sizeof(UI*)) - -/// @implemented -UI::UI(HWND hWnd) : m_hWnd(hWnd) -{ -} - -/// @implemented -UI::~UI() -{ - delete m_pComp; -} - -/// @unimplemented -HRESULT UI::_Create() -{ - m_pComp = new(cicNoThrow) UIComposition(); - if (!m_pComp) - return E_OUTOFMEMORY; - - SetWindowLongPtrW(m_hWnd, UIGWLP_UI, (LONG_PTR)this); - //FIXME - return S_OK; -} - /// @implemented -void UI::_Destroy() -{ - m_pComp->OnDestroy(); - SetWindowLongPtrW(m_hWnd, UIGWLP_UI, 0); -} - -/// @implemented -void UI::OnCreate(HWND hWnd) -{ - UI *pUI = (UI*)GetWindowLongPtrW(hWnd, UIGWLP_UI); - if (pUI) - return; - pUI = new(cicNoThrow) UI(hWnd); - if (pUI) - pUI->_Create(); -} - -/// @implemented -void UI::OnDestroy(HWND hWnd) -{ - UI *pUI = (UI*)GetWindowLongPtrW(hWnd, UIGWLP_UI); - if (!pUI) - return; - - pUI->_Destroy(); - delete pUI; -} - -/// @implemented -void UI::OnImeSetContext(CicIMCLock& imcLock, WPARAM wParam, LPARAM lParam) -{ - m_pComp->OnImeSetContext(imcLock, m_hWnd, wParam, lParam); -} - -/*********************************************************************** - * CIMEUIWindowHandler - */ - -struct CIMEUIWindowHandler -{ - static LRESULT CALLBACK ImeUIMsImeHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - static LRESULT CALLBACK ImeUIMsImeMouseHandler(HWND hWnd, WPARAM wParam, LPARAM lParam); - static LRESULT CALLBACK ImeUIMsImeModeBiasHandler(HWND hWnd, WPARAM wParam, LPARAM lParam); - static LRESULT CALLBACK ImeUIMsImeReconvertRequest(HWND hWnd, WPARAM wParam, LPARAM lParam); - static LRESULT CALLBACK ImeUIWndProcWorker(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -}; - -/// @unimplemented -LRESULT CALLBACK -CIMEUIWindowHandler::ImeUIMsImeMouseHandler(HWND hWnd, WPARAM wParam, LPARAM lParam) -{ - return 0; //FIXME -} - -/// @unimplemented -LRESULT CALLBACK -CIMEUIWindowHandler::ImeUIMsImeModeBiasHandler(HWND hWnd, WPARAM wParam, LPARAM lParam) -{ - return 0; //FIXME -} - -/// @unimplemented -LRESULT CALLBACK -CIMEUIWindowHandler::ImeUIMsImeReconvertRequest(HWND hWnd, WPARAM wParam, LPARAM lParam) -{ - return 0; //FIXME -} - -/// @implemented -LRESULT CALLBACK -CIMEUIWindowHandler::ImeUIMsImeHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (uMsg == WM_MSIME_MOUSE) - return ImeUIMsImeMouseHandler(hWnd, wParam, lParam); - if (uMsg == WM_MSIME_MODEBIAS) - return ImeUIMsImeModeBiasHandler(hWnd, wParam, lParam); - if (uMsg == WM_MSIME_RECONVERTREQUEST) - return ImeUIMsImeReconvertRequest(hWnd, wParam, lParam); - if (uMsg == WM_MSIME_SERVICE) - { - TLS *pTLS = TLS::GetTLS(); - if (pTLS && pTLS->m_pProfile) - { - LANGID LangID; - pTLS->m_pProfile->GetLangId(&LangID); - if (PRIMARYLANGID(LangID) == LANG_KOREAN) - return FALSE; - } - return TRUE; - } - return 0; -} - -/// @unimplemented -LRESULT CALLBACK -CIMEUIWindowHandler::ImeUIWndProcWorker(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +BOOL AttachIME(VOID) { - TLS *pTLS = TLS::GetTLS(); - if (pTLS && (pTLS->m_dwSystemInfoFlags & IME_SYSINFO_WINLOGON)) - { - if (uMsg == WM_CREATE) - return -1; - return DefWindowProcW(hWnd, uMsg, wParam, lParam); - } - - switch (uMsg) - { - case WM_CREATE: - { - UI::OnCreate(hWnd); - break; - } - case WM_DESTROY: - case WM_ENDSESSION: - { - UI::OnDestroy(hWnd); - break; - } - case WM_IME_STARTCOMPOSITION: - case WM_IME_COMPOSITION: - case WM_IME_ENDCOMPOSITION: - case WM_IME_SETCONTEXT: - case WM_IME_NOTIFY: - case WM_IME_SELECT: - case WM_TIMER: - { - HIMC hIMC = (HIMC)GetWindowLongPtrW(hWnd, UIGWLP_HIMC); - UI* pUI = (UI*)GetWindowLongPtrW(hWnd, UIGWLP_UI); - CicIMCLock imcLock(hIMC); - switch (uMsg) - { - case WM_IME_STARTCOMPOSITION: - { - pUI->m_pComp->OnImeStartComposition(imcLock, pUI->m_hWnd); - break; - } - case WM_IME_COMPOSITION: - { - if (lParam & GCS_COMPSTR) - { - pUI->m_pComp->OnImeCompositionUpdate(imcLock); - ::SetTimer(hWnd, 0, 10, NULL); - //FIXME - } - break; - } - case WM_IME_ENDCOMPOSITION: - { - ::KillTimer(hWnd, 0); - pUI->m_pComp->OnImeEndComposition(); - break; - } - case WM_IME_SETCONTEXT: - { - pUI->OnImeSetContext(imcLock, wParam, lParam); - ::KillTimer(hWnd, 1); - ::SetTimer(hWnd, 1, 300, NULL); - break; - } - case WM_TIMER: - { - //FIXME - ::KillTimer(hWnd, wParam); - break; - } - case WM_IME_NOTIFY: - case WM_IME_SELECT: - default: - { - pUI->m_pComp->OnPaintTheme(wParam); - break; - } - } - break; - } - default: - { - if (IsMsImeMessage(uMsg)) - return CIMEUIWindowHandler::ImeUIMsImeHandler(hWnd, uMsg, wParam, lParam); - return DefWindowProcW(hWnd, uMsg, wParam, lParam); - } - } - - return 0; + return RegisterImeClass() && RegisterMSIMEMessage(); } /// @implemented -EXTERN_C LRESULT CALLBACK -UIWndProc( - _In_ HWND hWnd, - _In_ UINT uMsg, - _In_ WPARAM wParam, - _In_ LPARAM lParam) +VOID DetachIME(VOID) { - return CIMEUIWindowHandler::ImeUIWndProcWorker(hWnd, uMsg, wParam, lParam); + UnregisterImeClass(); } -/// @unimplemented -BOOL RegisterImeClass(VOID) +EXTERN_C VOID TFUninitLib(VOID) { - WNDCLASSEXW wcx; - - if (!GetClassInfoExW(g_hInst, L"MSCTFIME UI", &wcx)) - { - ZeroMemory(&wcx, sizeof(wcx)); - wcx.cbSize = sizeof(WNDCLASSEXW); - wcx.cbWndExtra = UIGWLP_SIZE; - wcx.hIcon = LoadIconW(0, (LPCWSTR)IDC_ARROW); - wcx.hInstance = g_hInst; - wcx.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW); - wcx.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH); - wcx.style = CS_IME | CS_GLOBALCLASS; - wcx.lpfnWndProc = UIWndProc; - wcx.lpszClassName = L"MSCTFIME UI"; - if (!RegisterClassExW(&wcx)) - return FALSE; - } - - if (!GetClassInfoExW(g_hInst, L"MSCTFIME Composition", &wcx)) + if (g_pPropCache) { - ZeroMemory(&wcx, sizeof(wcx)); - wcx.cbSize = sizeof(WNDCLASSEXW); - wcx.cbWndExtra = sizeof(DWORD); - wcx.hIcon = NULL; - wcx.hInstance = g_hInst; - wcx.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_IBEAM); - wcx.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH); - wcx.style = CS_IME | CS_HREDRAW | CS_VREDRAW; - wcx.lpfnWndProc = UIComposition::CompWndProc; - wcx.lpszClassName = L"MSCTFIME Composition"; - if (!RegisterClassExW(&wcx)) - return FALSE; + delete g_pPropCache; + g_pPropCache = NULL; } - - return TRUE; -} - -/// @implemented -VOID UnregisterImeClass(VOID) -{ - WNDCLASSEXW wcx; - - GetClassInfoExW(g_hInst, L"MSCTFIME UI", &wcx); - UnregisterClassW(L"MSCTFIME UI", g_hInst); - DestroyIcon(wcx.hIcon); - DestroyIcon(wcx.hIconSm); - - GetClassInfoExW(g_hInst, L"MSCTFIME Composition", &wcx); - UnregisterClassW(L"MSCTFIME Composition", g_hInst); - DestroyIcon(wcx.hIcon); - DestroyIcon(wcx.hIconSm); -} - -/// @implemented -BOOL AttachIME(VOID) -{ - return RegisterImeClass() && RegisterMSIMEMessage(); -} - -/// @implemented -VOID DetachIME(VOID) -{ - UnregisterImeClass(); } /// @implemented @@ -3667,11 +900,9 @@ BOOL ProcessAttach(HINSTANCE hinstDLL) return AttachIME(); } -/// @unimplemented +/// @implemented VOID ProcessDetach(HINSTANCE hinstDLL) { - // FIXME - TF_DllDetachInOther(); if (gfTFInitLib) diff --git a/dll/ime/msctfime/msctfime.h b/dll/ime/msctfime/msctfime.h index 040ecc11c96..f7ada8fbd6e 100644 --- a/dll/ime/msctfime/msctfime.h +++ b/dll/ime/msctfime/msctfime.h @@ -34,6 +34,23 @@ #include +EXTERN_C BOOLEAN WINAPI DllShutdownInProgress(VOID); + +HRESULT InitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread); +HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread); + +DEFINE_GUID(GUID_COMPARTMENT_CTFIME_DIMFLAGS, 0xA94C5FD2, 0xC471, 0x4031, 0x95, 0x46, 0x70, 0x9C, 0x17, 0x30, 0x0C, 0xB9); +DEFINE_GUID(GUID_COMPARTMENT_CTFIME_CICINPUTCONTEXT, 0x85A688F7, 0x6DC8, 0x4F17, 0xA8, 0x3A, 0xB1, 0x1C, 0x09, 0xCD, 0xD7, 0xBF); + #include "resource.h" +#include "bridge.h" +#include "compartment.h" +#include "functions.h" +#include "inputcontext.h" +#include "profile.h" +#include "sinks.h" +#include "tls.h" +#include "ui.h" + extern HINSTANCE g_hInst; diff --git a/dll/ime/msctfime/profile.cpp b/dll/ime/msctfime/profile.cpp new file mode 100644 index 00000000000..9ec7cd12ff3 --- /dev/null +++ b/dll/ime/msctfime/profile.cpp @@ -0,0 +1,173 @@ +/* + * PROJECT: ReactOS msctfime.ime + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Profile of msctfime.ime + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#include "msctfime.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msctfime); + +/// @implemented +CicProfile::CicProfile() +{ + m_dwFlags &= 0xFFFFFFF0; + m_cRefs = 1; + m_pIPProfiles = NULL; + m_pActiveLanguageProfileNotifySink = NULL; + m_LangID1 = 0; + m_nCodePage = CP_ACP; + m_LangID2 = 0; + m_dwUnknown1 = 0; +} + +/// @implemented +CicProfile::~CicProfile() +{ + if (m_pIPProfiles) + { + if (m_LangID1) + m_pIPProfiles->ChangeCurrentLanguage(m_LangID1); + + m_pIPProfiles->Release(); + m_pIPProfiles = NULL; + } + + if (m_pActiveLanguageProfileNotifySink) + { + m_pActiveLanguageProfileNotifySink->_Unadvise(); + m_pActiveLanguageProfileNotifySink->Release(); + m_pActiveLanguageProfileNotifySink = NULL; + } +} + +/// @implemented +STDMETHODIMP CicProfile::QueryInterface(REFIID riid, LPVOID* ppvObj) +{ + *ppvObj = NULL; + return E_NOINTERFACE; +} + +/// @implemented +STDMETHODIMP_(ULONG) CicProfile::AddRef() +{ + return ::InterlockedIncrement(&m_cRefs); +} + +/// @implemented +STDMETHODIMP_(ULONG) CicProfile::Release() +{ + if (::InterlockedDecrement(&m_cRefs) == 0) + { + delete this; + return 0; + } + return m_cRefs; +} + +/// @implemented +INT CALLBACK +CicProfile::ActiveLanguageProfileNotifySinkCallback( + REFGUID rguid1, + REFGUID rguid2, + BOOL fActivated, + LPVOID pUserData) +{ + CicProfile *pThis = (CicProfile *)pUserData; + pThis->m_dwFlags &= ~0xE; + return 0; +} + +/// @implemented +HRESULT CicProfile::GetCodePageA(_Out_ UINT *puCodePage) +{ + if (!puCodePage) + return E_INVALIDARG; + + if (m_dwFlags & 2) + { + *puCodePage = m_nCodePage; + return S_OK; + } + + *puCodePage = 0; + + LANGID LangID; + HRESULT hr = GetLangId(&LangID); + if (FAILED(hr)) + return E_FAIL; + + WCHAR szBuff[12]; + INT cch = ::GetLocaleInfoW(LangID, LOCALE_IDEFAULTANSICODEPAGE, szBuff, _countof(szBuff)); + if (cch) + { + szBuff[cch] = 0; + m_nCodePage = *puCodePage = wcstoul(szBuff, NULL, 10); + m_dwFlags |= 2; + } + + return S_OK; +} + +/// @implemented +HRESULT CicProfile::GetLangId(_Out_ LANGID *pLangID) +{ + *pLangID = 0; + + if (!m_pIPProfiles) + return E_FAIL; + + if (m_dwFlags & 4) + { + *pLangID = m_LangID2; + return S_OK; + } + + HRESULT hr = m_pIPProfiles->GetCurrentLanguage(pLangID); + if (SUCCEEDED(hr)) + { + m_dwFlags |= 4; + m_LangID2 = *pLangID; + } + + return hr; +} + +/// @implemented +HRESULT +CicProfile::InitProfileInstance(_Inout_ TLS *pTLS) +{ + HRESULT hr = TF_CreateInputProcessorProfiles(&m_pIPProfiles); + if (FAILED(hr)) + return hr; + + if (!m_pActiveLanguageProfileNotifySink) + { + CActiveLanguageProfileNotifySink *pSink = + new(cicNoThrow) CActiveLanguageProfileNotifySink( + CicProfile::ActiveLanguageProfileNotifySinkCallback, this); + if (!pSink) + { + m_pIPProfiles->Release(); + m_pIPProfiles = NULL; + return E_FAIL; + } + m_pActiveLanguageProfileNotifySink = pSink; + } + + if (pTLS->m_pThreadMgr) + m_pActiveLanguageProfileNotifySink->_Advise(pTLS->m_pThreadMgr); + + return hr; +} + +/// @unimplemented +HRESULT +CicProfile::GetActiveLanguageProfile( + _In_ HKL hKL, + _In_ REFGUID rguid, + _Out_ TF_LANGUAGEPROFILE *pProfile) +{ + return E_NOTIMPL; +} diff --git a/dll/ime/msctfime/profile.h b/dll/ime/msctfime/profile.h new file mode 100644 index 00000000000..2943750ad46 --- /dev/null +++ b/dll/ime/msctfime/profile.h @@ -0,0 +1,51 @@ +/* + * PROJECT: ReactOS msctfime.ime + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Profile of msctfime.ime + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#pragma once + +#include "sinks.h" + +class CicProfile : public IUnknown +{ +protected: + ITfInputProcessorProfiles *m_pIPProfiles; + CActiveLanguageProfileNotifySink *m_pActiveLanguageProfileNotifySink; + LANGID m_LangID1; + WORD m_padding1; + DWORD m_dwFlags; + UINT m_nCodePage; + LANGID m_LangID2; + WORD m_padding2; + DWORD m_dwUnknown1; + LONG m_cRefs; + + static INT CALLBACK + ActiveLanguageProfileNotifySinkCallback( + REFGUID rguid1, + REFGUID rguid2, + BOOL fActivated, + LPVOID pUserData); + +public: + CicProfile(); + virtual ~CicProfile(); + + // IUnknown interface + STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + + HRESULT + GetActiveLanguageProfile( + _In_ HKL hKL, + _In_ REFGUID rguid, + _Out_ TF_LANGUAGEPROFILE *pProfile); + HRESULT GetLangId(_Out_ LANGID *pLangID); + HRESULT GetCodePageA(_Out_ UINT *puCodePage); + + HRESULT InitProfileInstance(_Inout_ TLS *pTLS); +}; diff --git a/dll/ime/msctfime/sinks.cpp b/dll/ime/msctfime/sinks.cpp new file mode 100644 index 00000000000..235079c4d94 --- /dev/null +++ b/dll/ime/msctfime/sinks.cpp @@ -0,0 +1,539 @@ +/* + * PROJECT: ReactOS msctfime.ime + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: The sinks of msctfime.ime + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#include "msctfime.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msctfime); + +/// @implemented +CCompartmentEventSink::CCompartmentEventSink(FN_EVENTSINK fnEventSink, LPVOID pUserData) + : m_array() + , m_cRefs(1) + , m_fnEventSink(fnEventSink) + , m_pUserData(pUserData) +{ +} + +/// @implemented +CCompartmentEventSink::~CCompartmentEventSink() +{ +} + +/// @implemented +STDMETHODIMP CCompartmentEventSink::QueryInterface(REFIID riid, LPVOID* ppvObj) +{ + if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfCompartmentEventSink)) + { + *ppvObj = this; + AddRef(); + return S_OK; + } + + *ppvObj = NULL; + return E_NOINTERFACE; +} + +/// @implemented +STDMETHODIMP_(ULONG) CCompartmentEventSink::AddRef() +{ + return ::InterlockedIncrement(&m_cRefs); +} + +/// @implemented +STDMETHODIMP_(ULONG) CCompartmentEventSink::Release() +{ + if (::InterlockedDecrement(&m_cRefs) == 0) + { + delete this; + return 0; + } + return m_cRefs; +} + +/// @implemented +STDMETHODIMP CCompartmentEventSink::OnChange(REFGUID rguid) +{ + return m_fnEventSink(m_pUserData, rguid); +} + +/// @implemented +HRESULT +CCompartmentEventSink::_Advise(IUnknown *pUnknown, REFGUID rguid, BOOL bThread) +{ + CESMAP *pCesMap = m_array.Append(1); + if (!pCesMap) + return E_OUTOFMEMORY; + + ITfSource *pSource = NULL; + + HRESULT hr = GetCompartment(pUnknown, rguid, &pCesMap->m_pComp, bThread); + if (FAILED(hr)) + { + hr = pCesMap->m_pComp->QueryInterface(IID_ITfSource, (void **)&pSource); + if (FAILED(hr)) + { + hr = pSource->AdviseSink(IID_ITfCompartmentEventSink, this, &pCesMap->m_dwCookie); + if (FAILED(hr)) + { + if (pCesMap->m_pComp) + { + pCesMap->m_pComp->Release(); + pCesMap->m_pComp = NULL; + } + m_array.Remove(m_array.size() - 1, 1); + } + else + { + hr = S_OK; + } + } + } + + if (pSource) + pSource->Release(); + + return hr; +} + +/// @implemented +HRESULT CCompartmentEventSink::_Unadvise() +{ + CESMAP *pCesMap = m_array.data(); + size_t cItems = m_array.size(); + if (!cItems) + return S_OK; + + do + { + ITfSource *pSource = NULL; + HRESULT hr = pCesMap->m_pComp->QueryInterface(IID_ITfSource, (void **)&pSource); + if (SUCCEEDED(hr)) + pSource->UnadviseSink(pCesMap->m_dwCookie); + + if (pCesMap->m_pComp) + { + pCesMap->m_pComp->Release(); + pCesMap->m_pComp = NULL; + } + + if (pSource) + pSource->Release(); + + ++pCesMap; + --cItems; + } while (cItems); + + return S_OK; +} + +/***********************************************************************/ + +/// @implemented +CTextEventSink::CTextEventSink(FN_ENDEDIT fnEndEdit, LPVOID pCallbackPV) +{ + m_cRefs = 1; + m_pUnknown = NULL; + m_dwEditSinkCookie = (DWORD)-1; + m_dwLayoutSinkCookie = (DWORD)-1; + m_fnLayoutChange = NULL; + m_fnEndEdit = fnEndEdit; + m_pCallbackPV = pCallbackPV; +} + +/// @implemented +CTextEventSink::~CTextEventSink() +{ +} + +/// @implemented +STDMETHODIMP CTextEventSink::QueryInterface(REFIID riid, LPVOID* ppvObj) +{ + if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfTextEditSink)) + { + *ppvObj = this; + AddRef(); + return S_OK; + } + if (IsEqualIID(riid, IID_ITfTextLayoutSink)) + { + *ppvObj = static_cast(this); + AddRef(); + return S_OK; + } + return E_NOINTERFACE; +} + +/// @implemented +STDMETHODIMP_(ULONG) CTextEventSink::AddRef() +{ + return ::InterlockedIncrement(&m_cRefs); +} + +/// @implemented +STDMETHODIMP_(ULONG) CTextEventSink::Release() +{ + if (::InterlockedDecrement(&m_cRefs) == 0) + { + delete this; + return 0; + } + return m_cRefs; +} + +struct TEXT_EVENT_SINK_END_EDIT +{ + TfEditCookie m_ecReadOnly; + ITfEditRecord *m_pEditRecord; + ITfContext *m_pContext; +}; + +/// @implemented +STDMETHODIMP CTextEventSink::OnEndEdit( + ITfContext *pic, + TfEditCookie ecReadOnly, + ITfEditRecord *pEditRecord) +{ + TEXT_EVENT_SINK_END_EDIT Data = { ecReadOnly, pEditRecord, pic }; + return m_fnEndEdit(1, m_pCallbackPV, (LPVOID)&Data); +} + +/// @implemented +STDMETHODIMP CTextEventSink::OnLayoutChange( + ITfContext *pContext, + TfLayoutCode lcode, + ITfContextView *pContextView) +{ + switch (lcode) + { + case TF_LC_CREATE: + return m_fnLayoutChange(3, m_fnEndEdit, pContextView); + case TF_LC_CHANGE: + return m_fnLayoutChange(2, m_fnEndEdit, pContextView); + case TF_LC_DESTROY: + return m_fnLayoutChange(4, m_fnEndEdit, pContextView); + default: + return E_INVALIDARG; + } +} + +/// @implemented +HRESULT CTextEventSink::_Advise(IUnknown *pUnknown, UINT uFlags) +{ + m_pUnknown = NULL; + m_uFlags = uFlags; + + ITfSource *pSource = NULL; + HRESULT hr = pUnknown->QueryInterface(IID_ITfSource, (void**)&pSource); + if (SUCCEEDED(hr)) + { + ITfTextEditSink *pSink = static_cast(this); + if (uFlags & 1) + hr = pSource->AdviseSink(IID_ITfTextEditSink, pSink, &m_dwEditSinkCookie); + if (SUCCEEDED(hr) && (uFlags & 2)) + hr = pSource->AdviseSink(IID_ITfTextLayoutSink, pSink, &m_dwLayoutSinkCookie); + + if (SUCCEEDED(hr)) + { + m_pUnknown = pUnknown; + pUnknown->AddRef(); + } + else + { + pSource->UnadviseSink(m_dwEditSinkCookie); + } + } + + if (pSource) + pSource->Release(); + + return hr; +} + +/// @implemented +HRESULT CTextEventSink::_Unadvise() +{ + if (!m_pUnknown) + return E_FAIL; + + ITfSource *pSource = NULL; + HRESULT hr = m_pUnknown->QueryInterface(IID_ITfSource, (void**)&pSource); + if (SUCCEEDED(hr)) + { + if (m_uFlags & 1) + hr = pSource->UnadviseSink(m_dwEditSinkCookie); + if (m_uFlags & 2) + hr = pSource->UnadviseSink(m_dwLayoutSinkCookie); + + pSource->Release(); + } + + m_pUnknown->Release(); + m_pUnknown = NULL; + + return E_NOTIMPL; +} + +/***********************************************************************/ + +/// @implemented +CThreadMgrEventSink::CThreadMgrEventSink( + _In_ FN_INITDOCMGR fnInit, + _In_ FN_PUSHPOP fnPushPop, + _Inout_ LPVOID pvCallbackPV) +{ + m_fnInit = fnInit; + m_fnPushPop = fnPushPop; + m_pCallbackPV = pvCallbackPV; + m_cRefs = 1; +} + +/// @implemented +STDMETHODIMP CThreadMgrEventSink::QueryInterface(REFIID riid, LPVOID* ppvObj) +{ + if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfThreadMgrEventSink)) + { + *ppvObj = this; + AddRef(); + return S_OK; + } + *ppvObj = NULL; + return E_NOINTERFACE; +} + +/// @implemented +STDMETHODIMP_(ULONG) CThreadMgrEventSink::AddRef() +{ + return ::InterlockedIncrement(&m_cRefs); +} + +/// @implemented +STDMETHODIMP_(ULONG) CThreadMgrEventSink::Release() +{ + if (::InterlockedDecrement(&m_cRefs) == 0) + { + delete this; + return 0; + } + return m_cRefs; +} + +INT CALLBACK +CThreadMgrEventSink::DIMCallback( + UINT nCode, + ITfDocumentMgr *pDocMgr1, + ITfDocumentMgr *pDocMgr2, + LPVOID pUserData) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CThreadMgrEventSink::OnInitDocumentMgr(ITfDocumentMgr *pdim) +{ + if (!m_fnInit) + return S_OK; + return m_fnInit(0, pdim, NULL, m_pCallbackPV); +} + +STDMETHODIMP CThreadMgrEventSink::OnUninitDocumentMgr(ITfDocumentMgr *pdim) +{ + if (!m_fnInit) + return S_OK; + return m_fnInit(1, pdim, NULL, m_pCallbackPV); +} + +STDMETHODIMP +CThreadMgrEventSink::OnSetFocus(ITfDocumentMgr *pdimFocus, ITfDocumentMgr *pdimPrevFocus) +{ + if (!m_fnInit) + return S_OK; + return m_fnInit(2, pdimFocus, pdimPrevFocus, m_pCallbackPV); +} + +STDMETHODIMP CThreadMgrEventSink::OnPushContext(ITfContext *pic) +{ + if (!m_fnPushPop) + return S_OK; + return m_fnPushPop(3, pic, m_pCallbackPV); +} + +STDMETHODIMP CThreadMgrEventSink::OnPopContext(ITfContext *pic) +{ + if (!m_fnPushPop) + return S_OK; + return m_fnPushPop(4, pic, m_pCallbackPV); +} + +void CThreadMgrEventSink::SetCallbackPV(_Inout_ LPVOID pv) +{ + if (!m_pCallbackPV) + m_pCallbackPV = pv; +} + +HRESULT CThreadMgrEventSink::_Advise(ITfThreadMgr *pThreadMgr) +{ + m_pThreadMgr = NULL; + + HRESULT hr = E_FAIL; + ITfSource *pSource = NULL; + if (pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource) == S_OK && + pSource->AdviseSink(IID_ITfThreadMgrEventSink, this, &m_dwCookie) == S_OK) + { + m_pThreadMgr = pThreadMgr; + pThreadMgr->AddRef(); + hr = S_OK; + } + + if (pSource) + pSource->Release(); + + return hr; +} + +HRESULT CThreadMgrEventSink::_Unadvise() +{ + HRESULT hr = E_FAIL; + ITfSource *pSource = NULL; + + if (m_pThreadMgr) + { + if (m_pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource) == S_OK && + pSource->UnadviseSink(m_dwCookie) == S_OK) + { + hr = S_OK; + } + + if (pSource) + pSource->Release(); + } + + if (m_pThreadMgr) + { + m_pThreadMgr->Release(); + m_pThreadMgr = NULL; + } + + return hr; +} + +/***********************************************************************/ + +/// @implemented +CActiveLanguageProfileNotifySink::CActiveLanguageProfileNotifySink( + _In_ FN_COMPARE fnCompare, + _Inout_opt_ void *pUserData) +{ + m_dwConnection = (DWORD)-1; + m_fnCompare = fnCompare; + m_cRefs = 1; + m_pUserData = pUserData; +} + +/// @implemented +CActiveLanguageProfileNotifySink::~CActiveLanguageProfileNotifySink() +{ +} + +/// @implemented +STDMETHODIMP CActiveLanguageProfileNotifySink::QueryInterface(REFIID riid, LPVOID* ppvObj) +{ + if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfActiveLanguageProfileNotifySink)) + { + *ppvObj = this; + AddRef(); + return S_OK; + } + *ppvObj = NULL; + return E_NOINTERFACE; +} + +/// @implemented +STDMETHODIMP_(ULONG) CActiveLanguageProfileNotifySink::AddRef() +{ + return ::InterlockedIncrement(&m_cRefs); +} + +/// @implemented +STDMETHODIMP_(ULONG) CActiveLanguageProfileNotifySink::Release() +{ + if (::InterlockedDecrement(&m_cRefs) == 0) + { + delete this; + return 0; + } + return m_cRefs; +} + +/// @implemented +STDMETHODIMP +CActiveLanguageProfileNotifySink::OnActivated( + REFCLSID clsid, + REFGUID guidProfile, + BOOL fActivated) +{ + if (!m_fnCompare) + return 0; + + return m_fnCompare(clsid, guidProfile, fActivated, m_pUserData); +} + +/// @implemented +HRESULT +CActiveLanguageProfileNotifySink::_Advise( + ITfThreadMgr *pThreadMgr) +{ + m_pThreadMgr = NULL; + + ITfSource *pSource = NULL; + HRESULT hr = pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource); + if (FAILED(hr)) + return E_FAIL; + + hr = pSource->AdviseSink(IID_ITfActiveLanguageProfileNotifySink, this, &m_dwConnection); + if (SUCCEEDED(hr)) + { + m_pThreadMgr = pThreadMgr; + pThreadMgr->AddRef(); + hr = S_OK; + } + else + { + hr = E_FAIL; + } + + if (pSource) + pSource->Release(); + + return hr; +} + +/// @implemented +HRESULT +CActiveLanguageProfileNotifySink::_Unadvise() +{ + if (!m_pThreadMgr) + return E_FAIL; + + ITfSource *pSource = NULL; + HRESULT hr = m_pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource); + if (SUCCEEDED(hr)) + { + hr = pSource->UnadviseSink(m_dwConnection); + if (SUCCEEDED(hr)) + hr = S_OK; + } + + if (pSource) + pSource->Release(); + + if (m_pThreadMgr) + { + m_pThreadMgr->Release(); + m_pThreadMgr = NULL; + } + + return hr; +} diff --git a/dll/ime/msctfime/sinks.h b/dll/ime/msctfime/sinks.h new file mode 100644 index 00000000000..9d1fb7885c6 --- /dev/null +++ b/dll/ime/msctfime/sinks.h @@ -0,0 +1,166 @@ +/* + * PROJECT: ReactOS msctfime.ime + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: The sinks of msctfime.ime + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#pragma once + +/***********************************************************************/ + +typedef struct CESMAP +{ + ITfCompartment *m_pComp; + DWORD m_dwCookie; +} CESMAP, *PCESMAP; + +typedef INT (CALLBACK *FN_EVENTSINK)(LPVOID, REFGUID); + +class CCompartmentEventSink : public ITfCompartmentEventSink +{ + CicArray m_array; + LONG m_cRefs; + FN_EVENTSINK m_fnEventSink; + LPVOID m_pUserData; + +public: + CCompartmentEventSink(FN_EVENTSINK fnEventSink, LPVOID pUserData); + virtual ~CCompartmentEventSink(); + + HRESULT _Advise(IUnknown *pUnknown, REFGUID rguid, BOOL bThread); + HRESULT _Unadvise(); + + // IUnknown interface + STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + + // ITfCompartmentEventSink interface + STDMETHODIMP OnChange(REFGUID rguid) override; +}; + +/***********************************************************************/ + +typedef INT (CALLBACK *FN_ENDEDIT)(INT, LPVOID, LPVOID); +typedef INT (CALLBACK *FN_LAYOUTCHANGE)(UINT nType, FN_ENDEDIT fnEndEdit, ITfContextView *pView); + +class CTextEventSink : public ITfTextEditSink, ITfTextLayoutSink +{ +protected: + LONG m_cRefs; + IUnknown *m_pUnknown; + DWORD m_dwEditSinkCookie; + DWORD m_dwLayoutSinkCookie; + union + { + UINT m_uFlags; + FN_LAYOUTCHANGE m_fnLayoutChange; + }; + FN_ENDEDIT m_fnEndEdit; + LPVOID m_pCallbackPV; + +public: + CTextEventSink(FN_ENDEDIT fnEndEdit, LPVOID pCallbackPV); + virtual ~CTextEventSink(); + + HRESULT _Advise(IUnknown *pUnknown, UINT uFlags); + HRESULT _Unadvise(); + + // IUnknown interface + STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + + // ITfTextEditSink interface + STDMETHODIMP OnEndEdit( + ITfContext *pic, + TfEditCookie ecReadOnly, + ITfEditRecord *pEditRecord) override; + + // ITfTextLayoutSink interface + STDMETHODIMP + OnLayoutChange( + ITfContext *pContext, + TfLayoutCode lcode, + ITfContextView *pContextView) override; +}; + +/***********************************************************************/ + +typedef INT (CALLBACK *FN_INITDOCMGR)(UINT, ITfDocumentMgr *, ITfDocumentMgr *, LPVOID); +typedef INT (CALLBACK *FN_PUSHPOP)(UINT, ITfContext *, LPVOID); + +class CThreadMgrEventSink : public ITfThreadMgrEventSink +{ +protected: + ITfThreadMgr *m_pThreadMgr; + DWORD m_dwCookie; + FN_INITDOCMGR m_fnInit; + FN_PUSHPOP m_fnPushPop; + DWORD m_dw; + LPVOID m_pCallbackPV; + LONG m_cRefs; + +public: + CThreadMgrEventSink( + _In_ FN_INITDOCMGR fnInit, + _In_ FN_PUSHPOP fnPushPop = NULL, + _Inout_ LPVOID pvCallbackPV = NULL); + virtual ~CThreadMgrEventSink() { } + + void SetCallbackPV(_Inout_ LPVOID pv); + HRESULT _Advise(ITfThreadMgr *pThreadMgr); + HRESULT _Unadvise(); + + // IUnknown interface + STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + + // ITfThreadMgrEventSink interface + STDMETHODIMP OnInitDocumentMgr(ITfDocumentMgr *pdim) override; + STDMETHODIMP OnUninitDocumentMgr(ITfDocumentMgr *pdim) override; + STDMETHODIMP OnSetFocus(ITfDocumentMgr *pdimFocus, ITfDocumentMgr *pdimPrevFocus) override; + STDMETHODIMP OnPushContext(ITfContext *pic) override; + STDMETHODIMP OnPopContext(ITfContext *pic) override; + + static INT CALLBACK DIMCallback( + UINT nCode, + ITfDocumentMgr *pDocMgr1, + ITfDocumentMgr *pDocMgr2, + LPVOID pUserData); +}; + +/***********************************************************************/ + +class CActiveLanguageProfileNotifySink : public ITfActiveLanguageProfileNotifySink +{ +protected: + typedef INT (CALLBACK *FN_COMPARE)(REFGUID rguid1, REFGUID rguid2, BOOL fActivated, + LPVOID pUserData); + LONG m_cRefs; + ITfThreadMgr *m_pThreadMgr; + DWORD m_dwConnection; + FN_COMPARE m_fnCompare; + LPVOID m_pUserData; + +public: + CActiveLanguageProfileNotifySink(_In_ FN_COMPARE fnCompare, _Inout_opt_ void *pUserData); + virtual ~CActiveLanguageProfileNotifySink(); + + HRESULT _Advise(ITfThreadMgr *pThreadMgr); + HRESULT _Unadvise(); + + // IUnknown interface + STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + + // ITfActiveLanguageProfileNotifySink interface + STDMETHODIMP + OnActivated( + REFCLSID clsid, + REFGUID guidProfile, + BOOL fActivated) override; +}; diff --git a/dll/ime/msctfime/tls.cpp b/dll/ime/msctfime/tls.cpp new file mode 100644 index 00000000000..efb6f9726f5 --- /dev/null +++ b/dll/ime/msctfime/tls.cpp @@ -0,0 +1,56 @@ +/* + * PROJECT: ReactOS msctfime.ime + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Thread-local storage + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#include "msctfime.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msctfime); + +DWORD TLS::s_dwTlsIndex = (DWORD)-1; + +/// @implemented +TLS* TLS::InternalAllocateTLS() +{ + TLS *pTLS = TLS::PeekTLS(); + if (pTLS) + return pTLS; + + if (DllShutdownInProgress()) + return NULL; + + pTLS = (TLS *)cicMemAllocClear(sizeof(TLS)); + if (!pTLS) + return NULL; + + if (!::TlsSetValue(s_dwTlsIndex, pTLS)) + { + cicMemFree(pTLS); + return NULL; + } + + pTLS->m_dwFlags1 |= 1; + pTLS->m_dwUnknown2 |= 1; + return pTLS; +} + +/// @implemented +BOOL TLS::InternalDestroyTLS() +{ + TLS *pTLS = TLS::PeekTLS(); + if (!pTLS) + return FALSE; + + if (pTLS->m_pBridge) + pTLS->m_pBridge->Release(); + if (pTLS->m_pProfile) + pTLS->m_pProfile->Release(); + if (pTLS->m_pThreadMgr) + pTLS->m_pThreadMgr->Release(); + + cicMemFree(pTLS); + ::TlsSetValue(s_dwTlsIndex, NULL); + return TRUE; +} diff --git a/dll/ime/msctfime/tls.h b/dll/ime/msctfime/tls.h new file mode 100644 index 00000000000..28f6d427177 --- /dev/null +++ b/dll/ime/msctfime/tls.h @@ -0,0 +1,74 @@ +/* + * PROJECT: ReactOS msctfime.ime + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Thread-local storage + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#pragma once + +class TLS; + +class CicBridge; +class CicProfile; + +class TLS +{ +public: + static DWORD s_dwTlsIndex; + + DWORD m_dwSystemInfoFlags; + CicBridge *m_pBridge; + CicProfile *m_pProfile; + ITfThreadMgr_P *m_pThreadMgr; + DWORD m_dwFlags1; + DWORD m_dwFlags2; + DWORD m_dwUnknown2; + BOOL m_bDestroyed; + DWORD m_dwNowOpening; + DWORD m_NonEAComposition; + DWORD m_cWnds; + + /** + * @implemented + */ + static BOOL Initialize() + { + s_dwTlsIndex = ::TlsAlloc(); + return s_dwTlsIndex != (DWORD)-1; + } + + /** + * @implemented + */ + static VOID Uninitialize() + { + if (s_dwTlsIndex != (DWORD)-1) + { + ::TlsFree(s_dwTlsIndex); + s_dwTlsIndex = (DWORD)-1; + } + } + + /** + * @implemented + */ + static TLS* GetTLS() + { + if (s_dwTlsIndex == (DWORD)-1) + return NULL; + + return InternalAllocateTLS(); + } + + /** + * @implemented + */ + static TLS* PeekTLS() + { + return (TLS*)::TlsGetValue(TLS::s_dwTlsIndex); + } + + static TLS* InternalAllocateTLS(); + static BOOL InternalDestroyTLS(); +}; diff --git a/dll/ime/msctfime/ui.cpp b/dll/ime/msctfime/ui.cpp new file mode 100644 index 00000000000..74a8c733de0 --- /dev/null +++ b/dll/ime/msctfime/ui.cpp @@ -0,0 +1,393 @@ +/* + * PROJECT: ReactOS msctfime.ime + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: User Interface of msctfime.ime + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#include "msctfime.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msctfime); + +UINT WM_MSIME_SERVICE = 0; +UINT WM_MSIME_UIREADY = 0; +UINT WM_MSIME_RECONVERTREQUEST = 0; +UINT WM_MSIME_RECONVERT = 0; +UINT WM_MSIME_DOCUMENTFEED = 0; +UINT WM_MSIME_QUERYPOSITION = 0; +UINT WM_MSIME_MODEBIAS = 0; +UINT WM_MSIME_SHOWIMEPAD = 0; +UINT WM_MSIME_MOUSE = 0; +UINT WM_MSIME_KEYMAP = 0; + +/// @implemented +BOOL IsMsImeMessage(_In_ UINT uMsg) +{ + return (uMsg == WM_MSIME_SERVICE || + uMsg == WM_MSIME_UIREADY || + uMsg == WM_MSIME_RECONVERTREQUEST || + uMsg == WM_MSIME_RECONVERT || + uMsg == WM_MSIME_DOCUMENTFEED || + uMsg == WM_MSIME_QUERYPOSITION || + uMsg == WM_MSIME_MODEBIAS || + uMsg == WM_MSIME_SHOWIMEPAD || + uMsg == WM_MSIME_MOUSE || + uMsg == WM_MSIME_KEYMAP); +} + +/// @implemented +BOOL RegisterMSIMEMessage(VOID) +{ + // Using ANSI (A) version here can reduce binary size. + WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService"); + WM_MSIME_UIREADY = RegisterWindowMessageA("MSIMEUIReady"); + WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest"); + WM_MSIME_RECONVERT = RegisterWindowMessageA("MSIMEReconvert"); + WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed"); + WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition"); + WM_MSIME_MODEBIAS = RegisterWindowMessageA("MSIMEModeBias"); + WM_MSIME_SHOWIMEPAD = RegisterWindowMessageA("MSIMEShowImePad"); + WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation"); + WM_MSIME_KEYMAP = RegisterWindowMessageA("MSIMEKeyMap"); + return (WM_MSIME_SERVICE && + WM_MSIME_UIREADY && + WM_MSIME_RECONVERTREQUEST && + WM_MSIME_RECONVERT && + WM_MSIME_DOCUMENTFEED && + WM_MSIME_QUERYPOSITION && + WM_MSIME_MODEBIAS && + WM_MSIME_SHOWIMEPAD && + WM_MSIME_MOUSE && + WM_MSIME_KEYMAP); +} + +// For GetWindowLongPtr/SetWindowLongPtr +#define UIGWLP_HIMC 0 +#define UIGWLP_UI sizeof(HIMC) +#define UIGWLP_SIZE (UIGWLP_UI + sizeof(UI*)) + +/// @unimplemented +void UIComposition::OnImeStartComposition(CicIMCLock& imcLock, HWND hUIWnd) +{ + //FIXME +} + +/// @unimplemented +void UIComposition::OnImeCompositionUpdate(CicIMCLock& imcLock) +{ + //FIXME +} + +/// @unimplemented +void UIComposition::OnImeEndComposition() +{ + //FIXME +} + +/// @unimplemented +void UIComposition::OnImeSetContext(CicIMCLock& imcLock, HWND hUIWnd, WPARAM wParam, LPARAM lParam) +{ + //FIXME +} + +/// @unimplemented +void UIComposition::OnPaintTheme(WPARAM wParam) +{ + //FIXME +} + +/// @unimplemented +void UIComposition::OnDestroy() +{ + //FIXME +} + +/// @unimplemented +LRESULT CALLBACK +UIComposition::CompWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (uMsg == WM_CREATE) + return -1; // FIXME + return 0; +} + +/***********************************************************************/ + +/// @implemented +UI::UI(HWND hWnd) : m_hWnd(hWnd) +{ +} + +/// @implemented +UI::~UI() +{ + delete m_pComp; +} + +/// @unimplemented +HRESULT UI::_Create() +{ + m_pComp = new(cicNoThrow) UIComposition(); + if (!m_pComp) + return E_OUTOFMEMORY; + + SetWindowLongPtrW(m_hWnd, UIGWLP_UI, (LONG_PTR)this); + //FIXME + return S_OK; +} + +/// @implemented +void UI::_Destroy() +{ + m_pComp->OnDestroy(); + SetWindowLongPtrW(m_hWnd, UIGWLP_UI, 0); +} + +/// @implemented +void UI::OnCreate(HWND hWnd) +{ + UI *pUI = (UI*)GetWindowLongPtrW(hWnd, UIGWLP_UI); + if (pUI) + return; + pUI = new(cicNoThrow) UI(hWnd); + if (pUI) + pUI->_Create(); +} + +/// @implemented +void UI::OnDestroy(HWND hWnd) +{ + UI *pUI = (UI*)GetWindowLongPtrW(hWnd, UIGWLP_UI); + if (!pUI) + return; + + pUI->_Destroy(); + delete pUI; +} + +/// @implemented +void UI::OnImeSetContext(CicIMCLock& imcLock, WPARAM wParam, LPARAM lParam) +{ + m_pComp->OnImeSetContext(imcLock, m_hWnd, wParam, lParam); +} + +/***********************************************************************/ + +struct CIMEUIWindowHandler +{ + static LRESULT CALLBACK ImeUIMsImeHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + static LRESULT CALLBACK ImeUIMsImeMouseHandler(HWND hWnd, WPARAM wParam, LPARAM lParam); + static LRESULT CALLBACK ImeUIMsImeModeBiasHandler(HWND hWnd, WPARAM wParam, LPARAM lParam); + static LRESULT CALLBACK ImeUIMsImeReconvertRequest(HWND hWnd, WPARAM wParam, LPARAM lParam); + static LRESULT CALLBACK ImeUIWndProcWorker(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +}; + +/// @unimplemented +LRESULT CALLBACK +CIMEUIWindowHandler::ImeUIMsImeMouseHandler(HWND hWnd, WPARAM wParam, LPARAM lParam) +{ + return 0; //FIXME +} + +/// @unimplemented +LRESULT CALLBACK +CIMEUIWindowHandler::ImeUIMsImeModeBiasHandler(HWND hWnd, WPARAM wParam, LPARAM lParam) +{ + return 0; //FIXME +} + +/// @unimplemented +LRESULT CALLBACK +CIMEUIWindowHandler::ImeUIMsImeReconvertRequest(HWND hWnd, WPARAM wParam, LPARAM lParam) +{ + return 0; //FIXME +} + +/// @implemented +LRESULT CALLBACK +CIMEUIWindowHandler::ImeUIMsImeHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (uMsg == WM_MSIME_MOUSE) + return ImeUIMsImeMouseHandler(hWnd, wParam, lParam); + if (uMsg == WM_MSIME_MODEBIAS) + return ImeUIMsImeModeBiasHandler(hWnd, wParam, lParam); + if (uMsg == WM_MSIME_RECONVERTREQUEST) + return ImeUIMsImeReconvertRequest(hWnd, wParam, lParam); + if (uMsg == WM_MSIME_SERVICE) + { + TLS *pTLS = TLS::GetTLS(); + if (pTLS && pTLS->m_pProfile) + { + LANGID LangID; + pTLS->m_pProfile->GetLangId(&LangID); + if (PRIMARYLANGID(LangID) == LANG_KOREAN) + return FALSE; + } + return TRUE; + } + return 0; +} + +/// @unimplemented +LRESULT CALLBACK +CIMEUIWindowHandler::ImeUIWndProcWorker(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + TLS *pTLS = TLS::GetTLS(); + if (pTLS && (pTLS->m_dwSystemInfoFlags & IME_SYSINFO_WINLOGON)) + { + if (uMsg == WM_CREATE) + return -1; + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + } + + switch (uMsg) + { + case WM_CREATE: + { + UI::OnCreate(hWnd); + break; + } + case WM_DESTROY: + case WM_ENDSESSION: + { + UI::OnDestroy(hWnd); + break; + } + case WM_IME_STARTCOMPOSITION: + case WM_IME_COMPOSITION: + case WM_IME_ENDCOMPOSITION: + case WM_IME_SETCONTEXT: + case WM_IME_NOTIFY: + case WM_IME_SELECT: + case WM_TIMER: + { + HIMC hIMC = (HIMC)GetWindowLongPtrW(hWnd, UIGWLP_HIMC); + UI* pUI = (UI*)GetWindowLongPtrW(hWnd, UIGWLP_UI); + CicIMCLock imcLock(hIMC); + switch (uMsg) + { + case WM_IME_STARTCOMPOSITION: + { + pUI->m_pComp->OnImeStartComposition(imcLock, pUI->m_hWnd); + break; + } + case WM_IME_COMPOSITION: + { + if (lParam & GCS_COMPSTR) + { + pUI->m_pComp->OnImeCompositionUpdate(imcLock); + ::SetTimer(hWnd, 0, 10, NULL); + //FIXME + } + break; + } + case WM_IME_ENDCOMPOSITION: + { + ::KillTimer(hWnd, 0); + pUI->m_pComp->OnImeEndComposition(); + break; + } + case WM_IME_SETCONTEXT: + { + pUI->OnImeSetContext(imcLock, wParam, lParam); + ::KillTimer(hWnd, 1); + ::SetTimer(hWnd, 1, 300, NULL); + break; + } + case WM_TIMER: + { + //FIXME + ::KillTimer(hWnd, wParam); + break; + } + case WM_IME_NOTIFY: + case WM_IME_SELECT: + default: + { + pUI->m_pComp->OnPaintTheme(wParam); + break; + } + } + break; + } + default: + { + if (IsMsImeMessage(uMsg)) + return CIMEUIWindowHandler::ImeUIMsImeHandler(hWnd, uMsg, wParam, lParam); + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + } + } + + return 0; +} + +/***********************************************************************/ + +/// @implemented +EXTERN_C LRESULT CALLBACK +UIWndProc( + _In_ HWND hWnd, + _In_ UINT uMsg, + _In_ WPARAM wParam, + _In_ LPARAM lParam) +{ + return CIMEUIWindowHandler::ImeUIWndProcWorker(hWnd, uMsg, wParam, lParam); +} + +/***********************************************************************/ + +/// @unimplemented +BOOL RegisterImeClass(VOID) +{ + WNDCLASSEXW wcx; + + if (!GetClassInfoExW(g_hInst, L"MSCTFIME UI", &wcx)) + { + ZeroMemory(&wcx, sizeof(wcx)); + wcx.cbSize = sizeof(WNDCLASSEXW); + wcx.cbWndExtra = UIGWLP_SIZE; + wcx.hIcon = LoadIconW(0, (LPCWSTR)IDC_ARROW); + wcx.hInstance = g_hInst; + wcx.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW); + wcx.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH); + wcx.style = CS_IME | CS_GLOBALCLASS; + wcx.lpfnWndProc = UIWndProc; + wcx.lpszClassName = L"MSCTFIME UI"; + if (!RegisterClassExW(&wcx)) + return FALSE; + } + + if (!GetClassInfoExW(g_hInst, L"MSCTFIME Composition", &wcx)) + { + ZeroMemory(&wcx, sizeof(wcx)); + wcx.cbSize = sizeof(WNDCLASSEXW); + wcx.cbWndExtra = sizeof(DWORD); + wcx.hIcon = NULL; + wcx.hInstance = g_hInst; + wcx.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_IBEAM); + wcx.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH); + wcx.style = CS_IME | CS_HREDRAW | CS_VREDRAW; + wcx.lpfnWndProc = UIComposition::CompWndProc; + wcx.lpszClassName = L"MSCTFIME Composition"; + if (!RegisterClassExW(&wcx)) + return FALSE; + } + + return TRUE; +} + +/// @implemented +VOID UnregisterImeClass(VOID) +{ + WNDCLASSEXW wcx; + + GetClassInfoExW(g_hInst, L"MSCTFIME UI", &wcx); + UnregisterClassW(L"MSCTFIME UI", g_hInst); + DestroyIcon(wcx.hIcon); + DestroyIcon(wcx.hIconSm); + + GetClassInfoExW(g_hInst, L"MSCTFIME Composition", &wcx); + UnregisterClassW(L"MSCTFIME Composition", g_hInst); + DestroyIcon(wcx.hIcon); + DestroyIcon(wcx.hIconSm); +} diff --git a/dll/ime/msctfime/ui.h b/dll/ime/msctfime/ui.h new file mode 100644 index 00000000000..e9433fc734c --- /dev/null +++ b/dll/ime/msctfime/ui.h @@ -0,0 +1,68 @@ +/* + * PROJECT: ReactOS msctfime.ime + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: User Interface of msctfime.ime + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#pragma once + +/***********************************************************************/ + +extern UINT WM_MSIME_SERVICE; +extern UINT WM_MSIME_UIREADY; +extern UINT WM_MSIME_RECONVERTREQUEST; +extern UINT WM_MSIME_RECONVERT; +extern UINT WM_MSIME_DOCUMENTFEED; +extern UINT WM_MSIME_QUERYPOSITION; +extern UINT WM_MSIME_MODEBIAS; +extern UINT WM_MSIME_SHOWIMEPAD; +extern UINT WM_MSIME_MOUSE; +extern UINT WM_MSIME_KEYMAP; + +BOOL IsMsImeMessage(_In_ UINT uMsg); +BOOL RegisterMSIMEMessage(VOID); + +/***********************************************************************/ + +struct UIComposition +{ + void OnImeStartComposition(CicIMCLock& imcLock, HWND hUIWnd); + void OnImeCompositionUpdate(CicIMCLock& imcLock); + void OnImeEndComposition(); + void OnImeSetContext(CicIMCLock& imcLock, HWND hUIWnd, WPARAM wParam, LPARAM lParam); + void OnPaintTheme(WPARAM wParam); + void OnDestroy(); + + static LRESULT CALLBACK CompWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +}; + +/***********************************************************************/ + +struct UI +{ + HWND m_hWnd; + UIComposition *m_pComp; + + UI(HWND hWnd); + virtual ~UI(); + + HRESULT _Create(); + void _Destroy(); + + static void OnCreate(HWND hWnd); + static void OnDestroy(HWND hWnd); + void OnImeSetContext(CicIMCLock& imcLock, WPARAM wParam, LPARAM lParam); +}; + +/***********************************************************************/ + +EXTERN_C LRESULT CALLBACK +UIWndProc( + _In_ HWND hWnd, + _In_ UINT uMsg, + _In_ WPARAM wParam, + _In_ LPARAM lParam); + +BOOL RegisterImeClass(VOID); +VOID UnregisterImeClass(VOID); diff --git a/dll/win32/dbghelp/path.c b/dll/win32/dbghelp/path.c index 6639375d444..92db186be41 100644 --- a/dll/win32/dbghelp/path.c +++ b/dll/win32/dbghelp/path.c @@ -673,6 +673,7 @@ WCHAR *get_dos_file_name(const WCHAR *filename) WCHAR *dos_path; size_t len; +#ifndef __REACTOS__ if (*filename == '/') { char *unix_path; @@ -683,6 +684,7 @@ WCHAR *get_dos_file_name(const WCHAR *filename) heap_free(unix_path); } else +#endif { len = lstrlenW(filename); dos_path = heap_alloc((len + 1) * sizeof(WCHAR)); diff --git a/dll/win32/msctf/utils.cpp b/dll/win32/msctf/utils.cpp index 4fc57a5ac0d..ec469ceef28 100644 --- a/dll/win32/msctf/utils.cpp +++ b/dll/win32/msctf/utils.cpp @@ -519,6 +519,11 @@ VOID InitCUASFlag(VOID) } } +EXTERN_C VOID TFUninitLib(VOID) +{ + // Do nothing +} + /** * @unimplemented */ diff --git a/dll/win32/msutb/msutb.cpp b/dll/win32/msutb/msutb.cpp index 74c537ede80..912edc45598 100644 --- a/dll/win32/msutb/msutb.cpp +++ b/dll/win32/msutb/msutb.cpp @@ -6207,6 +6207,11 @@ BEGIN_OBJECT_MAP(ObjectMap) #endif END_OBJECT_MAP() +EXTERN_C VOID TFUninitLib(VOID) +{ + // Do nothing +} + /// @implemented BOOL ProcessAttach(HINSTANCE hinstDLL) { diff --git a/dll/win32/shell32/CDefView.cpp b/dll/win32/shell32/CDefView.cpp index 49ccc18cdea..cc5d1624ff7 100644 --- a/dll/win32/shell32/CDefView.cpp +++ b/dll/win32/shell32/CDefView.cpp @@ -50,17 +50,17 @@ typedef struct #define SHV_CHANGE_NOTIFY WM_USER + 0x1111 -/* For the context menu of the def view, the id of the items are based on 1 because we need - to call TrackPopupMenu and let it use the 0 value as an indication that the menu was canceled */ +// For the context menu of the def view, the id of the items are based on 1 because we need +// to call TrackPopupMenu and let it use the 0 value as an indication that the menu was canceled #define CONTEXT_MENU_BASE_ID 1 -/* Convert client coordinates to listview coordinates */ +// Convert client coordinates to listview coordinates static void ClientToListView(HWND hwndLV, POINT *ppt) { POINT Origin = {}; - /* FIXME: LVM_GETORIGIN is broken. See CORE-17266 */ + // FIXME: LVM_GETORIGIN is broken. See CORE-17266 if (!ListView_GetOrigin(hwndLV, &Origin)) return; @@ -94,7 +94,6 @@ struct MenuCleanup } }; - class CDefView : public CWindowImpl, public CComObjectRootEx, @@ -107,302 +106,301 @@ class CDefView : public IViewObject, public IServiceProvider { - private: - CComPtr m_pSFParent; - CComPtr m_pSF2Parent; - CComPtr m_pShellFolderViewCB; - CComPtr m_pShellBrowser; - CComPtr m_pCommDlgBrowser; - CComPtr m_pShellFolderViewDual; - CListView m_ListView; - HWND m_hWndParent; - FOLDERSETTINGS m_FolderSettings; - HMENU m_hMenu; /* Handle to the menu bar of the browser */ - HMENU m_hMenuArrangeModes; /* Handle to the popup menu with the arrange modes */ - HMENU m_hMenuViewModes; /* Handle to the popup menu with the view modes */ - HMENU m_hContextMenu; /* Handle to the open context menu */ - BOOL m_bmenuBarInitialized; - UINT m_uState; - UINT m_cidl; - PCUITEMID_CHILD *m_apidl; - PIDLIST_ABSOLUTE m_pidlParent; - LISTVIEW_SORT_INFO m_sortInfo; - ULONG m_hNotify; /* Change notification handle */ - HACCEL m_hAccel; - DWORD m_dwAspects; - DWORD m_dwAdvf; - CComPtr m_pAdvSink; - // for drag and drop - CComPtr m_pSourceDataObject; - CComPtr m_pCurDropTarget; /* The sub-item, which is currently dragged over */ - CComPtr m_pCurDataObject; /* The dragged data-object */ - LONG m_iDragOverItem; /* Dragged over item's index, iff m_pCurDropTarget != NULL */ - UINT m_cScrollDelay; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */ - POINT m_ptLastMousePos; /* Mouse position at last DragOver call */ - POINT m_ptFirstMousePos; /* Mouse position when the drag operation started */ - DWORD m_grfKeyState; - // - CComPtr m_pCM; - CComPtr m_pFileMenu; - - BOOL m_isEditing; - BOOL m_isParentFolderSpecial; - - CLSID m_Category; - BOOL m_Destroyed; - SFVM_CUSTOMVIEWINFO_DATA m_viewinfo_data; - - HICON m_hMyComputerIcon; - - private: - HRESULT _MergeToolbar(); - BOOL _Sort(); - HRESULT _DoFolderViewCB(UINT uMsg, WPARAM wParam, LPARAM lParam); - HRESULT _GetSnapToGrid(); - void _MoveSelectionOnAutoArrange(POINT pt); - INT _FindInsertableIndexFromPoint(POINT pt); - void _HandleStatusBarResize(int width); - void _ForceStatusBarResize(); - void _DoCopyToMoveToFolder(BOOL bCopy); - - public: - CDefView(); - ~CDefView(); - HRESULT WINAPI Initialize(IShellFolder *shellFolder); - HRESULT IncludeObject(PCUITEMID_CHILD pidl); - HRESULT OnDefaultCommand(); - HRESULT OnStateChange(UINT uFlags); - void UpdateStatusbar(); - void CheckToolbar(); - BOOL CreateList(); - void UpdateListColors(); - BOOL InitList(); - static INT CALLBACK ListViewCompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData); - - PCUITEMID_CHILD _PidlByItem(int i); - PCUITEMID_CHILD _PidlByItem(LVITEM& lvItem); - int LV_FindItemByPidl(PCUITEMID_CHILD pidl); - int LV_AddItem(PCUITEMID_CHILD pidl); - BOOLEAN LV_DeleteItem(PCUITEMID_CHILD pidl); - BOOLEAN LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew); - BOOLEAN LV_ProdItem(PCUITEMID_CHILD pidl); - static INT CALLBACK fill_list(LPVOID ptr, LPVOID arg); - HRESULT FillList(); - HRESULT FillFileMenu(); - HRESULT FillEditMenu(); - HRESULT FillViewMenu(); - HRESULT FillArrangeAsMenu(HMENU hmenuArrange); - HRESULT CheckViewMode(HMENU hmenuView); - UINT GetSelections(); - HRESULT OpenSelectedItems(); - void OnDeactivate(); - void DoActivate(UINT uState); - HRESULT drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); - HRESULT InvokeContextMenuCommand(CComPtr& pCM, LPCSTR lpVerb, POINT* pt = NULL); - LRESULT OnExplorerCommand(UINT uCommand, BOOL bUseSelection); - - // *** IOleWindow methods *** - virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd); - virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode); - - // *** IShellView methods *** - virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(MSG *pmsg); - virtual HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable); - virtual HRESULT STDMETHODCALLTYPE UIActivate(UINT uState); - virtual HRESULT STDMETHODCALLTYPE Refresh(); - virtual HRESULT STDMETHODCALLTYPE CreateViewWindow(IShellView *psvPrevious, LPCFOLDERSETTINGS pfs, IShellBrowser *psb, RECT *prcView, HWND *phWnd); - virtual HRESULT STDMETHODCALLTYPE DestroyViewWindow(); - virtual HRESULT STDMETHODCALLTYPE GetCurrentInfo(LPFOLDERSETTINGS pfs); - virtual HRESULT STDMETHODCALLTYPE AddPropertySheetPages(DWORD dwReserved, LPFNSVADDPROPSHEETPAGE pfn, LPARAM lparam); - virtual HRESULT STDMETHODCALLTYPE SaveViewState(); - virtual HRESULT STDMETHODCALLTYPE SelectItem(PCUITEMID_CHILD pidlItem, SVSIF uFlags); - virtual HRESULT STDMETHODCALLTYPE GetItemObject(UINT uItem, REFIID riid, void **ppv); - - // *** IShellView2 methods *** - virtual HRESULT STDMETHODCALLTYPE GetView(SHELLVIEWID *view_guid, ULONG view_type); - virtual HRESULT STDMETHODCALLTYPE CreateViewWindow2(LPSV2CVW2_PARAMS view_params); - virtual HRESULT STDMETHODCALLTYPE HandleRename(LPCITEMIDLIST new_pidl); - virtual HRESULT STDMETHODCALLTYPE SelectAndPositionItem(LPCITEMIDLIST item, UINT flags, POINT *point); - - // *** IShellView3 methods *** - virtual HRESULT STDMETHODCALLTYPE CreateViewWindow3(IShellBrowser *psb, IShellView *psvPrevious, SV3CVW3_FLAGS view_flags, FOLDERFLAGS mask, FOLDERFLAGS flags, FOLDERVIEWMODE mode, const SHELLVIEWID *view_id, RECT *prcView, HWND *hwnd); - - // *** IFolderView methods *** - virtual HRESULT STDMETHODCALLTYPE GetCurrentViewMode(UINT *pViewMode); - virtual HRESULT STDMETHODCALLTYPE SetCurrentViewMode(UINT ViewMode); - virtual HRESULT STDMETHODCALLTYPE GetFolder(REFIID riid, void **ppv); - virtual HRESULT STDMETHODCALLTYPE Item(int iItemIndex, PITEMID_CHILD *ppidl); - virtual HRESULT STDMETHODCALLTYPE ItemCount(UINT uFlags, int *pcItems); - virtual HRESULT STDMETHODCALLTYPE Items(UINT uFlags, REFIID riid, void **ppv); - virtual HRESULT STDMETHODCALLTYPE GetSelectionMarkedItem(int *piItem); - virtual HRESULT STDMETHODCALLTYPE GetFocusedItem(int *piItem); - virtual HRESULT STDMETHODCALLTYPE GetItemPosition(PCUITEMID_CHILD pidl, POINT *ppt); - virtual HRESULT STDMETHODCALLTYPE GetSpacing(POINT *ppt); - virtual HRESULT STDMETHODCALLTYPE GetDefaultSpacing(POINT *ppt); - virtual HRESULT STDMETHODCALLTYPE GetAutoArrange(); - virtual HRESULT STDMETHODCALLTYPE SelectItem(int iItem, DWORD dwFlags); - virtual HRESULT STDMETHODCALLTYPE SelectAndPositionItems(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, POINT *apt, DWORD dwFlags); - - // *** IShellFolderView methods *** - virtual HRESULT STDMETHODCALLTYPE Rearrange(LPARAM sort); - virtual HRESULT STDMETHODCALLTYPE GetArrangeParam(LPARAM *sort); - virtual HRESULT STDMETHODCALLTYPE ArrangeGrid(); - virtual HRESULT STDMETHODCALLTYPE AutoArrange(); - virtual HRESULT STDMETHODCALLTYPE AddObject(PITEMID_CHILD pidl, UINT *item); - virtual HRESULT STDMETHODCALLTYPE GetObject(PITEMID_CHILD *pidl, UINT item); - virtual HRESULT STDMETHODCALLTYPE RemoveObject(PITEMID_CHILD pidl, UINT *item); - virtual HRESULT STDMETHODCALLTYPE GetObjectCount(UINT *count); - virtual HRESULT STDMETHODCALLTYPE SetObjectCount(UINT count, UINT flags); - virtual HRESULT STDMETHODCALLTYPE UpdateObject(PITEMID_CHILD pidl_old, PITEMID_CHILD pidl_new, UINT *item); - virtual HRESULT STDMETHODCALLTYPE RefreshObject(PITEMID_CHILD pidl, UINT *item); - virtual HRESULT STDMETHODCALLTYPE SetRedraw(BOOL redraw); - virtual HRESULT STDMETHODCALLTYPE GetSelectedCount(UINT *count); - virtual HRESULT STDMETHODCALLTYPE GetSelectedObjects(PCUITEMID_CHILD **pidl, UINT *items); - virtual HRESULT STDMETHODCALLTYPE IsDropOnSource(IDropTarget *drop_target); - virtual HRESULT STDMETHODCALLTYPE GetDragPoint(POINT *pt); - virtual HRESULT STDMETHODCALLTYPE GetDropPoint(POINT *pt); - virtual HRESULT STDMETHODCALLTYPE MoveIcons(IDataObject *obj); - virtual HRESULT STDMETHODCALLTYPE SetItemPos(PCUITEMID_CHILD pidl, POINT *pt); - virtual HRESULT STDMETHODCALLTYPE IsBkDropTarget(IDropTarget *drop_target); - virtual HRESULT STDMETHODCALLTYPE SetClipboard(BOOL move); - virtual HRESULT STDMETHODCALLTYPE SetPoints(IDataObject *obj); - virtual HRESULT STDMETHODCALLTYPE GetItemSpacing(ITEMSPACING *spacing); - virtual HRESULT STDMETHODCALLTYPE SetCallback(IShellFolderViewCB *new_cb, IShellFolderViewCB **old_cb); - virtual HRESULT STDMETHODCALLTYPE Select(UINT flags); - virtual HRESULT STDMETHODCALLTYPE QuerySupport(UINT *support); - virtual HRESULT STDMETHODCALLTYPE SetAutomationObject(IDispatch *disp); - - // *** IOleCommandTarget methods *** - virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT *pCmdText); - virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut); - - // *** IDropTarget methods *** - virtual HRESULT STDMETHODCALLTYPE DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); - virtual HRESULT STDMETHODCALLTYPE DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); - virtual HRESULT STDMETHODCALLTYPE DragLeave(); - virtual HRESULT STDMETHODCALLTYPE Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); - - // *** IDropSource methods *** - virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState); - virtual HRESULT STDMETHODCALLTYPE GiveFeedback(DWORD dwEffect); - - // *** IViewObject methods *** - virtual HRESULT STDMETHODCALLTYPE Draw(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, - HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, - BOOL ( STDMETHODCALLTYPE *pfnContinue )(ULONG_PTR dwContinue), ULONG_PTR dwContinue); - virtual HRESULT STDMETHODCALLTYPE GetColorSet(DWORD dwDrawAspect, LONG lindex, void *pvAspect, - DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **ppColorSet); - virtual HRESULT STDMETHODCALLTYPE Freeze(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze); - virtual HRESULT STDMETHODCALLTYPE Unfreeze(DWORD dwFreeze); - virtual HRESULT STDMETHODCALLTYPE SetAdvise(DWORD aspects, DWORD advf, IAdviseSink *pAdvSink); - virtual HRESULT STDMETHODCALLTYPE GetAdvise(DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink); - - // *** IServiceProvider methods *** - virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject); - - // Message handlers - LRESULT OnShowWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnGetDlgCode(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnPrintClient(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnSysColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnGetShellBrowser(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnNCCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnCustomItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - - virtual VOID OnFinalMessage(HWND) override; - - static ATL::CWndClassInfo& GetWndClassInfo() - { - static ATL::CWndClassInfo wc = - { - { sizeof(WNDCLASSEX), CS_PARENTDC, StartWindowProc, - 0, 0, NULL, NULL, - LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"SHELLDLL_DefView", NULL - }, - NULL, NULL, IDC_ARROW, TRUE, 0, _T("") - }; - return wc; - } - - virtual WNDPROC GetWindowProc() +private: + CComPtr m_pSFParent; + CComPtr m_pSF2Parent; + CComPtr m_pShellFolderViewCB; + CComPtr m_pShellBrowser; + CComPtr m_pCommDlgBrowser; + CComPtr m_pShellFolderViewDual; + CListView m_ListView; + HWND m_hWndParent; + FOLDERSETTINGS m_FolderSettings; + HMENU m_hMenu; // Handle to the menu bar of the browser + HMENU m_hMenuArrangeModes; // Handle to the popup menu with the arrange modes + HMENU m_hMenuViewModes; // Handle to the popup menu with the view modes + HMENU m_hContextMenu; // Handle to the open context menu + BOOL m_bmenuBarInitialized; + UINT m_uState; + UINT m_cidl; + PCUITEMID_CHILD *m_apidl; + PIDLIST_ABSOLUTE m_pidlParent; + LISTVIEW_SORT_INFO m_sortInfo; + ULONG m_hNotify; // Change notification handle + HACCEL m_hAccel; + DWORD m_dwAspects; + DWORD m_dwAdvf; + CComPtr m_pAdvSink; + // for drag and drop + CComPtr m_pSourceDataObject; + CComPtr m_pCurDropTarget; // The sub-item, which is currently dragged over + CComPtr m_pCurDataObject; // The dragged data-object + LONG m_iDragOverItem; // Dragged over item's index, if m_pCurDropTarget != NULL + UINT m_cScrollDelay; // Send a WM_*SCROLL msg every 250 ms during drag-scroll + POINT m_ptLastMousePos; // Mouse position at last DragOver call + POINT m_ptFirstMousePos; // Mouse position when the drag operation started + DWORD m_grfKeyState; + // + CComPtr m_pCM; + CComPtr m_pFileMenu; + + BOOL m_isEditing; + BOOL m_isParentFolderSpecial; + + CLSID m_Category; + BOOL m_Destroyed; + SFVM_CUSTOMVIEWINFO_DATA m_viewinfo_data; + + HICON m_hMyComputerIcon; + + HRESULT _MergeToolbar(); + BOOL _Sort(); + HRESULT _DoFolderViewCB(UINT uMsg, WPARAM wParam, LPARAM lParam); + HRESULT _GetSnapToGrid(); + void _MoveSelectionOnAutoArrange(POINT pt); + INT _FindInsertableIndexFromPoint(POINT pt); + void _HandleStatusBarResize(int width); + void _ForceStatusBarResize(); + void _DoCopyToMoveToFolder(BOOL bCopy); + +public: + CDefView(); + ~CDefView(); + HRESULT WINAPI Initialize(IShellFolder *shellFolder); + HRESULT IncludeObject(PCUITEMID_CHILD pidl); + HRESULT OnDefaultCommand(); + HRESULT OnStateChange(UINT uFlags); + void UpdateStatusbar(); + void CheckToolbar(); + BOOL CreateList(); + void UpdateListColors(); + BOOL InitList(); + static INT CALLBACK ListViewCompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData); + + PCUITEMID_CHILD _PidlByItem(int i); + PCUITEMID_CHILD _PidlByItem(LVITEM& lvItem); + int LV_FindItemByPidl(PCUITEMID_CHILD pidl); + int LV_AddItem(PCUITEMID_CHILD pidl); + BOOLEAN LV_DeleteItem(PCUITEMID_CHILD pidl); + BOOLEAN LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew); + BOOLEAN LV_ProdItem(PCUITEMID_CHILD pidl); + static INT CALLBACK fill_list(LPVOID ptr, LPVOID arg); + HRESULT FillList(); + HRESULT FillFileMenu(); + HRESULT FillEditMenu(); + HRESULT FillViewMenu(); + HRESULT FillArrangeAsMenu(HMENU hmenuArrange); + HRESULT CheckViewMode(HMENU hmenuView); + UINT GetSelections(); + HRESULT OpenSelectedItems(); + void OnDeactivate(); + void DoActivate(UINT uState); + HRESULT drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); + HRESULT InvokeContextMenuCommand(CComPtr& pCM, LPCSTR lpVerb, POINT* pt = NULL); + LRESULT OnExplorerCommand(UINT uCommand, BOOL bUseSelection); + + // *** IOleWindow methods *** + virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd); + virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode); + + // *** IShellView methods *** + virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(MSG *pmsg); + virtual HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable); + virtual HRESULT STDMETHODCALLTYPE UIActivate(UINT uState); + virtual HRESULT STDMETHODCALLTYPE Refresh(); + virtual HRESULT STDMETHODCALLTYPE CreateViewWindow(IShellView *psvPrevious, LPCFOLDERSETTINGS pfs, IShellBrowser *psb, RECT *prcView, HWND *phWnd); + virtual HRESULT STDMETHODCALLTYPE DestroyViewWindow(); + virtual HRESULT STDMETHODCALLTYPE GetCurrentInfo(LPFOLDERSETTINGS pfs); + virtual HRESULT STDMETHODCALLTYPE AddPropertySheetPages(DWORD dwReserved, LPFNSVADDPROPSHEETPAGE pfn, LPARAM lparam); + virtual HRESULT STDMETHODCALLTYPE SaveViewState(); + virtual HRESULT STDMETHODCALLTYPE SelectItem(PCUITEMID_CHILD pidlItem, SVSIF uFlags); + virtual HRESULT STDMETHODCALLTYPE GetItemObject(UINT uItem, REFIID riid, void **ppv); + + // *** IShellView2 methods *** + virtual HRESULT STDMETHODCALLTYPE GetView(SHELLVIEWID *view_guid, ULONG view_type); + virtual HRESULT STDMETHODCALLTYPE CreateViewWindow2(LPSV2CVW2_PARAMS view_params); + virtual HRESULT STDMETHODCALLTYPE HandleRename(LPCITEMIDLIST new_pidl); + virtual HRESULT STDMETHODCALLTYPE SelectAndPositionItem(LPCITEMIDLIST item, UINT flags, POINT *point); + + // *** IShellView3 methods *** + virtual HRESULT STDMETHODCALLTYPE CreateViewWindow3(IShellBrowser *psb, IShellView *psvPrevious, SV3CVW3_FLAGS view_flags, FOLDERFLAGS mask, FOLDERFLAGS flags, FOLDERVIEWMODE mode, const SHELLVIEWID *view_id, RECT *prcView, HWND *hwnd); + + // *** IFolderView methods *** + virtual HRESULT STDMETHODCALLTYPE GetCurrentViewMode(UINT *pViewMode); + virtual HRESULT STDMETHODCALLTYPE SetCurrentViewMode(UINT ViewMode); + virtual HRESULT STDMETHODCALLTYPE GetFolder(REFIID riid, void **ppv); + virtual HRESULT STDMETHODCALLTYPE Item(int iItemIndex, PITEMID_CHILD *ppidl); + virtual HRESULT STDMETHODCALLTYPE ItemCount(UINT uFlags, int *pcItems); + virtual HRESULT STDMETHODCALLTYPE Items(UINT uFlags, REFIID riid, void **ppv); + virtual HRESULT STDMETHODCALLTYPE GetSelectionMarkedItem(int *piItem); + virtual HRESULT STDMETHODCALLTYPE GetFocusedItem(int *piItem); + virtual HRESULT STDMETHODCALLTYPE GetItemPosition(PCUITEMID_CHILD pidl, POINT *ppt); + virtual HRESULT STDMETHODCALLTYPE GetSpacing(POINT *ppt); + virtual HRESULT STDMETHODCALLTYPE GetDefaultSpacing(POINT *ppt); + virtual HRESULT STDMETHODCALLTYPE GetAutoArrange(); + virtual HRESULT STDMETHODCALLTYPE SelectItem(int iItem, DWORD dwFlags); + virtual HRESULT STDMETHODCALLTYPE SelectAndPositionItems(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, POINT *apt, DWORD dwFlags); + + // *** IShellFolderView methods *** + virtual HRESULT STDMETHODCALLTYPE Rearrange(LPARAM sort); + virtual HRESULT STDMETHODCALLTYPE GetArrangeParam(LPARAM *sort); + virtual HRESULT STDMETHODCALLTYPE ArrangeGrid(); + virtual HRESULT STDMETHODCALLTYPE AutoArrange(); + virtual HRESULT STDMETHODCALLTYPE AddObject(PITEMID_CHILD pidl, UINT *item); + virtual HRESULT STDMETHODCALLTYPE GetObject(PITEMID_CHILD *pidl, UINT item); + virtual HRESULT STDMETHODCALLTYPE RemoveObject(PITEMID_CHILD pidl, UINT *item); + virtual HRESULT STDMETHODCALLTYPE GetObjectCount(UINT *count); + virtual HRESULT STDMETHODCALLTYPE SetObjectCount(UINT count, UINT flags); + virtual HRESULT STDMETHODCALLTYPE UpdateObject(PITEMID_CHILD pidl_old, PITEMID_CHILD pidl_new, UINT *item); + virtual HRESULT STDMETHODCALLTYPE RefreshObject(PITEMID_CHILD pidl, UINT *item); + virtual HRESULT STDMETHODCALLTYPE SetRedraw(BOOL redraw); + virtual HRESULT STDMETHODCALLTYPE GetSelectedCount(UINT *count); + virtual HRESULT STDMETHODCALLTYPE GetSelectedObjects(PCUITEMID_CHILD **pidl, UINT *items); + virtual HRESULT STDMETHODCALLTYPE IsDropOnSource(IDropTarget *drop_target); + virtual HRESULT STDMETHODCALLTYPE GetDragPoint(POINT *pt); + virtual HRESULT STDMETHODCALLTYPE GetDropPoint(POINT *pt); + virtual HRESULT STDMETHODCALLTYPE MoveIcons(IDataObject *obj); + virtual HRESULT STDMETHODCALLTYPE SetItemPos(PCUITEMID_CHILD pidl, POINT *pt); + virtual HRESULT STDMETHODCALLTYPE IsBkDropTarget(IDropTarget *drop_target); + virtual HRESULT STDMETHODCALLTYPE SetClipboard(BOOL move); + virtual HRESULT STDMETHODCALLTYPE SetPoints(IDataObject *obj); + virtual HRESULT STDMETHODCALLTYPE GetItemSpacing(ITEMSPACING *spacing); + virtual HRESULT STDMETHODCALLTYPE SetCallback(IShellFolderViewCB *new_cb, IShellFolderViewCB **old_cb); + virtual HRESULT STDMETHODCALLTYPE Select(UINT flags); + virtual HRESULT STDMETHODCALLTYPE QuerySupport(UINT *support); + virtual HRESULT STDMETHODCALLTYPE SetAutomationObject(IDispatch *disp); + + // *** IOleCommandTarget methods *** + virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText); + virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut); + + // *** IDropTarget methods *** + virtual HRESULT STDMETHODCALLTYPE DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); + virtual HRESULT STDMETHODCALLTYPE DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); + virtual HRESULT STDMETHODCALLTYPE DragLeave(); + virtual HRESULT STDMETHODCALLTYPE Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); + + // *** IDropSource methods *** + virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState); + virtual HRESULT STDMETHODCALLTYPE GiveFeedback(DWORD dwEffect); + + // *** IViewObject methods *** + virtual HRESULT STDMETHODCALLTYPE Draw(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, + HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, + BOOL (STDMETHODCALLTYPE *pfnContinue)(ULONG_PTR dwContinue), ULONG_PTR dwContinue); + virtual HRESULT STDMETHODCALLTYPE GetColorSet(DWORD dwDrawAspect, LONG lindex, void *pvAspect, + DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **ppColorSet); + virtual HRESULT STDMETHODCALLTYPE Freeze(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze); + virtual HRESULT STDMETHODCALLTYPE Unfreeze(DWORD dwFreeze); + virtual HRESULT STDMETHODCALLTYPE SetAdvise(DWORD aspects, DWORD advf, IAdviseSink *pAdvSink); + virtual HRESULT STDMETHODCALLTYPE GetAdvise(DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink); + + // *** IServiceProvider methods *** + virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject); + + // Message handlers + LRESULT OnShowWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnGetDlgCode(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnPrintClient(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnSysColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnGetShellBrowser(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnNCCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnCustomItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + + virtual VOID OnFinalMessage(HWND) override; + + static ATL::CWndClassInfo& GetWndClassInfo() + { + static ATL::CWndClassInfo wc = { - return WindowProc; - } - - static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) - { - CDefView *pThis; - LRESULT result; - - // Must hold a reference during message handling - pThis = reinterpret_cast(hWnd); - pThis->AddRef(); - result = CWindowImpl::WindowProc(hWnd, uMsg, wParam, lParam); - pThis->Release(); - return result; - } - - BEGIN_MSG_MAP(CDefView) - MESSAGE_HANDLER(WM_SIZE, OnSize) - MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) - MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus) - MESSAGE_HANDLER(WM_NCCREATE, OnNCCreate) - MESSAGE_HANDLER(WM_CREATE, OnCreate) - MESSAGE_HANDLER(WM_ACTIVATE, OnActivate) - MESSAGE_HANDLER(WM_NOTIFY, OnNotify) - MESSAGE_HANDLER(WM_COMMAND, OnCommand) - MESSAGE_HANDLER(SHV_CHANGE_NOTIFY, OnChangeNotify) - MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu) - MESSAGE_HANDLER(WM_DRAWITEM, OnCustomItem) - MESSAGE_HANDLER(WM_MEASUREITEM, OnCustomItem) - MESSAGE_HANDLER(WM_SHOWWINDOW, OnShowWindow) - MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) - MESSAGE_HANDLER(WM_PRINTCLIENT, OnPrintClient) - MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSysColorChange) - MESSAGE_HANDLER(CWM_GETISHELLBROWSER, OnGetShellBrowser) - MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) - MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup) - END_MSG_MAP() - - BEGIN_COM_MAP(CDefView) - // Windows returns E_NOINTERFACE for IOleWindow - // COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow) - COM_INTERFACE_ENTRY_IID(IID_IShellView, IShellView) - COM_INTERFACE_ENTRY_IID(IID_CDefView, IShellView) - COM_INTERFACE_ENTRY_IID(IID_IShellView2, IShellView2) - COM_INTERFACE_ENTRY_IID(IID_IFolderView, IFolderView) - COM_INTERFACE_ENTRY_IID(IID_IShellFolderView, IShellFolderView) - COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget) - COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget) - COM_INTERFACE_ENTRY_IID(IID_IDropSource, IDropSource) - COM_INTERFACE_ENTRY_IID(IID_IViewObject, IViewObject) - COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider) - END_COM_MAP() + { sizeof(WNDCLASSEX), CS_PARENTDC, StartWindowProc, + 0, 0, NULL, NULL, + LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"SHELLDLL_DefView", NULL + }, + NULL, NULL, IDC_ARROW, TRUE, 0, _T("") + }; + return wc; + } + + virtual WNDPROC GetWindowProc() + { + return WindowProc; + } + + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + CDefView *pThis; + LRESULT result; + + // Must hold a reference during message handling + pThis = reinterpret_cast(hWnd); + pThis->AddRef(); + result = CWindowImpl::WindowProc(hWnd, uMsg, wParam, lParam); + pThis->Release(); + return result; + } + + BEGIN_MSG_MAP(CDefView) + MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) + MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus) + MESSAGE_HANDLER(WM_NCCREATE, OnNCCreate) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_ACTIVATE, OnActivate) + MESSAGE_HANDLER(WM_NOTIFY, OnNotify) + MESSAGE_HANDLER(WM_COMMAND, OnCommand) + MESSAGE_HANDLER(SHV_CHANGE_NOTIFY, OnChangeNotify) + MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu) + MESSAGE_HANDLER(WM_DRAWITEM, OnCustomItem) + MESSAGE_HANDLER(WM_MEASUREITEM, OnCustomItem) + MESSAGE_HANDLER(WM_SHOWWINDOW, OnShowWindow) + MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPrintClient) + MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSysColorChange) + MESSAGE_HANDLER(CWM_GETISHELLBROWSER, OnGetShellBrowser) + MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) + MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup) + END_MSG_MAP() + + BEGIN_COM_MAP(CDefView) + // Windows returns E_NOINTERFACE for IOleWindow + // COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow) + COM_INTERFACE_ENTRY_IID(IID_IShellView, IShellView) + COM_INTERFACE_ENTRY_IID(IID_CDefView, IShellView) + COM_INTERFACE_ENTRY_IID(IID_IShellView2, IShellView2) + COM_INTERFACE_ENTRY_IID(IID_IFolderView, IFolderView) + COM_INTERFACE_ENTRY_IID(IID_IShellFolderView, IShellFolderView) + COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget) + COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget) + COM_INTERFACE_ENTRY_IID(IID_IDropSource, IDropSource) + COM_INTERFACE_ENTRY_IID(IID_IViewObject, IViewObject) + COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider) + END_COM_MAP() }; -/*menu items */ +// menu items #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500) #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501) #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502) #define ID_LISTVIEW 1 -/*windowsx.h */ +// windowsx.h #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp) #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp) #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp) @@ -470,10 +468,8 @@ HRESULT WINAPI CDefView::Initialize(IShellFolder *shellFolder) return S_OK; } -/********************************************************** - * - * ##### helperfunctions for communication with ICommDlgBrowser ##### - */ +// ##### helperfunctions for communication with ICommDlgBrowser ##### + HRESULT CDefView::IncludeObject(PCUITEMID_CHILD pidl) { HRESULT ret = S_OK; @@ -564,7 +560,7 @@ void CDefView::UpdateStatusbar() LRESULT lResult; m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 0, (LPARAM)szPartText, &lResult); - /* Don't bother with the extra processing if we only have one StatusBar part. */ + // Don't bother with the extra processing if we only have one StatusBar part if (!m_isParentFolderSpecial) { DWORD uTotalFileSize = 0; @@ -573,7 +569,7 @@ void CDefView::UpdateStatusbar() INT nItem = -1; bool bIsOnlyFoldersSelected = true; - /* If we have something selected then only count selected file sizes. */ + // If we have something selected then only count selected file sizes if (cSelectedItems) { uFileFlags = LVNI_SELECTED; @@ -591,8 +587,8 @@ void CDefView::UpdateStatusbar() } } - /* Don't show the file size text if there is 0 bytes in the folder - * OR we only have folders selected. */ + // Don't show the file size text if there is 0 bytes in the folder + // OR we only have folders selected if ((cSelectedItems && !bIsOnlyFoldersSelected) || uTotalFileSize) { StrFormatByteSizeW(uTotalFileSize, szPartText, _countof(szPartText)); @@ -604,7 +600,7 @@ void CDefView::UpdateStatusbar() m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 1, (LPARAM)szPartText, &lResult); - /* If we are in a Recycle Bin folder then show no text for the location part. */ + // If we are in a Recycle Bin then show no text for the location part if (!_ILIsBitBucket(m_pidlParent)) { LoadStringW(shell32_hInstance, IDS_MYCOMPUTER, szPartText, _countof(szPartText)); @@ -616,16 +612,10 @@ void CDefView::UpdateStatusbar() } } -/********************************************************** - * - * ##### helperfunctions for initializing the view ##### - */ -/********************************************************** -* ShellView_CreateList() -* -* - creates the list view window -*/ +// ##### helperfunctions for initializing the view ##### + +// creates the list view window BOOL CDefView::CreateList() { HRESULT hr; @@ -646,7 +636,7 @@ BOOL CDefView::CreateList() } else { - dwStyle |= LVS_SHOWSELALWAYS; // MSDN says FWF_SHOWSELALWAYS is deprecated, always turn on for folders. + dwStyle |= LVS_SHOWSELALWAYS; // MSDN says FWF_SHOWSELALWAYS is deprecated, always turn on for folders dwStyle |= (m_FolderSettings.fFlags & FWF_ALIGNLEFT) ? LVS_ALIGNLEFT : LVS_ALIGNTOP; ListExStyle = LVS_EX_DOUBLEBUFFER; } @@ -666,19 +656,15 @@ BOOL CDefView::CreateList() case FVM_ICON: dwStyle |= LVS_ICON; break; - case FVM_DETAILS: dwStyle |= LVS_REPORT; break; - case FVM_SMALLICON: dwStyle |= LVS_SMALLICON; break; - case FVM_LIST: dwStyle |= LVS_LIST; break; - default: dwStyle |= LVS_LIST; break; @@ -704,7 +690,7 @@ BOOL CDefView::CreateList() #if 0 // FIXME: Because this is a negative, everyone gets the new flag by default unless they - // opt out. This code should be enabled when the shell looks like Vista instead of 2003. + // opt out. This code should be enabled when shell looks like Vista instead of 2003 if (!(m_FolderSettings.fFlags & FWF_NOHEADERINALLVIEWS)) ListExStyle |= LVS_EX_HEADERINALLVIEWS; #endif @@ -779,16 +765,12 @@ void CDefView::UpdateListColors() m_ListView.SetTextColor(clrText); - // Background is painted by the parent via WM_PRINTCLIENT. + // Background is painted by the parent via WM_PRINTCLIENT m_ListView.SetExtendedListViewStyle(LVS_EX_TRANSPARENTBKGND, LVS_EX_TRANSPARENTBKGND); } } -/********************************************************** -* ShellView_InitList() -* -* - adds all needed columns to the shellview -*/ +// adds all needed columns to the shellview BOOL CDefView::InitList() { SHELLDETAILS sd; @@ -869,7 +851,7 @@ BOOL CDefView::_Sort() hHeader = (HWND)m_ListView.SendMessage(LVM_GETHEADER, 0, 0); ZeroMemory(&hColumn, sizeof(hColumn)); - /* If the sorting column changed, remove the sorting style from the old column */ + // If the sorting column changed, remove sorting style from the old column if ( (m_sortInfo.nLastHeaderID != -1) && (m_sortInfo.nLastHeaderID != m_sortInfo.nHeaderID) ) { @@ -906,9 +888,6 @@ PCUITEMID_CHILD CDefView::_PidlByItem(LVITEM& lvItem) return reinterpret_cast(lvItem.lParam); } -/********************************************************** -* LV_FindItemByPidl() -*/ int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl) { ASSERT(m_ListView); @@ -924,9 +903,6 @@ int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl) return -1; } -/********************************************************** -* LV_AddItem() -*/ int CDefView::LV_AddItem(PCUITEMID_CHILD pidl) { LVITEMW lvItem; @@ -938,20 +914,17 @@ int CDefView::LV_AddItem(PCUITEMID_CHILD pidl) if (_DoFolderViewCB(SFVM_ADDINGOBJECT, 0, (LPARAM)pidl) == S_FALSE) return -1; - lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/ - lvItem.iItem = m_ListView.GetItemCount(); /*add the item to the end of the list*/ + lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; // set mask + lvItem.iItem = m_ListView.GetItemCount(); // add item to lists end lvItem.iSubItem = 0; - lvItem.lParam = reinterpret_cast(ILClone(pidl)); /*set the item's data*/ - lvItem.pszText = LPSTR_TEXTCALLBACKW; /*get text on a callback basis*/ - lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/ + lvItem.lParam = reinterpret_cast(ILClone(pidl)); // set item's data + lvItem.pszText = LPSTR_TEXTCALLBACKW; // get text on a callback basis + lvItem.iImage = I_IMAGECALLBACK; // get image on a callback basis lvItem.stateMask = LVIS_CUT; return m_ListView.InsertItem(&lvItem); } -/********************************************************** -* LV_DeleteItem() -*/ BOOLEAN CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl) { int nIndex; @@ -967,9 +940,6 @@ BOOLEAN CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl) return m_ListView.DeleteItem(nIndex); } -/********************************************************** -* LV_RenameItem() -*/ BOOLEAN CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew) { int nItem; @@ -981,35 +951,34 @@ BOOLEAN CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew nItem = LV_FindItemByPidl(pidlOld); - if ( -1 != nItem ) + if (-1 != nItem) { - lvItem.mask = LVIF_PARAM; /* only the pidl */ + lvItem.mask = LVIF_PARAM; // only the pidl lvItem.iItem = nItem; lvItem.iSubItem = 0; m_ListView.GetItem(&lvItem); - LPVOID oldPidl = reinterpret_cast(lvItem.lParam); /* Store the old pidl until the new item is replaced */ + // Store old pidl until new item is replaced + LPVOID oldPidl = reinterpret_cast(lvItem.lParam); lvItem.mask = LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT; lvItem.iItem = nItem; lvItem.iSubItem = 0; - lvItem.lParam = reinterpret_cast(ILClone(pidlNew)); /* set the item's data */ + lvItem.lParam = reinterpret_cast(ILClone(pidlNew)); // set item's data lvItem.pszText = LPSTR_TEXTCALLBACKW; lvItem.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidlNew, 0); m_ListView.SetItem(&lvItem); m_ListView.Update(nItem); - SHFree(oldPidl); /* Now that the new item is in place, we can safely release the old pidl */ + // Now that the new item is in place, we can safely release the old pidl + SHFree(oldPidl); - return TRUE; /* FIXME: better handling */ + return TRUE; // FIXME: better handling } return FALSE; } -/********************************************************** -* LV_ProdItem() -*/ BOOLEAN CDefView::LV_ProdItem(PCUITEMID_CHILD pidl) { int nItem; @@ -1035,19 +1004,12 @@ BOOLEAN CDefView::LV_ProdItem(PCUITEMID_CHILD pidl) return FALSE; } -/********************************************************** -* ShellView_FillList() -* -* - gets the objectlist from the shellfolder -* - sorts the list -* - fills the list into the view -*/ INT CALLBACK CDefView::fill_list(LPVOID ptr, LPVOID arg) { PITEMID_CHILD pidl = static_cast(ptr); CDefView *pThis = static_cast(arg); - /* in a commdlg This works as a filemask*/ + // in a commdlg this works as a filemask if (pThis->IncludeObject(pidl) == S_OK && pThis->m_ListView) pThis->LV_AddItem(pidl); @@ -1055,6 +1017,10 @@ INT CALLBACK CDefView::fill_list(LPVOID ptr, LPVOID arg) return TRUE; } +/// +// - gets the objectlist from the shellfolder +// - sorts the list +// - fills the list into the view HRESULT CDefView::FillList() { CComPtr pEnumIDList; @@ -1067,7 +1033,7 @@ HRESULT CDefView::FillList() TRACE("%p\n", this); - /* determine if there is a setting to show all the hidden files/folders */ + // determine if there is a setting to show all the hidden files/folders dwValue = 1; cbValue = sizeof(dwValue); SHGetValueW(HKEY_CURRENT_USER, @@ -1090,7 +1056,7 @@ HRESULT CDefView::FillList() m_ListView.SendMessageW(LVM_SETCALLBACKMASK, LVIS_CUT, 0); } - /* get the itemlist from the shfolder */ + // get the itemlist from the shfolder hRes = m_pSFParent->EnumObjects(m_hWnd, dFlags, &pEnumIDList); if (hRes != S_OK) { @@ -1099,14 +1065,12 @@ HRESULT CDefView::FillList() return(hRes); } - /* create a pointer array */ + // create a pointer array hdpa = DPA_Create(16); if (!hdpa) - { return(E_OUTOFMEMORY); - } - /* copy the items into the array*/ + // copy the items into the array while((S_OK == pEnumIDList->Next(1, &pidl, &dwFetched)) && dwFetched) { if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1) @@ -1115,7 +1079,7 @@ HRESULT CDefView::FillList() } } - /*turn the listview's redrawing off*/ + // turn listview's redrawing off m_ListView.SetRedraw(FALSE); DPA_DestroyCallback( hdpa, fill_list, this); @@ -1142,7 +1106,7 @@ HRESULT CDefView::FillList() m_viewinfo_data.cbSize = sizeof(m_viewinfo_data); _DoFolderViewCB(SFVM_GET_CUSTOMVIEWINFO, 0, (LPARAM)&m_viewinfo_data); - /*turn the listview's redrawing back on and force it to draw*/ + // turn listview's redrawing back on and force it to draw m_ListView.SetRedraw(TRUE); UpdateListColors(); @@ -1276,9 +1240,6 @@ VOID CDefView::OnFinalMessage(HWND) this->Release(); } -/********************************************************** -* ShellView_OnCreate() -*/ LRESULT CDefView::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { CComPtr pdt; @@ -1289,7 +1250,7 @@ LRESULT CDefView::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget, &pdt)))) { if (FAILED(RegisterDragDrop(m_hWnd, pdt))) - ERR("Registering Drag Drop Failed\n"); + ERR("Error Registering DragDrop\n"); } /* register for receiving notifications */ @@ -1323,22 +1284,22 @@ LRESULT CDefView::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, ntreg); - /* _DoFolderViewCB(SFVM_GETNOTIFY, ?? ??) */ + //_DoFolderViewCB(SFVM_GETNOTIFY, ?? ??) m_hAccel = LoadAcceleratorsW(shell32_hInstance, MAKEINTRESOURCEW(IDA_SHELLVIEW)); BOOL bPreviousParentSpecial = m_isParentFolderSpecial; - /* A folder is special if it is the Desktop folder, - * a network folder, or a Control Panel folder. */ - m_isParentFolderSpecial = _ILIsDesktop(m_pidlParent) || _ILIsNetHood(m_pidlParent) + // A folder is special if it is the Desktop folder, + // a network folder, or a Control Panel folder + m_isParentFolderSpecial = _ILIsDesktop(m_pidlParent) || _ILIsNetHood(m_pidlParent) || _ILIsControlPanel(ILFindLastID(m_pidlParent)); - /* Only force StatusBar part refresh if the state - * changed from the previous folder. */ + // Only force StatusBar part refresh if the state + // changed from the previous folder if (bPreviousParentSpecial != m_isParentFolderSpecial) { - /* This handles changing StatusBar parts. */ + // This handles changing StatusBar parts _ForceStatusBarResize(); } @@ -1347,9 +1308,7 @@ LRESULT CDefView::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl return S_OK; } -/********************************************************** - * #### Handling of the menus #### - */ +// #### Handling of the menus #### extern "C" DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID); @@ -1362,8 +1321,8 @@ HMENU GetSubmenuByID(HMENU hmenu, UINT id) return NULL; } -/* ReallyGetMenuItemID returns the id of an item even if it opens a submenu, - GetMenuItemID returns -1 if the specified item opens a submenu */ +// ReallyGetMenuItemID returns the id of an item even if it opens a submenu, +// GetMenuItemID returns -1 if the specified item opens a submenu UINT ReallyGetMenuItemID(HMENU hmenu, int i) { MENUITEMINFOW mii = {sizeof(mii), MIIM_ID}; @@ -1387,13 +1346,13 @@ HRESULT CDefView::FillFileMenu() DeleteMenu(hFileMenu, i, MF_BYPOSITION); } - /* In case we still have this left over, clean it up! */ + // In case we still have this left over, clean it up if (m_pFileMenu) { IUnknown_SetSite(m_pFileMenu, NULL); m_pFileMenu.Release(); } - /* Store the context menu in m_pFileMenu and keep it in order to invoke the selected command later on */ + // Store context menu in m_pFileMenu and keep it to invoke the selected command later on HRESULT hr = GetItemObject(SVGIO_SELECTION, IID_PPV_ARG(IContextMenu, &m_pFileMenu)); if (FAILED_UNEXPECTEDLY(hr)) return hr; @@ -1482,7 +1441,6 @@ HRESULT CDefView::FillArrangeAsMenu(HMENU hmenuArrange) CheckMenuItem(hmenuArrange, FCIDM_SHVIEW_ALIGNTOGRID, MF_UNCHECKED); } - return S_OK; } @@ -1499,14 +1457,11 @@ HRESULT CDefView::CheckViewMode(HMENU hmenuView) return S_OK; } -/********************************************************** -* ShellView_GetSelections() -* -* - fills the m_apidl list with the selected objects -* -* RETURNS -* number of selected items -*/ +/// +// - fills the m_apidl list with the selected objects +// +// RETURNS +// number of selected items UINT CDefView::GetSelections() { SHFree(m_apidl); @@ -1559,7 +1514,7 @@ HRESULT CDefView::InvokeContextMenuCommand(CComPtr& pCM, LPCSTR lp } HRESULT hr = pCM->InvokeCommand((LPCMINVOKECOMMANDINFO)&cmi); - // Most of our callers will do this, but in case they don't do that (File menu!) + // Most of our callers will do this, but if they would forget (File menu!) IUnknown_SetSite(pCM, NULL); pCM.Release(); @@ -1569,9 +1524,6 @@ HRESULT CDefView::InvokeContextMenuCommand(CComPtr& pCM, LPCSTR lp return S_OK; } -/********************************************************** - * ShellView_OpenSelectedItems() - */ HRESULT CDefView::OpenSelectedItems() { HMENU hMenu; @@ -1612,9 +1564,6 @@ HRESULT CDefView::OpenSelectedItems() return hResult; } -/********************************************************** - * ShellView_DoContextMenu() - */ LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { POINT pt; @@ -1625,7 +1574,7 @@ LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b if (m_hContextMenu != NULL) { - ERR("HACK: Aborting context menu in nested call!\n"); + ERR("HACK: Aborting context menu in nested call\n"); return 0; } @@ -1633,7 +1582,7 @@ LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b if (!m_hContextMenu) return E_FAIL; - if (lParam != ~0) // unless app key (menu key) was pressed + if (lParam != ~0) // unless app key (menu key) was pressed { pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); @@ -1652,18 +1601,18 @@ LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b } m_cidl = m_ListView.GetSelectedCount(); - /* In case we still have this left over, clean it up! */ - hResult = GetItemObject( m_cidl ? SVGIO_SELECTION : SVGIO_BACKGROUND, IID_PPV_ARG(IContextMenu, &m_pCM)); + // In case we still have this left over, clean it up + hResult = GetItemObject(m_cidl ? SVGIO_SELECTION : SVGIO_BACKGROUND, IID_PPV_ARG(IContextMenu, &m_pCM)); MenuCleanup _(m_pCM, m_hContextMenu); if (FAILED_UNEXPECTEDLY(hResult)) return 0; - /* Use 1 as the first id as we want 0 the mean that the user canceled the menu */ + // Use 1 as the first id we want. 0 means that user canceled the menu hResult = m_pCM->QueryContextMenu(m_hContextMenu, 0, CONTEXT_MENU_BASE_ID, FCIDM_SHVIEWLAST, CMF_NORMAL); if (FAILED_UNEXPECTEDLY(hResult)) return 0; - /* There is no position requested, so try to find one */ + // There is no position requested, so try to find one if (lParam == ~0) { HWND hFocus = ::GetFocus(); @@ -1671,17 +1620,17 @@ LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b if (hFocus == m_ListView.m_hWnd || m_ListView.IsChild(hFocus)) { - /* Is there an item focused and selected? */ + // Is there an item focused and selected? lvIndex = m_ListView.GetNextItem(-1, LVIS_SELECTED|LVIS_FOCUSED); - /* If not, find the first selected item */ + // If not, find the first selected item if (lvIndex < 0) lvIndex = m_ListView.GetNextItem(-1, LVIS_SELECTED); } - /* We got something */ + // We got something if (lvIndex > -1) { - /* Let's find the center of the icon */ + // Find the center of the icon RECT rc = { LVIR_ICON }; m_ListView.SendMessage(LVM_GETITEMRECT, lvIndex, (LPARAM)&rc); pt.x = (rc.right + rc.left) / 2; @@ -1689,14 +1638,14 @@ LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b } else { - /* We have to drop it somewhere.. */ + // We have to drop it somewhere pt.x = pt.y = 0; } m_ListView.ClientToScreen(&pt); } - // This runs the message loop, calling back to us with f.e. WM_INITPOPUP (hence why m_hContextMenu and m_pCM exist) + // This runs the message loop, calling back to us with f.e. WM_INITPOPUP (hence why m_hContextMenu and m_pCM exist) uCommand = TrackPopupMenu(m_hContextMenu, TPM_LEFTALIGN | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, pt.x, pt.y, 0, m_hWnd, NULL); @@ -1717,7 +1666,7 @@ LRESULT CDefView::OnExplorerCommand(UINT uCommand, BOOL bUseSelection) HMENU hMenu = NULL; CComPtr pCM; - hResult = GetItemObject( bUseSelection ? SVGIO_SELECTION : SVGIO_BACKGROUND, IID_PPV_ARG(IContextMenu, &pCM)); + hResult = GetItemObject(bUseSelection ? SVGIO_SELECTION : SVGIO_BACKGROUND, IID_PPV_ARG(IContextMenu, &pCM)); if (FAILED_UNEXPECTEDLY(hResult)) return 0; @@ -1736,7 +1685,7 @@ LRESULT CDefView::OnExplorerCommand(UINT uCommand, BOOL bUseSelection) if (bUseSelection) { - // FIXME: we should cache this.... + // FIXME: we should cache this SFGAOF rfg = SFGAO_BROWSABLE | SFGAO_CANCOPY | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSTEM | SFGAO_FOLDER; hResult = m_pSFParent->GetAttributesOf(m_cidl, m_apidl, &rfg); if (FAILED_UNEXPECTEDLY(hResult)) @@ -1759,13 +1708,8 @@ LRESULT CDefView::OnExplorerCommand(UINT uCommand, BOOL bUseSelection) return 0; } -/********************************************************** - * ##### message handling ##### - */ +// ##### message handling ##### -/********************************************************** -* ShellView_OnSize() -*/ LRESULT CDefView::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { WORD wWidth, wHeight; @@ -1790,12 +1734,7 @@ LRESULT CDefView::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled return 0; } -/********************************************************** -* ShellView_OnDeactivate() -* -* NOTES -* internal -*/ +// internal void CDefView::OnDeactivate() { TRACE("%p\n", this); @@ -1803,7 +1742,6 @@ void CDefView::OnDeactivate() if (m_uState != SVUIA_DEACTIVATE) { // TODO: cleanup menu after deactivation - m_uState = SVUIA_DEACTIVATE; } } @@ -1812,7 +1750,7 @@ void CDefView::DoActivate(UINT uState) { TRACE("%p uState=%x\n", this, uState); - /*don't do anything if the state isn't really changing */ + // don't do anything if the state isn't really changing if (m_uState == uState) { return; @@ -1865,19 +1803,12 @@ void CDefView::_DoCopyToMoveToFolder(BOOL bCopy) InvokeContextMenuCommand(pCM, (bCopy ? "copyto" : "moveto"), NULL); } -/********************************************************** -* ShellView_OnActivate() -*/ LRESULT CDefView::OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { DoActivate(SVUIA_ACTIVATE_FOCUS); return 0; } -/********************************************************** -* ShellView_OnSetFocus() -* -*/ LRESULT CDefView::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { TRACE("%p\n", this); @@ -1898,9 +1829,6 @@ LRESULT CDefView::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHan return 0; } -/********************************************************** -* ShellView_OnKillFocus() -*/ LRESULT CDefView::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { TRACE("(%p) stub\n", this); @@ -1912,12 +1840,7 @@ LRESULT CDefView::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHa return 0; } -/********************************************************** -* ShellView_OnCommand() -* -* NOTES -* the CmdID's are the ones from the context menu -*/ +// the CmdID's are the ones from the context menu LRESULT CDefView::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { DWORD dwCmdID; @@ -1938,25 +1861,21 @@ LRESULT CDefView::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHand m_ListView.ModifyStyle(LVS_TYPEMASK, LVS_SMALLICON); CheckToolbar(); break; - case FCIDM_SHVIEW_BIGICON: m_FolderSettings.ViewMode = FVM_ICON; m_ListView.ModifyStyle(LVS_TYPEMASK, LVS_ICON); CheckToolbar(); break; - case FCIDM_SHVIEW_LISTVIEW: m_FolderSettings.ViewMode = FVM_LIST; m_ListView.ModifyStyle(LVS_TYPEMASK, LVS_LIST); CheckToolbar(); break; - case FCIDM_SHVIEW_REPORTVIEW: m_FolderSettings.ViewMode = FVM_DETAILS; m_ListView.ModifyStyle(LVS_TYPEMASK, LVS_REPORT); CheckToolbar(); break; - /* the menu-ID's for sorting are 0x30... see shrec.rc */ case 0x30: case 0x31: @@ -1966,7 +1885,6 @@ LRESULT CDefView::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHand m_sortInfo.bIsAscending = TRUE; _Sort(); break; - case FCIDM_SHVIEW_SNAPTOGRID: m_ListView.Arrange(LVA_SNAPTOGRID); break; @@ -1985,17 +1903,14 @@ LRESULT CDefView::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHand case FCIDM_SHVIEW_SELECTALL: m_ListView.SetItemState(-1, LVIS_SELECTED, LVIS_SELECTED); break; - case FCIDM_SHVIEW_INVERTSELECTION: nCount = m_ListView.GetItemCount(); for (int i=0; i < nCount; i++) m_ListView.SetItemState(i, m_ListView.GetItemState(i, LVIS_SELECTED) ? 0 : LVIS_SELECTED, LVIS_SELECTED); break; - case FCIDM_SHVIEW_REFRESH: Refresh(); break; - case FCIDM_SHVIEW_DELETE: case FCIDM_SHVIEW_CUT: case FCIDM_SHVIEW_COPY: @@ -2003,29 +1918,24 @@ LRESULT CDefView::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHand case FCIDM_SHVIEW_PROPERTIES: if (SHRestricted(REST_NOVIEWCONTEXTMENU)) return 0; - return OnExplorerCommand(dwCmdID, TRUE); - case FCIDM_SHVIEW_COPYTO: case FCIDM_SHVIEW_MOVETO: _DoCopyToMoveToFolder(dwCmdID == FCIDM_SHVIEW_COPYTO); return 0; - case FCIDM_SHVIEW_INSERT: case FCIDM_SHVIEW_UNDO: case FCIDM_SHVIEW_INSERTLINK: case FCIDM_SHVIEW_NEWFOLDER: return OnExplorerCommand(dwCmdID, FALSE); default: - { - /* WM_COMMAND messages from the file menu are routed to the CDefView so as to let m_pFileMenu handle the command */ + // WM_COMMAND messages from file menu are routed to CDefView to let m_pFileMenu handle them if (m_pFileMenu && dwCmd == 0) { HMENU Dummy = NULL; MenuCleanup _(m_pFileMenu, Dummy); InvokeContextMenuCommand(m_pFileMenu, MAKEINTRESOURCEA(dwCmdID), NULL); } - } } return 0; @@ -2051,18 +1961,14 @@ SelectExtOnRename(void) return !!dwValue; } -/********************************************************** -* ShellView_OnNotify() -*/ - LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { - UINT CtlID; - LPNMHDR lpnmh; - LPNMLISTVIEW lpnmlv; - NMLVDISPINFOW *lpdi; - PCUITEMID_CHILD pidl; - BOOL unused; + UINT CtlID; + LPNMHDR lpnmh; + LPNMLISTVIEW lpnmlv; + NMLVDISPINFOW *lpdi; + PCUITEMID_CHILD pidl; + BOOL unused; CtlID = wParam; lpnmh = (LPNMHDR)lParam; @@ -2077,67 +1983,52 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl TRACE("-- NM_SETFOCUS %p\n", this); OnSetFocus(0, 0, 0, unused); break; - case NM_KILLFOCUS: TRACE("-- NM_KILLFOCUS %p\n", this); OnDeactivate(); /* Notify the ICommDlgBrowser interface */ OnStateChange(CDBOSC_KILLFOCUS); break; - case NM_CUSTOMDRAW: TRACE("-- NM_CUSTOMDRAW %p\n", this); return CDRF_DODEFAULT; - case NM_RELEASEDCAPTURE: TRACE("-- NM_RELEASEDCAPTURE %p\n", this); break; - case NM_CLICK: TRACE("-- NM_CLICK %p\n", this); break; - case NM_RCLICK: TRACE("-- NM_RCLICK %p\n", this); break; - case NM_DBLCLK: TRACE("-- NM_DBLCLK %p\n", this); OpenSelectedItems(); break; - case NM_RETURN: TRACE("-- NM_RETURN %p\n", this); OpenSelectedItems(); break; - case HDN_ENDTRACKW: TRACE("-- HDN_ENDTRACKW %p\n", this); - /*nColumn1 = m_ListView.GetColumnWidth(0); - nColumn2 = m_ListView.GetColumnWidth(1);*/ + //nColumn1 = m_ListView.GetColumnWidth(0); + //nColumn2 = m_ListView.GetColumnWidth(1); break; - case LVN_DELETEITEM: TRACE("-- LVN_DELETEITEM %p\n", this); - /*delete the pidl because we made a copy of it*/ SHFree(reinterpret_cast(lpnmlv->lParam)); - break; - case LVN_DELETEALLITEMS: TRACE("-- LVN_DELETEALLITEMS %p\n", this); return FALSE; - case LVN_INSERTITEM: TRACE("-- LVN_INSERTITEM (STUB)%p\n", this); break; - case LVN_ITEMACTIVATE: TRACE("-- LVN_ITEMACTIVATE %p\n", this); - OnStateChange(CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */ + OnStateChange(CDBOSC_SELCHANGE); // browser will get the IDataObject break; - case LVN_COLUMNCLICK: m_sortInfo.nHeaderID = lpnmlv->iSubItem; if (m_sortInfo.nLastHeaderID == m_sortInfo.nHeaderID) @@ -2146,7 +2037,6 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl m_sortInfo.bIsAscending = TRUE; _Sort(); break; - case LVN_GETDISPINFOA: case LVN_GETDISPINFOW: TRACE("-- LVN_GETDISPINFO %p\n", this); @@ -2188,25 +2078,20 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl if (SUCCEEDED(m_pSFParent->GetAttributesOf(1, &pidl, &attributes))) { if (attributes & SFGAO_HIDDEN) - { lpdi->item.state |= LVIS_CUT; - } } } lpdi->item.mask |= LVIF_DI_SETITEM; break; - case LVN_ITEMCHANGED: TRACE("-- LVN_ITEMCHANGED %p\n", this); - OnStateChange(CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */ + OnStateChange(CDBOSC_SELCHANGE); // browser will get the IDataObject UpdateStatusbar(); _DoFolderViewCB(SFVM_SELECTIONCHANGED, NULL/* FIXME */, NULL/* FIXME */); break; - case LVN_BEGINDRAG: case LVN_BEGINRDRAG: TRACE("-- LVN_BEGINDRAG\n"); - if (GetSelections()) { CComPtr pda; @@ -2218,15 +2103,11 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl LPNMLISTVIEW params = (LPNMLISTVIEW)lParam; if (SUCCEEDED(m_pSFParent->GetAttributesOf(m_cidl, m_apidl, &dwAttributes))) - { dwEffect |= dwAttributes & (SFGAO_CANCOPY | SFGAO_CANLINK); - } CComPtr piaso; if (SUCCEEDED(pda->QueryInterface(IID_PPV_ARG(IAsyncOperation, &piaso)))) - { piaso->SetAsyncMode(TRUE); - } DWORD dwEffect2; @@ -2243,14 +2124,11 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl m_ListView.GetItemPosition(params->iItem, &ptItem); ImageList_BeginDrag(big_icons, iIcon, params->ptAction.x - ptItem.x, params->ptAction.y - ptItem.y); - DoDragDrop(pda, this, dwEffect, &dwEffect2); - m_pSourceDataObject.Release(); } } break; - case LVN_BEGINLABELEDITW: { DWORD dwAttr = SFGAO_CANRENAME; @@ -2264,7 +2142,7 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl HWND hEdit = reinterpret_cast(m_ListView.SendMessage(LVM_GETEDITCONTROL)); SHLimitInputEdit(hEdit, m_pSFParent); - /* smartass-renaming: See CORE-15242 */ + // smartass-renaming: See CORE-15242 if (!(dwAttr & SFGAO_FOLDER) && (dwAttr & SFGAO_FILESYSTEM) && (lpdi->item.mask & LVIF_TEXT) && !SelectExtOnRename()) { @@ -2286,14 +2164,11 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl m_isEditing = TRUE; return FALSE; } - return TRUE; } - case LVN_ENDLABELEDITW: { TRACE("-- LVN_ENDLABELEDITW %p\n", this); - m_isEditing = FALSE; if (lpdi->item.pszText) @@ -2320,7 +2195,6 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl return FALSE; } - default: TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh->code); break; @@ -2329,12 +2203,10 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl return 0; } -/* - * This is just a quick hack to make the desktop work correctly. - * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that - * a folder should know if it should update upon a change notification. - * It is exported by merged folders at a minimum. - */ +// This is just a quick hack to make the desktop work correctly. +// ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the +// way that a folder should know if it should update upon a change notification. +// It is exported by merged folders at a minimum. static BOOL ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1, PCIDLIST_ABSOLUTE pidl2) { if (!pidl1 || !pidl2) @@ -2378,12 +2250,9 @@ static BOOL ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1, PCIDLIST_ABSOLUTE return FALSE; } -/********************************************************** -* ShellView_OnChange() -*/ LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { - // The change notify can come before WM_CREATE. + // The change notify can come before WM_CREATE if (!m_ListView) return FALSE; @@ -2411,22 +2280,16 @@ LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & if (bParent0) { if (LV_FindItemByPidl(ILFindLastID(Pidls[0])) == -1) - { LV_AddItem(ILFindLastID(Pidls[0])); - } else - { LV_ProdItem(ILFindLastID(Pidls[0])); - } } break; - case SHCNE_RMDIR: case SHCNE_DELETE: if (bParent0) LV_DeleteItem(ILFindLastID(Pidls[0])); break; - case SHCNE_RENAMEFOLDER: case SHCNE_RENAMEITEM: if (bParent0 && bParent1) @@ -2436,12 +2299,10 @@ LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & else if (bParent1) LV_AddItem(ILFindLastID(Pidls[1])); break; - case SHCNE_UPDATEITEM: if (bParent0) LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[0])); break; - case SHCNE_UPDATEDIR: Refresh(); break; @@ -2454,20 +2315,17 @@ LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & HRESULT SHGetMenuIdFromMenuMsg(UINT uMsg, LPARAM lParam, UINT *CmdId); HRESULT SHSetMenuIdInMenuMsg(UINT uMsg, LPARAM lParam, UINT CmdId); -/********************************************************** -* CDefView::OnCustomItem -*/ LRESULT CDefView::OnCustomItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { if (!m_pCM) { /* no menu */ - ERR("no context menu!!!\n"); + ERR("no context menu\n"); return FALSE; } - /* The lParam of WM_DRAWITEM WM_MEASUREITEM contain a menu id and this also needs to - be changed to a menu identifier offset */ + // lParam of WM_DRAWITEM WM_MEASUREITEM contains a menu id and + // this also needs to be changed to a menu identifier offset UINT CmdID; HRESULT hres = SHGetMenuIdFromMenuMsg(uMsg, lParam, &CmdID); if (SUCCEEDED(hres)) @@ -2489,9 +2347,6 @@ LRESULT CDefView::OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL return S_OK; } -/********************************************************** -* CDefView::OnInitMenuPopup -*/ LRESULT CDefView::OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { HMENU hmenu = (HMENU) wParam; @@ -2499,9 +2354,7 @@ LRESULT CDefView::OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL UINT menuItemId; if (m_pCM) - { OnCustomItem(uMsg, wParam, lParam, bHandled); - } HMENU hViewMenu = GetSubmenuByID(m_hMenu, FCIDM_MENU_VIEW); @@ -2552,18 +2405,9 @@ LRESULT CDefView::OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL return FALSE; } -/********************************************************** -* -* -* The INTERFACE of the IShellView object -* -* -********************************************************** -*/ -/********************************************************** -* ShellView_GetWindow -*/ +// The INTERFACE of the IShellView object + HRESULT WINAPI CDefView::GetWindow(HWND *phWnd) { TRACE("(%p)\n", this); @@ -2580,12 +2424,7 @@ HRESULT WINAPI CDefView::ContextSensitiveHelp(BOOL fEnterMode) return E_NOTIMPL; } -/********************************************************** -* IShellView_TranslateAccelerator -* -* FIXME: -* use the accel functions -*/ +// FIXME: use the accel functions HRESULT WINAPI CDefView::TranslateAccelerator(LPMSG lpmsg) { if (m_isEditing) @@ -2596,7 +2435,7 @@ HRESULT WINAPI CDefView::TranslateAccelerator(LPMSG lpmsg) if (::TranslateAcceleratorW(m_hWnd, m_hAccel, lpmsg) != 0) return S_OK; - TRACE("-- key=0x%04lx\n", lpmsg->wParam) ; + TRACE("-- key=0x%04lx\n", lpmsg->wParam); } return m_pShellBrowser->TranslateAcceleratorSB(lpmsg, 0); @@ -2604,30 +2443,27 @@ HRESULT WINAPI CDefView::TranslateAccelerator(LPMSG lpmsg) HRESULT WINAPI CDefView::EnableModeless(BOOL fEnable) { - FIXME("(%p) stub\n", this); - + FIXME("(%p)\n", this); return E_NOTIMPL; } HRESULT WINAPI CDefView::UIActivate(UINT uState) { - TRACE("(%p)->(state=%x) stub\n", this, uState); + TRACE("(%p)->(state=%x)\n", this, uState); - /* don't do anything if the state isn't really changing */ + // don't do anything if the state isn't changing if (m_uState == uState) - { return S_OK; - } - /* OnActivate handles the menu merging and internal state */ + // OnActivate handles the menu merging and internal state DoActivate(uState); - /* only do This if we are active */ + // only do this if we are active if (uState != SVUIA_DEACTIVATE) { _ForceStatusBarResize(); - /* Set the text for the status bar */ + // Set the text for the status bar UpdateStatusbar(); } @@ -2661,7 +2497,7 @@ HRESULT WINAPI CDefView::DestroyViewWindow() if (m_hAccel) { - // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN + // MSDN: Accelerator tables loaded from resources are freed automatically when application terminates m_hAccel = NULL; } @@ -2815,7 +2651,6 @@ HRESULT WINAPI CDefView::GetItemObject(UINT uItem, REFIID riid, LPVOID *ppvOut) hr = m_pShellFolderViewDual->QueryInterface(riid, ppvOut); } break; - case SVGIO_SELECTION: GetSelections(); hr = m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, m_apidl, riid, 0, ppvOut); @@ -3050,9 +2885,8 @@ HRESULT STDMETHODCALLTYPE CDefView::SelectAndPositionItems(UINT cidl, PCUITEMID_ return S_OK; } -/********************************************************** - * IShellView2 implementation - */ + +// IShellView2 implementation HRESULT STDMETHODCALLTYPE CDefView::GetView(SHELLVIEWID *view_guid, ULONG view_type) { @@ -3159,9 +2993,8 @@ HRESULT STDMETHODCALLTYPE CDefView::SelectAndPositionItem(LPCITEMIDLIST item, UI return E_NOTIMPL; } -/********************************************************** - * IShellFolderView implementation - */ +// IShellFolderView implementation + HRESULT STDMETHODCALLTYPE CDefView::Rearrange(LPARAM sort) { FIXME("(%p)->(%ld) stub\n", this, sort); @@ -3378,9 +3211,6 @@ HRESULT STDMETHODCALLTYPE CDefView::SetAutomationObject(IDispatch *disp) return E_NOTIMPL; } -/********************************************************** - * ISVOleCmdTarget_QueryStatus (IOleCommandTarget) - */ HRESULT WINAPI CDefView::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT *pCmdText) { FIXME("(%p)->(%p(%s) 0x%08x %p %p\n", @@ -3398,11 +3228,10 @@ HRESULT WINAPI CDefView::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLE return OLECMDERR_E_UNKNOWNGROUP; } -/********************************************************** - * ISVOleCmdTarget_Exec (IOleCommandTarget) - * - * nCmdID is the OLECMDID_* enumeration - */ +/// +// ISVOleCmdTarget_Exec(IOleCommandTarget) +// +// nCmdID is the OLECMDID_* enumeration HRESULT WINAPI CDefView::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) { FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n", @@ -3424,7 +3253,7 @@ HRESULT WINAPI CDefView::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCm if (m_hMenuViewModes) { - /* Duplicate all but the last two items of the view modes menu */ + // Duplicate all but the last two items of the view modes menu HMENU hmenuViewPopup = CreatePopupMenu(); Shell_MergeMenus(hmenuViewPopup, m_hMenuViewModes, 0, 0, 0xFFFF, 0); DeleteMenu(hmenuViewPopup, GetMenuItemCount(hmenuViewPopup) - 1, MF_BYPOSITION); @@ -3477,8 +3306,8 @@ HRESULT CDefView::drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEf to remember the last key state when the button was pressed */ m_grfKeyState = grfKeyState; - /* Map from global to client coordinates and query the index of the listview-item, which is - * currently under the mouse cursor. */ + // Map from global to client coordinates and query the index of the + // listview-item, which is currently under the mouse cursor. LVHITTESTINFO htinfo = {{pt.x, pt.y}, LVHT_ONITEM}; ScreenToClient(&htinfo.pt); lResult = m_ListView.HitTest(&htinfo); @@ -3487,9 +3316,9 @@ HRESULT CDefView::drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEf ::GetClientRect(m_ListView, &clientRect); if (htinfo.pt.x == m_ptLastMousePos.x && htinfo.pt.y == m_ptLastMousePos.y && (htinfo.pt.x < SCROLLAREAWIDTH || htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH || - htinfo.pt.y < SCROLLAREAWIDTH || htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH )) + htinfo.pt.y < SCROLLAREAWIDTH || htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH)) { - m_cScrollDelay = (m_cScrollDelay + 1) % 5; /* DragOver is called every 50 ms */ + m_cScrollDelay = (m_cScrollDelay + 1) % 5; // DragOver is called every 50 ms if (m_cScrollDelay == 0) { /* Mouse did hover another 250 ms over the scroll-area */ @@ -3508,7 +3337,7 @@ HRESULT CDefView::drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEf } else { - m_cScrollDelay = 0; /* Reset, if the cursor is not over the listview's scroll-area */ + m_cScrollDelay = 0; // Reset, if cursor is not over the listview's scroll-area } m_ptLastMousePos = htinfo.pt; @@ -3530,11 +3359,11 @@ HRESULT CDefView::drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEf } } - /* If we are still over the previous sub-item, notify it via DragOver and return. */ + // If we are still over the previous sub-item, notify it via DragOver and return if (m_pCurDropTarget && lResult == m_iDragOverItem) return m_pCurDropTarget->DragOver(grfKeyState, pt, pdwEffect); - /* We've left the previous sub-item, notify it via DragLeave and Release it. */ + // We've left the previous sub-item, notify it via DragLeave and release it if (m_pCurDropTarget) { PCUITEMID_CHILD pidl = _PidlByItem(m_iDragOverItem); @@ -3549,23 +3378,23 @@ HRESULT CDefView::drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEf if (lResult == -1) { - /* We are not above one of the listview's subitems. Bind to the parent folder's - * DropTarget interface. */ + // We are not above one of the listview's subitems. Bind to the + // parent folder's DropTarget interface. hr = m_pSFParent->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget,&m_pCurDropTarget)); } else { - /* Query the relative PIDL of the shellfolder object represented by the currently - * dragged over listview-item ... */ + // Query the relative PIDL of the shellfolder object represented + // by the currently dragged over listview-item ... PCUITEMID_CHILD pidl = _PidlByItem(lResult); - /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */ + // ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object hr = m_pSFParent->GetUIObjectOf(m_ListView, 1, &pidl, IID_NULL_PPV_ARG(IDropTarget, &m_pCurDropTarget)); } IUnknown_SetSite(m_pCurDropTarget, (IShellView *)this); - /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */ + // If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state if (FAILED(hr)) { *pdwEffect = DROPEFFECT_NONE; @@ -3577,7 +3406,7 @@ HRESULT CDefView::drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEf SelectItem(m_iDragOverItem, SVSI_SELECT); } - /* Notify the item just entered via DragEnter. */ + // Notify the item just entered via DragEnter return m_pCurDropTarget->DragEnter(m_pCurDataObject, grfKeyState, pt, pdwEffect); } @@ -3636,7 +3465,7 @@ INT CDefView::_FindInsertableIndexFromPoint(POINT pt) INT dx, dy; BOOL bSmall = ((m_ListView.GetStyle() & LVS_TYPEMASK) != LVS_ICON); - /* FIXME: LVM_GETORIGIN is broken. See CORE-17266 */ + // FIXME: LVM_GETORIGIN is broken. See CORE-17266 pt.x += m_ListView.GetScrollPos(SB_HORZ); pt.y += m_ListView.GetScrollPos(SB_VERT); @@ -3713,28 +3542,28 @@ void CDefView::_HandleStatusBarResize(int nWidth) const int nLocationPartLength = 150; const int nRightPartsLength = nFileSizePartLength + nLocationPartLength; int nObjectsPartLength = nWidth - nRightPartsLength; - - /* If the window is small enough just divide each part into thirds - * This is the behavior of Windows Server 2003. */ + + // If the window is small enough just divide each part into thirds + // to match the behavior of Windows Server 2003 if (nObjectsPartLength <= nLocationPartLength) nObjectsPartLength = nFileSizePartLength = nWidth / 3; int nPartArray[] = {nObjectsPartLength, nObjectsPartLength + nFileSizePartLength, -1}; - + m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETPARTS, _countof(nPartArray), (LPARAM)nPartArray, &lResult); } void CDefView::_ForceStatusBarResize() { - /* Get the handle for the status bar */ + // Get the handle for the status bar HWND fStatusBar; m_pShellBrowser->GetControlWindow(FCW_STATUS, &fStatusBar); - /* Get the size of our status bar */ + // Get the size of our status bar RECT statusBarSize; ::GetWindowRect(fStatusBar, &statusBarSize); - /* Resize the status bar */ + // Resize the status bar _HandleStatusBarResize(statusBarSize.right - statusBarSize.left); } @@ -3864,10 +3693,6 @@ HRESULT WINAPI CDefView::Drop(IDataObject* pDataObject, DWORD grfKeyState, POINT return S_OK; } -/********************************************************** - * ISVDropSource implementation - */ - HRESULT WINAPI CDefView::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) { TRACE("(%p)\n", this); @@ -3887,35 +3712,27 @@ HRESULT WINAPI CDefView::GiveFeedback(DWORD dwEffect) return DRAGDROP_S_USEDEFAULTCURSORS; } -/********************************************************** - * ISVViewObject implementation - */ - HRESULT WINAPI CDefView::Draw(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue), ULONG_PTR dwContinue) { FIXME("Stub: this=%p\n", this); - return E_NOTIMPL; } HRESULT WINAPI CDefView::GetColorSet(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDevice, LOGPALETTE **ppColorSet) { FIXME("Stub: this=%p\n", this); - return E_NOTIMPL; } HRESULT WINAPI CDefView::Freeze(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze) { FIXME("Stub: this=%p\n", this); - return E_NOTIMPL; } HRESULT WINAPI CDefView::Unfreeze(DWORD dwFreeze) { FIXME("Stub: this=%p\n", this); - return E_NOTIMPL; } @@ -3923,7 +3740,7 @@ HRESULT WINAPI CDefView::SetAdvise(DWORD aspects, DWORD advf, IAdviseSink *pAdvS { FIXME("partial stub: %p 0x%08x 0x%08x %p\n", this, aspects, advf, pAdvSink); - /* FIXME: we set the AdviseSink, but never use it to send any advice */ + // FIXME: we set the AdviseSink, but never use it to send any advice m_pAdvSink = pAdvSink; m_dwAspects = aspects; m_dwAdvf = advf; @@ -4005,8 +3822,8 @@ HRESULT CDefView_CreateInstance(IShellFolder *pFolder, REFIID riid, LPVOID * ppv } HRESULT WINAPI SHCreateShellFolderViewEx( - LPCSFV psvcbi, /* [in] shelltemplate struct */ - IShellView **ppsv) /* [out] IShellView pointer */ + LPCSFV psvcbi, // [in] shelltemplate struct + IShellView **ppsv) // [out] IShellView pointer { CComPtr psv; HRESULT hRes; @@ -4025,7 +3842,7 @@ HRESULT WINAPI SHCreateShellFolderViewEx( } HRESULT WINAPI SHCreateShellFolderView(const SFV_CREATE *pcsfv, - IShellView **ppsv) + IShellView **ppsv) { CComPtr psv; HRESULT hRes; diff --git a/dll/win32/shell32/CDefaultContextMenu.cpp b/dll/win32/shell32/CDefaultContextMenu.cpp index 72913f36918..4d0f34a47d4 100644 --- a/dll/win32/shell32/CDefaultContextMenu.cpp +++ b/dll/win32/shell32/CDefaultContextMenu.cpp @@ -1193,7 +1193,7 @@ CDefaultContextMenu::TryToBrowse( hr = SHILCombine(m_pidlFolder, pidlChild, &pidl); if (FAILED_UNEXPECTEDLY(hr)) return hr; - + hr = psb->BrowseObject(pidl, wFlags & ~SBSP_RELATIVE); ILFree(pidl); return hr; diff --git a/dll/win32/shell32/COpenWithMenu.cpp b/dll/win32/shell32/COpenWithMenu.cpp index 759f6c41436..feb30a3a091 100644 --- a/dll/win32/shell32/COpenWithMenu.cpp +++ b/dll/win32/shell32/COpenWithMenu.cpp @@ -716,7 +716,7 @@ BOOL COpenWithList::SetDefaultHandler(SApp *pApp, LPCWSTR pwszFilename) /* Create file extension key */ if (RegCreateKeyExW(HKEY_CLASSES_ROOT, pwszExt, 0, NULL, 0, KEY_READ|KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS) { - ERR("Cannot open ext key\n"); + ERR("Can't open ext key\n"); return FALSE; } @@ -870,7 +870,7 @@ BOOL COpenWithDialog::IsNoOpen(HWND hwnd) return TRUE; else if (dReturnValue == -1) { - ERR("IsNoOpen failed to load the dialog box.\n"); + ERR("IsNoOpen failed to load dialog box\n"); return TRUE; } } diff --git a/dll/win32/shell32/CShellLink.cpp b/dll/win32/shell32/CShellLink.cpp index bdd1b617082..aa1fbfbaba5 100644 --- a/dll/win32/shell32/CShellLink.cpp +++ b/dll/win32/shell32/CShellLink.cpp @@ -2572,7 +2572,7 @@ HRESULT STDMETHODCALLTYPE CShellLink::InvokeCommand(LPCMINVOKECOMMANDINFO lpici) HRESULT hr = Resolve(lpici->hwnd, 0); if (FAILED(hr)) { - TRACE("failed to resolve component with error 0x%08x\n", hr); + TRACE("failed to resolve component error 0x%08x\n", hr); return hr; } diff --git a/dll/win32/shell32/dialogs/folder_options.cpp b/dll/win32/shell32/dialogs/folder_options.cpp index bad8fc484c8..ea0e4ed4b4b 100644 --- a/dll/win32/shell32/dialogs/folder_options.cpp +++ b/dll/win32/shell32/dialogs/folder_options.cpp @@ -283,7 +283,7 @@ Options_RunDLLCommon(HWND hWnd, HINSTANCE hInst, int fOptions, DWORD nCmdShow) case 1: // show taskbar options dialog - FIXME("notify explorer to show taskbar options dialog\n"); + FIXME("notify explorer to show taskbar options dlg\n"); //PostMessage(GetShellWindow(), WM_USER+22, fOptions, 0); break; diff --git a/dll/win32/shell32/droptargets/CFSDropTarget.cpp b/dll/win32/shell32/droptargets/CFSDropTarget.cpp index f480ffa9808..4d9e506f870 100644 --- a/dll/win32/shell32/droptargets/CFSDropTarget.cpp +++ b/dll/win32/shell32/droptargets/CFSDropTarget.cpp @@ -491,7 +491,7 @@ HRESULT CFSDropTarget::_DoDrop(IDataObject *pDataObject, if (SUCCEEDED(pDataObject->QueryGetData(&fmt))) { hr = pDataObject->GetData(&fmt, &medium); - TRACE("CFSTR_SHELLIDLIST.\n"); + TRACE("CFSTR_SHELLIDLIST\n"); if (FAILED(hr)) { ERR("CFSTR_SHELLIDLIST failed\n"); @@ -721,7 +721,7 @@ HRESULT CFSDropTarget::_DoDrop(IDataObject *pDataObject, } else { - ERR("No viable drop format.\n"); + ERR("No viable drop format\n"); hr = E_FAIL; } return hr; diff --git a/dll/win32/shell32/folders/CControlPanelFolder.cpp b/dll/win32/shell32/folders/CControlPanelFolder.cpp index 085b074ee18..7306862f966 100644 --- a/dll/win32/shell32/folders/CControlPanelFolder.cpp +++ b/dll/win32/shell32/folders/CControlPanelFolder.cpp @@ -411,7 +411,7 @@ HRESULT WINAPI CControlPanelFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_A else if (_ILIsSpecialFolder(*apidl)) m_regFolder->GetAttributesOf(1, apidl, rgfInOut); else - ERR("Got an unknown pidl here!\n"); + ERR("Got unknown pidl\n"); apidl++; cidl--; } @@ -448,7 +448,6 @@ HRESULT WINAPI CControlPanelFolder::GetUIObjectOf(HWND hwndOwner, *ppvOut = NULL; if (IsEqualIID(riid, IID_IContextMenu) && (cidl >= 1)) { - /* HACK: We should use callbacks from CDefaultContextMenu instead of creating one on our own */ BOOL bHasCpl = FALSE; for (UINT i = 0; i < cidl; i++) diff --git a/dll/win32/shell32/folders/CDrivesFolder.cpp b/dll/win32/shell32/folders/CDrivesFolder.cpp index 2293884e9ea..cf76b47392d 100644 --- a/dll/win32/shell32/folders/CDrivesFolder.cpp +++ b/dll/win32/shell32/folders/CDrivesFolder.cpp @@ -24,7 +24,7 @@ #include #include -WINE_DEFAULT_DEBUG_CHANNEL (shell); +WINE_DEFAULT_DEBUG_CHANNEL(shell); /* CDrivesFolder should create a CRegFolder to represent the virtual items that exist only in @@ -599,7 +599,7 @@ CDrivesFolder::CDrivesFolder() CDrivesFolder::~CDrivesFolder() { - TRACE ("-- destroying IShellFolder(%p)\n", this); + TRACE("-- destroying IShellFolder(%p)\n", this); SHFree(pidlRoot); } @@ -680,13 +680,13 @@ HRESULT WINAPI CDrivesFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLEST else if (_ILIsSpecialFolder(pidlTemp)) m_regFolder->GetAttributesOf(1, &pidlTemp, pdwAttributes); else - ERR("Got an unknown pidl here!\n"); + ERR("Got unknown pidl\n"); } } *ppidl = pidlTemp; - TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr); + TRACE("(%p)->(-- ret=0x%08x)\n", this, hr); return hr; } @@ -867,7 +867,7 @@ HRESULT WINAPI CDrivesFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVO SFV_CREATE sfvparams = {sizeof(SFV_CREATE), this}; hr = SHCreateShellFolderView(&sfvparams, (IShellView**)ppvOut); } - TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut); + TRACE("-- (%p)->(interface=%p)\n", this, ppvOut); return hr; } @@ -876,8 +876,8 @@ HRESULT WINAPI CDrivesFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVO */ HRESULT WINAPI CDrivesFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD * rgfInOut) { - TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n", - this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0); + TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n", + this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0); if (cidl && !apidl) return E_INVALIDARG; @@ -911,7 +911,7 @@ HRESULT WINAPI CDrivesFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY a /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */ *rgfInOut &= ~SFGAO_VALIDATE; - TRACE ("-- result=0x%08x\n", *rgfInOut); + TRACE("-- result=0x%08x\n", *rgfInOut); return S_OK; } @@ -951,8 +951,8 @@ HRESULT WINAPI CDrivesFolder::GetUIObjectOf(HWND hwndOwner, } else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1)) { - hr = IDataObject_Constructor (hwndOwner, - pidlRoot, apidl, cidl, TRUE, (IDataObject **)&pObj); + hr = IDataObject_Constructor(hwndOwner, + pidlRoot, apidl, cidl, TRUE, (IDataObject **)&pObj); } else if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1)) { @@ -977,7 +977,7 @@ HRESULT WINAPI CDrivesFolder::GetUIObjectOf(HWND hwndOwner, hr = E_OUTOFMEMORY; *ppvOut = pObj; - TRACE ("(%p)->hr=0x%08x\n", this, hr); + TRACE("(%p)->hr=0x%08x\n", this, hr); return hr; } @@ -989,7 +989,7 @@ HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFla LPWSTR pszPath; HRESULT hr = S_OK; - TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet); + TRACE("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet); pdump (pidl); if (!strRet) @@ -1029,9 +1029,9 @@ HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFla DWORD dwVolumeSerialNumber, dwMaximumComponentLength, dwFileSystemFlags; GetVolumeInformationW(wszDrive, pszPath, - MAX_PATH - 7, - &dwVolumeSerialNumber, - &dwMaximumComponentLength, &dwFileSystemFlags, NULL, 0); + MAX_PATH - 7, + &dwVolumeSerialNumber, + &dwMaximumComponentLength, &dwFileSystemFlags, NULL, 0); pszPath[MAX_PATH-1] = L'\0'; if (!wcslen(pszPath)) @@ -1062,10 +1062,10 @@ HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFla } } } - wcscat (pszPath, L" ("); + wcscat(pszPath, L" ("); wszDrive[2] = L'\0'; - wcscat (pszPath, wszDrive); - wcscat (pszPath, L")"); + wcscat(pszPath, wszDrive); + wcscat(pszPath, L")"); } if (SUCCEEDED(hr)) @@ -1111,19 +1111,19 @@ HRESULT WINAPI CDrivesFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, HRESULT WINAPI CDrivesFolder::GetDefaultSearchGUID(GUID * pguid) { - FIXME ("(%p)\n", this); + FIXME("(%p)\n", this); return E_NOTIMPL; } HRESULT WINAPI CDrivesFolder::EnumSearches(IEnumExtraSearch ** ppenum) { - FIXME ("(%p)\n", this); + FIXME("(%p)\n", this); return E_NOTIMPL; } HRESULT WINAPI CDrivesFolder::GetDefaultColumn (DWORD dwRes, ULONG *pSort, ULONG *pDisplay) { - TRACE ("(%p)\n", this); + TRACE("(%p)\n", this); if (pSort) *pSort = 0; @@ -1134,7 +1134,7 @@ HRESULT WINAPI CDrivesFolder::GetDefaultColumn (DWORD dwRes, ULONG *pSort, ULONG HRESULT WINAPI CDrivesFolder::GetDefaultColumnState(UINT iColumn, DWORD * pcsFlags) { - TRACE ("(%p)\n", this); + TRACE("(%p)\n", this); if (!pcsFlags || iColumn >= _countof(MyComputerSFHeader)) return E_INVALIDARG; @@ -1144,7 +1144,7 @@ HRESULT WINAPI CDrivesFolder::GetDefaultColumnState(UINT iColumn, DWORD * pcsFla HRESULT WINAPI CDrivesFolder::GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID * pscid, VARIANT * pv) { - FIXME ("(%p)\n", this); + FIXME("(%p)\n", this); return E_NOTIMPL; } @@ -1152,7 +1152,7 @@ HRESULT WINAPI CDrivesFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, S { HRESULT hr; - TRACE ("(%p)->(%p %i %p)\n", this, pidl, iColumn, psd); + TRACE("(%p)->(%p %i %p)\n", this, pidl, iColumn, psd); if (!psd || iColumn >= _countof(MyComputerSFHeader)) return E_INVALIDARG; @@ -1232,7 +1232,7 @@ HRESULT WINAPI CDrivesFolder::MapColumnToSCID(UINT column, SHCOLUMNID * pscid) */ HRESULT WINAPI CDrivesFolder::GetClassID(CLSID *lpClassId) { - TRACE ("(%p)\n", this); + TRACE("(%p)\n", this); if (!lpClassId) return E_POINTER; diff --git a/dll/win32/shell32/folders/CRegFolder.cpp b/dll/win32/shell32/folders/CRegFolder.cpp index 5b2d513569b..6c5c3f7f3cb 100644 --- a/dll/win32/shell32/folders/CRegFolder.cpp +++ b/dll/win32/shell32/folders/CRegFolder.cpp @@ -513,7 +513,7 @@ HRESULT WINAPI CRegFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apid if (_ILIsSpecialFolder(*apidl)) GetGuidItemAttributes(*apidl, rgfInOut); else - ERR("Got an unknown pidl here!\n"); + ERR("Got unknown pidl\n"); apidl++; cidl--; } diff --git a/dll/win32/shell32/shellmenu/CStartMenu.cpp b/dll/win32/shell32/shellmenu/CStartMenu.cpp index 85d61e9f3f7..311b6516124 100644 --- a/dll/win32/shell32/shellmenu/CStartMenu.cpp +++ b/dll/win32/shell32/shellmenu/CStartMenu.cpp @@ -533,7 +533,7 @@ RSHELL_CStartMenu_CreateInstance(REFIID riid, void **ppv) hr = SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAMS, &pidlProgramsAbsolute); if (FAILED_UNEXPECTEDLY(hr)) { - WARN("USER Programs folder not found.\n"); + WARN("USER Programs folder not found\n"); hr = SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_PROGRAMS, &pidlProgramsAbsolute); if (FAILED_UNEXPECTEDLY(hr)) return hr; diff --git a/dll/win32/shell32/shlfolder.cpp b/dll/win32/shell32/shlfolder.cpp index 92dff6c81ef..d4146506038 100644 --- a/dll/win32/shell32/shlfolder.cpp +++ b/dll/win32/shell32/shlfolder.cpp @@ -26,7 +26,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); - /*************************************************************************** * GetNextElement (internal function) * @@ -424,8 +423,6 @@ SHOpenFolderAndSelectItems(PCIDLIST_ABSOLUTE pidlFolder, return E_FAIL; } - - static DWORD WINAPI _ShowPropertiesDialogThread(LPVOID lpParameter) diff --git a/sdk/lib/3rdparty/libwine/path.c b/sdk/lib/3rdparty/libwine/path.c index d8f11bdafc5..8c620024e11 100644 --- a/sdk/lib/3rdparty/libwine/path.c +++ b/sdk/lib/3rdparty/libwine/path.c @@ -61,6 +61,8 @@ WCHAR * CDECL wine_get_dos_file_name( LPCSTR str ) #ifdef __REACTOS__ ERR("Got absolute UNIX path name in function wine_get_dos_file_name. This is not UNIX. Please fix the caller!\n"); ERR("File name: %s\n", str); + /* Return empty path */ + return RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, 1 * sizeof(UNICODE_NULL)); #else len += 8; /* \??\unix prefix */ if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL; diff --git a/sdk/lib/cicero/cicbase.cpp b/sdk/lib/cicero/cicbase.cpp index cf76100e1cd..5c93f858d54 100644 --- a/sdk/lib/cicero/cicbase.cpp +++ b/sdk/lib/cicero/cicbase.cpp @@ -254,13 +254,3 @@ TFInitLib(FN_CoCreateInstance fnCoCreateInstance) _cicGetSetUserCoCreateInstance(fnCoCreateInstance); return TRUE; } - -/** - * @unimplemented - */ -EXTERN_C -VOID -TFUninitLib(VOID) -{ - //FIXME -} diff --git a/sdk/lib/cicero/cicutb.h b/sdk/lib/cicero/cicutb.h index b831ecc82bf..18bfbc874f0 100644 --- a/sdk/lib/cicero/cicutb.h +++ b/sdk/lib/cicero/cicutb.h @@ -17,10 +17,12 @@ DEFINE_GUID(IID_ITfLangBarMgr_P, 0xD72C0FA9, 0xADD5, 0x4AF0, 0x87, DEFINE_GUID(IID_ITfLangBarEventSink_P, 0x7A460360, 0xDA21, 0x4B09, 0xA8, 0xA0, 0x8A, 0x69, 0xE7, 0x28, 0xD8, 0x93); DEFINE_GUID(CLSID_MSUTBDeskBand, 0x540D8A8B, 0x1C3F, 0x4E32, 0x81, 0x32, 0x53, 0x0F, 0x6A, 0x50, 0x20, 0x90); DEFINE_GUID(CATID_DeskBand, 0x00021492, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); +DEFINE_GUID( + GUID_TFCAT_DISPLAYATTRIBUTEPROPERTY, 0xB95F181B, 0xEA4C, 0x4AF1, 0x80, 0x56, 0x7C, 0x32, 0x1A, 0xBB, 0xB0, 0x91); typedef struct CIC_LIBTHREAD { - IUnknown *m_pUnknown1; + ITfCategoryMgr *m_pCategoryMgr; ITfDisplayAttributeMgr *m_pDisplayAttrMgr; } CIC_LIBTHREAD, *PCIC_LIBTHREAD; @@ -44,10 +46,10 @@ inline void TFUninitLib_Thread(PCIC_LIBTHREAD pLibThread) if (!pLibThread) return; - if (pLibThread->m_pUnknown1) + if (pLibThread->m_pCategoryMgr) { - pLibThread->m_pUnknown1->Release(); - pLibThread->m_pUnknown1 = NULL; + pLibThread->m_pCategoryMgr->Release(); + pLibThread->m_pCategoryMgr = NULL; } if (pLibThread->m_pDisplayAttrMgr) {