ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
January 2018
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
37 participants
372 discussions
Start a n
N
ew thread
01/01: [NTOSKRNL] Allow pinned dirty VACB to be lazy written. This is an addition to 07e6e9c. Also, fix a cppcheck warning (so minor!).
by Pierre Schweitzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2362e0faae65397fb50c7…
commit 2362e0faae65397fb50c7072f83a8b5f8cfe2282 Author: Pierre Schweitzer <pierre(a)reactos.org> AuthorDate: Thu Jan 25 21:56:19 2018 +0100 Commit: Pierre Schweitzer <pierre(a)reactos.org> CommitDate: Thu Jan 25 22:00:20 2018 +0100 [NTOSKRNL] Allow pinned dirty VACB to be lazy written. This is an addition to 07e6e9c. Also, fix a cppcheck warning (so minor!). CORE-14249 --- ntoskrnl/cc/view.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c index 6f4457f5bf..e8da9a51c8 100644 --- a/ntoskrnl/cc/view.c +++ b/ntoskrnl/cc/view.c @@ -250,7 +250,8 @@ CcRosFlushDirtyPages ( ASSERT(current->Dirty); /* One reference is added above */ - if (current->ReferenceCount > 2) + if ((current->ReferenceCount > 2 && current->PinCount == 0) || + (current->ReferenceCount > 3 && current->PinCount > 1)) { CcRosReleaseVacbLock(current); current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite( @@ -883,7 +884,7 @@ CcRosCreateVacb ( #if MI_TRACE_PFNS if ((SharedCacheMap->FileObject) && (SharedCacheMap->FileObject->FileName.Buffer)) { - PWCHAR pos = NULL; + PWCHAR pos; ULONG len = 0; pos = wcsrchr(SharedCacheMap->FileObject->FileName.Buffer, '\\'); if (pos)
6 years, 11 months
1
0
0
0
01/01: [NTOSKRNL] Contrary to WinDBG !filecache, we don't display CONTROL_AREA but shared cache map
by Pierre Schweitzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9c27193a43535f0387a09…
commit 9c27193a43535f0387a09ad9873b7ca2b387f255 Author: Pierre Schweitzer <pierre(a)reactos.org> AuthorDate: Thu Jan 25 13:47:00 2018 +0100 Commit: Pierre Schweitzer <pierre(a)reactos.org> CommitDate: Thu Jan 25 13:47:00 2018 +0100 [NTOSKRNL] Contrary to WinDBG !filecache, we don't display CONTROL_AREA but shared cache map --- ntoskrnl/cc/view.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c index f58fa5d3cc..6f4457f5bf 100644 --- a/ntoskrnl/cc/view.c +++ b/ntoskrnl/cc/view.c @@ -1500,7 +1500,8 @@ ExpKdbgExtFileCache(ULONG Argc, PCHAR Argv[]) PLIST_ENTRY ListEntry; UNICODE_STRING NoName = RTL_CONSTANT_STRING(L"No name for File"); - KdbpPrint("Control\t\tValid\tDirty\tName\n"); + KdbpPrint(" Usage Summary (in kb)\n"); + KdbpPrint("Shared\t\tValid\tDirty\tName\n"); /* No need to lock the spin lock here, we're in DBG */ for (ListEntry = CcCleanSharedCacheMapList.Flink; ListEntry != &CcCleanSharedCacheMapList;
6 years, 11 months
1
0
0
0
01/01: [NTOSKRNL] Fix MSVC build?
by Pierre Schweitzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5c52ae66950007d72f1d7…
commit 5c52ae66950007d72f1d72c336f9a129f625f173 Author: Pierre Schweitzer <pierre(a)reactos.org> AuthorDate: Wed Jan 24 22:03:23 2018 +0100 Commit: Pierre Schweitzer <pierre(a)reactos.org> CommitDate: Wed Jan 24 22:03:23 2018 +0100 [NTOSKRNL] Fix MSVC build? --- ntoskrnl/cc/view.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c index adf79eba7d..f58fa5d3cc 100644 --- a/ntoskrnl/cc/view.c +++ b/ntoskrnl/cc/view.c @@ -1493,6 +1493,7 @@ CcInitView ( return TRUE; } +#if DBG && defined(KDBG) BOOLEAN ExpKdbgExtFileCache(ULONG Argc, PCHAR Argv[]) { @@ -1547,5 +1548,6 @@ ExpKdbgExtFileCache(ULONG Argc, PCHAR Argv[]) return TRUE; } +#endif /* EOF */
6 years, 11 months
1
0
0
0
02/02: [NTOSKRNL] Implement (it's a bit raw for now!) the !filecache command in KDBG
by Pierre Schweitzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cb52c8212501589681aa8…
commit cb52c8212501589681aa8927ede568b73b51e3ea Author: Pierre Schweitzer <pierre(a)reactos.org> AuthorDate: Wed Jan 24 21:45:37 2018 +0100 Commit: Pierre Schweitzer <pierre(a)reactos.org> CommitDate: Wed Jan 24 21:46:16 2018 +0100 [NTOSKRNL] Implement (it's a bit raw for now!) the !filecache command in KDBG --- ntoskrnl/cc/view.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ ntoskrnl/kdbg/kdb_cli.c | 2 ++ 2 files changed, 57 insertions(+) diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c index a9e83bb5b1..adf79eba7d 100644 --- a/ntoskrnl/cc/view.c +++ b/ntoskrnl/cc/view.c @@ -1493,4 +1493,59 @@ CcInitView ( return TRUE; } +BOOLEAN +ExpKdbgExtFileCache(ULONG Argc, PCHAR Argv[]) +{ + PLIST_ENTRY ListEntry; + UNICODE_STRING NoName = RTL_CONSTANT_STRING(L"No name for File"); + + KdbpPrint("Control\t\tValid\tDirty\tName\n"); + /* No need to lock the spin lock here, we're in DBG */ + for (ListEntry = CcCleanSharedCacheMapList.Flink; + ListEntry != &CcCleanSharedCacheMapList; + ListEntry = ListEntry->Flink) + { + PLIST_ENTRY Vacbs; + ULONG Valid = 0, Dirty = 0; + PROS_SHARED_CACHE_MAP SharedCacheMap; + PUNICODE_STRING FileName; + + SharedCacheMap = CONTAINING_RECORD(ListEntry, ROS_SHARED_CACHE_MAP, SharedCacheMapLinks); + + /* First, count for all the associated VACB */ + for (Vacbs = SharedCacheMap->CacheMapVacbListHead.Flink; + Vacbs != &SharedCacheMap->CacheMapVacbListHead; + Vacbs = Vacbs->Flink) + { + PROS_VACB Vacb; + + Vacb = CONTAINING_RECORD(Vacbs, ROS_VACB, CacheMapVacbListEntry); + if (Vacb->Dirty) + { + Dirty += VACB_MAPPING_GRANULARITY / 1024; + } + if (Vacb->Valid) + { + Valid += VACB_MAPPING_GRANULARITY / 1024; + } + } + + /* Setup name */ + if (SharedCacheMap->FileObject != NULL && + SharedCacheMap->FileObject->FileName.Length != 0) + { + FileName = &SharedCacheMap->FileObject->FileName; + } + else + { + FileName = &NoName; + } + + /* And print */ + KdbpPrint("%p\t%d\t%d\t%wZ\n", SharedCacheMap, Valid, Dirty, FileName); + } + + return TRUE; +} + /* EOF */ diff --git a/ntoskrnl/kdbg/kdb_cli.c b/ntoskrnl/kdbg/kdb_cli.c index fe83d5d421..dfb01f4960 100644 --- a/ntoskrnl/kdbg/kdb_cli.c +++ b/ntoskrnl/kdbg/kdb_cli.c @@ -93,6 +93,7 @@ static BOOLEAN KdbpCmdDmesg(ULONG Argc, PCHAR Argv[]); BOOLEAN ExpKdbgExtPool(ULONG Argc, PCHAR Argv[]); BOOLEAN ExpKdbgExtPoolUsed(ULONG Argc, PCHAR Argv[]); +BOOLEAN ExpKdbgExtFileCache(ULONG Argc, PCHAR Argv[]); #ifdef __ROS_DWARF__ static BOOLEAN KdbpCmdPrintStruct(ULONG Argc, PCHAR Argv[]); @@ -186,6 +187,7 @@ static const struct { "help", "help", "Display help screen.", KdbpCmdHelp }, { "!pool", "!pool [Address [Flags]]", "Display information about pool allocations.", ExpKdbgExtPool }, { "!poolused", "!poolused [Flags [Tag]]", "Display pool usage.", ExpKdbgExtPoolUsed }, + { "!filecache", "!filecache", "Display cache usage.", ExpKdbgExtFileCache }, }; /* FUNCTIONS *****************************************************************/
6 years, 11 months
1
0
0
0
01/02: [NTOSKRNL] Link all the shared cache map together.
by Pierre Schweitzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9d1e16663ad086e4aadcb…
commit 9d1e16663ad086e4aadcb6f2bfdca34989da09e5 Author: Pierre Schweitzer <pierre(a)reactos.org> AuthorDate: Wed Jan 24 21:24:05 2018 +0100 Commit: Pierre Schweitzer <pierre(a)reactos.org> CommitDate: Wed Jan 24 21:46:16 2018 +0100 [NTOSKRNL] Link all the shared cache map together. --- ntoskrnl/cc/view.c | 19 +++++++++++++++++++ ntoskrnl/include/internal/cc.h | 1 + 2 files changed, 20 insertions(+) diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c index 5588a912db..a9e83bb5b1 100644 --- a/ntoskrnl/cc/view.c +++ b/ntoskrnl/cc/view.c @@ -63,18 +63,22 @@ ULONG CcLazyWriteIos = 0; * - Amount of dirty pages * - List for deferred writes * - Spinlock when dealing with the deferred list + * - List for "clean" shared cache maps */ ULONG CcDirtyPageThreshold = 0; ULONG CcTotalDirtyPages = 0; LIST_ENTRY CcDeferredWrites; KSPIN_LOCK CcDeferredWriteSpinLock; +LIST_ENTRY CcCleanSharedCacheMapList; /* Internal vars (ROS): * - Event to notify lazy writer to shutdown * - Event to inform watchers lazy writer is done for this loop + * - Lock for the CcCleanSharedCacheMapList list */ KEVENT iLazyWriterShutdown; KEVENT iLazyWriterNotify; +KSPIN_LOCK iSharedCacheMapLock; #if DBG static void CcRosVacbIncRefCount_(PROS_VACB vacb, const char* file, int line) @@ -1139,6 +1143,8 @@ CcRosDeleteFileCache ( SharedCacheMap->OpenCount--; if (SharedCacheMap->OpenCount == 0) { + KIRQL OldIrql; + FileObject->SectionObjectPointer->SharedCacheMap = NULL; /* @@ -1173,6 +1179,11 @@ CcRosDeleteFileCache ( current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry); CcRosInternalFreeVacb(current); } + + KeAcquireSpinLock(&iSharedCacheMapLock, &OldIrql); + RemoveEntryList(&SharedCacheMap->SharedCacheMapLinks); + KeReleaseSpinLock(&iSharedCacheMapLock, OldIrql); + ExFreeToNPagedLookasideList(&SharedCacheMapLookasideList, SharedCacheMap); KeAcquireGuardedMutex(&ViewLock); } @@ -1317,6 +1328,8 @@ CcRosInitializeFileCache ( KeAcquireGuardedMutex(&ViewLock); if (SharedCacheMap == NULL) { + KIRQL OldIrql; + SharedCacheMap = ExAllocateFromNPagedLookasideList(&SharedCacheMapLookasideList); if (SharedCacheMap == NULL) { @@ -1338,6 +1351,10 @@ CcRosInitializeFileCache ( KeInitializeSpinLock(&SharedCacheMap->CacheMapLock); InitializeListHead(&SharedCacheMap->CacheMapVacbListHead); FileObject->SectionObjectPointer->SharedCacheMap = SharedCacheMap; + + KeAcquireSpinLock(&iSharedCacheMapLock, &OldIrql); + InsertTailList(&CcCleanSharedCacheMapList, &SharedCacheMap->SharedCacheMapLinks); + KeReleaseSpinLock(&iSharedCacheMapLock, OldIrql); } if (FileObject->PrivateCacheMap == NULL) { @@ -1395,7 +1412,9 @@ CcInitView ( InitializeListHead(&DirtyVacbListHead); InitializeListHead(&VacbLruListHead); InitializeListHead(&CcDeferredWrites); + InitializeListHead(&CcCleanSharedCacheMapList); KeInitializeSpinLock(&CcDeferredWriteSpinLock); + KeInitializeSpinLock(&iSharedCacheMapLock); KeInitializeGuardedMutex(&ViewLock); ExInitializeNPagedLookasideList(&iBcbLookasideList, NULL, diff --git a/ntoskrnl/include/internal/cc.h b/ntoskrnl/include/internal/cc.h index 2699dfcf43..913517a762 100644 --- a/ntoskrnl/include/internal/cc.h +++ b/ntoskrnl/include/internal/cc.h @@ -160,6 +160,7 @@ typedef struct _ROS_SHARED_CACHE_MAP KSPIN_LOCK CacheMapLock; ULONG OpenCount; ULONG DirtyPageThreshold; + LIST_ENTRY SharedCacheMapLinks; #if DBG BOOLEAN Trace; /* enable extra trace output for this cache map and it's VACBs */ #endif
6 years, 11 months
1
0
0
0
01/01: [ATL_APITEST] CComObject.cpp: Fix output test name copypasta.
by Serge Gautherie
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=804472fab852d04c4c3a4…
commit 804472fab852d04c4c3a4ff61b7f051d1b486bfb Author: Serge Gautherie <reactos-git_serge_171003(a)gautherie.fr> AuthorDate: Fri Dec 22 23:52:47 2017 +0100 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Wed Jan 24 18:59:19 2018 +0100 [ATL_APITEST] CComObject.cpp: Fix output test name copypasta. --- modules/rostests/apitests/atl/CComObject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/rostests/apitests/atl/CComObject.cpp b/modules/rostests/apitests/atl/CComObject.cpp index f7d16e1e69..840f88a967 100644 --- a/modules/rostests/apitests/atl/CComObject.cpp +++ b/modules/rostests/apitests/atl/CComObject.cpp @@ -143,7 +143,7 @@ START_TEST(CComObject) } #ifndef __REACTOS__ - printf("CImage: %i tests executed (0 marked as todo, %i failures), 0 skipped.\n", g_tests_executed, g_tests_failed); + printf("CComObject: %i tests executed (0 marked as todo, %i failures), 0 skipped.\n", g_tests_executed, g_tests_failed); return g_tests_failed; #endif }
6 years, 11 months
1
0
0
0
01/01: [TRANSLATION] [DESK] Update russian translation (#323)
by Stanislav Motylkov
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0acd59b541aced0b2688b…
commit 0acd59b541aced0b2688b1d9c34bc150d5a5534f Author: Stanislav Motylkov <x86corez(a)gmail.com> AuthorDate: Wed Jan 24 18:13:51 2018 +0300 Commit: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito(a)reactos.org> CommitDate: Wed Jan 24 16:13:51 2018 +0100 [TRANSLATION] [DESK] Update russian translation (#323) --- dll/cpl/desk/lang/ru-RU.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dll/cpl/desk/lang/ru-RU.rc b/dll/cpl/desk/lang/ru-RU.rc index 62925bbbe9..62e46914bc 100644 --- a/dll/cpl/desk/lang/ru-RU.rc +++ b/dll/cpl/desk/lang/ru-RU.rc @@ -109,7 +109,7 @@ BEGIN "button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "Скр&ывать указатели вызова с клавиатуры до нажатия <Alt>", IDC_EFFAPPEARANCE_KEYBOARDCUES, "button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 - CONTROL "Use &flat menus", IDC_EFFAPPEARANCE_FLATMENUS, + CONTROL "Использовать п&лоские меню", IDC_EFFAPPEARANCE_FLATMENUS, "button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 140, 267, 19 PUSHBUTTON "Отмена", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "OK", IDOK, 172, 165, 50, 14
6 years, 11 months
1
0
0
0
01/01: [BASE/APPLICATIONS] Hebrew translation updates (#321)
by Baruch Rutman
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b917d826a41fa782dd579…
commit b917d826a41fa782dd5790bf0f5553941b2b44a2 Author: Baruch Rutman <peterooch(a)gmail.com> AuthorDate: Wed Jan 24 17:00:43 2018 +0200 Commit: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito(a)reactos.org> CommitDate: Wed Jan 24 16:00:43 2018 +0100 [BASE/APPLICATIONS] Hebrew translation updates (#321) Translation updates + mirroring support. --- base/applications/calc/lang/he-IL.rc | 92 ++++++++------- base/applications/charmap/charmap.c | 12 ++ base/applications/charmap/lang/he-IL.rc | 3 + base/applications/clipbrd/clipbrd.c | 10 ++ base/applications/clipbrd/clipbrd.rc | 3 + base/applications/clipbrd/lang/he-IL.rc | 65 +++++++++++ base/applications/clipbrd/precomp.h | 1 + base/applications/dxdiag/lang/he-IL.rc | 8 ++ base/applications/fontview/lang/he-IL.rc | 4 +- base/applications/games/solitaire/lang/he-IL.rc | 14 ++- base/applications/games/spider/lang/he-IL.rc | 2 + base/applications/games/winmine/lang/he-IL.rc | 3 + base/applications/magnify/lang/he-IL.rc | 3 + base/applications/mplay32/lang/he-IL.rc | 38 +++--- base/applications/mplay32/mplay32.c | 10 ++ base/applications/mplay32/mplay32.h | 1 + base/applications/msconfig/lang/he-IL.rc | 22 ++-- base/applications/mspaint/lang/he-IL.rc | 5 +- base/applications/mstsc/connectdialog.c | 2 +- base/applications/mstsc/lang/he-IL.rc | 7 +- base/applications/notepad/lang/he-IL.rc | 6 +- base/applications/osk/lang/he-IL.rc | 128 +++++++++++++++++++++ base/applications/osk/rsrc.rc | 3 + base/applications/rapps/lang/he-IL.rc | 42 ++++--- .../applications/screensavers/3dtext/lang/he-IL.rc | 1 + base/applications/shutdown/lang/he-IL.rc | 3 +- base/applications/sndrec32/lang/he-IL.rc | 25 ++-- base/applications/sndrec32/sndrec32.cpp | 11 ++ base/applications/sndvol32/lang/he-IL.rc | 4 +- base/applications/wordpad/lang/he-IL.rc | 5 + base/applications/wordpad/wordpad.c | 10 ++ 31 files changed, 427 insertions(+), 116 deletions(-) diff --git a/base/applications/calc/lang/he-IL.rc b/base/applications/calc/lang/he-IL.rc index ad9a338a08..0db39f4f8c 100644 --- a/base/applications/calc/lang/he-IL.rc +++ b/base/applications/calc/lang/he-IL.rc @@ -6,29 +6,30 @@ LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT IDD_DIALOG_SCIENTIFIC DIALOGEX 0, 0, 316, 163 STYLE DS_SHELLFONT | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "מחשבון ReactOS" MENU IDR_MENU_SCIENTIFIC_1 FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - GROUPBOX "", IDC_STATIC, 5 ,14, 141, 20 - CONTROL "הקסהדסימלי", IDC_RADIO_HEX, "Button", BS_AUTORADIOBUTTON, 8, 21, 30, 10 - CONTROL "עשרוני", IDC_RADIO_DEC, "Button", BS_AUTORADIOBUTTON, 41, 21, 30, 10 - CONTROL "אוקטלי", IDC_RADIO_OCT, "Button", BS_AUTORADIOBUTTON, 74, 21, 30, 10 - CONTROL "בינארי", IDC_RADIO_BIN, "Button", BS_AUTORADIOBUTTON, 107, 21, 30, 10 - GROUPBOX "", IDC_STATIC, 5, 34, 84, 20 + GROUPBOX "", IDC_STATIC, 4 ,14, 141, 20 + CONTROL "הקס", IDC_RADIO_HEX, "Button", BS_AUTORADIOBUTTON, 6, 21, 30, 10 + CONTROL "עשרוני", IDC_RADIO_DEC, "Button", BS_AUTORADIOBUTTON, 36, 21, 34, 10 + CONTROL "אוקטלי", IDC_RADIO_OCT, "Button", BS_AUTORADIOBUTTON, 73, 21, 37, 10 + CONTROL "בינרי", IDC_RADIO_BIN, "Button", BS_AUTORADIOBUTTON, 113, 21, 30, 10 + GROUPBOX "", IDC_STATIC, 4, 34, 84, 20 CONTROL "Inv", IDC_CHECK_INV, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 8, 41, 26, 10 CONTROL "Hyp", IDC_CHECK_HYP, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 49, 41, 29, 10 CTEXT "", IDC_TEXT_PARENT, 93, 38, 18, 16, SS_CENTERIMAGE, WS_EX_CLIENTEDGE CTEXT "", IDC_TEXT_MEMORY, 126, 38, 18, 16, SS_CENTERIMAGE, WS_EX_CLIENTEDGE - PUSHBUTTON "Sta", IDC_BUTTON_STA, 5, 60, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "Sta", IDC_BUTTON_STA, 4, 60, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "Ave", IDC_BUTTON_AVE, 5, 80, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "Ave", IDC_BUTTON_AVE, 4, 80, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | WS_DISABLED | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "Sum", IDC_BUTTON_SUM, 5, 100, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "Sum", IDC_BUTTON_SUM, 4, 100, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | WS_DISABLED | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "s", IDC_BUTTON_S, 5, 120, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "s", IDC_BUTTON_S, 4, 120, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | WS_DISABLED | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "Dat", IDC_BUTTON_DAT, 5, 140, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "Dat", IDC_BUTTON_DAT, 4, 140, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | WS_DISABLED | BS_OWNERDRAW | WS_TABSTOP PUSHBUTTON "F-E", IDC_BUTTON_FE, 38, 60, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP @@ -70,15 +71,15 @@ BEGIN BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP PUSHBUTTON "pi", IDC_BUTTON_PI, 123, 140, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "7", IDC_BUTTON_7, 156, 60, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "9", IDC_BUTTON_9, 156, 60, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "4", IDC_BUTTON_4, 156, 80, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "6", IDC_BUTTON_6, 156, 80, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "1", IDC_BUTTON_1, 156, 100, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "3", IDC_BUTTON_3, 156, 100, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP PUSHBUTTON "0", IDC_BUTTON_0, 156, 120, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "A", IDC_BUTTON_A, 156, 140, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "F", IDC_BUTTON_F, 156, 140, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP PUSHBUTTON "8", IDC_BUTTON_8, 182, 60, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP @@ -88,17 +89,17 @@ BEGIN BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP PUSHBUTTON "+/-", IDC_BUTTON_SIGN, 182, 120, 24, 18,BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "B", IDC_BUTTON_B, 182, 140, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "E", IDC_BUTTON_E, 182, 140, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "9", IDC_BUTTON_9, 208, 60, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "7", IDC_BUTTON_7, 208, 60, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "6", IDC_BUTTON_6, 208, 80, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "4", IDC_BUTTON_4, 208, 80, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "3", IDC_BUTTON_3, 208, 100, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "1", IDC_BUTTON_1, 208, 100, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP PUSHBUTTON ",", IDC_BUTTON_DOT, 208, 120, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "C", IDC_BUTTON_C, 208, 140, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "D", IDC_BUTTON_D, 208, 140, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP PUSHBUTTON "/", IDC_BUTTON_DIV, 234, 60, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP @@ -108,7 +109,7 @@ BEGIN BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP PUSHBUTTON "+", IDC_BUTTON_ADD, 234, 120, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "D", IDC_BUTTON_D, 234, 140, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "C", IDC_BUTTON_C, 234, 140, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP PUSHBUTTON "Mod", IDC_BUTTON_MOD, 260, 60, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP @@ -118,7 +119,7 @@ BEGIN BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP PUSHBUTTON "=", IDC_BUTTON_EQU, 260, 120, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "E", IDC_BUTTON_E, 260, 140, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "B", IDC_BUTTON_B, 260, 140, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP PUSHBUTTON "And", IDC_BUTTON_AND, 286, 60, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP @@ -128,7 +129,7 @@ BEGIN BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP PUSHBUTTON "Int", IDC_BUTTON_INT, 286, 120, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "F", IDC_BUTTON_F, 286, 140, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "A", IDC_BUTTON_A, 286, 140, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP GROUPBOX "", IDC_STATIC, 147, 14, 163, 20 CONTROL "Qword", IDC_RADIO_QWORD, "Button", BS_AUTORADIOBUTTON | @@ -141,7 +142,7 @@ BEGIN NOT WS_VISIBLE, 270, 21, 38, 10 CONTROL "מעלות", IDC_RADIO_DEG, "Button", BS_AUTORADIOBUTTON, 150, 21, 45, 10 CONTROL "רדיאנים", IDC_RADIO_RAD, "Button", BS_AUTORADIOBUTTON, 204, 21, 45, 10 - CONTROL "Gradians", IDC_RADIO_GRAD, "Button", BS_AUTORADIOBUTTON, 258, 21, 45, 10 + CONTROL "גרדיאנים", IDC_RADIO_GRAD, "Button", BS_AUTORADIOBUTTON, 258, 21, 45, 10 PUSHBUTTON "C", IDC_BUTTON_CANC, 267, 38, 43, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP PUSHBUTTON "CE", IDC_BUTTON_CE, 222, 38, 43, 18, BS_CENTER | BS_VCENTER | @@ -154,6 +155,7 @@ END IDD_DIALOG_STANDARD DIALOGEX 0, 0, 169, 128 STYLE DS_SHELLFONT | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "מחשבון ReactOS" MENU IDR_MENU_STANDARD FONT 8, "MS Shell Dlg", 0, 0, 0x1 @@ -162,14 +164,14 @@ BEGIN BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP PUSHBUTTON "CE", IDC_BUTTON_CE, 80, 23, 41, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "Back", IDC_BUTTON_BACK, 36, 23, 42, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "חזרה", IDC_BUTTON_BACK, 36, 23, 42, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP RTEXT "", IDC_TEXT_OUTPUT, 5, 1, 159, 14, SS_CENTERIMAGE, WS_EX_CLIENTEDGE - PUSHBUTTON "7", IDC_BUTTON_7, 36, 45, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "9", IDC_BUTTON_9, 36, 45, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "4", IDC_BUTTON_4, 36, 65, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "6", IDC_BUTTON_6, 36, 65, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "1", IDC_BUTTON_1, 36, 85, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "3", IDC_BUTTON_3, 36, 85, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP PUSHBUTTON "0", IDC_BUTTON_0, 36, 105, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP @@ -181,11 +183,11 @@ BEGIN BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP PUSHBUTTON "+/-", IDC_BUTTON_SIGN, 62, 105, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "9", IDC_BUTTON_9, 88, 45, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "7", IDC_BUTTON_7, 88, 45, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "6", IDC_BUTTON_6, 88, 65, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "4", IDC_BUTTON_4, 88, 65, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP - PUSHBUTTON "3", IDC_BUTTON_3, 88, 85, 24, 18, BS_CENTER | BS_VCENTER | + PUSHBUTTON "1", IDC_BUTTON_1, 88, 85, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP PUSHBUTTON ",", IDC_BUTTON_DOT, 88, 105, 24, 18, BS_CENTER | BS_VCENTER | BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP @@ -219,6 +221,7 @@ END IDD_DIALOG_CONVERSION DIALOGEX 0, 0, 320, 130 STYLE DS_SHELLFONT | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "מחשבון ReactOS" MENU IDR_MENU_STANDARD FONT 8, "MS Shell Dlg" @@ -237,14 +240,14 @@ BEGIN BS_VCENTER | BS_NOTIFY | WS_TABSTOP, 276, 24, 40, 17 CONTROL "CE", IDC_BUTTON_CE, "Button", BS_OWNERDRAW | BS_CENTER | BS_VCENTER | BS_NOTIFY | WS_TABSTOP, 232, 24, 40, 17 - CONTROL "Back", IDC_BUTTON_BACK, "Button", BS_OWNERDRAW | BS_CENTER | + CONTROL "חזרה", IDC_BUTTON_BACK, "Button", BS_OWNERDRAW | BS_CENTER | BS_VCENTER | BS_NOTIFY | WS_TABSTOP, 188, 24, 40,17 RTEXT "", IDC_TEXT_OUTPUT, 5, 1, 312, 14, SS_CENTERIMAGE, WS_EX_CLIENTEDGE - CONTROL "7", IDC_BUTTON_7, "Button", BS_OWNERDRAW | BS_CENTER | + CONTROL "9", IDC_BUTTON_9, "Button", BS_OWNERDRAW | BS_CENTER | BS_VCENTER | BS_NOTIFY | WS_TABSTOP, 188, 48, 24, 18 - CONTROL "4", IDC_BUTTON_4, "Button", BS_OWNERDRAW | BS_CENTER | + CONTROL "6", IDC_BUTTON_6, "Button", BS_OWNERDRAW | BS_CENTER | BS_VCENTER | BS_NOTIFY | WS_TABSTOP, 188, 67, 24, 18 - CONTROL "1", IDC_BUTTON_1, "Button", BS_OWNERDRAW | BS_CENTER | + CONTROL "3", IDC_BUTTON_3, "Button", BS_OWNERDRAW | BS_CENTER | BS_VCENTER | BS_NOTIFY | WS_TABSTOP, 188, 86, 24, 18 CONTROL "0", IDC_BUTTON_0, "Button", BS_OWNERDRAW | BS_CENTER | BS_VCENTER | BS_NOTIFY | WS_TABSTOP, 188, 105, 24, 18 @@ -256,11 +259,11 @@ BEGIN BS_VCENTER | BS_NOTIFY | WS_TABSTOP, 214, 86, 24, 18 CONTROL "+/-", IDC_BUTTON_SIGN, "Button", BS_OWNERDRAW | BS_CENTER | BS_VCENTER | BS_NOTIFY | WS_TABSTOP, 214, 105, 24, 18 - CONTROL "9", IDC_BUTTON_9, "Button", BS_OWNERDRAW | BS_CENTER | + CONTROL "7", IDC_BUTTON_7, "Button", BS_OWNERDRAW | BS_CENTER | BS_VCENTER | BS_NOTIFY | WS_TABSTOP, 240, 48, 24, 18 - CONTROL "6", IDC_BUTTON_6, "Button", BS_OWNERDRAW | BS_CENTER | + CONTROL "4", IDC_BUTTON_4, "Button", BS_OWNERDRAW | BS_CENTER | BS_VCENTER | BS_NOTIFY | WS_TABSTOP, 240, 67, 24, 18 - CONTROL "3", IDC_BUTTON_3, "Button", BS_OWNERDRAW | BS_CENTER | + CONTROL "1", IDC_BUTTON_1, "Button", BS_OWNERDRAW | BS_CENTER | BS_VCENTER | BS_NOTIFY | WS_TABSTOP, 240, 86, 24, 18 CONTROL ",", IDC_BUTTON_DOT, "Button", BS_OWNERDRAW | BS_CENTER | BS_VCENTER | BS_NOTIFY | WS_TABSTOP, 240, 105, 24, 18 @@ -294,6 +297,7 @@ END IDD_DIALOG_STAT DIALOGEX 0, 0, 163, 85 STYLE DS_SHELLFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "תיבת סטטיסטיקה" FONT 8, "MS Shell Dlg" BEGIN @@ -323,11 +327,11 @@ BEGIN MENUITEM "הקס\tF5", IDM_VIEW_HEX, CHECKED MENUITEM "עשרוני\tF6", IDM_VIEW_DEC, CHECKED MENUITEM "אוקטלי\tF7", IDM_VIEW_OCT, CHECKED - MENUITEM "בינארי\tF8", IDM_VIEW_BIN, CHECKED + MENUITEM "בינרי\tF8", IDM_VIEW_BIN, CHECKED MENUITEM SEPARATOR MENUITEM "מעלות\tF2", IDM_VIEW_DEG, CHECKED MENUITEM "רדיאנים\tF3", IDM_VIEW_RAD, CHECKED - MENUITEM "Gradians\tF4", IDM_VIEW_GRAD, CHECKED + MENUITEM "גרדיאנים\tF4", IDM_VIEW_GRAD, CHECKED MENUITEM SEPARATOR MENUITEM "קיבוץ ספרות", IDM_VIEW_GROUP, CHECKED END @@ -355,7 +359,7 @@ BEGIN MENUITEM "הקס\tF5", IDM_VIEW_HEX, CHECKED MENUITEM "עשרוני\tF6", IDM_VIEW_DEC, CHECKED MENUITEM "אוקטלי\tF7", IDM_VIEW_OCT, CHECKED - MENUITEM "בינארי\tF8", IDM_VIEW_BIN, CHECKED + MENUITEM "בינרי\tF8", IDM_VIEW_BIN, CHECKED MENUITEM SEPARATOR MENUITEM "Qword\tF12", IDM_VIEW_QWORD, CHECKED MENUITEM "Dword\tF2", IDM_VIEW_DWORD, CHECKED @@ -432,7 +436,7 @@ END STRINGTABLE BEGIN IDS_ANGLE_DEGREES "מעלות" - IDS_ANGLE_GRADIANS "Gradians" + IDS_ANGLE_GRADIANS "גרדיאנים" IDS_ANGLE_RADIANS "רדיאנים" END @@ -493,14 +497,14 @@ BEGIN IDS_CURRENCY_CZECH_KORUNA "קורונה צ'כי" IDS_CURRENCY_DEUTSCHE_MARK "מארק גרמני" IDS_CURRENCY_DUTCH_GUILDER "גילדר הולנדי" - IDS_CURRENCY_ESTONIAN_KROON "Estonian kroon" + IDS_CURRENCY_ESTONIAN_KROON "קרון אסטוני" IDS_CURRENCY_EURO "אירו" IDS_CURRENCY_FINNISH_MARKKA "מארקה פינית" IDS_CURRENCY_FRENCH_FRANC "פרנק צרפתי" IDS_CURRENCY_GREEK_DRACHMA "דרכמה יוונית" IDS_CURRENCY_IRISH_POUND "לירה אירית" IDS_CURRENCY_ITALIAN_LIRA "לירה איטלקית" - IDS_CURRENCY_LATVIAN_LATS "Latvian lats" + IDS_CURRENCY_LATVIAN_LATS "לטים לטבים" IDS_CURRENCY_LITHUANIAN_LITAS "Lithuanian litas" IDS_CURRENCY_LUXEMBOURG_FRANC "פרנק לוקסמבורגי" IDS_CURRENCY_MALTESE_LIRA "לירה מלטזי" diff --git a/base/applications/charmap/charmap.c b/base/applications/charmap/charmap.c index 5cd864e182..85378ecc95 100644 --- a/base/applications/charmap/charmap.c +++ b/base/applications/charmap/charmap.c @@ -11,6 +11,7 @@ #include <commctrl.h> #include <richedit.h> +#include <winnls.h> #define REMOVE_ADVANCED @@ -593,6 +594,17 @@ wWinMain(HINSTANCE hInst, HINSTANCE hGetUName = NULL; hInstance = hInst; + + /* Mirroring code for the titlebar */ + switch (GetUserDefaultUILanguage()) + { + case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT): + SetProcessDefaultLayout(LAYOUT_RTL); + break; + + default: + break; + } iccx.dwSize = sizeof(INITCOMMONCONTROLSEX); iccx.dwICC = ICC_TAB_CLASSES; diff --git a/base/applications/charmap/lang/he-IL.rc b/base/applications/charmap/lang/he-IL.rc index a89077351d..47c94fbc62 100644 --- a/base/applications/charmap/lang/he-IL.rc +++ b/base/applications/charmap/lang/he-IL.rc @@ -4,6 +4,7 @@ LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT IDD_CHARMAP DIALOGEX 6, 6, 292, 224 FONT 8, "MS Shell Dlg", 0, 0 STYLE DS_SHELLFONT | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_LAYOUTRTL BEGIN LTEXT "גופן", IDC_STATIC, 6, 7, 24, 9 COMBOBOX IDC_FONTCOMBO, 36, 5, 210, 210, WS_CHILD | WS_VISIBLE | @@ -22,6 +23,7 @@ END IDD_ADVANCED DIALOGEX 0, 0, 292, 64 STYLE DS_SHELLFONT | WS_CHILD +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" BEGIN LTEXT "ערכת תווים:", IDC_STATIC, 8, 8, 48, 8 @@ -39,6 +41,7 @@ IDD_ABOUTBOX DIALOGEX 22, 16, 210, 182 CAPTION "אודות מפת תווים" FONT 8, "MS Shell Dlg", 0, 0 STYLE DS_SHELLFONT | WS_BORDER | WS_DLGFRAME | WS_SYSMENU | DS_MODALFRAME +EXSTYLE WS_EX_LAYOUTRTL BEGIN LTEXT "Character Map v0.1\nCopyright (C) 2007 Ged Murphy (gedmurphy(a)reactos.org)", IDC_STATIC, 48, 7, 150, 36 PUSHBUTTON "סגור", IDOK, 75, 162, 44, 15 diff --git a/base/applications/clipbrd/clipbrd.c b/base/applications/clipbrd/clipbrd.c index cb1f1d75c9..bef831cd8b 100644 --- a/base/applications/clipbrd/clipbrd.c +++ b/base/applications/clipbrd/clipbrd.c @@ -538,6 +538,16 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wndclass.lpszMenuName = MAKEINTRESOURCEW(MAIN_MENU); wndclass.lpszClassName = szClassName; + + switch (GetUserDefaultUILanguage()) + { + case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT): + SetProcessDefaultLayout(LAYOUT_RTL); + break; + + default: + break; + } if (!RegisterClassExW(&wndclass)) { diff --git a/base/applications/clipbrd/clipbrd.rc b/base/applications/clipbrd/clipbrd.rc index 47b8e20e8d..2d0b3750de 100644 --- a/base/applications/clipbrd/clipbrd.rc +++ b/base/applications/clipbrd/clipbrd.rc @@ -31,6 +31,9 @@ CLPFILE_ICON ICON "res/clpfile.ico" #ifdef LANGUAGE_FR_FR #include "lang/fr-FR.rc" #endif +#ifdef LANGUAGE_HE_IL + #include "lang/he-IL.rc" +#endif #ifdef LANGUAGE_PL_PL #include "lang/pl-PL.rc" #endif diff --git a/base/applications/clipbrd/lang/he-IL.rc b/base/applications/clipbrd/lang/he-IL.rc new file mode 100644 index 0000000000..0377cb2767 --- /dev/null +++ b/base/applications/clipbrd/lang/he-IL.rc @@ -0,0 +1,65 @@ +LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT + +ID_ACCEL ACCELERATORS +BEGIN + VK_DELETE, CMD_DELETE, VIRTKEY +END + +MAIN_MENU MENU +BEGIN + POPUP "&קובץ" + BEGIN + MENUITEM "&פתיחה...", CMD_OPEN + MENUITEM "&שמירה בשם...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "&יציאה", CMD_EXIT + END + POPUP "&עריכה" + BEGIN + MENUITEM "&מחק\tDel", CMD_DELETE + END + POPUP "&תצוגה" + BEGIN + MENUITEM "&אוטומטי", CMD_AUTOMATIC + END + POPUP "ע&זרה" + BEGIN + MENUITEM "&נושאי עזרה", CMD_HELP + MENUITEM SEPARATOR + MENUITEM "&אודות", CMD_ABOUT + END +END + +STRINGTABLE +BEGIN + STRING_CLIPBOARD "צופה לוח גזירה" + STRING_CLIPFILE "Clipboard Element" + STRING_DELETE_MSG "לנקות את לוח הגזירה?" + STRING_DELETE_TITLE "ניקוי לוח גזירה" + STRING_FORMAT_NT "קבצי לוח גזירה של ReactOS (*.clp)" + STRING_FORMAT_GEN "קבצי לוח גזירה (*.clp)" +END + +STRINGTABLE +BEGIN + STRING_CF_UNKNOWN "תבנית לא ידועה" + STRING_CF_TEXT "טקסט" + STRING_CF_BITMAP "מפת סיבים" + STRING_CF_OEMTEXT "טקסט OEM" + STRING_CF_UNICODETEXT "טקסט יוניקוד" + STRING_CF_DIB "DIB Bitmap" + STRING_CF_LOCALE "Locale Data" + STRING_CF_ENHMETAFILE "Enhanced Metafile" + STRING_CF_METAFILEPICT "Metafile" + STRING_CF_PALETTE "ערכת צבעים" + STRING_CF_DIBV5 "DIB Bitmap (Version 5)" + STRING_CF_SYLK "Symbolic Link Format" + STRING_CF_DIF "Data Interchange Format" + STRING_CF_HDROP "Drop Data" +END + +STRINGTABLE +BEGIN + ERROR_UNSUPPORTED_FORMAT "לוח הגזירה מכיל נתונים בתבנית שלא ניתנת להצגה." + ERROR_INVALID_FILE_FORMAT "הקובץ אינו קובץ לוח גזירה תקין." +END diff --git a/base/applications/clipbrd/precomp.h b/base/applications/clipbrd/precomp.h index acea48a9c8..5159ec2e5d 100644 --- a/base/applications/clipbrd/precomp.h +++ b/base/applications/clipbrd/precomp.h @@ -14,6 +14,7 @@ #include <shellapi.h> #include <htmlhelp.h> #include <commdlg.h> +#include <winnls.h> #include "resources.h" #include "cliputils.h" diff --git a/base/applications/dxdiag/lang/he-IL.rc b/base/applications/dxdiag/lang/he-IL.rc index 32196c8961..f8118cfc8d 100644 --- a/base/applications/dxdiag/lang/he-IL.rc +++ b/base/applications/dxdiag/lang/he-IL.rc @@ -4,6 +4,7 @@ LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT IDD_MAIN_DIALOG DIALOGEX 0, 0, 478, 280 STYLE DS_SHELLFONT | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "כלי אבחון - ReactX" FONT 8, "MS Shell Dlg" BEGIN @@ -16,6 +17,7 @@ END IDD_SYSTEM_DIALOG DIALOGEX 0, 0, 462, 220 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" BEGIN LTEXT "כלי זה מדווח על מידע מפורט אודות הרכיבים ומנהלי ההתקנים של ReactX המותקנים במערכת שלך.", IDC_STATIC, 5, 0, 443, 17 @@ -48,6 +50,7 @@ END IDD_DISPLAY_DIALOG DIALOGEX 0, 0, 462, 220 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "התקן", IDC_STATIC, 5, 0, 250, 95 @@ -98,6 +101,7 @@ END IDD_SOUND_DIALOG DIALOGEX 0, 0, 462, 220 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "התקן", IDC_STATIC, 5, 0, 250, 95 @@ -136,6 +140,7 @@ END IDD_MUSIC_DIALOG DIALOGEX 0, 0, 462, 220 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" BEGIN RTEXT "General MIDI DLS Collection:", IDC_STATIC, 0, 0, 100, 10 @@ -154,6 +159,7 @@ END IDD_INPUT_DIALOG DIALOGEX 0, 0, 462, 220 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "התקני DirectInput", IDC_STATIC, 5, 0, 452, 85 @@ -167,6 +173,7 @@ END IDD_NETWORK_DIALOG DIALOGEX 0, 0, 462, 220 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "ספקי שירות רשומים של DirectPlay", IDC_STATIC, 5, 0, 452, 75 @@ -181,6 +188,7 @@ END IDD_HELP_DIALOG DIALOGEX 0, 0, 462, 220 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" BEGIN LTEXT "Still can't find the information you're looking for? Here are some additional things you can do:", IDC_STATIC, 5, 0, 300, 10 diff --git a/base/applications/fontview/lang/he-IL.rc b/base/applications/fontview/lang/he-IL.rc index fc245c95c9..4a6eacdb8a 100644 --- a/base/applications/fontview/lang/he-IL.rc +++ b/base/applications/fontview/lang/he-IL.rc @@ -19,6 +19,6 @@ TrueType Font Collection (*.ttc)\0*.ttc\0\ OpenType Font (*.otf)\0*.otf\0\ OpenType Font Collection (*.otc)\0*.otc\0\ All Files (*.*)\0*.*\0" - IDS_PREVIOUS "< P&revious" - IDS_NEXT "&Next >" + IDS_PREVIOUS "< &קודם" + IDS_NEXT "&הבא >" END diff --git a/base/applications/games/solitaire/lang/he-IL.rc b/base/applications/games/solitaire/lang/he-IL.rc index 067c135103..49129736df 100644 --- a/base/applications/games/solitaire/lang/he-IL.rc +++ b/base/applications/games/solitaire/lang/he-IL.rc @@ -12,16 +12,17 @@ LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT IDD_OPTIONS DIALOGEX 0, 0, 186, 118 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT +EXSTYLE WS_EX_LAYOUTRTL CAPTION "אפשרויות" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "משיכה", -1, 7, 7, 90, 40 AUTORADIOBUTTON "משוך &אחד", IDC_OPT_DRAWONE, 14, 19, 70, 10, WS_GROUP | WS_TABSTOP AUTORADIOBUTTON "משוך &שלושה", IDC_OPT_DRAWTHREE, 14, 32, 70, 10 - GROUPBOX "Scoring", -1, 100, 7, 75, 53 - AUTORADIOBUTTON "&Standard", IDC_OPT_STANDARD, 107, 19, 60, 10, WS_GROUP | WS_TABSTOP - AUTORADIOBUTTON "&Vegas", IDC_OPT_VEGAS, 107, 32, 60, 10 - AUTORADIOBUTTON "&None", IDC_OPT_NOSCORE, 107, 45, 60, 10 + GROUPBOX "ניקוד", -1, 100, 7, 75, 53 + AUTORADIOBUTTON "&רגיל", IDC_OPT_STANDARD, 107, 19, 60, 10, WS_GROUP | WS_TABSTOP + AUTORADIOBUTTON "&ווגאס", IDC_OPT_VEGAS, 107, 32, 60, 10 + AUTORADIOBUTTON "&ללא ניקוד", IDC_OPT_NOSCORE, 107, 45, 60, 10 AUTOCHECKBOX "משחק קצוב בזמן", IDC_OPT_SHOWTIME, 7 ,51 ,72 ,10, WS_TABSTOP AUTOCHECKBOX "שורת מצב", IDC_OPT_STATUSBAR, 7, 66, 64, 10, WS_TABSTOP AUTOCHECKBOX "&Keep Score", IDC_OPT_KEEPSCORE, 100, 66, 65, 10, WS_TABSTOP @@ -33,6 +34,7 @@ IDD_CARDBACK DIALOGEX 6, 6, 345, 185 CAPTION "בחירת גב הקלפים" FONT 8, "MS Shell Dlg" STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT +EXSTYLE WS_EX_LAYOUTRTL BEGIN CONTROL "", IDC_CARDBACK1, "Static", SS_NOTIFY, 4, 7, 50, 71 CONTROL "", IDC_CARDBACK2, "Static", SS_NOTIFY, 61, 7, 50, 71 @@ -59,8 +61,8 @@ BEGIN IDS_SOL_QUIT "להפסיק את המשחק הנוכחי?" IDS_SOL_WIN "כל הכבוד, ניצחת!" IDS_SOL_DEAL "לחלק שוב?" - IDS_SOL_SCORE "Score: %d" - IDS_SOL_TIME "Time: %d" + IDS_SOL_SCORE "ניקוד: %d" + IDS_SOL_TIME "זמן: %d" END /* Menus */ diff --git a/base/applications/games/spider/lang/he-IL.rc b/base/applications/games/spider/lang/he-IL.rc index 14aeedf910..9941b9980e 100644 --- a/base/applications/games/spider/lang/he-IL.rc +++ b/base/applications/games/spider/lang/he-IL.rc @@ -14,6 +14,7 @@ IDD_CARDBACK DIALOGEX 6, 6, 345, 185 CAPTION "בחר חפיסה" FONT 8, "MS Shell Dlg" STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT +EXSTYLE WS_EX_LAYOUTRTL BEGIN CONTROL "", IDC_CARDBACK1, "Static", SS_NOTIFY, 4, 7, 50, 71 CONTROL "", IDC_CARDBACK2, "Static", SS_NOTIFY, 61, 7, 50, 71 @@ -33,6 +34,7 @@ END IDD_DIFFICULTY DIALOGEX 100, 100, 106, 80 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT +EXSTYLE WS_EX_LAYOUTRTL CAPTION "רמת קושי" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/games/winmine/lang/he-IL.rc b/base/applications/games/winmine/lang/he-IL.rc index e4ad8baec6..64ef25feea 100644 --- a/base/applications/games/winmine/lang/he-IL.rc +++ b/base/applications/games/winmine/lang/he-IL.rc @@ -31,6 +31,7 @@ END DLG_TIMES DIALOGEX 0, 0, 160, 80 STYLE DS_MODALFRAME | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_POPUP | DS_SHELLFONT +EXSTYLE WS_EX_LAYOUTRTL CAPTION "שיאני שולה המוקשים" FONT 8, "MS Shell Dlg" BEGIN @@ -49,6 +50,7 @@ END DLG_CONGRATS DIALOGEX 0, 0, 160, 60 STYLE DS_MODALFRAME | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_POPUP | DS_SHELLFONT +EXSTYLE WS_EX_LAYOUTRTL CAPTION "כל הכבוד!" FONT 8, "MS Shell Dlg" BEGIN @@ -59,6 +61,7 @@ END DLG_CUSTOM DIALOGEX 0, 0, 100, 100 STYLE DS_MODALFRAME | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_POPUP | DS_SHELLFONT +EXSTYLE WS_EX_LAYOUTRTL CAPTION "משחק מותאם" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/magnify/lang/he-IL.rc b/base/applications/magnify/lang/he-IL.rc index 5c8d42f95b..327fccb176 100644 --- a/base/applications/magnify/lang/he-IL.rc +++ b/base/applications/magnify/lang/he-IL.rc @@ -21,6 +21,7 @@ END IDD_ABOUTBOX DIALOGEX 22, 17, 220, 75 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "אודות" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -32,6 +33,7 @@ END IDD_DIALOGOPTIONS DIALOGEX 0, 0, 153, 182 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "הגדרות זכוכית מגדלת" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN @@ -57,6 +59,7 @@ END IDD_WARNINGDIALOG DIALOGEX 0, 0, 250, 97 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION +EXSTYLE WS_EX_LAYOUTRTL CAPTION "זכוכית מגדלת של ReactOS" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN diff --git a/base/applications/mplay32/lang/he-IL.rc b/base/applications/mplay32/lang/he-IL.rc index 246488084c..e64972cebb 100644 --- a/base/applications/mplay32/lang/he-IL.rc +++ b/base/applications/mplay32/lang/he-IL.rc @@ -9,23 +9,23 @@ BEGIN MENUITEM SEPARATOR MENUITEM "&יציאה", IDM_EXIT END - POPUP "&Play" + POPUP "&הפעלה" BEGIN - MENUITEM "Play/&Pause\tCtrl+P", IDC_PLAY - MENUITEM "St&op\tCtrl+S", IDC_STOP + MENUITEM "נגינה/&השהייה\tCtrl+P", IDC_PLAY + MENUITEM "&עצירה\tCtrl+S", IDC_STOP MENUITEM SEPARATOR - MENUITEM "Repea&t\tCtrl+T", IDM_REPEAT + MENUITEM "&חזרה\tCtrl+T", IDM_REPEAT END - POPUP "&View" + POPUP "&תצוגה" BEGIN - MENUITEM "Single-Window &Mode", IDM_SWITCHVIEW + MENUITEM "&מצב חלון יחיד", IDM_SWITCHVIEW END - POPUP "&Device" + POPUP "&התקן" BEGIN MENUITEM SEPARATOR - MENUITEM "&Properties", IDM_DEVPROPS + MENUITEM "&מאפיינים", IDM_DEVPROPS MENUITEM SEPARATOR - MENUITEM "&Volume Control", IDM_VOLUMECTL + MENUITEM "&בקרת עוצמה", IDM_VOLUMECTL END POPUP "&עזרה" BEGIN @@ -44,14 +44,14 @@ END STRINGTABLE BEGIN - IDS_MODE_UNKNOWN "Unknown" - IDS_MODE_OPEN "Opened" - IDS_MODE_STOP "Stopped" - IDS_MODE_PLAY "Playing" - IDS_MODE_PAUSE "Paused" - IDS_MODE_RECORD "Recording" - IDS_MODE_SEEK "Seeking" - IDS_MODE_NOT_READY "Not ready" + IDS_MODE_UNKNOWN "לא ידוע" + IDS_MODE_OPEN "נפתח" + IDS_MODE_STOP "נעצר" + IDS_MODE_PLAY "מנגן" + IDS_MODE_PAUSE "מושהה" + IDS_MODE_RECORD "מקליט" + IDS_MODE_SEEK "מחפש" + IDS_MODE_NOT_READY "לא מוכן" IDS_ALL_TYPES_FILTER "כל הקבצים הנתמכים" IDS_TOOLTIP_PLAY "נגן" IDS_TOOLTIP_STOP "עצור" @@ -60,8 +60,8 @@ BEGIN IDS_TOOLTIP_SEEKBACK "חפש אחורנית" IDS_TOOLTIP_SEEKFORW "חפש קדימה" IDS_TOOLTIP_FORWARD "דלג קדימה" - IDS_TOOLTIP_PAUSE "Pause" + IDS_TOOLTIP_PAUSE "השהה" IDS_APPTITLE "נגן המולטימדיה של ReactOS" IDS_PLAY "נגן" - IDS_DEFAULTMCIERRMSG "No description is available for this error." + IDS_DEFAULTMCIERRMSG "אין תיאור זמין עבור שגיאה זו." END diff --git a/base/applications/mplay32/mplay32.c b/base/applications/mplay32/mplay32.c index 8a900d1d6c..bf2a12da88 100644 --- a/base/applications/mplay32/mplay32.c +++ b/base/applications/mplay32/mplay32.c @@ -1473,6 +1473,16 @@ _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT nCmdShow) HANDLE hAccel; hInstance = hInst; + + switch (GetUserDefaultUILanguage()) + { + case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT): + SetProcessDefaultLayout(LAYOUT_RTL); + break; + + default: + break; + } LoadString(hInstance, IDS_APPTITLE, szAppTitle, ARRAYSIZE(szAppTitle)); diff --git a/base/applications/mplay32/mplay32.h b/base/applications/mplay32/mplay32.h index 6ea6b3d1d5..a7da65a337 100644 --- a/base/applications/mplay32/mplay32.h +++ b/base/applications/mplay32/mplay32.h @@ -12,5 +12,6 @@ #include <commctrl.h> #include <tchar.h> #include <strsafe.h> +#include <winnls.h> #include "resource.h" diff --git a/base/applications/msconfig/lang/he-IL.rc b/base/applications/msconfig/lang/he-IL.rc index 6424e30926..2a47e2d97c 100644 --- a/base/applications/msconfig/lang/he-IL.rc +++ b/base/applications/msconfig/lang/he-IL.rc @@ -5,6 +5,7 @@ LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT IDD_MSCONFIG_DIALOG DIALOGEX 0, 0, 378, 220 STYLE DS_SHELLFONT | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "כלי שירות לקביעת תצורת המערכת" FONT 8, "MS Shell Dlg" BEGIN @@ -17,6 +18,7 @@ END IDD_STARTUP_PAGE DIALOGEX 0, 0, 362, 175 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" BEGIN CONTROL "List3", IDC_STARTUP_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | @@ -27,6 +29,7 @@ END IDD_SYSTEM_PAGE DIALOGEX 0, 0, 362, 175 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_SYSTEM_TREE, "SysTreeView32", TVS_HASBUTTONS | TVS_HASLINES | @@ -45,6 +48,7 @@ END IDD_TOOLS_PAGE DIALOGEX 0, 0, 362, 175 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" BEGIN CONTROL "List2", IDC_TOOLS_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | @@ -55,6 +59,7 @@ END IDD_SERVICES_PAGE DIALOGEX 0, 0, 362, 175 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" BEGIN CONTROL "List1", IDC_SERVICES_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | @@ -65,6 +70,7 @@ END IDD_GENERAL_PAGE DIALOGEX 0, 0, 362, 175 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "בחירת אתחול", -1, 10, 10, 340, 150, 0, WS_EX_TRANSPARENT @@ -78,13 +84,14 @@ END IDD_FREELDR_PAGE DIALOGEX 0, 0, 362, 175 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" BEGIN LISTBOX IDC_LIST_BOX, 10, 10, 340, 50, WS_CHILD | WS_VISIBLE | WS_TABSTOP | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_HSCROLL - PUSHBUTTON "&בדוק את כל נתיבי האתחול", IDC_BTN_CHECK_BOOT_PATH, 114, 65, 97, 12 - PUSHBUTTON "&קבע כברירת מחדל", IDC_BTN_SET_DEFAULT_BOOT, 198, 65, 70, 12 - PUSHBUTTON "הזז למעלה", IDC_BTN_MOVE_UP_BOOT_OPTION, 190, 65, 70, 12 + PUSHBUTTON "&בדוק את כל נתיבי האתחול", IDC_BTN_CHECK_BOOT_PATH, 12, 65, 97, 12 + PUSHBUTTON "&קבע כברירת מחדל", IDC_BTN_SET_DEFAULT_BOOT, 115, 65, 74, 12 + PUSHBUTTON "הזז למעלה", IDC_BTN_MOVE_UP_BOOT_OPTION, 200, 65, 70, 12 PUSHBUTTON "הזז למטה", IDC_BTN_MOVE_DOWN_BOOT_OPTION, 280, 65, 70, 12 GROUPBOX "אפשרויות אתחול", -1, 10, 80, 250, 90, 0, WS_EX_TRANSPARENT CHECKBOX "/SA&FEBOOT", IDC_CBX_SAFE_BOOT, 15, 90, 55, 10 @@ -92,14 +99,15 @@ BEGIN CHECKBOX "/&BOOTLOG", IDC_CBX_BOOT_LOG, 15, 120, 50, 10 CHECKBOX "/BAS&EVIDEO", IDC_CBX_BASE_VIDEO, 15, 135, 55, 10 CHECKBOX "/S&OS", IDC_CBX_SOS, 15, 150, 50, 10 - PUSHBUTTON "&אפשרויות מתקדמות", IDC_BTN_ADVANCED_OPTIONS, 100, 150, 70, 12 - LTEXT "זמן קצוב:", -1, 280, 91, 30, 10 - EDITTEXT IDC_TXT_BOOT_TIMEOUT, 303, 90, 25, 12, ES_LEFT - LTEXT "שניות", -1, 330, 91, 21, 10 + PUSHBUTTON "&אפשרויות מתקדמות", IDC_BTN_ADVANCED_OPTIONS, 180, 150, 75, 12 + LTEXT "זמן קצוב:", -1, 263, 90, 32, 10 + EDITTEXT IDC_TXT_BOOT_TIMEOUT, 300, 90, 25, 12, ES_LEFT + LTEXT "שניות", -1, 327, 90, 21, 10 END IDD_FREELDR_ADVANCED_PAGE DIALOGEX 0, 0, 175, 175 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" BEGIN CHECKBOX "/&MAXMEM=", IDC_CBX_MAX_MEM, 10, 10, 50, 10 diff --git a/base/applications/mspaint/lang/he-IL.rc b/base/applications/mspaint/lang/he-IL.rc index 32610f45d5..cc8b08e720 100644 --- a/base/applications/mspaint/lang/he-IL.rc +++ b/base/applications/mspaint/lang/he-IL.rc @@ -15,7 +15,7 @@ BEGIN MENUITEM "Page Setup...", IDM_FILEPAGESETUP MENUITEM "Print...\tCtrl+P", IDM_FILEPRINT MENUITEM SEPARATOR - MENUITEM "Send...", IDM_FILESEND + MENUITEM "שליחה...", IDM_FILESEND MENUITEM SEPARATOR MENUITEM "קבע כרקע שולחן העבודה (פרוש)", IDM_FILEASWALLPAPERPLANE MENUITEM "קבע כרקע שולחן העבודה (מרכז)", IDM_FILEASWALLPAPERCENTERED @@ -115,6 +115,7 @@ END IDD_MIRRORROTATE DIALOGEX 100, 100, 180, 100 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" CAPTION "סובב והפוך את התמונה" BEGIN @@ -131,6 +132,7 @@ END IDD_ATTRIBUTES DIALOGEX 100, 100, 225, 120 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" CAPTION "תכונות" BEGIN @@ -158,6 +160,7 @@ END IDD_STRETCHSKEW DIALOGEX 100, 100, 225, 150 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" CAPTION "Stretch and skew image" BEGIN diff --git a/base/applications/mstsc/connectdialog.c b/base/applications/mstsc/connectdialog.c index 86bc002062..67f0966d7e 100644 --- a/base/applications/mstsc/connectdialog.c +++ b/base/applications/mstsc/connectdialog.c @@ -1262,7 +1262,7 @@ DlgProc(HWND hDlg, szBuffer, -1, &txtRc, - DT_BOTTOM | DT_SINGLELINE | DT_NOCLIP); + DT_BOTTOM | DT_SINGLELINE | DT_NOCLIP | DT_CENTER); //DT_CENTER makes the text visible in RTL layouts... SelectObject(hdc, hFontOld); DeleteObject(hFont); } diff --git a/base/applications/mstsc/lang/he-IL.rc b/base/applications/mstsc/lang/he-IL.rc index 2f22b87eda..45aaad493a 100644 --- a/base/applications/mstsc/lang/he-IL.rc +++ b/base/applications/mstsc/lang/he-IL.rc @@ -2,6 +2,7 @@ LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT IDD_GENERAL DIALOGEX 0, 0, 242, 175 STYLE DS_SHELLFONT | WS_CHILD +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN GROUPBOX "הגדרות כניסה", IDC_STATIC, 7, 7, 228, 89 @@ -21,6 +22,7 @@ END IDD_DISPLAY DIALOGEX 0, 0, 242, 175 STYLE DS_SHELLFONT | WS_CHILD +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN GROUPBOX "תצורת תצוגה", IDC_STATIC, 7, 7, 228, 68 @@ -39,6 +41,7 @@ END IDD_CONNECTDIALOG DIALOGEX 0, 0, 260, 262 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "חיבור לשולחן עבודה מרוחק" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN @@ -55,10 +58,10 @@ BEGIN IDS_HIGHCOLOR15 "32,768 צבעים (15 סיביות)" IDS_HIGHCOLOR16 "65,536 צבעים (16 סיביות)" IDS_HIGHCOLOR24 "16,777,216 צבעים (24 סיביות)" - IDS_HIGHCOLOR32 "Highest Quality (32 bit)" + IDS_HIGHCOLOR32 "איכות הכי גבוהה (32 סיביות)" IDS_PIXEL "%lux%lu פיקסלים" IDS_FULLSCREEN "מסך מלא" IDS_BROWSESERVER "<Browse for more...>" IDS_HEADERTEXT1 "שולחן עבודה מרוחק" - IDS_HEADERTEXT2 "חיבור" + IDS_HEADERTEXT2 "חיבור" //fix: text gets reversed for some reason... END diff --git a/base/applications/notepad/lang/he-IL.rc b/base/applications/notepad/lang/he-IL.rc index 172c6f959d..249697caf8 100644 --- a/base/applications/notepad/lang/he-IL.rc +++ b/base/applications/notepad/lang/he-IL.rc @@ -70,6 +70,7 @@ END /* Dialog 'Page setup' */ DIALOG_PAGESETUP DIALOGEX 0, 0, 365, 193 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" CAPTION "Page Setup" BEGIN @@ -107,18 +108,20 @@ END /* Dialog 'Encoding' */ DIALOG_ENCODING DIALOGEX 0, 0, 256, 44 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" CAPTION "קידוד" BEGIN COMBOBOX ID_ENCODING, 54, 0, 156, 80, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP LTEXT "קידוד:", 0x155, 5, 2, 41, 12 COMBOBOX ID_EOLN, 54, 18, 156, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Endlines:", 0x156, 5, 20, 41, 12 + LTEXT "סופי שורות:", 0x156, 5, 20, 41, 12 END /* Dialog 'Go To' */ DIALOG_GOTO DIALOGEX 0, 0, 165, 50 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" CAPTION "מעבר אל שורה" BEGIN @@ -130,6 +133,7 @@ END IDD_ABOUTBOX DIALOGEX 22, 16, 284, 170 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "אודות פנקס הרשימות של ReactOS" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/osk/lang/he-IL.rc b/base/applications/osk/lang/he-IL.rc new file mode 100644 index 0000000000..52d0887db3 --- /dev/null +++ b/base/applications/osk/lang/he-IL.rc @@ -0,0 +1,128 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/applications/osk/lang/he-IL.rc + * PURPOSE: On screen keyboard (Hebrew resources). + * TRANSLATORS: Baruch Rutman + */ + +LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT + +MAIN_DIALOG DIALOGEX DISCARDABLE 0, 0, 608, 164 +CAPTION "לוח מקשים על התצוגה" +FONT 8, "MS Shell Dlg" +EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE +BEGIN + PUSHBUTTON "Esc",SCAN_CODE_110,3,3,23,22 + PUSHBUTTON "F1",SCAN_CODE_112,48,3,23,22 + PUSHBUTTON "F2",SCAN_CODE_113,75,3,23,22 + PUSHBUTTON "F3",SCAN_CODE_114,101,3,23,22 + PUSHBUTTON "F4",SCAN_CODE_115,128,3,23,22 + PUSHBUTTON "F5",SCAN_CODE_116,173,3,23,22 + PUSHBUTTON "F6",SCAN_CODE_117,199,3,23,22 + PUSHBUTTON "F7",SCAN_CODE_118,225,3,23,22 + PUSHBUTTON "F8",SCAN_CODE_119,251,3,23,22 + PUSHBUTTON "F9",SCAN_CODE_120,296,3,23,22 + PUSHBUTTON "F10",SCAN_CODE_121,323,3,23,22 + PUSHBUTTON "F11",SCAN_CODE_122,350,3,23,22 + PUSHBUTTON "F12",SCAN_CODE_123,377,3,23,22 + PUSHBUTTON "Prn",SCAN_CODE_124,411,3,23,22 + PUSHBUTTON "Stop",SCAN_CODE_125,438,3,23,22 + PUSHBUTTON "Attn",SCAN_CODE_126,465,3,23,22 + PUSHBUTTON "`",SCAN_CODE_1,3,35,23,22 + PUSHBUTTON "1",SCAN_CODE_2,30,35,23,22 + PUSHBUTTON "2",SCAN_CODE_3,57,35,23,22 + PUSHBUTTON "3",SCAN_CODE_4,84,35,23,22 + PUSHBUTTON "4",SCAN_CODE_5,111,35,23,22 + PUSHBUTTON "5",SCAN_CODE_6,138,35,23,22 + PUSHBUTTON "6",SCAN_CODE_7,165,35,23,22 + PUSHBUTTON "7",SCAN_CODE_8,192,35,23,22 + PUSHBUTTON "8",SCAN_CODE_9,219,35,23,22 + PUSHBUTTON "9",SCAN_CODE_10,246,35,23,22 + PUSHBUTTON "0",SCAN_CODE_11,273,35,23,22 + PUSHBUTTON "-",SCAN_CODE_12,300,35,23,22 + PUSHBUTTON "=",SCAN_CODE_13,327,35,23,22 + PUSHBUTTON "<--",SCAN_CODE_15,354,35,47,22,BS_ICON + PUSHBUTTON "Tab",SCAN_CODE_16,3,61,35,22,BS_ICON + PUSHBUTTON "/",SCAN_CODE_17,42,61,23,22 + PUSHBUTTON "'",SCAN_CODE_18,69,61,23,22 + PUSHBUTTON "ק",SCAN_CODE_19,96,61,23,22 + PUSHBUTTON "ר",SCAN_CODE_20,123,61,23,22 + PUSHBUTTON "א",SCAN_CODE_21,150,61,23,22 + PUSHBUTTON "ט",SCAN_CODE_22,177,61,23,22 + PUSHBUTTON "ו",SCAN_CODE_23,204,61,23,22 + PUSHBUTTON "ן",SCAN_CODE_24,231,61,23,22 + PUSHBUTTON "ם",SCAN_CODE_25,258,61,23,22 + PUSHBUTTON "פ",SCAN_CODE_26,285,61,23,22 + PUSHBUTTON "[",SCAN_CODE_27,312,61,23,22 + PUSHBUTTON "]",SCAN_CODE_28,339,61,23,22 + PUSHBUTTON "\\",SCAN_CODE_29,366,61,35,22 + PUSHBUTTON "Caps Lock",SCAN_CODE_30,3,87,46,22,BS_ICON + PUSHBUTTON "ש",SCAN_CODE_31,53,87,23,22 + PUSHBUTTON "ד",SCAN_CODE_32,80,87,23,22 + PUSHBUTTON "ג",SCAN_CODE_33,107,87,23,22 + PUSHBUTTON "כ",SCAN_CODE_34,134,87,23,22 + PUSHBUTTON "ע",SCAN_CODE_35,161,87,23,22 + PUSHBUTTON "י",SCAN_CODE_36,188,87,23,22 + PUSHBUTTON "ח",SCAN_CODE_37,215,87,23,22 + PUSHBUTTON "ל",SCAN_CODE_38,242,87,23,22 + PUSHBUTTON "ך",SCAN_CODE_39,269,87,23,22 + PUSHBUTTON "ף",SCAN_CODE_40,296,87,23,22 + PUSHBUTTON ",",SCAN_CODE_41,323,87,23,22 + PUSHBUTTON "ret",SCAN_CODE_43,350,87,51,22,BS_ICON + PUSHBUTTON "shift",SCAN_CODE_44,3,113,57,22,BS_ICON|BS_PUSHLIKE|BS_AUTOCHECKBOX + PUSHBUTTON "ז",SCAN_CODE_46,64,113,23,22 + PUSHBUTTON "ס",SCAN_CODE_47,91,113,23,22 + PUSHBUTTON "ב",SCAN_CODE_48,118,113,23,22 + PUSHBUTTON "ה",SCAN_CODE_49,145,113,23,22 + PUSHBUTTON "נ",SCAN_CODE_50,172,113,23,22 + PUSHBUTTON "מ",SCAN_CODE_51,199,113,23,22 + PUSHBUTTON "צ",SCAN_CODE_52,226,113,23,22 + PUSHBUTTON "ת",SCAN_CODE_53,253,113,23,22 + PUSHBUTTON "ץ",SCAN_CODE_54,280,113,23,22 + PUSHBUTTON ".",SCAN_CODE_55,307,113,23,22 + PUSHBUTTON "shift",SCAN_CODE_57,334,113,67,22,BS_ICON|BS_PUSHLIKE|BS_AUTOCHECKBOX + PUSHBUTTON "ctrl",SCAN_CODE_58,3,139,41,22,BS_PUSHLIKE|BS_AUTOCHECKBOX + PUSHBUTTON "ROS",SCAN_CODE_127,48,139,30,22,BS_ICON + PUSHBUTTON "alt",SCAN_CODE_60,82,139,30,22,BS_PUSHLIKE|BS_AUTOCHECKBOX + PUSHBUTTON "",SCAN_CODE_61,116,139,143,22 + PUSHBUTTON "alt gr",SCAN_CODE_62,264,139,30,22,BS_PUSHLIKE|BS_AUTOCHECKBOX + PUSHBUTTON "ROS",SCAN_CODE_128,298,139,30,22,BS_ICON + PUSHBUTTON "menu",SCAN_CODE_129,332,139,30,22,BS_ICON + PUSHBUTTON "ctrl",SCAN_CODE_64,366,139,35,22,BS_PUSHLIKE|BS_AUTOCHECKBOX + PUSHBUTTON "ins",SCAN_CODE_75,411,35,23,22 + PUSHBUTTON "del",SCAN_CODE_76,411,61,23,22 + PUSHBUTTON "home",SCAN_CODE_80,438,35,23,22,BS_ICON + PUSHBUTTON "end",SCAN_CODE_81,438,61,23,22 + PUSHBUTTON "pg up",SCAN_CODE_85,465,35,23,22,BS_ICON + PUSHBUTTON "pg down",SCAN_CODE_86,465,61,23,22,BS_ICON + PUSHBUTTON "<-",SCAN_CODE_79,411,139,23,22,BS_ICON + PUSHBUTTON "^",SCAN_CODE_83,438,113,23,22,BS_ICON + PUSHBUTTON "v",SCAN_CODE_84,438,139,23,22,BS_ICON + PUSHBUTTON "->",SCAN_CODE_89,465,139,23,22,BS_ICON + PUSHBUTTON "num",SCAN_CODE_90,500,35,23,22 + PUSHBUTTON "7",SCAN_CODE_91,500,61,23,22 + PUSHBUTTON "4",SCAN_CODE_92,500,87,23,22 + PUSHBUTTON "1",SCAN_CODE_93,500,113,23,22 + PUSHBUTTON "/",SCAN_CODE_95,527,35,23,22 + PUSHBUTTON "8",SCAN_CODE_96,527,61,23,22 + PUSHBUTTON "5",SCAN_CODE_97,527,87,23,22 + PUSHBUTTON "2",SCAN_CODE_98,527,113,23,22 + PUSHBUTTON "0",SCAN_CODE_99,500,139,50,22 + PUSHBUTTON "*",SCAN_CODE_100,554,35,23,22 + PUSHBUTTON "9",SCAN_CODE_101,554,61,23,22 + PUSHBUTTON "6",SCAN_CODE_102,554,87,23,22 + PUSHBUTTON "3",SCAN_CODE_103,554,113,23,22 + PUSHBUTTON ".",SCAN_CODE_104,554,139,23,22 + PUSHBUTTON "-",SCAN_CODE_105,581,35,23,22 + PUSHBUTTON "+",SCAN_CODE_106,581,61,23,48 + PUSHBUTTON "ent",SCAN_CODE_108,581,113,23,48 + CTEXT "Num",IDC_STATIC,510,4,21,8 + CONTROL "",IDC_LED_NUM,"Static",SS_CENTER|SS_NOTIFY,518,16,4,3 + CTEXT "Caps",IDC_STATIC,540,4,21,8 + CONTROL "",IDC_LED_CAPS,"Static",SS_CENTER|SS_NOTIFY,548,16,4,3 + CTEXT "Scroll",IDC_STATIC,572,4,21,8 + CONTROL "",IDC_LED_SCROLL,"Static",SS_CENTER|SS_NOTIFY,580,16,4,3 +END + +/* EOF */ diff --git a/base/applications/osk/rsrc.rc b/base/applications/osk/rsrc.rc index 6b678eedcc..cdbf119f56 100644 --- a/base/applications/osk/rsrc.rc +++ b/base/applications/osk/rsrc.rc @@ -67,6 +67,9 @@ IDI_BOTTOM ICON "res/bottom.ico" #ifdef LANGUAGE_FR_FR #include "lang/fr-FR.rc" #endif +#ifdef LANGUAGE_HE_IL + #include "lang/he-IL.rc" +#endif #ifdef LANGUAGE_IT_IT #include "lang/it-IT.rc" #endif diff --git a/base/applications/rapps/lang/he-IL.rc b/base/applications/rapps/lang/he-IL.rc index b1498345c9..c348a7aa7a 100644 --- a/base/applications/rapps/lang/he-IL.rc +++ b/base/applications/rapps/lang/he-IL.rc @@ -20,7 +20,7 @@ BEGIN MENUITEM SEPARATOR MENUITEM "רענון\tF5", ID_REFRESH MENUITEM SEPARATOR - MENUITEM "Update Da&tabase\tCtrl+F5", ID_RESETDB + MENUITEM "עדכון מסד נתונים\tCtrl+F5", ID_RESETDB END POPUP "עזרה" BEGIN @@ -50,12 +50,13 @@ BEGIN MENUITEM SEPARATOR MENUITEM "רענן\tF5", ID_REFRESH MENUITEM SEPARATOR - MENUITEM "Update Da&tabase\tCtrl+F5", ID_RESETDB + MENUITEM "עדכון מסד נתונים\tCtrl+F5", ID_RESETDB END END IDD_SETTINGS_DIALOG DIALOGEX 0, 0, 250, 215 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "הגדרות" FONT 8, "MS Shell Dlg" BEGIN @@ -68,12 +69,12 @@ BEGIN EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL PUSHBUTTON "בחר", IDC_CHOOSE, 187, 85, 50, 14 AUTOCHECKBOX "מחק את קובץ ההתקנה לאחר סיום ההתקנה", IDC_DEL_AFTER_INSTALL, 16, 100, 218, 12 - GROUPBOX "Proxy", -1, 4, 116, 240, 76 - CONTROL "System proxy settings", IDC_PROXY_DEFAULT, "Button", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 15, 130, 210, 10 - CONTROL "Direct (No proxy)", IDC_NO_PROXY, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 15, 145, 210, 10 - CONTROL "Proxy", IDC_USE_PROXY, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 15, 160, 74, 10 + GROUPBOX "שרת פרוקסי", -1, 4, 116, 240, 76 + CONTROL "הגדרות פרוקסי של המערכת", IDC_PROXY_DEFAULT, "Button", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 15, 130, 210, 10 + CONTROL "חיבור ישיר(ללא פרוקסי)", IDC_NO_PROXY, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 15, 145, 210, 10 + CONTROL "פרוקסי", IDC_USE_PROXY, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 15, 160, 74, 10 EDITTEXT IDC_PROXY_SERVER, 90, 160, 147, 12, ES_AUTOHSCROLL | WS_DISABLED - LTEXT "No proxy for", -1, 27, 175, 64, 10 + LTEXT "ללא פרוקסי עבור:", -1, 27, 175, 64, 10 EDITTEXT IDC_NO_PROXY_FOR, 90, 175, 147, 12, ES_AUTOHSCROLL | WS_DISABLED PUSHBUTTON "ברירת מחדל", IDC_DEFAULT_SETTINGS, 8, 195, 60, 14 PUSHBUTTON "אישור", IDOK, 116, 195, 60, 14 @@ -82,6 +83,7 @@ END IDD_INSTALL_DIALOG DIALOGEX 0, 0, 216, 97 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "התקנת תכנית" FONT 8, "MS Shell Dlg" BEGIN @@ -94,6 +96,7 @@ END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 72 STYLE DS_SHELLFONT | DS_CENTER | WS_BORDER | WS_CAPTION | WS_POPUP | WS_SYSMENU | WS_VISIBLE +EXSTYLE WS_EX_LAYOUTRTL CAPTION "הורדה %ls…" FONT 8, "MS Shell Dlg" BEGIN @@ -104,6 +107,7 @@ END IDD_ABOUT_DIALOG DIALOGEX 22, 16, 190, 66 STYLE DS_SHELLFONT | WS_BORDER | WS_DLGFRAME | WS_SYSMENU | DS_MODALFRAME +EXSTYLE WS_EX_LAYOUTRTL CAPTION "אודות" FONT 8, "MS Shell Dlg" BEGIN @@ -119,7 +123,7 @@ BEGIN IDS_TOOLTIP_MODIFY "שינוי" IDS_TOOLTIP_SETTINGS "הגדרות" IDS_TOOLTIP_REFRESH "רענון" - IDS_TOOLTIP_UPDATE_DB "Update Database" + IDS_TOOLTIP_UPDATE_DB "עדכון מסד נתונים" IDS_TOOLTIP_EXIT "יציאה" END @@ -154,13 +158,13 @@ END STRINGTABLE BEGIN IDS_AINFO_VERSION "\nגרסה: " - IDS_AINFO_AVAILABLEVERSION "\nAvailable Version: " + IDS_AINFO_AVAILABLEVERSION "\nגרסה זמינה: " IDS_AINFO_DESCRIPTION "\nתיאור: " IDS_AINFO_SIZE "\nגודל: " IDS_AINFO_URLSITE "\nדף בית: " IDS_AINFO_LICENSE "\nרישיון: " IDS_AINFO_URLDOWNLOAD "\nהורד: " - IDS_AINFO_LANGUAGES "\nLanguages: " + IDS_AINFO_LANGUAGES "\nשפות: " END STRINGTABLE @@ -217,19 +221,19 @@ END STRINGTABLE BEGIN - IDS_STATUS_INSTALLED "Installed" - IDS_STATUS_NOTINSTALLED "Not installed" - IDS_STATUS_DOWNLOADED "Downloaded" - IDS_STATUS_UPDATE_AVAILABLE "Update available" - IDS_STATUS_DOWNLOADING "Downloading…" - IDS_STATUS_INSTALLING "Installing…" - IDS_STATUS_WAITING "Waiting to install…" - IDS_STATUS_FINISHED "Finished" + IDS_STATUS_INSTALLED "מותקן" + IDS_STATUS_NOTINSTALLED "לא מותקן" + IDS_STATUS_DOWNLOADED "הורד" + IDS_STATUS_UPDATE_AVAILABLE "עדכון זמין" + IDS_STATUS_DOWNLOADING "מוריד..." + IDS_STATUS_INSTALLING "מתקין..." + IDS_STATUS_WAITING "מחכה להתקנה..." + IDS_STATUS_FINISHED "הסתיים" END STRINGTABLE BEGIN - IDS_LICENSE_OPENSOURCE "Open Source" + IDS_LICENSE_OPENSOURCE "קוד פתוח" IDS_LICENSE_FREEWARE "Freeware" IDS_LICENSE_TRIAL "Trial/Demo" END diff --git a/base/applications/screensavers/3dtext/lang/he-IL.rc b/base/applications/screensavers/3dtext/lang/he-IL.rc index b5a9d3e88d..3468e6d895 100644 --- a/base/applications/screensavers/3dtext/lang/he-IL.rc +++ b/base/applications/screensavers/3dtext/lang/he-IL.rc @@ -2,6 +2,7 @@ LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT DLG_SCRNSAVECONFIGURE DIALOGEX 0, 0, 273, 178 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "הגדרות שומר מסך של טקסט תלת מימדי" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN diff --git a/base/applications/shutdown/lang/he-IL.rc b/base/applications/shutdown/lang/he-IL.rc index 33064cbf59..7b654f98af 100644 --- a/base/applications/shutdown/lang/he-IL.rc +++ b/base/applications/shutdown/lang/he-IL.rc @@ -3,6 +3,7 @@ LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT /* Dialog */ IDD_GUI DIALOGEX 0, 0, 240, 255 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "כיבוי מרחוק" FONT 8, "MS Shell Dlg" BEGIN @@ -13,7 +14,7 @@ BEGIN PUSHBUTTON "הוסף...", IDC_ADD_SYSTEM, 179, 19, 50, 14 PUSHBUTTON "הסר", IDC_REMOVE_SYSTEM, 179, 36, 50, 14, WS_DISABLED PUSHBUTTON "סייר...", IDC_BROWSE_SYSTEM, 179, 53, 50, 14 - LTEXT "Action", IDC_ACTION, 11, 81, 20, 14 + LTEXT "פעולות", IDC_ACTION, 11, 81, 20, 14 COMBOBOX IDC_ACTION_TYPE, 37, 79, 129, 14, WS_TABSTOP | CBS_DROPDOWN CHECKBOX "הזהר משתמשים", IDC_WARN_USERS, 167, 78, 68, 14, BS_AUTOCHECKBOX | WS_TABSTOP LTEXT "הצג אזהרה ל-", IDC_SHOW_WARN_ONE, 11, 99, 65, 14 diff --git a/base/applications/sndrec32/lang/he-IL.rc b/base/applications/sndrec32/lang/he-IL.rc index d4b39e91d0..c5d9725182 100644 --- a/base/applications/sndrec32/lang/he-IL.rc +++ b/base/applications/sndrec32/lang/he-IL.rc @@ -8,6 +8,7 @@ END IDD_ABOUTBOX DIALOGEX 0, 0, 196, 75 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "אודות הרשמקול של ReactOS" FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN @@ -25,34 +26,34 @@ BEGIN MENUITEM "פתח...", ID_FILE_OPEN MENUITEM "שמור", ID_FILE_SAVE, GRAYED MENUITEM "שמור בשם...", ID_FILE_SAVEAS, GRAYED - MENUITEM "Restore...", ID_FILE_RESTORE, GRAYED - MENUITEM "Properties", ID_FILE_PROPERTIES + MENUITEM "שחזור...", ID_FILE_RESTORE, GRAYED + MENUITEM "מאפיינים", ID_FILE_PROPERTIES MENUITEM SEPARATOR MENUITEM "יציאה", ID_FILE_EXIT END - POPUP "&Edit" + POPUP "&עריכה" BEGIN - MENUITEM "&Copy", ID_EDIT_COPY + MENUITEM "&העתק", ID_EDIT_COPY MENUITEM "&Paste Insert", ID_EDIT_PASTE, GRAYED MENUITEM "Paste Mi&x", ID_EDIT_PASTEMIX, GRAYED MENUITEM SEPARATOR - MENUITEM "&Insert File...", ID_EDIT_INSERTFILE + MENUITEM "הכנסת קובץ...", ID_EDIT_INSERTFILE MENUITEM "&Mix with File...", ID_EDIT_MIXFILE MENUITEM SEPARATOR MENUITEM "Delete &Before Current Position",ID_EDIT_DELETEBEFORE, GRAYED MENUITEM "Delete &After Current Position",ID_EDIT_DELETEAFTER, GRAYED MENUITEM SEPARATOR - MENUITEM "A&udio Properties", ID_EDIT_AUDIOPROPS + MENUITEM "מאפייני שמע", ID_EDIT_AUDIOPROPS END - POPUP "Effect&s" + POPUP "א&פקטים" BEGIN - MENUITEM "&Increase Volume (by 25%)", ID_EFFECTS_INCVOL - MENUITEM "&Decrease Volume", ID_EFFECTS_DECVOL + MENUITEM "ה&גברת עוצמה(ב 25%)", ID_EFFECTS_INCVOL + MENUITEM "ה&נמכת עוצמה", ID_EFFECTS_DECVOL MENUITEM SEPARATOR - MENUITEM "&Increase Speed (by 100%)", ID_EFFECTS_INCSPD - MENUITEM "&Decrease Speed", ID_EFFECTS_DECSPD + MENUITEM "הגברת &מהירות (ב 100%)", ID_EFFECTS_INCSPD + MENUITEM "הו&רדת מהירות", ID_EFFECTS_DECSPD MENUITEM SEPARATOR - MENUITEM "&Add Echo", ID_EFFECTS_ECHO + MENUITEM "הוספת הד", ID_EFFECTS_ECHO MENUITEM "&Reverse", ID_EFFECTS_REVERSE END POPUP "?" diff --git a/base/applications/sndrec32/sndrec32.cpp b/base/applications/sndrec32/sndrec32.cpp index 4ba05825b1..7eabc446fa 100644 --- a/base/applications/sndrec32/sndrec32.cpp +++ b/base/applications/sndrec32/sndrec32.cpp @@ -10,6 +10,7 @@ #include <commctrl.h> #include <commdlg.h> +#include <winnls.h> #include "sndrec32.h" #include "shellapi.h" @@ -117,6 +118,16 @@ _tWinMain(HINSTANCE hInstance, s_info.cbSize = sizeof( NONCLIENTMETRICS ); InitCommonControls(); + + switch (GetUserDefaultUILanguage()) + { + case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT): + SetProcessDefaultLayout(LAYOUT_RTL); + break; + + default: + break; + } win_first = wout_first = FALSE; diff --git a/base/applications/sndvol32/lang/he-IL.rc b/base/applications/sndvol32/lang/he-IL.rc index 7f7c024448..02bd4c6e6a 100644 --- a/base/applications/sndvol32/lang/he-IL.rc +++ b/base/applications/sndvol32/lang/he-IL.rc @@ -25,7 +25,8 @@ END IDD_PREFERENCES DIALOGEX 0, 0, 224, 250 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "מאפייני" +EXSTYLE WS_EX_LAYOUTRTL +CAPTION "מאפיינים" FONT 8, "MS Shell Dlg" BEGIN LTEXT "התקן ערבול:", -1, 7, 8, 48, 9 @@ -43,6 +44,7 @@ END IDD_VOLUME_CTRL DIALOG 0, 0, 90, 150 STYLE WS_POPUP | WS_BORDER +EXSTYLE WS_EX_LAYOUTRTL FONT 8, "MS Shell Dlg" BEGIN LTEXT "ראשי", IDC_LINE_NAME, 4, 7, 100, 15 diff --git a/base/applications/wordpad/lang/he-IL.rc b/base/applications/wordpad/lang/he-IL.rc index 16a136bde9..aed2911564 100644 --- a/base/applications/wordpad/lang/he-IL.rc +++ b/base/applications/wordpad/lang/he-IL.rc @@ -196,6 +196,7 @@ END IDD_DATETIME DIALOGEX 30, 20, 130, 80 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "תאריך ושעה" FONT 8, "MS Shell Dlg" BEGIN @@ -207,6 +208,7 @@ END IDD_NEWFILE DIALOGEX 30, 20, 140, 80 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "חדש" FONT 8, "MS Shell Dlg" BEGIN @@ -218,6 +220,7 @@ END IDD_PARAFORMAT DIALOGEX 30, 20, 220, 110 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "עיצוב פסקה" FONT 8, "MS Shell Dlg" BEGIN @@ -236,6 +239,7 @@ END IDD_TABSTOPS DIALOGEX 30, 20, 200, 110 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_LAYOUTRTL CAPTION "טאבים" FONT 8, "MS Shell Dlg" BEGIN @@ -250,6 +254,7 @@ END IDD_FORMATOPTS DIALOGEX 0, 0, 280, 110 STYLE DS_SHELLFONT | DS_SYSMODAL +EXSTYLE WS_EX_LAYOUTRTL CAPTION "" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/wordpad/wordpad.c b/base/applications/wordpad/wordpad.c index 0895ee99a5..23c8120399 100644 --- a/base/applications/wordpad/wordpad.c +++ b/base/applications/wordpad/wordpad.c @@ -2656,6 +2656,16 @@ int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hOldInstance, LPSTR szCmdPar 'T','A','B','L','E','\0'}; InitCommonControlsEx(&classes); + + switch (GetUserDefaultUILanguage()) + { + case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT): + SetProcessDefaultLayout(LAYOUT_RTL); + break; + + default: + break; + } hAccel = LoadAcceleratorsW(hInstance, wszAccelTable);
6 years, 11 months
1
0
0
0
01/01: [WINHTTP_WINETEST] Properly re-add the ROS diff removed during last winesync. This avoids timeouts in the winhttp:notification test.
by Pierre Schweitzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=89670a48aba0939f5ca2b…
commit 89670a48aba0939f5ca2b2cc2e0ed29918a337ae Author: Pierre Schweitzer <pierre(a)reactos.org> AuthorDate: Wed Jan 24 15:55:38 2018 +0100 Commit: Pierre Schweitzer <pierre(a)reactos.org> CommitDate: Wed Jan 24 15:56:49 2018 +0100 [WINHTTP_WINETEST] Properly re-add the ROS diff removed during last winesync. This avoids timeouts in the winhttp:notification test. ROSTESTS-295 CORE-14248 --- modules/rostests/winetests/winhttp/notification.c | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/rostests/winetests/winhttp/notification.c b/modules/rostests/winetests/winhttp/notification.c index bcb7a0b318..2322eae0a7 100644 --- a/modules/rostests/winetests/winhttp/notification.c +++ b/modules/rostests/winetests/winhttp/notification.c @@ -1043,6 +1043,7 @@ if (!winetest_interactive) { skip("Skipping test_persistent_connection due to hang. See ROSTESTS-295.\n"); } +else #endif test_persistent_connection( si.port );
6 years, 11 months
1
0
0
0
01/01: [EXPLORER] Split up the notification area into a few more manageable pieces.
by David Quintana
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3d75cc0814cc7e2167b9a…
commit 3d75cc0814cc7e2167b9aac05823ca18b8a3cdc6 Author: David Quintana <gigaherz(a)gmail.com> AuthorDate: Wed Jan 24 14:41:06 2018 +0100 Commit: David Quintana <gigaherz(a)gmail.com> CommitDate: Wed Jan 24 14:41:31 2018 +0100 [EXPLORER] Split up the notification area into a few more manageable pieces. --- base/shell/explorer/CMakeLists.txt | 2 + base/shell/explorer/precomp.h | 12 + base/shell/explorer/syspager.cpp | 1228 +++++++++++++++++++++++ base/shell/explorer/syspager.h | 203 ++++ base/shell/explorer/trayclock.cpp | 576 +++++++++++ base/shell/explorer/trayclock.h | 94 ++ base/shell/explorer/trayntfy.cpp | 1947 ------------------------------------ 7 files changed, 2115 insertions(+), 1947 deletions(-) diff --git a/base/shell/explorer/CMakeLists.txt b/base/shell/explorer/CMakeLists.txt index f935f4dafd..fa66d2e428 100644 --- a/base/shell/explorer/CMakeLists.txt +++ b/base/shell/explorer/CMakeLists.txt @@ -16,9 +16,11 @@ list(APPEND SOURCE startmnucust.cpp startmnusite.cpp startup.cpp + syspager.cpp taskband.cpp taskswnd.cpp tbsite.cpp + trayclock.cpp trayntfy.cpp trayprop.cpp traywnd.cpp diff --git a/base/shell/explorer/precomp.h b/base/shell/explorer/precomp.h index 9aaa351f76..1aacb42ce3 100644 --- a/base/shell/explorer/precomp.h +++ b/base/shell/explorer/precomp.h @@ -384,4 +384,16 @@ Tray_OnStartMenuDismissed(ITrayWindow* Tray); HRESULT IsSameObject(IN IUnknown *punk1, IN IUnknown *punk2); +/* +* syspager.c +*/ + +#include "syspager.h" + +/* +* trayclock.c +*/ + +#include "trayclock.h" + #endif /* _EXPLORER_PRECOMP__H_ */ diff --git a/base/shell/explorer/syspager.cpp b/base/shell/explorer/syspager.cpp new file mode 100644 index 0000000000..7a55360853 --- /dev/null +++ b/base/shell/explorer/syspager.cpp @@ -0,0 +1,1228 @@ +/* + * ReactOS Explorer + * + * Copyright 2006 - 2007 Thomas Weidenmueller <w3seek(a)reactos.org> + * Copyright 2018 Ged Murphy <gedmurphy(a)reactos.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "precomp.h" + +// Data comes from shell32/systray.cpp -> TrayNotifyCDS_Dummy +typedef struct _SYS_PAGER_COPY_DATA +{ + DWORD cookie; + DWORD notify_code; + NOTIFYICONDATA nicon_data; +} SYS_PAGER_COPY_DATA, *PSYS_PAGER_COPY_DATA; + +CIconWatcher::CIconWatcher() : + m_hWatcherThread(NULL), + m_WakeUpEvent(NULL), + m_hwndSysTray(NULL), + m_Loop(false) +{ +} + +CIconWatcher::~CIconWatcher() +{ + Uninitialize(); + DeleteCriticalSection(&m_ListLock); + + if (m_WakeUpEvent) + CloseHandle(m_WakeUpEvent); + if (m_hWatcherThread) + CloseHandle(m_hWatcherThread); +} + +bool CIconWatcher::Initialize(_In_ HWND hWndParent) +{ + m_hwndSysTray = hWndParent; + + InitializeCriticalSection(&m_ListLock); + m_WakeUpEvent = CreateEventW(NULL, FALSE, FALSE, NULL); + if (m_WakeUpEvent == NULL) + return false; + + m_hWatcherThread = (HANDLE)_beginthreadex(NULL, + 0, + WatcherThread, + (LPVOID)this, + 0, + NULL); + if (m_hWatcherThread == NULL) + return false; + + return true; +} + +void CIconWatcher::Uninitialize() +{ + m_Loop = false; + if (m_WakeUpEvent) + SetEvent(m_WakeUpEvent); + + EnterCriticalSection(&m_ListLock); + + POSITION Pos; + for (size_t i = 0; i < m_WatcherList.GetCount(); i++) + { + Pos = m_WatcherList.FindIndex(i); + if (Pos) + { + IconWatcherData *Icon; + Icon = m_WatcherList.GetAt(Pos); + delete Icon; + } + } + m_WatcherList.RemoveAll(); + + LeaveCriticalSection(&m_ListLock); +} + +bool CIconWatcher::AddIconToWatcher(_In_ NOTIFYICONDATA *iconData) +{ + DWORD ProcessId; + (void)GetWindowThreadProcessId(iconData->hWnd, &ProcessId); + + HANDLE hProcess; + hProcess = OpenProcess(SYNCHRONIZE, FALSE, ProcessId); + if (hProcess == NULL) + { + return false; + } + + IconWatcherData *Icon = new IconWatcherData(iconData); + Icon->hProcess = hProcess; + Icon->ProcessId; + + bool Added = false; + EnterCriticalSection(&m_ListLock); + + // The likelyhood of someone having more than 64 icons in their tray is + // pretty slim. We could spin up a new thread for each multiple of 64, but + // it's not worth the effort, so we just won't bother watching those icons + if (m_WatcherList.GetCount() < MAXIMUM_WAIT_OBJECTS) + { + m_WatcherList.AddTail(Icon); + SetEvent(m_WakeUpEvent); + Added = true; + } + + LeaveCriticalSection(&m_ListLock); + + if (!Added) + { + delete Icon; + } + + return Added; +} + +bool CIconWatcher::RemoveIconFromWatcher(_In_ NOTIFYICONDATA *iconData) +{ + EnterCriticalSection(&m_ListLock); + + IconWatcherData *Icon; + Icon = GetListEntry(iconData, NULL, true); + + SetEvent(m_WakeUpEvent); + LeaveCriticalSection(&m_ListLock); + + delete Icon; + return true; +} + +IconWatcherData* CIconWatcher::GetListEntry(_In_opt_ NOTIFYICONDATA *iconData, _In_opt_ HANDLE hProcess, _In_ bool Remove) +{ + IconWatcherData *Entry = NULL; + POSITION NextPosition = m_WatcherList.GetHeadPosition(); + POSITION Position; + do + { + Position = NextPosition; + + Entry = m_WatcherList.GetNext(NextPosition); + if (Entry) + { + if ((iconData && ((Entry->IconData.hWnd == iconData->hWnd) && (Entry->IconData.uID == iconData->uID))) || + (hProcess && (Entry->hProcess == hProcess))) + { + if (Remove) + m_WatcherList.RemoveAt(Position); + break; + } + } + Entry = NULL; + + } while (NextPosition != NULL); + + return Entry; +} + +UINT WINAPI CIconWatcher::WatcherThread(_In_opt_ LPVOID lpParam) +{ + CIconWatcher* This = reinterpret_cast<CIconWatcher *>(lpParam); + HANDLE *WatchList = NULL; + + This->m_Loop = true; + while (This->m_Loop) + { + EnterCriticalSection(&This->m_ListLock); + + DWORD Size; + Size = This->m_WatcherList.GetCount() + 1; + ASSERT(Size <= MAXIMUM_WAIT_OBJECTS); + + if (WatchList) + delete WatchList; + WatchList = new HANDLE[Size]; + WatchList[0] = This->m_WakeUpEvent; + + POSITION Pos; + for (size_t i = 0; i < This->m_WatcherList.GetCount(); i++) + { + Pos = This->m_WatcherList.FindIndex(i); + if (Pos) + { + IconWatcherData *Icon; + Icon = This->m_WatcherList.GetAt(Pos); + WatchList[i + 1] = Icon->hProcess; + } + } + + LeaveCriticalSection(&This->m_ListLock); + + DWORD Status; + Status = WaitForMultipleObjects(Size, + WatchList, + FALSE, + INFINITE); + if (Status == WAIT_OBJECT_0) + { + // We've been kicked, we have updates to our list (or we're exiting the thread) + if (This->m_Loop) + TRACE("Updating watched icon list"); + } + else if ((Status >= WAIT_OBJECT_0 + 1) && (Status < Size)) + { + IconWatcherData *Icon; + Icon = This->GetListEntry(NULL, WatchList[Status], false); + + TRACE("Pid %lu owns a notification icon and has stopped without deleting it. We'll cleanup on its behalf", Icon->ProcessId); + + int len = FIELD_OFFSET(SYS_PAGER_COPY_DATA, nicon_data) + Icon->IconData.cbSize; + PSYS_PAGER_COPY_DATA pnotify_data = (PSYS_PAGER_COPY_DATA)new BYTE[len]; + pnotify_data->cookie = 1; + pnotify_data->notify_code = NIM_DELETE; + memcpy(&pnotify_data->nicon_data, &Icon->IconData, Icon->IconData.cbSize); + + COPYDATASTRUCT data; + data.dwData = 1; + data.cbData = len; + data.lpData = pnotify_data; + + BOOL Success = FALSE; + HWND parentHWND = ::GetParent(GetParent(This->m_hwndSysTray)); + if (parentHWND) + Success = ::SendMessage(parentHWND, WM_COPYDATA, (WPARAM)&Icon->IconData, (LPARAM)&data); + + delete pnotify_data; + + if (!Success) + { + // If we failed to handle the delete message, forcibly remove it + This->RemoveIconFromWatcher(&Icon->IconData); + } + } + else + { + if (Status == WAIT_FAILED) + { + Status = GetLastError(); + } + ERR("Failed to wait on process handles : %lu\n", Status); + This->Uninitialize(); + } + } + + if (WatchList) + delete WatchList; + + return 0; +} + +/* +* NotifyToolbar +*/ + +CBalloonQueue::CBalloonQueue() : + m_hwndParent(NULL), + m_tooltips(NULL), + m_toolbar(NULL), + m_current(NULL), + m_currentClosed(false), + m_timer(-1) +{ +} + +void CBalloonQueue::Init(HWND hwndParent, CToolbar<InternalIconData> * toolbar, CTooltips * balloons) +{ + m_hwndParent = hwndParent; + m_toolbar = toolbar; + m_tooltips = balloons; +} + +void CBalloonQueue::Deinit() +{ + if (m_timer >= 0) + { + ::KillTimer(m_hwndParent, m_timer); + } +} + +bool CBalloonQueue::OnTimer(int timerId) +{ + if (timerId != m_timer) + return false; + + ::KillTimer(m_hwndParent, m_timer); + m_timer = -1; + + if (m_current && !m_currentClosed) + { + Close(m_current); + } + else + { + m_current = NULL; + m_currentClosed = false; + if (!m_queue.IsEmpty()) + { + Info info = m_queue.RemoveHead(); + Show(info); + } + } + + return true; +} + +void CBalloonQueue::UpdateInfo(InternalIconData * notifyItem) +{ + size_t len = 0; + HRESULT hr = StringCchLength(notifyItem->szInfo, _countof(notifyItem->szInfo), &len); + if (SUCCEEDED(hr) && len > 0) + { + Info info(notifyItem); + + // If m_current == notifyItem, we want to replace the previous balloon even if there is a queue. + if (m_current != notifyItem && (m_current != NULL || !m_queue.IsEmpty())) + { + m_queue.AddTail(info); + } + else + { + Show(info); + } + } + else + { + Close(notifyItem); + } +} + +void CBalloonQueue::RemoveInfo(InternalIconData * notifyItem) +{ + Close(notifyItem); + + POSITION position = m_queue.GetHeadPosition(); + while(position != NULL) + { + Info& info = m_queue.GetNext(position); + if (info.pSource == notifyItem) + { + m_queue.RemoveAt(position); + } + } +} + +void CBalloonQueue::CloseCurrent() +{ + if (m_current != NULL) + Close(m_current); +} + +int CBalloonQueue::IndexOf(InternalIconData * pdata) +{ + int count = m_toolbar->GetButtonCount(); + for (int i = 0; i < count; i++) + { + if (m_toolbar->GetItemData(i) == pdata) + return i; + } + return -1; +} + +void CBalloonQueue::SetTimer(int length) +{ + m_timer = ::SetTimer(m_hwndParent, BalloonsTimerId, length, NULL); +} + +void CBalloonQueue::Show(Info& info) +{ + TRACE("ShowBalloonTip called for flags=%x text=%ws; title=%ws\n", info.uIcon, info.szInfo, info.szInfoTitle); + + // TODO: NIF_REALTIME, NIIF_NOSOUND, other Vista+ flags + + const int index = IndexOf(info.pSource); + RECT rc; + m_toolbar->GetItemRect(index, &rc); + m_toolbar->ClientToScreen(&rc); + const WORD x = (rc.left + rc.right) / 2; + const WORD y = (rc.top + rc.bottom) / 2; + + m_tooltips->SetTitle(info.szInfoTitle, info.uIcon); + m_tooltips->TrackPosition(x, y); + m_tooltips->UpdateTipText(m_hwndParent, reinterpret_cast<LPARAM>(m_toolbar->m_hWnd), info.szInfo); + m_tooltips->TrackActivate(m_hwndParent, reinterpret_cast<LPARAM>(m_toolbar->m_hWnd)); + + m_current = info.pSource; + int timeout = info.uTimeout; + if (timeout < MinTimeout) timeout = MinTimeout; + if (timeout > MaxTimeout) timeout = MaxTimeout; + + SetTimer(timeout); +} + +void CBalloonQueue::Close(IN OUT InternalIconData * notifyItem) +{ + TRACE("HideBalloonTip called\n"); + + if (m_current == notifyItem && !m_currentClosed) + { + // Prevent Re-entry + m_currentClosed = true; + m_tooltips->TrackDeactivate(); + SetTimer(CooldownBetweenBalloons); + } +} + +/* + * NotifyToolbar + */ + +CNotifyToolbar::CNotifyToolbar() : + m_ImageList(NULL), + m_VisibleButtonCount(0), + m_BalloonQueue(NULL) +{ +} + +CNotifyToolbar::~CNotifyToolbar() +{ +} + +int CNotifyToolbar::GetVisibleButtonCount() +{ + return m_VisibleButtonCount; +} + +int CNotifyToolbar::FindItem(IN HWND hWnd, IN UINT uID, InternalIconData ** pdata) +{ + int count = GetButtonCount(); + + for (int i = 0; i < count; i++) + { + InternalIconData * data = GetItemData(i); + + if (data->hWnd == hWnd && + data->uID == uID) + { + if (pdata) + *pdata = data; + return i; + } + } + + return -1; +} + +int CNotifyToolbar::FindExistingSharedIcon(HICON handle) +{ + int count = GetButtonCount(); + for (int i = 0; i < count; i++) + { + InternalIconData * data = GetItemData(i); + if (data->hIcon == handle) + { + TBBUTTON btn; + GetButton(i, &btn); + return btn.iBitmap; + } + } + + return -1; +} + +BOOL CNotifyToolbar::AddButton(IN CONST NOTIFYICONDATA *iconData) +{ + TBBUTTON tbBtn; + InternalIconData * notifyItem; + WCHAR text[] = L""; + + TRACE("Adding icon %d from hWnd %08x flags%s%s state%s%s", + iconData->uID, iconData->hWnd, + (iconData->uFlags & NIF_ICON) ? " ICON" : "", + (iconData->uFlags & NIF_STATE) ? " STATE" : "", + (iconData->dwState & NIS_HIDDEN) ? " HIDDEN" : "", + (iconData->dwState & NIS_SHAREDICON) ? " SHARED" : ""); + + int index = FindItem(iconData->hWnd, iconData->uID, ¬ifyItem); + if (index >= 0) + { + TRACE("Icon %d from hWnd %08x ALREADY EXISTS!", iconData->uID, iconData->hWnd); + return FALSE; + } + + notifyItem = new InternalIconData(); + ZeroMemory(notifyItem, sizeof(*notifyItem)); + + notifyItem->hWnd = iconData->hWnd; + notifyItem->uID = iconData->uID; + + tbBtn.fsState = TBSTATE_ENABLED; + tbBtn.fsStyle = BTNS_NOPREFIX; + tbBtn.dwData = (DWORD_PTR)notifyItem; + tbBtn.iString = (INT_PTR) text; + tbBtn.idCommand = GetButtonCount(); + + if (iconData->uFlags & NIF_STATE) + { + notifyItem->dwState = iconData->dwState & iconData->dwStateMask; + } + + if (iconData->uFlags & NIF_MESSAGE) + { + notifyItem->uCallbackMessage = iconData->uCallbackMessage; + } + + if (iconData->uFlags & NIF_ICON) + { + notifyItem->hIcon = iconData->hIcon; + BOOL hasSharedIcon = notifyItem->dwState & NIS_SHAREDICON; + if (hasSharedIcon) + { + INT iIcon = FindExistingSharedIcon(notifyItem->hIcon); + if (iIcon < 0) + { + notifyItem->hIcon = NULL; + TRACE("Shared icon requested, but HICON not found!!!"); + } + tbBtn.iBitmap = iIcon; + } + else + { + tbBtn.iBitmap = ImageList_AddIcon(m_ImageList, notifyItem->hIcon); + } + } + + if (iconData->uFlags & NIF_TIP) + { + StringCchCopy(notifyItem->szTip, _countof(notifyItem->szTip), iconData->szTip); + } + + if (iconData->uFlags & NIF_INFO) + { + // NOTE: In Vista+, the uTimeout value is disregarded, and the accessibility settings are used always. + StrNCpy(notifyItem->szInfo, iconData->szInfo, _countof(notifyItem->szInfo)); + StrNCpy(notifyItem->szInfoTitle, iconData->szInfoTitle, _countof(notifyItem->szInfo)); + notifyItem->dwInfoFlags = iconData->dwInfoFlags; + notifyItem->uTimeout = iconData->uTimeout; + } + + if (notifyItem->dwState & NIS_HIDDEN) + { + tbBtn.fsState |= TBSTATE_HIDDEN; + } + else + { + m_VisibleButtonCount++; + } + + /* TODO: support VERSION_4 (NIF_GUID, NIF_REALTIME, NIF_SHOWTIP) */ + + CToolbar::AddButton(&tbBtn); + SetButtonSize(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); + + if (iconData->uFlags & NIF_INFO) + { + m_BalloonQueue->UpdateInfo(notifyItem); + } + + return TRUE; +} + +BOOL CNotifyToolbar::SwitchVersion(IN CONST NOTIFYICONDATA *iconData) +{ + InternalIconData * notifyItem; + int index = FindItem(iconData->hWnd, iconData->uID, ¬ifyItem); + if (index < 0) + { + WARN("Icon %d from hWnd %08x DOES NOT EXIST!", iconData->uID, iconData->hWnd); + return FALSE; + } + + if (iconData->uVersion != 0 && iconData->uVersion != NOTIFYICON_VERSION) + { + WARN("Tried to set the version of icon %d from hWnd %08x, to an unknown value %d. Vista+ program?", iconData->uID, iconData->hWnd, iconData->uVersion); + return FALSE; + } + + // We can not store the version in the uVersion field, because it's union'd with uTimeout, + // which we also need to keep track of. + notifyItem->uVersionCopy = iconData->uVersion; + + return TRUE; +} + +BOOL CNotifyToolbar::UpdateButton(IN CONST NOTIFYICONDATA *iconData) +{ + InternalIconData * notifyItem; + TBBUTTONINFO tbbi = { 0 }; + + TRACE("Updating icon %d from hWnd %08x flags%s%s state%s%s", + iconData->uID, iconData->hWnd, + (iconData->uFlags & NIF_ICON) ? " ICON" : "", + (iconData->uFlags & NIF_STATE) ? " STATE" : "", + (iconData->dwState & NIS_HIDDEN) ? " HIDDEN" : "", + (iconData->dwState & NIS_SHAREDICON) ? " SHARED" : ""); + + int index = FindItem(iconData->hWnd, iconData->uID, ¬ifyItem); + if (index < 0) + { + WARN("Icon %d from hWnd %08x DOES NOT EXIST!", iconData->uID, iconData->hWnd); + return AddButton(iconData); + } + + TBBUTTON btn; + GetButton(index, &btn); + int oldIconIndex = btn.iBitmap; + + tbbi.cbSize = sizeof(tbbi); + tbbi.dwMask = TBIF_BYINDEX | TBIF_COMMAND; + tbbi.idCommand = index; + + if (iconData->uFlags & NIF_STATE) + { + if (iconData->dwStateMask & NIS_HIDDEN && + (notifyItem->dwState & NIS_HIDDEN) != (iconData->dwState & NIS_HIDDEN)) + { + tbbi.dwMask |= TBIF_STATE; + if (iconData->dwState & NIS_HIDDEN) + { + tbbi.fsState |= TBSTATE_HIDDEN; + m_VisibleButtonCount--; + } + else + { + tbbi.fsState &= ~TBSTATE_HIDDEN; + m_VisibleButtonCount++; + } + } + + notifyItem->dwState &= ~iconData->dwStateMask; + notifyItem->dwState |= (iconData->dwState & iconData->dwStateMask); + } + + if (iconData->uFlags & NIF_MESSAGE) + { + notifyItem->uCallbackMessage = iconData->uCallbackMessage; + } + + if (iconData->uFlags & NIF_ICON) + { + BOOL hasSharedIcon = notifyItem->dwState & NIS_SHAREDICON; + if (hasSharedIcon) + { + INT iIcon = FindExistingSharedIcon(iconData->hIcon); + if (iIcon >= 0) + { + notifyItem->hIcon = iconData->hIcon; + tbbi.dwMask |= TBIF_IMAGE; + tbbi.iImage = iIcon; + } + else + { + TRACE("Shared icon requested, but HICON not found!!! IGNORING!"); + } + } + else + { + notifyItem->hIcon = iconData->hIcon; + tbbi.dwMask |= TBIF_IMAGE; + tbbi.iImage = ImageList_ReplaceIcon(m_ImageList, oldIconIndex, notifyItem->hIcon); + } + } + + if (iconData->uFlags & NIF_TIP) + { + StringCchCopy(notifyItem->szTip, _countof(notifyItem->szTip), iconData->szTip); + } + + if (iconData->uFlags & NIF_INFO) + { + // NOTE: In Vista+, the uTimeout value is disregarded, and the accessibility settings are used always. + StrNCpy(notifyItem->szInfo, iconData->szInfo, _countof(notifyItem->szInfo)); + StrNCpy(notifyItem->szInfoTitle, iconData->szInfoTitle, _countof(notifyItem->szInfo)); + notifyItem->dwInfoFlags = iconData->dwInfoFlags; + notifyItem->uTimeout = iconData->uTimeout; + } + + /* TODO: support VERSION_4 (NIF_GUID, NIF_REALTIME, NIF_SHOWTIP) */ + + SetButtonInfo(index, &tbbi); + + if (iconData->uFlags & NIF_INFO) + { + m_BalloonQueue->UpdateInfo(notifyItem); + } + + return TRUE; +} + +BOOL CNotifyToolbar::RemoveButton(IN CONST NOTIFYICONDATA *iconData) +{ + InternalIconData * notifyItem; + + TRACE("Removing icon %d from hWnd %08x", iconData->uID, iconData->hWnd); + + int index = FindItem(iconData->hWnd, iconData->uID, ¬ifyItem); + if (index < 0) + { + TRACE("Icon %d from hWnd %08x ALREADY MISSING!", iconData->uID, iconData->hWnd); + + return FALSE; + } + + if (!(notifyItem->dwState & NIS_HIDDEN)) + { + m_VisibleButtonCount--; + } + + if (!(notifyItem->dwState & NIS_SHAREDICON)) + { + TBBUTTON btn; + GetButton(index, &btn); + int oldIconIndex = btn.iBitmap; + ImageList_Remove(m_ImageList, oldIconIndex); + + // Update other icons! + int count = GetButtonCount(); + for (int i = 0; i < count; i++) + { + TBBUTTON btn; + GetButton(i, &btn); + + if (btn.iBitmap > oldIconIndex) + { + TBBUTTONINFO tbbi2 = { 0 }; + tbbi2.cbSize = sizeof(tbbi2); + tbbi2.dwMask = TBIF_BYINDEX | TBIF_IMAGE; + tbbi2.iImage = btn.iBitmap-1; + SetButtonInfo(i, &tbbi2); + } + } + } + + m_BalloonQueue->RemoveInfo(notifyItem); + + DeleteButton(index); + + delete notifyItem; + + return TRUE; +} + +VOID CNotifyToolbar::ResizeImagelist() +{ + int cx, cy; + HIMAGELIST iml; + + if (!ImageList_GetIconSize(m_ImageList, &cx, &cy)) + return; + + if (cx == GetSystemMetrics(SM_CXSMICON) && cy == GetSystemMetrics(SM_CYSMICON)) + return; + + iml = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 | ILC_MASK, 0, 1000); + if (!iml) + return; + + ImageList_Destroy(m_ImageList); + m_ImageList = iml; + SetImageList(m_ImageList); + + int count = GetButtonCount(); + for (int i = 0; i < count; i++) + { + InternalIconData * data = GetItemData(i); + BOOL hasSharedIcon = data->dwState & NIS_SHAREDICON; + INT iIcon = hasSharedIcon ? FindExistingSharedIcon(data->hIcon) : -1; + if (iIcon < 0) + iIcon = ImageList_AddIcon(iml, data->hIcon); + TBBUTTONINFO tbbi = { sizeof(tbbi), TBIF_BYINDEX | TBIF_IMAGE, 0, iIcon}; + SetButtonInfo(i, &tbbi); + } + + SetButtonSize(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); +} + +VOID CNotifyToolbar::SendMouseEvent(IN WORD wIndex, IN UINT uMsg, IN WPARAM wParam) +{ + static LPCWSTR eventNames [] = { + L"WM_MOUSEMOVE", + L"WM_LBUTTONDOWN", + L"WM_LBUTTONUP", + L"WM_LBUTTONDBLCLK", + L"WM_RBUTTONDOWN", + L"WM_RBUTTONUP", + L"WM_RBUTTONDBLCLK", + L"WM_MBUTTONDOWN", + L"WM_MBUTTONUP", + L"WM_MBUTTONDBLCLK", + L"WM_MOUSEWHEEL", + L"WM_XBUTTONDOWN", + L"WM_XBUTTONUP", + L"WM_XBUTTONDBLCLK" + }; + + InternalIconData * notifyItem = GetItemData(wIndex); + + if (!::IsWindow(notifyItem->hWnd)) + { + // We detect and destroy icons with invalid handles only on mouse move over systray, same as MS does. + // Alternatively we could search for them periodically (would waste more resources). + TRACE("Destroying icon %d with invalid handle hWnd=%08x\n", notifyItem->uID, notifyItem->hWnd); + + RemoveButton(notifyItem); + + HWND parentHWND = ::GetParent(::GetParent(GetParent())); + ::SendMessage(parentHWND, WM_SIZE, 0, 0); + + return; + } + + if (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST) + { + TRACE("Sending message %S from button %d to %p (msg=%x, w=%x, l=%x)...\n", + eventNames[uMsg - WM_MOUSEFIRST], wIndex, + notifyItem->hWnd, notifyItem->uCallbackMessage, notifyItem->uID, uMsg); + } + + DWORD pid; + GetWindowThreadProcessId(notifyItem->hWnd, &pid); + + if (pid == GetCurrentProcessId() || + (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST)) + { + ::PostMessage(notifyItem->hWnd, + notifyItem->uCallbackMessage, + notifyItem->uID, + uMsg); + } + else + { + SendMessage(notifyItem->hWnd, + notifyItem->uCallbackMessage, + notifyItem->uID, + uMsg); + } +} + +LRESULT CNotifyToolbar::OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + + INT iBtn = HitTest(&pt); + + if (iBtn >= 0) + { + SendMouseEvent(iBtn, uMsg, wParam); + } + + bHandled = FALSE; + return FALSE; +} + +static VOID GetTooltipText(LPARAM data, LPTSTR szTip, DWORD cchTip) +{ + InternalIconData * notifyItem = reinterpret_cast<InternalIconData *>(data); + if (notifyItem) + { + StringCchCopy(szTip, cchTip, notifyItem->szTip); + } + else + { + StringCchCopy(szTip, cchTip, L""); + } +} + +LRESULT CNotifyToolbar::OnTooltipShow(INT uCode, LPNMHDR hdr, BOOL& bHandled) +{ + RECT rcTip, rcItem; + ::GetWindowRect(hdr->hwndFrom, &rcTip); + + SIZE szTip = { rcTip.right - rcTip.left, rcTip.bottom - rcTip.top }; + + INT iBtn = GetHotItem(); + + if (iBtn >= 0) + { + MONITORINFO monInfo = { 0 }; + HMONITOR hMon = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST); + + monInfo.cbSize = sizeof(monInfo); + + if (hMon) + GetMonitorInfo(hMon, &monInfo); + else + ::GetWindowRect(GetDesktopWindow(), &monInfo.rcMonitor); + + GetItemRect(iBtn, &rcItem); + + POINT ptItem = { rcItem.left, rcItem.top }; + SIZE szItem = { rcItem.right - rcItem.left, rcItem.bottom - rcItem.top }; + ClientToScreen(&ptItem); + + ptItem.x += szItem.cx / 2; + ptItem.y -= szTip.cy; + + if (ptItem.x + szTip.cx > monInfo.rcMonitor.right) + ptItem.x = monInfo.rcMonitor.right - szTip.cx; + + if (ptItem.y + szTip.cy > monInfo.rcMonitor.bottom) + ptItem.y = monInfo.rcMonitor.bottom - szTip.cy; + + if (ptItem.x < monInfo.rcMonitor.left) + ptItem.x = monInfo.rcMonitor.left; + + if (ptItem.y < monInfo.rcMonitor.top) + ptItem.y = monInfo.rcMonitor.top; + + TRACE("ptItem { %d, %d }\n", ptItem.x, ptItem.y); + + ::SetWindowPos(hdr->hwndFrom, NULL, ptItem.x, ptItem.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + + return TRUE; + } + + bHandled = FALSE; + return 0; +} + +void CNotifyToolbar::Initialize(HWND hWndParent, CBalloonQueue * queue) +{ + m_BalloonQueue = queue; + + DWORD styles = + WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | + TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | TBSTYLE_WRAPABLE | TBSTYLE_TRANSPARENT | + CCS_TOP | CCS_NORESIZE | CCS_NOPARENTALIGN | CCS_NODIVIDER; + + SubclassWindow(CToolbar::Create(hWndParent, styles)); + + // Force the toolbar tooltips window to always show tooltips even if not foreground + HWND tooltipsWnd = (HWND)SendMessageW(TB_GETTOOLTIPS); + if (tooltipsWnd) + { + ::SetWindowLong(tooltipsWnd, GWL_STYLE, ::GetWindowLong(tooltipsWnd, GWL_STYLE) | TTS_ALWAYSTIP); + } + + SetWindowTheme(m_hWnd, L"TrayNotify", NULL); + + m_ImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 | ILC_MASK, 0, 1000); + SetImageList(m_ImageList); + + TBMETRICS tbm = {sizeof(tbm)}; + tbm.dwMask = TBMF_BARPAD | TBMF_BUTTONSPACING | TBMF_PAD; + tbm.cxPad = 1; + tbm.cyPad = 1; + tbm.cxButtonSpacing = 1; + tbm.cyButtonSpacing = 1; + SetMetrics(&tbm); + + SetButtonSize(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); +} + +/* + * SysPagerWnd + */ +const WCHAR szSysPagerWndClass[] = L"SysPager"; + +CSysPagerWnd::CSysPagerWnd() {} +CSysPagerWnd::~CSysPagerWnd() {} + +LRESULT CSysPagerWnd::DrawBackground(HDC hdc) +{ + RECT rect; + + GetClientRect(&rect); + DrawThemeParentBackground(m_hWnd, hdc, &rect); + + return TRUE; +} + +LRESULT CSysPagerWnd::OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + HDC hdc = (HDC) wParam; + + if (!IsAppThemed()) + { + bHandled = FALSE; + return 0; + } + + return DrawBackground(hdc); +} + +LRESULT CSysPagerWnd::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + Toolbar.Initialize(m_hWnd, &m_BalloonQueue); + CIconWatcher::Initialize(m_hWnd); + + HWND hWndTop = GetAncestor(m_hWnd, GA_ROOT); + + m_Balloons.Create(hWndTop, TTS_NOPREFIX | TTS_BALLOON | TTS_CLOSE); + + TOOLINFOW ti = { 0 }; + ti.cbSize = TTTOOLINFOW_V1_SIZE; + ti.uFlags = TTF_TRACK | TTF_IDISHWND; + ti.uId = reinterpret_cast<UINT_PTR>(Toolbar.m_hWnd); + ti.hwnd = m_hWnd; + ti.lpszText = NULL; + ti.lParam = NULL; + + BOOL ret = m_Balloons.AddTool(&ti); + if (!ret) + { + WARN("AddTool failed, LastError=%d (probably meaningless unless non-zero)\n", GetLastError()); + } + + m_BalloonQueue.Init(m_hWnd, &Toolbar, &m_Balloons); + + // Explicitly request running applications to re-register their systray icons + ::SendNotifyMessageW(HWND_BROADCAST, + RegisterWindowMessageW(L"TaskbarCreated"), + 0, 0); + + return TRUE; +} + +LRESULT CSysPagerWnd::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + m_BalloonQueue.Deinit(); + CIconWatcher::Uninitialize(); + return TRUE; +} + +BOOL CSysPagerWnd::NotifyIconCmd(WPARAM wParam, LPARAM lParam) +{ + PCOPYDATASTRUCT cpData = (PCOPYDATASTRUCT) lParam; + if (cpData->dwData == 1) + { + SYS_PAGER_COPY_DATA * data; + NOTIFYICONDATA *iconData; + BOOL ret = FALSE; + + int VisibleButtonCount = Toolbar.GetVisibleButtonCount(); + + data = (PSYS_PAGER_COPY_DATA) cpData->lpData; + iconData = &data->nicon_data; + + TRACE("NotifyIconCmd received. Code=%d\n", data->notify_code); + switch (data->notify_code) + { + case NIM_ADD: + ret = Toolbar.AddButton(iconData); + if (ret == TRUE) + { + (void)AddIconToWatcher(iconData); + } + break; + case NIM_MODIFY: + ret = Toolbar.UpdateButton(iconData); + break; + case NIM_DELETE: + ret = Toolbar.RemoveButton(iconData); + if (ret == TRUE) + { + (void)RemoveIconFromWatcher(iconData); + } + break; + case NIM_SETFOCUS: + Toolbar.SetFocus(); + ret = TRUE; + case NIM_SETVERSION: + ret = Toolbar.SwitchVersion(iconData); + default: + TRACE("NotifyIconCmd received with unknown code %d.\n", data->notify_code); + return FALSE; + } + + if (VisibleButtonCount != Toolbar.GetVisibleButtonCount()) + { + HWND parentHWND = ::GetParent(GetParent()); + ::SendMessage(parentHWND, WM_SIZE, 0, 0); + } + + return ret; + } + + return TRUE; +} + +void CSysPagerWnd::GetSize(IN BOOL IsHorizontal, IN PSIZE size) +{ + /* Get the ideal height or width */ +#if 0 + /* Unfortunately this doens't work correctly in ros */ + Toolbar.GetIdealSize(!IsHorizontal, size); + + /* Make the reference dimension an exact multiple of the icon size */ + if (IsHorizontal) + size->cy -= size->cy % GetSystemMetrics(SM_CYSMICON); + else + size->cx -= size->cx % GetSystemMetrics(SM_CXSMICON); + +#else + INT rows = 0; + INT columns = 0; + INT cyButton = GetSystemMetrics(SM_CYSMICON) + 2; + INT cxButton = GetSystemMetrics(SM_CXSMICON) + 2; + int VisibleButtonCount = Toolbar.GetVisibleButtonCount(); + + if (IsHorizontal) + { + rows = max(size->cy / cyButton, 1); + columns = (VisibleButtonCount + rows - 1) / rows; + } + else + { + columns = max(size->cx / cxButton, 1); + rows = (VisibleButtonCount + columns - 1) / columns; + } + size->cx = columns * cxButton; + size->cy = rows * cyButton; +#endif +} + +LRESULT CSysPagerWnd::OnGetInfoTip(INT uCode, LPNMHDR hdr, BOOL& bHandled) +{ + NMTBGETINFOTIPW * nmtip = (NMTBGETINFOTIPW *) hdr; + GetTooltipText(nmtip->lParam, nmtip->pszText, nmtip->cchTextMax); + return TRUE; +} + +LRESULT CSysPagerWnd::OnCustomDraw(INT uCode, LPNMHDR hdr, BOOL& bHandled) +{ + NMCUSTOMDRAW * cdraw = (NMCUSTOMDRAW *) hdr; + switch (cdraw->dwDrawStage) + { + case CDDS_PREPAINT: + return CDRF_NOTIFYITEMDRAW; + + case CDDS_ITEMPREPAINT: + return TBCDRF_NOBACKGROUND | TBCDRF_NOEDGES | TBCDRF_NOOFFSET | TBCDRF_NOMARK | TBCDRF_NOETCHEDEFFECT; + } + return TRUE; +} + +LRESULT CSysPagerWnd::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + LRESULT Ret = TRUE; + SIZE szClient; + szClient.cx = LOWORD(lParam); + szClient.cy = HIWORD(lParam); + + Ret = DefWindowProc(uMsg, wParam, lParam); + + if (Toolbar) + { + Toolbar.SetWindowPos(NULL, 0, 0, szClient.cx, szClient.cy, SWP_NOZORDER); + Toolbar.AutoSize(); + + RECT rc; + Toolbar.GetClientRect(&rc); + + SIZE szBar = { rc.right - rc.left, rc.bottom - rc.top }; + + INT xOff = (szClient.cx - szBar.cx) / 2; + INT yOff = (szClient.cy - szBar.cy) / 2; + + Toolbar.SetWindowPos(NULL, xOff, yOff, szBar.cx, szBar.cy, SWP_NOZORDER); + } + return Ret; +} + +LRESULT CSysPagerWnd::OnCtxMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + bHandled = TRUE; + return 0; +} + +LRESULT CSysPagerWnd::OnBalloonPop(UINT uCode, LPNMHDR hdr , BOOL& bHandled) +{ + m_BalloonQueue.CloseCurrent(); + bHandled = TRUE; + return 0; +} + +LRESULT CSysPagerWnd::OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + if (m_BalloonQueue.OnTimer(wParam)) + { + bHandled = TRUE; + } + + return 0; +} + +void CSysPagerWnd::ResizeImagelist() +{ + Toolbar.ResizeImagelist(); +} + +HWND CSysPagerWnd::_Init(IN HWND hWndParent, IN BOOL bVisible) +{ + DWORD dwStyle; + + /* Create the window. The tray window is going to move it to the correct + position and resize it as needed. */ + dwStyle = WS_CHILD | WS_CLIPSIBLINGS; + if (bVisible) + dwStyle |= WS_VISIBLE; + + Create(hWndParent, 0, NULL, dwStyle); + + if (!m_hWnd) + { + return NULL; + } + + SetWindowTheme(m_hWnd, L"TrayNotify", NULL); + + return m_hWnd; +} diff --git a/base/shell/explorer/syspager.h b/base/shell/explorer/syspager.h new file mode 100644 index 0000000000..381c143a32 --- /dev/null +++ b/base/shell/explorer/syspager.h @@ -0,0 +1,203 @@ +#pragma once + +struct InternalIconData : NOTIFYICONDATA +{ + // Must keep a separate copy since the original is unioned with uTimeout. + UINT uVersionCopy; +}; + +struct IconWatcherData +{ + HANDLE hProcess; + DWORD ProcessId; + NOTIFYICONDATA IconData; + + IconWatcherData(NOTIFYICONDATA *iconData) : + hProcess(NULL), ProcessId(0) + { + IconData.cbSize = sizeof(NOTIFYICONDATA); + IconData.hWnd = iconData->hWnd; + IconData.uID = iconData->uID; + IconData.guidItem = iconData->guidItem; + } + + ~IconWatcherData() + { + if (hProcess) + { + CloseHandle(hProcess); + } + } +}; + +class CIconWatcher +{ + CAtlList<IconWatcherData *> m_WatcherList; + CRITICAL_SECTION m_ListLock; + HANDLE m_hWatcherThread; + HANDLE m_WakeUpEvent; + HWND m_hwndSysTray; + bool m_Loop; + +public: + CIconWatcher(); + + virtual ~CIconWatcher(); + + bool Initialize(_In_ HWND hWndParent); + void Uninitialize(); + + bool AddIconToWatcher(_In_ NOTIFYICONDATA *iconData); + bool RemoveIconFromWatcher(_In_ NOTIFYICONDATA *iconData); + + IconWatcherData* GetListEntry(_In_opt_ NOTIFYICONDATA *iconData, _In_opt_ HANDLE hProcess, _In_ bool Remove); + +private: + + static UINT WINAPI WatcherThread(_In_opt_ LPVOID lpParam); +}; + +class CBalloonQueue +{ +public: + static const int TimerInterval = 2000; + static const int BalloonsTimerId = 1; + static const int MinTimeout = 10000; + static const int MaxTimeout = 30000; + static const int CooldownBetweenBalloons = 2000; + +private: + struct Info + { + InternalIconData * pSource; + WCHAR szInfo[256]; + WCHAR szInfoTitle[64]; + WPARAM uIcon; + UINT uTimeout; + + Info(InternalIconData * source) + { + pSource = source; + StrNCpy(szInfo, source->szInfo, _countof(szInfo)); + StrNCpy(szInfoTitle, source->szInfoTitle, _countof(szInfoTitle)); + uIcon = source->dwInfoFlags & NIIF_ICON_MASK; + if (source->dwInfoFlags == NIIF_USER) + uIcon = reinterpret_cast<WPARAM>(source->hIcon); + uTimeout = source->uTimeout; + } + }; + + HWND m_hwndParent; + + CTooltips * m_tooltips; + + CAtlList<Info> m_queue; + + CToolbar<InternalIconData> * m_toolbar; + + InternalIconData * m_current; + bool m_currentClosed; + + int m_timer; + +public: + CBalloonQueue(); + + void Init(HWND hwndParent, CToolbar<InternalIconData> * toolbar, CTooltips * balloons); + void Deinit(); + + bool OnTimer(int timerId); + void UpdateInfo(InternalIconData * notifyItem); + void RemoveInfo(InternalIconData * notifyItem); + void CloseCurrent(); + +private: + + int IndexOf(InternalIconData * pdata); + void SetTimer(int length); + void Show(Info& info); + void Close(IN OUT InternalIconData * notifyItem); +}; + +class CNotifyToolbar : + public CWindowImplBaseT< CToolbar<InternalIconData>, CControlWinTraits > +{ + HIMAGELIST m_ImageList; + int m_VisibleButtonCount; + + CBalloonQueue * m_BalloonQueue; + +public: + CNotifyToolbar(); + virtual ~CNotifyToolbar(); + + int GetVisibleButtonCount(); + int FindItem(IN HWND hWnd, IN UINT uID, InternalIconData ** pdata); + int FindExistingSharedIcon(HICON handle); + BOOL AddButton(IN CONST NOTIFYICONDATA *iconData); + BOOL SwitchVersion(IN CONST NOTIFYICONDATA *iconData); + BOOL UpdateButton(IN CONST NOTIFYICONDATA *iconData); + BOOL RemoveButton(IN CONST NOTIFYICONDATA *iconData); + VOID ResizeImagelist(); + +private: + VOID SendMouseEvent(IN WORD wIndex, IN UINT uMsg, IN WPARAM wParam); + LRESULT OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnTooltipShow(INT uCode, LPNMHDR hdr, BOOL& bHandled); + +public: + BEGIN_MSG_MAP(CNotifyToolbar) + MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseEvent) + NOTIFY_CODE_HANDLER(TTN_SHOW, OnTooltipShow) + END_MSG_MAP() + + void Initialize(HWND hWndParent, CBalloonQueue * queue); +}; + +extern const WCHAR szSysPagerWndClass[]; + +class CSysPagerWnd : + public CComObjectRootEx<CComMultiThreadModelNoCS>, + public CWindowImpl < CSysPagerWnd, CWindow, CControlWinTraits >, + public CIconWatcher +{ + CNotifyToolbar Toolbar; + CTooltips m_Balloons; + CBalloonQueue m_BalloonQueue; + +public: + CSysPagerWnd(); + virtual ~CSysPagerWnd(); + + LRESULT DrawBackground(HDC hdc); + LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnGetInfoTip(INT uCode, LPNMHDR hdr, BOOL& bHandled); + LRESULT OnCustomDraw(INT uCode, LPNMHDR hdr, BOOL& bHandled); + LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnCtxMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnBalloonPop(UINT uCode, LPNMHDR hdr, BOOL& bHandled); + LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + +public: + BOOL NotifyIconCmd(WPARAM wParam, LPARAM lParam); + void GetSize(IN BOOL IsHorizontal, IN PSIZE size); + void ResizeImagelist(); + + DECLARE_WND_CLASS_EX(szSysPagerWndClass, CS_DBLCLKS, COLOR_3DFACE) + + BEGIN_MSG_MAP(CSysPagerWnd) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) + MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_CONTEXTMENU, OnCtxMenu) + MESSAGE_HANDLER(WM_TIMER, OnTimer) + NOTIFY_CODE_HANDLER(TTN_POP, OnBalloonPop) + NOTIFY_CODE_HANDLER(TBN_GETINFOTIPW, OnGetInfoTip) + NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw) + END_MSG_MAP() + + HWND _Init(IN HWND hWndParent, IN BOOL bVisible); +}; diff --git a/base/shell/explorer/trayclock.cpp b/base/shell/explorer/trayclock.cpp new file mode 100644 index 0000000000..125fc73b7d --- /dev/null +++ b/base/shell/explorer/trayclock.cpp @@ -0,0 +1,576 @@ +/* + * ReactOS Explorer + * + * Copyright 2006 - 2007 Thomas Weidenmueller <w3seek(a)reactos.org> + * Copyright 2018 Ged Murphy <gedmurphy(a)reactos.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "precomp.h" + +/* + * TrayClockWnd + */ + +const WCHAR szTrayClockWndClass[] = L"TrayClockWClass"; + +#define ID_TRAYCLOCK_TIMER 0 +#define ID_TRAYCLOCK_TIMER_INIT 1 + +#define TRAY_CLOCK_WND_SPACING_X 0 +#define TRAY_CLOCK_WND_SPACING_Y 0 + +CTrayClockWnd::CTrayClockWnd() : + hWndNotify(NULL), + hFont(NULL), + dwFlags(0), + LineSpacing(0), + VisibleLines(0) +{ + ZeroMemory(&textColor, sizeof(textColor)); + ZeroMemory(&rcText, sizeof(rcText)); + ZeroMemory(&LocalTime, sizeof(LocalTime)); + ZeroMemory(&CurrentSize, sizeof(CurrentSize)); + ZeroMemory(LineSizes, sizeof(LineSizes)); + ZeroMemory(szLines, sizeof(szLines)); +} +CTrayClockWnd::~CTrayClockWnd() { } + +LRESULT CTrayClockWnd::OnThemeChanged() +{ + LOGFONTW clockFont; + HTHEME clockTheme; + HFONT hFont; + + clockTheme = OpenThemeData(m_hWnd, L"Clock"); + + if (clockTheme) + { + GetThemeFont(clockTheme, + NULL, + CLP_TIME, + 0, + TMT_FONT, + &clockFont); + + hFont = CreateFontIndirectW(&clockFont); + + GetThemeColor(clockTheme, + CLP_TIME, + 0, + TMT_TEXTCOLOR, + &textColor); + + if (this->hFont != NULL) + DeleteObject(this->hFont); + + SetFont(hFont, FALSE); + } + else + { + /* We don't need to set a font here, our parent will use + * WM_SETFONT to set the right one when themes are not enabled. */ + textColor = RGB(0, 0, 0); + } + + CloseThemeData(clockTheme); + + return TRUE; +} + +LRESULT CTrayClockWnd::OnThemeChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + return OnThemeChanged(); +} + +BOOL CTrayClockWnd::MeasureLines() +{ + HDC hDC; + HFONT hPrevFont; + UINT c, i; + BOOL bRet = TRUE; + + hDC = GetDC(); + if (hDC != NULL) + { + if (hFont) + hPrevFont = (HFONT) SelectObject(hDC, hFont); + + for (i = 0; i < CLOCKWND_FORMAT_COUNT && bRet; i++) + { + if (szLines[i][0] != L'\0' && + !GetTextExtentPointW(hDC, szLines[i], wcslen(szLines[i]), + &LineSizes[i])) + { + bRet = FALSE; + break; + } + } + + if (hFont) + SelectObject(hDC, hPrevFont); + + ReleaseDC(hDC); + + if (bRet) + { + LineSpacing = 0; + + /* calculate the line spacing */ + for (i = 0, c = 0; i < CLOCKWND_FORMAT_COUNT; i++) + { + if (LineSizes[i].cx > 0) + { + LineSpacing += LineSizes[i].cy; + c++; + } + } + + if (c > 0) + { + /* We want a spacing of 1/2 line */ + LineSpacing = (LineSpacing / c) / 2; + } + + return TRUE; + } + } + + return FALSE; +} + +WORD CTrayClockWnd::GetMinimumSize(IN BOOL Horizontal, IN OUT PSIZE pSize) +{ + WORD iLinesVisible = 0; + UINT i; + SIZE szMax = { 0, 0 }; + + if (!LinesMeasured) + LinesMeasured = MeasureLines(); + + if (!LinesMeasured) + return 0; + + for (i = 0; i < CLOCKWND_FORMAT_COUNT; i++) + { + if (LineSizes[i].cx != 0) + { + if (iLinesVisible > 0) + { + if (Horizontal) + { + if (szMax.cy + LineSizes[i].cy + (LONG) LineSpacing > + pSize->cy - (2 * TRAY_CLOCK_WND_SPACING_Y)) + { + break; + } + } + else + { + if (LineSizes[i].cx > pSize->cx - (2 * TRAY_CLOCK_WND_SPACING_X)) + break; + } + + /* Add line spacing */ + szMax.cy += LineSpacing; + } + + iLinesVisible++; + + /* Increase maximum rectangle */ + szMax.cy += LineSizes[i].cy; + if (LineSizes[i].cx > szMax.cx - (2 * TRAY_CLOCK_WND_SPACING_X)) + szMax.cx = LineSizes[i].cx + (2 * TRAY_CLOCK_WND_SPACING_X); + } + } + + szMax.cx += 2 * TRAY_CLOCK_WND_SPACING_X; + szMax.cy += 2 * TRAY_CLOCK_WND_SPACING_Y; + + *pSize = szMax; + + return iLinesVisible; +} + +VOID CTrayClockWnd::UpdateWnd() +{ + SIZE szPrevCurrent; + UINT BufSize, i; + INT iRet; + RECT rcClient; + + ZeroMemory(LineSizes, sizeof(LineSizes)); + + szPrevCurrent = CurrentSize; + + for (i = 0; i < CLOCKWND_FORMAT_COUNT; i++) + { + szLines[i][0] = L'\0'; + BufSize = _countof(szLines[0]); + + if (ClockWndFormats[i].IsTime) + { + iRet = GetTimeFormat(LOCALE_USER_DEFAULT, + g_TaskbarSettings.bShowSeconds ? ClockWndFormats[i].dwFormatFlags : TIME_NOSECONDS, + &LocalTime, + ClockWndFormats[i].lpFormat, + szLines[i], + BufSize); + } + else + { + iRet = GetDateFormat(LOCALE_USER_DEFAULT, + ClockWndFormats[i].dwFormatFlags, + &LocalTime, + ClockWndFormats[i].lpFormat, + szLines[i], + BufSize); + } + + if (iRet != 0 && i == 0) + { + /* Set the window text to the time only */ + SetWindowText(szLines[i]); + } + } + + LinesMeasured = MeasureLines(); + + if (LinesMeasured && + GetClientRect(&rcClient)) + { + SIZE szWnd; + + szWnd.cx = rcClient.right; + szWnd.cy = rcClient.bottom; + + VisibleLines = GetMinimumSize(IsHorizontal, &szWnd); + CurrentSize = szWnd; + } + + if (IsWindowVisible()) + { + InvalidateRect(NULL, TRUE); + + if (hWndNotify != NULL && + (szPrevCurrent.cx != CurrentSize.cx || + szPrevCurrent.cy != CurrentSize.cy)) + { + NMHDR nmh; + + nmh.hwndFrom = m_hWnd; + nmh.idFrom = GetWindowLongPtr(GWLP_ID); + nmh.code = NTNWM_REALIGN; + + ::SendMessage(hWndNotify, + WM_NOTIFY, + (WPARAM) nmh.idFrom, + (LPARAM) &nmh); + } + } +} + +VOID CTrayClockWnd::Update() +{ + GetLocalTime(&LocalTime); + UpdateWnd(); +} + +UINT CTrayClockWnd::CalculateDueTime() +{ + UINT uiDueTime; + + /* Calculate the due time */ + GetLocalTime(&LocalTime); + uiDueTime = 1000 - (UINT) LocalTime.wMilliseconds; + if (g_TaskbarSettings.bShowSeconds) + uiDueTime += (UINT) LocalTime.wSecond * 100; + else + uiDueTime += (59 - (UINT) LocalTime.wSecond) * 1000; + + if (uiDueTime < USER_TIMER_MINIMUM || uiDueTime > USER_TIMER_MAXIMUM) + uiDueTime = 1000; + else + { + /* Add an artificial delay of 0.05 seconds to make sure the timer + doesn't fire too early*/ + uiDueTime += 50; + } + + return uiDueTime; +} + +BOOL CTrayClockWnd::ResetTime() +{ + UINT uiDueTime; + BOOL Ret; + + /* Disable all timers */ + if (IsTimerEnabled) + { + KillTimer(ID_TRAYCLOCK_TIMER); + IsTimerEnabled = FALSE; + } + + if (IsInitTimerEnabled) + { + KillTimer(ID_TRAYCLOCK_TIMER_INIT); + } + + uiDueTime = CalculateDueTime(); + + /* Set the new timer */ + Ret = SetTimer(ID_TRAYCLOCK_TIMER_INIT, uiDueTime, NULL) != 0; + IsInitTimerEnabled = Ret; + + /* Update the time */ + Update(); + + return Ret; +} + +VOID CTrayClockWnd::CalibrateTimer() +{ + UINT uiDueTime; + BOOL Ret; + UINT uiWait1, uiWait2; + + /* Kill the initialization timer */ + KillTimer(ID_TRAYCLOCK_TIMER_INIT); + IsInitTimerEnabled = FALSE; + + uiDueTime = CalculateDueTime(); + + if (g_TaskbarSettings.bShowSeconds) + { + uiWait1 = 1000 - 200; + uiWait2 = 1000; + } + else + { + uiWait1 = 60 * 1000 - 200; + uiWait2 = 60 * 1000; + } + + if (uiDueTime > uiWait1) + { + /* The update of the clock will be up to 200 ms late, but that's + acceptable. We're going to setup a timer that fires depending + uiWait2. */ + Ret = SetTimer(ID_TRAYCLOCK_TIMER, uiWait2, NULL) != 0; + IsTimerEnabled = Ret; + + /* Update the time */ + Update(); + } + else + { + /* Recalibrate the timer and recalculate again when the current + minute/second ends. */ + ResetTime(); + } +} + +LRESULT CTrayClockWnd::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + /* Disable all timers */ + if (IsTimerEnabled) + { + KillTimer(ID_TRAYCLOCK_TIMER); + } + + if (IsInitTimerEnabled) + { + KillTimer(ID_TRAYCLOCK_TIMER_INIT); + } + + return TRUE; +} + +LRESULT CTrayClockWnd::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + RECT rcClient; + HFONT hPrevFont; + INT iPrevBkMode; + UINT i, line; + + PAINTSTRUCT ps; + HDC hDC = (HDC) wParam; + + if (wParam == 0) + { + hDC = BeginPaint(&ps); + } + + if (hDC == NULL) + return FALSE; + + if (LinesMeasured && + GetClientRect(&rcClient)) + { + iPrevBkMode = SetBkMode(hDC, TRANSPARENT); + + SetTextColor(hDC, textColor); + + hPrevFont = (HFONT) SelectObject(hDC, hFont); + + rcClient.left = (rcClient.right / 2) - (CurrentSize.cx / 2); + rcClient.top = (rcClient.bottom / 2) - (CurrentSize.cy / 2); + rcClient.right = rcClient.left + CurrentSize.cx; + rcClient.bottom = rcClient.top + CurrentSize.cy; + + for (i = 0, line = 0; + i < CLOCKWND_FORMAT_COUNT && line < VisibleLines; + i++) + { + if (LineSizes[i].cx != 0) + { + TextOut(hDC, + rcClient.left + (CurrentSize.cx / 2) - (LineSizes[i].cx / 2) + + TRAY_CLOCK_WND_SPACING_X, + rcClient.top + TRAY_CLOCK_WND_SPACING_Y, + szLines[i], + wcslen(szLines[i])); + + rcClient.top += LineSizes[i].cy + LineSpacing; + line++; + } + } + + SelectObject(hDC, hPrevFont); + + SetBkMode(hDC, iPrevBkMode); + } + + if (wParam == 0) + { + EndPaint(&ps); + } + + return TRUE; +} + +VOID CTrayClockWnd::SetFont(IN HFONT hNewFont, IN BOOL bRedraw) +{ + hFont = hNewFont; + LinesMeasured = MeasureLines(); + if (bRedraw) + { + InvalidateRect(NULL, TRUE); + } +} + +LRESULT CTrayClockWnd::DrawBackground(HDC hdc) +{ + RECT rect; + + GetClientRect(&rect); + DrawThemeParentBackground(m_hWnd, hdc, &rect); + + return TRUE; +} + +LRESULT CTrayClockWnd::OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + HDC hdc = (HDC) wParam; + + if (!IsAppThemed()) + { + bHandled = FALSE; + return 0; + } + + return DrawBackground(hdc); +} + +LRESULT CTrayClockWnd::OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + switch (wParam) + { + case ID_TRAYCLOCK_TIMER: + Update(); + break; + + case ID_TRAYCLOCK_TIMER_INIT: + CalibrateTimer(); + break; + } + return TRUE; +} + +LRESULT CTrayClockWnd::OnGetMinimumSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + IsHorizontal = (BOOL) wParam; + + return (LRESULT) GetMinimumSize((BOOL) wParam, (PSIZE) lParam) != 0; +} + +LRESULT CTrayClockWnd::OnUpdateTime(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + return (LRESULT) ResetTime(); +} + +LRESULT CTrayClockWnd::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + return HTTRANSPARENT; +} + +LRESULT CTrayClockWnd::OnSetFont(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + SetFont((HFONT) wParam, (BOOL) LOWORD(lParam)); + return TRUE; +} + +LRESULT CTrayClockWnd::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + ResetTime(); + return TRUE; +} + +LRESULT CTrayClockWnd::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + SIZE szClient; + + szClient.cx = LOWORD(lParam); + szClient.cy = HIWORD(lParam); + + VisibleLines = GetMinimumSize(IsHorizontal, &szClient); + CurrentSize = szClient; + + InvalidateRect(NULL, TRUE); + return TRUE; +} + +HWND CTrayClockWnd::_Init(IN HWND hWndParent, IN BOOL bVisible) +{ + IsHorizontal = TRUE; + + hWndNotify = hWndParent; + + /* Create the window. The tray window is going to move it to the correct + position and resize it as needed. */ + DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS; + if (bVisible) + dwStyle |= WS_VISIBLE; + + Create(hWndParent, 0, NULL, dwStyle); + + if (m_hWnd != NULL) + SetWindowTheme(m_hWnd, L"TrayNotify", NULL); + + return m_hWnd; + +}; diff --git a/base/shell/explorer/trayclock.h b/base/shell/explorer/trayclock.h new file mode 100644 index 0000000000..23911dfae9 --- /dev/null +++ b/base/shell/explorer/trayclock.h @@ -0,0 +1,94 @@ +#pragma once + +const struct +{ + BOOL IsTime; + DWORD dwFormatFlags; + LPCWSTR lpFormat; +} ClockWndFormats[] = { + { TRUE, 0, NULL }, + { FALSE, 0, L"dddd" }, + { FALSE, DATE_SHORTDATE, NULL } +}; +const UINT ClockWndFormatsCount = _ARRAYSIZE(ClockWndFormats); + +#define CLOCKWND_FORMAT_COUNT ClockWndFormatsCount + +extern const WCHAR szTrayClockWndClass[]; +class CTrayClockWnd : + public CComObjectRootEx<CComMultiThreadModelNoCS>, + public CWindowImpl < CTrayClockWnd, CWindow, CControlWinTraits > +{ + HWND hWndNotify; + HFONT hFont; + COLORREF textColor; + RECT rcText; + SYSTEMTIME LocalTime; + + union + { + DWORD dwFlags; + struct + { + DWORD IsTimerEnabled : 1; + DWORD IsInitTimerEnabled : 1; + DWORD LinesMeasured : 1; + DWORD IsHorizontal : 1; + }; + }; + DWORD LineSpacing; + SIZE CurrentSize; + WORD VisibleLines; + SIZE LineSizes[CLOCKWND_FORMAT_COUNT]; + WCHAR szLines[CLOCKWND_FORMAT_COUNT][48]; + +public: + CTrayClockWnd(); + virtual ~CTrayClockWnd(); + +private: + LRESULT OnThemeChanged(); + LRESULT OnThemeChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + + BOOL MeasureLines(); + WORD GetMinimumSize(IN BOOL Horizontal, IN OUT PSIZE pSize); + VOID UpdateWnd(); + VOID Update(); + UINT CalculateDueTime(); + BOOL ResetTime(); + VOID CalibrateTimer(); + LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + VOID SetFont(IN HFONT hNewFont, IN BOOL bRedraw); + LRESULT DrawBackground(HDC hdc); + LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnGetMinimumSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnSetFont(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); +public: + LRESULT OnUpdateTime(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + +public: + DECLARE_WND_CLASS_EX(szTrayClockWndClass, CS_DBLCLKS, COLOR_3DFACE) + + BEGIN_MSG_MAP(CTrayClockWnd) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) + MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_PAINT, OnPaint) + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) + MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged) + MESSAGE_HANDLER(WM_TIMER, OnTimer) + MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest) + MESSAGE_HANDLER(WM_SETFONT, OnSetFont) + MESSAGE_HANDLER(TCWM_GETMINIMUMSIZE, OnGetMinimumSize) + MESSAGE_HANDLER(TCWM_UPDATETIME, OnUpdateTime) + + END_MSG_MAP() + + HWND _Init(IN HWND hWndParent, IN BOOL bVisible); +}; \ No newline at end of file diff --git a/base/shell/explorer/trayntfy.cpp b/base/shell/explorer/trayntfy.cpp index 1b05b501a7..9a0294e500 100644 --- a/base/shell/explorer/trayntfy.cpp +++ b/base/shell/explorer/trayntfy.cpp @@ -21,1953 +21,6 @@ #include "precomp.h" -/* - * SysPagerWnd - */ -static const WCHAR szSysPagerWndClass [] = L"SysPager"; - -// Data comes from shell32/systray.cpp -> TrayNotifyCDS_Dummy -typedef struct _SYS_PAGER_COPY_DATA -{ - DWORD cookie; - DWORD notify_code; - NOTIFYICONDATA nicon_data; -} SYS_PAGER_COPY_DATA, *PSYS_PAGER_COPY_DATA; - -struct InternalIconData : NOTIFYICONDATA -{ - // Must keep a separate copy since the original is unioned with uTimeout. - UINT uVersionCopy; -}; - -struct IconWatcherData -{ - HANDLE hProcess; - DWORD ProcessId; - NOTIFYICONDATA IconData; - - IconWatcherData(NOTIFYICONDATA *iconData) : - hProcess(NULL), ProcessId(0) - { - IconData.cbSize = sizeof(NOTIFYICONDATA); - IconData.hWnd = iconData->hWnd; - IconData.uID = iconData->uID; - IconData.guidItem = iconData->guidItem; - } - - ~IconWatcherData() - { - if (hProcess) - { - CloseHandle(hProcess); - } - } -}; - -class CIconWatcher -{ - CAtlList<IconWatcherData *> m_WatcherList; - CRITICAL_SECTION m_ListLock; - HANDLE m_hWatcherThread; - HANDLE m_WakeUpEvent; - HWND m_hwndSysTray; - bool m_Loop; - -public: - CIconWatcher() : - m_hWatcherThread(NULL), - m_WakeUpEvent(NULL), - m_hwndSysTray(NULL), - m_Loop(false) - { - } - - virtual ~CIconWatcher() - { - Uninitialize(); - DeleteCriticalSection(&m_ListLock); - - if (m_WakeUpEvent) - CloseHandle(m_WakeUpEvent); - if (m_hWatcherThread) - CloseHandle(m_hWatcherThread); - } - - bool Initialize(_In_ HWND hWndParent) - { - m_hwndSysTray = hWndParent; - - InitializeCriticalSection(&m_ListLock); - m_WakeUpEvent = CreateEventW(NULL, FALSE, FALSE, NULL); - if (m_WakeUpEvent == NULL) - return false; - - m_hWatcherThread = (HANDLE)_beginthreadex(NULL, - 0, - WatcherThread, - (LPVOID)this, - 0, - NULL); - if (m_hWatcherThread == NULL) - return false; - - return true; - } - - void Uninitialize() - { - m_Loop = false; - if (m_WakeUpEvent) - SetEvent(m_WakeUpEvent); - - EnterCriticalSection(&m_ListLock); - - POSITION Pos; - for (size_t i = 0; i < m_WatcherList.GetCount(); i++) - { - Pos = m_WatcherList.FindIndex(i); - if (Pos) - { - IconWatcherData *Icon; - Icon = m_WatcherList.GetAt(Pos); - delete Icon; - } - } - m_WatcherList.RemoveAll(); - - LeaveCriticalSection(&m_ListLock); - } - - bool AddIconToWatcher(_In_ NOTIFYICONDATA *iconData) - { - DWORD ProcessId; - (void)GetWindowThreadProcessId(iconData->hWnd, &ProcessId); - - HANDLE hProcess; - hProcess = OpenProcess(SYNCHRONIZE, FALSE, ProcessId); - if (hProcess == NULL) - { - return false; - } - - IconWatcherData *Icon = new IconWatcherData(iconData); - Icon->hProcess = hProcess; - Icon->ProcessId; - - bool Added = false; - EnterCriticalSection(&m_ListLock); - - // The likelyhood of someone having more than 64 icons in their tray is - // pretty slim. We could spin up a new thread for each multiple of 64, but - // it's not worth the effort, so we just won't bother watching those icons - if (m_WatcherList.GetCount() < MAXIMUM_WAIT_OBJECTS) - { - m_WatcherList.AddTail(Icon); - SetEvent(m_WakeUpEvent); - Added = true; - } - - LeaveCriticalSection(&m_ListLock); - - if (!Added) - { - delete Icon; - } - - return Added; - } - - bool RemoveIconFromWatcher(_In_ NOTIFYICONDATA *iconData) - { - EnterCriticalSection(&m_ListLock); - - IconWatcherData *Icon; - Icon = GetListEntry(iconData, NULL, true); - - SetEvent(m_WakeUpEvent); - LeaveCriticalSection(&m_ListLock); - - delete Icon; - return true; - } - - IconWatcherData* GetListEntry(_In_opt_ NOTIFYICONDATA *iconData, _In_opt_ HANDLE hProcess, _In_ bool Remove) - { - IconWatcherData *Entry = NULL; - POSITION NextPosition = m_WatcherList.GetHeadPosition(); - POSITION Position; - do - { - Position = NextPosition; - - Entry = m_WatcherList.GetNext(NextPosition); - if (Entry) - { - if ((iconData && ((Entry->IconData.hWnd == iconData->hWnd) && (Entry->IconData.uID == iconData->uID))) || - (hProcess && (Entry->hProcess == hProcess))) - { - if (Remove) - m_WatcherList.RemoveAt(Position); - break; - } - } - Entry = NULL; - - } while (NextPosition != NULL); - - return Entry; - } - -private: - - static UINT WINAPI WatcherThread(_In_opt_ LPVOID lpParam) - { - CIconWatcher* This = reinterpret_cast<CIconWatcher *>(lpParam); - HANDLE *WatchList = NULL; - - This->m_Loop = true; - while (This->m_Loop) - { - EnterCriticalSection(&This->m_ListLock); - - DWORD Size; - Size = This->m_WatcherList.GetCount() + 1; - ASSERT(Size <= MAXIMUM_WAIT_OBJECTS); - - if (WatchList) - delete WatchList; - WatchList = new HANDLE[Size]; - WatchList[0] = This->m_WakeUpEvent; - - POSITION Pos; - for (size_t i = 0; i < This->m_WatcherList.GetCount(); i++) - { - Pos = This->m_WatcherList.FindIndex(i); - if (Pos) - { - IconWatcherData *Icon; - Icon = This->m_WatcherList.GetAt(Pos); - WatchList[i + 1] = Icon->hProcess; - } - } - - LeaveCriticalSection(&This->m_ListLock); - - DWORD Status; - Status = WaitForMultipleObjects(Size, - WatchList, - FALSE, - INFINITE); - if (Status == WAIT_OBJECT_0) - { - // We've been kicked, we have updates to our list (or we're exiting the thread) - if (This->m_Loop) - TRACE("Updating watched icon list"); - } - else if ((Status >= WAIT_OBJECT_0 + 1) && (Status < Size)) - { - IconWatcherData *Icon; - Icon = This->GetListEntry(NULL, WatchList[Status], false); - - TRACE("Pid %lu owns a notification icon and has stopped without deleting it. We'll cleanup on its behalf", Icon->ProcessId); - - int len = FIELD_OFFSET(SYS_PAGER_COPY_DATA, nicon_data) + Icon->IconData.cbSize; - PSYS_PAGER_COPY_DATA pnotify_data = (PSYS_PAGER_COPY_DATA)new BYTE[len]; - pnotify_data->cookie = 1; - pnotify_data->notify_code = NIM_DELETE; - memcpy(&pnotify_data->nicon_data, &Icon->IconData, Icon->IconData.cbSize); - - COPYDATASTRUCT data; - data.dwData = 1; - data.cbData = len; - data.lpData = pnotify_data; - - BOOL Success = FALSE; - HWND parentHWND = ::GetParent(GetParent(This->m_hwndSysTray)); - if (parentHWND) - Success = ::SendMessage(parentHWND, WM_COPYDATA, (WPARAM)&Icon->IconData, (LPARAM)&data); - - delete pnotify_data; - - if (!Success) - { - // If we failed to handle the delete message, forcibly remove it - This->RemoveIconFromWatcher(&Icon->IconData); - } - } - else - { - if (Status == WAIT_FAILED) - { - Status = GetLastError(); - } - ERR("Failed to wait on process handles : %lu\n", Status); - This->Uninitialize(); - } - } - - if (WatchList) - delete WatchList; - - return 0; - } -}; - -class CBalloonQueue -{ -public: - static const int TimerInterval = 2000; - static const int BalloonsTimerId = 1; - static const int MinTimeout = 10000; - static const int MaxTimeout = 30000; - static const int CooldownBetweenBalloons = 2000; - -private: - struct Info - { - InternalIconData * pSource; - WCHAR szInfo[256]; - WCHAR szInfoTitle[64]; - WPARAM uIcon; - UINT uTimeout; - - Info(InternalIconData * source) - { - pSource = source; - StrNCpy(szInfo, source->szInfo, _countof(szInfo)); - StrNCpy(szInfoTitle, source->szInfoTitle, _countof(szInfoTitle)); - uIcon = source->dwInfoFlags & NIIF_ICON_MASK; - if (source->dwInfoFlags == NIIF_USER) - uIcon = reinterpret_cast<WPARAM>(source->hIcon); - uTimeout = source->uTimeout; - } - }; - - HWND m_hwndParent; - - CTooltips * m_tooltips; - - CAtlList<Info> m_queue; - - CToolbar<InternalIconData> * m_toolbar; - - InternalIconData * m_current; - bool m_currentClosed; - - int m_timer; - -public: - CBalloonQueue() : - m_hwndParent(NULL), - m_tooltips(NULL), - m_toolbar(NULL), - m_current(NULL), - m_currentClosed(false), - m_timer(-1) - { - } - - void Init(HWND hwndParent, CToolbar<InternalIconData> * toolbar, CTooltips * balloons) - { - m_hwndParent = hwndParent; - m_toolbar = toolbar; - m_tooltips = balloons; - } - - void Deinit() - { - if (m_timer >= 0) - { - ::KillTimer(m_hwndParent, m_timer); - } - } - - bool OnTimer(int timerId) - { - if (timerId != m_timer) - return false; - - ::KillTimer(m_hwndParent, m_timer); - m_timer = -1; - - if (m_current && !m_currentClosed) - { - Close(m_current); - } - else - { - m_current = NULL; - m_currentClosed = false; - if (!m_queue.IsEmpty()) - { - Info info = m_queue.RemoveHead(); - Show(info); - } - } - - return true; - } - - void UpdateInfo(InternalIconData * notifyItem) - { - size_t len = 0; - HRESULT hr = StringCchLength(notifyItem->szInfo, _countof(notifyItem->szInfo), &len); - if (SUCCEEDED(hr) && len > 0) - { - Info info(notifyItem); - - // If m_current == notifyItem, we want to replace the previous balloon even if there is a queue. - if (m_current != notifyItem && (m_current != NULL || !m_queue.IsEmpty())) - { - m_queue.AddTail(info); - } - else - { - Show(info); - } - } - else - { - Close(notifyItem); - } - } - - void RemoveInfo(InternalIconData * notifyItem) - { - Close(notifyItem); - - POSITION position = m_queue.GetHeadPosition(); - while(position != NULL) - { - Info& info = m_queue.GetNext(position); - if (info.pSource == notifyItem) - { - m_queue.RemoveAt(position); - } - } - } - - void CloseCurrent() - { - if (m_current != NULL) - Close(m_current); - } - -private: - - int IndexOf(InternalIconData * pdata) - { - int count = m_toolbar->GetButtonCount(); - for (int i = 0; i < count; i++) - { - if (m_toolbar->GetItemData(i) == pdata) - return i; - } - return -1; - } - - void SetTimer(int length) - { - m_timer = ::SetTimer(m_hwndParent, BalloonsTimerId, length, NULL); - } - - void Show(Info& info) - { - TRACE("ShowBalloonTip called for flags=%x text=%ws; title=%ws\n", info.uIcon, info.szInfo, info.szInfoTitle); - - // TODO: NIF_REALTIME, NIIF_NOSOUND, other Vista+ flags - - const int index = IndexOf(info.pSource); - RECT rc; - m_toolbar->GetItemRect(index, &rc); - m_toolbar->ClientToScreen(&rc); - const WORD x = (rc.left + rc.right) / 2; - const WORD y = (rc.top + rc.bottom) / 2; - - m_tooltips->SetTitle(info.szInfoTitle, info.uIcon); - m_tooltips->TrackPosition(x, y); - m_tooltips->UpdateTipText(m_hwndParent, reinterpret_cast<LPARAM>(m_toolbar->m_hWnd), info.szInfo); - m_tooltips->TrackActivate(m_hwndParent, reinterpret_cast<LPARAM>(m_toolbar->m_hWnd)); - - m_current = info.pSource; - int timeout = info.uTimeout; - if (timeout < MinTimeout) timeout = MinTimeout; - if (timeout > MaxTimeout) timeout = MaxTimeout; - - SetTimer(timeout); - } - - void Close(IN OUT InternalIconData * notifyItem) - { - TRACE("HideBalloonTip called\n"); - - if (m_current == notifyItem && !m_currentClosed) - { - // Prevent Re-entry - m_currentClosed = true; - m_tooltips->TrackDeactivate(); - SetTimer(CooldownBetweenBalloons); - } - } -}; - -class CNotifyToolbar : - public CWindowImplBaseT< CToolbar<InternalIconData>, CControlWinTraits > -{ - HIMAGELIST m_ImageList; - int m_VisibleButtonCount; - - CBalloonQueue * m_BalloonQueue; - -public: - CNotifyToolbar() : - m_ImageList(NULL), - m_VisibleButtonCount(0), - m_BalloonQueue(NULL) - { - } - - ~CNotifyToolbar() - { - } - - int GetVisibleButtonCount() - { - return m_VisibleButtonCount; - } - - int FindItem(IN HWND hWnd, IN UINT uID, InternalIconData ** pdata) - { - int count = GetButtonCount(); - - for (int i = 0; i < count; i++) - { - InternalIconData * data = GetItemData(i); - - if (data->hWnd == hWnd && - data->uID == uID) - { - if (pdata) - *pdata = data; - return i; - } - } - - return -1; - } - - int FindExistingSharedIcon(HICON handle) - { - int count = GetButtonCount(); - for (int i = 0; i < count; i++) - { - InternalIconData * data = GetItemData(i); - if (data->hIcon == handle) - { - TBBUTTON btn; - GetButton(i, &btn); - return btn.iBitmap; - } - } - - return -1; - } - - BOOL AddButton(IN CONST NOTIFYICONDATA *iconData) - { - TBBUTTON tbBtn; - InternalIconData * notifyItem; - WCHAR text[] = L""; - - TRACE("Adding icon %d from hWnd %08x flags%s%s state%s%s", - iconData->uID, iconData->hWnd, - (iconData->uFlags & NIF_ICON) ? " ICON" : "", - (iconData->uFlags & NIF_STATE) ? " STATE" : "", - (iconData->dwState & NIS_HIDDEN) ? " HIDDEN" : "", - (iconData->dwState & NIS_SHAREDICON) ? " SHARED" : ""); - - int index = FindItem(iconData->hWnd, iconData->uID, ¬ifyItem); - if (index >= 0) - { - TRACE("Icon %d from hWnd %08x ALREADY EXISTS!", iconData->uID, iconData->hWnd); - return FALSE; - } - - notifyItem = new InternalIconData(); - ZeroMemory(notifyItem, sizeof(*notifyItem)); - - notifyItem->hWnd = iconData->hWnd; - notifyItem->uID = iconData->uID; - - tbBtn.fsState = TBSTATE_ENABLED; - tbBtn.fsStyle = BTNS_NOPREFIX; - tbBtn.dwData = (DWORD_PTR)notifyItem; - tbBtn.iString = (INT_PTR) text; - tbBtn.idCommand = GetButtonCount(); - - if (iconData->uFlags & NIF_STATE) - { - notifyItem->dwState = iconData->dwState & iconData->dwStateMask; - } - - if (iconData->uFlags & NIF_MESSAGE) - { - notifyItem->uCallbackMessage = iconData->uCallbackMessage; - } - - if (iconData->uFlags & NIF_ICON) - { - notifyItem->hIcon = iconData->hIcon; - BOOL hasSharedIcon = notifyItem->dwState & NIS_SHAREDICON; - if (hasSharedIcon) - { - INT iIcon = FindExistingSharedIcon(notifyItem->hIcon); - if (iIcon < 0) - { - notifyItem->hIcon = NULL; - TRACE("Shared icon requested, but HICON not found!!!"); - } - tbBtn.iBitmap = iIcon; - } - else - { - tbBtn.iBitmap = ImageList_AddIcon(m_ImageList, notifyItem->hIcon); - } - } - - if (iconData->uFlags & NIF_TIP) - { - StringCchCopy(notifyItem->szTip, _countof(notifyItem->szTip), iconData->szTip); - } - - if (iconData->uFlags & NIF_INFO) - { - // NOTE: In Vista+, the uTimeout value is disregarded, and the accessibility settings are used always. - StrNCpy(notifyItem->szInfo, iconData->szInfo, _countof(notifyItem->szInfo)); - StrNCpy(notifyItem->szInfoTitle, iconData->szInfoTitle, _countof(notifyItem->szInfo)); - notifyItem->dwInfoFlags = iconData->dwInfoFlags; - notifyItem->uTimeout = iconData->uTimeout; - } - - if (notifyItem->dwState & NIS_HIDDEN) - { - tbBtn.fsState |= TBSTATE_HIDDEN; - } - else - { - m_VisibleButtonCount++; - } - - /* TODO: support VERSION_4 (NIF_GUID, NIF_REALTIME, NIF_SHOWTIP) */ - - CToolbar::AddButton(&tbBtn); - SetButtonSize(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); - - if (iconData->uFlags & NIF_INFO) - { - m_BalloonQueue->UpdateInfo(notifyItem); - } - - return TRUE; - } - - BOOL SwitchVersion(IN CONST NOTIFYICONDATA *iconData) - { - InternalIconData * notifyItem; - int index = FindItem(iconData->hWnd, iconData->uID, ¬ifyItem); - if (index < 0) - { - WARN("Icon %d from hWnd %08x DOES NOT EXIST!", iconData->uID, iconData->hWnd); - return FALSE; - } - - if (iconData->uVersion != 0 && iconData->uVersion != NOTIFYICON_VERSION) - { - WARN("Tried to set the version of icon %d from hWnd %08x, to an unknown value %d. Vista+ program?", iconData->uID, iconData->hWnd, iconData->uVersion); - return FALSE; - } - - // We can not store the version in the uVersion field, because it's union'd with uTimeout, - // which we also need to keep track of. - notifyItem->uVersionCopy = iconData->uVersion; - - return TRUE; - } - - BOOL UpdateButton(IN CONST NOTIFYICONDATA *iconData) - { - InternalIconData * notifyItem; - TBBUTTONINFO tbbi = { 0 }; - - TRACE("Updating icon %d from hWnd %08x flags%s%s state%s%s", - iconData->uID, iconData->hWnd, - (iconData->uFlags & NIF_ICON) ? " ICON" : "", - (iconData->uFlags & NIF_STATE) ? " STATE" : "", - (iconData->dwState & NIS_HIDDEN) ? " HIDDEN" : "", - (iconData->dwState & NIS_SHAREDICON) ? " SHARED" : ""); - - int index = FindItem(iconData->hWnd, iconData->uID, ¬ifyItem); - if (index < 0) - { - WARN("Icon %d from hWnd %08x DOES NOT EXIST!", iconData->uID, iconData->hWnd); - return AddButton(iconData); - } - - TBBUTTON btn; - GetButton(index, &btn); - int oldIconIndex = btn.iBitmap; - - tbbi.cbSize = sizeof(tbbi); - tbbi.dwMask = TBIF_BYINDEX | TBIF_COMMAND; - tbbi.idCommand = index; - - if (iconData->uFlags & NIF_STATE) - { - if (iconData->dwStateMask & NIS_HIDDEN && - (notifyItem->dwState & NIS_HIDDEN) != (iconData->dwState & NIS_HIDDEN)) - { - tbbi.dwMask |= TBIF_STATE; - if (iconData->dwState & NIS_HIDDEN) - { - tbbi.fsState |= TBSTATE_HIDDEN; - m_VisibleButtonCount--; - } - else - { - tbbi.fsState &= ~TBSTATE_HIDDEN; - m_VisibleButtonCount++; - } - } - - notifyItem->dwState &= ~iconData->dwStateMask; - notifyItem->dwState |= (iconData->dwState & iconData->dwStateMask); - } - - if (iconData->uFlags & NIF_MESSAGE) - { - notifyItem->uCallbackMessage = iconData->uCallbackMessage; - } - - if (iconData->uFlags & NIF_ICON) - { - BOOL hasSharedIcon = notifyItem->dwState & NIS_SHAREDICON; - if (hasSharedIcon) - { - INT iIcon = FindExistingSharedIcon(iconData->hIcon); - if (iIcon >= 0) - { - notifyItem->hIcon = iconData->hIcon; - tbbi.dwMask |= TBIF_IMAGE; - tbbi.iImage = iIcon; - } - else - { - TRACE("Shared icon requested, but HICON not found!!! IGNORING!"); - } - } - else - { - notifyItem->hIcon = iconData->hIcon; - tbbi.dwMask |= TBIF_IMAGE; - tbbi.iImage = ImageList_ReplaceIcon(m_ImageList, oldIconIndex, notifyItem->hIcon); - } - } - - if (iconData->uFlags & NIF_TIP) - { - StringCchCopy(notifyItem->szTip, _countof(notifyItem->szTip), iconData->szTip); - } - - if (iconData->uFlags & NIF_INFO) - { - // NOTE: In Vista+, the uTimeout value is disregarded, and the accessibility settings are used always. - StrNCpy(notifyItem->szInfo, iconData->szInfo, _countof(notifyItem->szInfo)); - StrNCpy(notifyItem->szInfoTitle, iconData->szInfoTitle, _countof(notifyItem->szInfo)); - notifyItem->dwInfoFlags = iconData->dwInfoFlags; - notifyItem->uTimeout = iconData->uTimeout; - } - - /* TODO: support VERSION_4 (NIF_GUID, NIF_REALTIME, NIF_SHOWTIP) */ - - SetButtonInfo(index, &tbbi); - - if (iconData->uFlags & NIF_INFO) - { - m_BalloonQueue->UpdateInfo(notifyItem); - } - - return TRUE; - } - - BOOL RemoveButton(IN CONST NOTIFYICONDATA *iconData) - { - InternalIconData * notifyItem; - - TRACE("Removing icon %d from hWnd %08x", iconData->uID, iconData->hWnd); - - int index = FindItem(iconData->hWnd, iconData->uID, ¬ifyItem); - if (index < 0) - { - TRACE("Icon %d from hWnd %08x ALREADY MISSING!", iconData->uID, iconData->hWnd); - - return FALSE; - } - - if (!(notifyItem->dwState & NIS_HIDDEN)) - { - m_VisibleButtonCount--; - } - - if (!(notifyItem->dwState & NIS_SHAREDICON)) - { - TBBUTTON btn; - GetButton(index, &btn); - int oldIconIndex = btn.iBitmap; - ImageList_Remove(m_ImageList, oldIconIndex); - - // Update other icons! - int count = GetButtonCount(); - for (int i = 0; i < count; i++) - { - TBBUTTON btn; - GetButton(i, &btn); - - if (btn.iBitmap > oldIconIndex) - { - TBBUTTONINFO tbbi2 = { 0 }; - tbbi2.cbSize = sizeof(tbbi2); - tbbi2.dwMask = TBIF_BYINDEX | TBIF_IMAGE; - tbbi2.iImage = btn.iBitmap-1; - SetButtonInfo(i, &tbbi2); - } - } - } - - m_BalloonQueue->RemoveInfo(notifyItem); - - DeleteButton(index); - - delete notifyItem; - - return TRUE; - } - - - VOID GetTooltipText(LPARAM data, LPTSTR szTip, DWORD cchTip) - { - InternalIconData * notifyItem = reinterpret_cast<InternalIconData *>(data); - if (notifyItem) - { - StringCchCopy(szTip, cchTip, notifyItem->szTip); - } - else - { - StringCchCopy(szTip, cchTip, L""); - } - } - - VOID ResizeImagelist() - { - int cx, cy; - HIMAGELIST iml; - - if (!ImageList_GetIconSize(m_ImageList, &cx, &cy)) - return; - - if (cx == GetSystemMetrics(SM_CXSMICON) && cy == GetSystemMetrics(SM_CYSMICON)) - return; - - iml = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 | ILC_MASK, 0, 1000); - if (!iml) - return; - - ImageList_Destroy(m_ImageList); - m_ImageList = iml; - SetImageList(m_ImageList); - - int count = GetButtonCount(); - for (int i = 0; i < count; i++) - { - InternalIconData * data = GetItemData(i); - BOOL hasSharedIcon = data->dwState & NIS_SHAREDICON; - INT iIcon = hasSharedIcon ? FindExistingSharedIcon(data->hIcon) : -1; - if (iIcon < 0) - iIcon = ImageList_AddIcon(iml, data->hIcon); - TBBUTTONINFO tbbi = { sizeof(tbbi), TBIF_BYINDEX | TBIF_IMAGE, 0, iIcon}; - SetButtonInfo(i, &tbbi); - } - - SetButtonSize(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); - } - -private: - - VOID SendMouseEvent(IN WORD wIndex, IN UINT uMsg, IN WPARAM wParam) - { - static LPCWSTR eventNames [] = { - L"WM_MOUSEMOVE", - L"WM_LBUTTONDOWN", - L"WM_LBUTTONUP", - L"WM_LBUTTONDBLCLK", - L"WM_RBUTTONDOWN", - L"WM_RBUTTONUP", - L"WM_RBUTTONDBLCLK", - L"WM_MBUTTONDOWN", - L"WM_MBUTTONUP", - L"WM_MBUTTONDBLCLK", - L"WM_MOUSEWHEEL", - L"WM_XBUTTONDOWN", - L"WM_XBUTTONUP", - L"WM_XBUTTONDBLCLK" - }; - - InternalIconData * notifyItem = GetItemData(wIndex); - - if (!::IsWindow(notifyItem->hWnd)) - { - // We detect and destroy icons with invalid handles only on mouse move over systray, same as MS does. - // Alternatively we could search for them periodically (would waste more resources). - TRACE("Destroying icon %d with invalid handle hWnd=%08x\n", notifyItem->uID, notifyItem->hWnd); - - RemoveButton(notifyItem); - - HWND parentHWND = ::GetParent(::GetParent(GetParent())); - ::SendMessage(parentHWND, WM_SIZE, 0, 0); - - return; - } - - if (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST) - { - TRACE("Sending message %S from button %d to %p (msg=%x, w=%x, l=%x)...\n", - eventNames[uMsg - WM_MOUSEFIRST], wIndex, - notifyItem->hWnd, notifyItem->uCallbackMessage, notifyItem->uID, uMsg); - } - - DWORD pid; - GetWindowThreadProcessId(notifyItem->hWnd, &pid); - - if (pid == GetCurrentProcessId() || - (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST)) - { - ::PostMessage(notifyItem->hWnd, - notifyItem->uCallbackMessage, - notifyItem->uID, - uMsg); - } - else - { - SendMessage(notifyItem->hWnd, - notifyItem->uCallbackMessage, - notifyItem->uID, - uMsg); - } - } - - LRESULT OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - - INT iBtn = HitTest(&pt); - - if (iBtn >= 0) - { - SendMouseEvent(iBtn, uMsg, wParam); - } - - bHandled = FALSE; - return FALSE; - } - - LRESULT OnTooltipShow(INT uCode, LPNMHDR hdr, BOOL& bHandled) - { - RECT rcTip, rcItem; - ::GetWindowRect(hdr->hwndFrom, &rcTip); - - SIZE szTip = { rcTip.right - rcTip.left, rcTip.bottom - rcTip.top }; - - INT iBtn = GetHotItem(); - - if (iBtn >= 0) - { - MONITORINFO monInfo = { 0 }; - HMONITOR hMon = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST); - - monInfo.cbSize = sizeof(monInfo); - - if (hMon) - GetMonitorInfo(hMon, &monInfo); - else - ::GetWindowRect(GetDesktopWindow(), &monInfo.rcMonitor); - - GetItemRect(iBtn, &rcItem); - - POINT ptItem = { rcItem.left, rcItem.top }; - SIZE szItem = { rcItem.right - rcItem.left, rcItem.bottom - rcItem.top }; - ClientToScreen(&ptItem); - - ptItem.x += szItem.cx / 2; - ptItem.y -= szTip.cy; - - if (ptItem.x + szTip.cx > monInfo.rcMonitor.right) - ptItem.x = monInfo.rcMonitor.right - szTip.cx; - - if (ptItem.y + szTip.cy > monInfo.rcMonitor.bottom) - ptItem.y = monInfo.rcMonitor.bottom - szTip.cy; - - if (ptItem.x < monInfo.rcMonitor.left) - ptItem.x = monInfo.rcMonitor.left; - - if (ptItem.y < monInfo.rcMonitor.top) - ptItem.y = monInfo.rcMonitor.top; - - TRACE("ptItem { %d, %d }\n", ptItem.x, ptItem.y); - - ::SetWindowPos(hdr->hwndFrom, NULL, ptItem.x, ptItem.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); - - return TRUE; - } - - bHandled = FALSE; - return 0; - } - -public: - BEGIN_MSG_MAP(CNotifyToolbar) - MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseEvent) - NOTIFY_CODE_HANDLER(TTN_SHOW, OnTooltipShow) - END_MSG_MAP() - - void Initialize(HWND hWndParent, CBalloonQueue * queue) - { - m_BalloonQueue = queue; - - DWORD styles = - WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | - TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | TBSTYLE_WRAPABLE | TBSTYLE_TRANSPARENT | - CCS_TOP | CCS_NORESIZE | CCS_NOPARENTALIGN | CCS_NODIVIDER; - - SubclassWindow(CToolbar::Create(hWndParent, styles)); - - // Force the toolbar tooltips window to always show tooltips even if not foreground - HWND tooltipsWnd = (HWND)SendMessageW(TB_GETTOOLTIPS); - if (tooltipsWnd) - { - ::SetWindowLong(tooltipsWnd, GWL_STYLE, ::GetWindowLong(tooltipsWnd, GWL_STYLE) | TTS_ALWAYSTIP); - } - - SetWindowTheme(m_hWnd, L"TrayNotify", NULL); - - m_ImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 | ILC_MASK, 0, 1000); - SetImageList(m_ImageList); - - TBMETRICS tbm = {sizeof(tbm)}; - tbm.dwMask = TBMF_BARPAD | TBMF_BUTTONSPACING | TBMF_PAD; - tbm.cxPad = 1; - tbm.cyPad = 1; - tbm.cxButtonSpacing = 1; - tbm.cyButtonSpacing = 1; - SetMetrics(&tbm); - - SetButtonSize(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); - } -}; - -class CSysPagerWnd : - public CComObjectRootEx<CComMultiThreadModelNoCS>, - public CWindowImpl < CSysPagerWnd, CWindow, CControlWinTraits >, - public CIconWatcher -{ - CNotifyToolbar Toolbar; - CTooltips m_Balloons; - CBalloonQueue m_BalloonQueue; - -public: - CSysPagerWnd() {} - virtual ~CSysPagerWnd() {} - - LRESULT DrawBackground(HDC hdc) - { - RECT rect; - - GetClientRect(&rect); - DrawThemeParentBackground(m_hWnd, hdc, &rect); - - return TRUE; - } - - LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - HDC hdc = (HDC) wParam; - - if (!IsAppThemed()) - { - bHandled = FALSE; - return 0; - } - - return DrawBackground(hdc); - } - - LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - Toolbar.Initialize(m_hWnd, &m_BalloonQueue); - CIconWatcher::Initialize(m_hWnd); - - HWND hWndTop = GetAncestor(m_hWnd, GA_ROOT); - - m_Balloons.Create(hWndTop, TTS_NOPREFIX | TTS_BALLOON | TTS_CLOSE); - - TOOLINFOW ti = { 0 }; - ti.cbSize = TTTOOLINFOW_V1_SIZE; - ti.uFlags = TTF_TRACK | TTF_IDISHWND; - ti.uId = reinterpret_cast<UINT_PTR>(Toolbar.m_hWnd); - ti.hwnd = m_hWnd; - ti.lpszText = NULL; - ti.lParam = NULL; - - BOOL ret = m_Balloons.AddTool(&ti); - if (!ret) - { - WARN("AddTool failed, LastError=%d (probably meaningless unless non-zero)\n", GetLastError()); - } - - m_BalloonQueue.Init(m_hWnd, &Toolbar, &m_Balloons); - - // Explicitly request running applications to re-register their systray icons - ::SendNotifyMessageW(HWND_BROADCAST, - RegisterWindowMessageW(L"TaskbarCreated"), - 0, 0); - - return TRUE; - } - - LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - m_BalloonQueue.Deinit(); - CIconWatcher::Uninitialize(); - return TRUE; - } - - BOOL NotifyIconCmd(WPARAM wParam, LPARAM lParam) - { - PCOPYDATASTRUCT cpData = (PCOPYDATASTRUCT) lParam; - if (cpData->dwData == 1) - { - SYS_PAGER_COPY_DATA * data; - NOTIFYICONDATA *iconData; - BOOL ret = FALSE; - - int VisibleButtonCount = Toolbar.GetVisibleButtonCount(); - - data = (PSYS_PAGER_COPY_DATA) cpData->lpData; - iconData = &data->nicon_data; - - TRACE("NotifyIconCmd received. Code=%d\n", data->notify_code); - switch (data->notify_code) - { - case NIM_ADD: - ret = Toolbar.AddButton(iconData); - if (ret == TRUE) - { - (void)AddIconToWatcher(iconData); - } - break; - case NIM_MODIFY: - ret = Toolbar.UpdateButton(iconData); - break; - case NIM_DELETE: - ret = Toolbar.RemoveButton(iconData); - if (ret == TRUE) - { - (void)RemoveIconFromWatcher(iconData); - } - break; - case NIM_SETFOCUS: - Toolbar.SetFocus(); - ret = TRUE; - case NIM_SETVERSION: - ret = Toolbar.SwitchVersion(iconData); - default: - TRACE("NotifyIconCmd received with unknown code %d.\n", data->notify_code); - return FALSE; - } - - if (VisibleButtonCount != Toolbar.GetVisibleButtonCount()) - { - HWND parentHWND = ::GetParent(GetParent()); - ::SendMessage(parentHWND, WM_SIZE, 0, 0); - } - - return ret; - } - - return TRUE; - } - - void GetSize(IN BOOL IsHorizontal, IN PSIZE size) - { - /* Get the ideal height or width */ -#if 0 - /* Unfortunately this doens't work correctly in ros */ - Toolbar.GetIdealSize(!IsHorizontal, size); - - /* Make the reference dimension an exact multiple of the icon size */ - if (IsHorizontal) - size->cy -= size->cy % GetSystemMetrics(SM_CYSMICON); - else - size->cx -= size->cx % GetSystemMetrics(SM_CXSMICON); - -#else - INT rows = 0; - INT columns = 0; - INT cyButton = GetSystemMetrics(SM_CYSMICON) + 2; - INT cxButton = GetSystemMetrics(SM_CXSMICON) + 2; - int VisibleButtonCount = Toolbar.GetVisibleButtonCount(); - - if (IsHorizontal) - { - rows = max(size->cy / cyButton, 1); - columns = (VisibleButtonCount + rows - 1) / rows; - } - else - { - columns = max(size->cx / cxButton, 1); - rows = (VisibleButtonCount + columns - 1) / columns; - } - size->cx = columns * cxButton; - size->cy = rows * cyButton; -#endif - } - - LRESULT OnGetInfoTip(INT uCode, LPNMHDR hdr, BOOL& bHandled) - { - NMTBGETINFOTIPW * nmtip = (NMTBGETINFOTIPW *) hdr; - Toolbar.GetTooltipText(nmtip->lParam, nmtip->pszText, nmtip->cchTextMax); - return TRUE; - } - - LRESULT OnCustomDraw(INT uCode, LPNMHDR hdr, BOOL& bHandled) - { - NMCUSTOMDRAW * cdraw = (NMCUSTOMDRAW *) hdr; - switch (cdraw->dwDrawStage) - { - case CDDS_PREPAINT: - return CDRF_NOTIFYITEMDRAW; - - case CDDS_ITEMPREPAINT: - return TBCDRF_NOBACKGROUND | TBCDRF_NOEDGES | TBCDRF_NOOFFSET | TBCDRF_NOMARK | TBCDRF_NOETCHEDEFFECT; - } - return TRUE; - } - - LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - LRESULT Ret = TRUE; - SIZE szClient; - szClient.cx = LOWORD(lParam); - szClient.cy = HIWORD(lParam); - - Ret = DefWindowProc(uMsg, wParam, lParam); - - if (Toolbar) - { - Toolbar.SetWindowPos(NULL, 0, 0, szClient.cx, szClient.cy, SWP_NOZORDER); - Toolbar.AutoSize(); - - RECT rc; - Toolbar.GetClientRect(&rc); - - SIZE szBar = { rc.right - rc.left, rc.bottom - rc.top }; - - INT xOff = (szClient.cx - szBar.cx) / 2; - INT yOff = (szClient.cy - szBar.cy) / 2; - - Toolbar.SetWindowPos(NULL, xOff, yOff, szBar.cx, szBar.cy, SWP_NOZORDER); - } - return Ret; - } - - LRESULT OnCtxMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - bHandled = TRUE; - return 0; - } - - LRESULT OnBalloonPop(UINT uCode, LPNMHDR hdr , BOOL& bHandled) - { - m_BalloonQueue.CloseCurrent(); - bHandled = TRUE; - return 0; - } - - LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - if (m_BalloonQueue.OnTimer(wParam)) - { - bHandled = TRUE; - } - - return 0; - } - - void ResizeImagelist() - { - Toolbar.ResizeImagelist(); - } - - DECLARE_WND_CLASS_EX(szSysPagerWndClass, CS_DBLCLKS, COLOR_3DFACE) - - BEGIN_MSG_MAP(CSysPagerWnd) - MESSAGE_HANDLER(WM_CREATE, OnCreate) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) - MESSAGE_HANDLER(WM_SIZE, OnSize) - MESSAGE_HANDLER(WM_CONTEXTMENU, OnCtxMenu) - MESSAGE_HANDLER(WM_TIMER, OnTimer) - NOTIFY_CODE_HANDLER(TTN_POP, OnBalloonPop) - NOTIFY_CODE_HANDLER(TBN_GETINFOTIPW, OnGetInfoTip) - NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw) - END_MSG_MAP() - - HWND _Init(IN HWND hWndParent, IN BOOL bVisible) - { - DWORD dwStyle; - - /* Create the window. The tray window is going to move it to the correct - position and resize it as needed. */ - dwStyle = WS_CHILD | WS_CLIPSIBLINGS; - if (bVisible) - dwStyle |= WS_VISIBLE; - - Create(hWndParent, 0, NULL, dwStyle); - - if (!m_hWnd) - { - return NULL; - } - - SetWindowTheme(m_hWnd, L"TrayNotify", NULL); - - return m_hWnd; - } -}; - -/* - * TrayClockWnd - */ - -static const WCHAR szTrayClockWndClass[] = L"TrayClockWClass"; - -#define ID_TRAYCLOCK_TIMER 0 -#define ID_TRAYCLOCK_TIMER_INIT 1 - -static const struct -{ - BOOL IsTime; - DWORD dwFormatFlags; - LPCWSTR lpFormat; -} ClockWndFormats [] = { - { TRUE, 0, NULL }, - { FALSE, 0, L"dddd" }, - { FALSE, DATE_SHORTDATE, NULL } -}; - -#define CLOCKWND_FORMAT_COUNT (_ARRAYSIZE(ClockWndFormats)) - -#define TRAY_CLOCK_WND_SPACING_X 0 -#define TRAY_CLOCK_WND_SPACING_Y 0 - -class CTrayClockWnd : - public CComObjectRootEx<CComMultiThreadModelNoCS>, - public CWindowImpl < CTrayClockWnd, CWindow, CControlWinTraits > -{ - HWND hWndNotify; - HFONT hFont; - COLORREF textColor; - RECT rcText; - SYSTEMTIME LocalTime; - - union - { - DWORD dwFlags; - struct - { - DWORD IsTimerEnabled : 1; - DWORD IsInitTimerEnabled : 1; - DWORD LinesMeasured : 1; - DWORD IsHorizontal : 1; - }; - }; - DWORD LineSpacing; - SIZE CurrentSize; - WORD VisibleLines; - SIZE LineSizes[CLOCKWND_FORMAT_COUNT]; - WCHAR szLines[CLOCKWND_FORMAT_COUNT][48]; - -public: - CTrayClockWnd() : - hWndNotify(NULL), - hFont(NULL), - dwFlags(0), - LineSpacing(0), - VisibleLines(0) - { - ZeroMemory(&textColor, sizeof(textColor)); - ZeroMemory(&rcText, sizeof(rcText)); - ZeroMemory(&LocalTime, sizeof(LocalTime)); - ZeroMemory(&CurrentSize, sizeof(CurrentSize)); - ZeroMemory(LineSizes, sizeof(LineSizes)); - ZeroMemory(szLines, sizeof(szLines)); - } - virtual ~CTrayClockWnd() { } - - LRESULT OnThemeChanged() - { - LOGFONTW clockFont; - HTHEME clockTheme; - HFONT hFont; - - clockTheme = OpenThemeData(m_hWnd, L"Clock"); - - if (clockTheme) - { - GetThemeFont(clockTheme, - NULL, - CLP_TIME, - 0, - TMT_FONT, - &clockFont); - - hFont = CreateFontIndirectW(&clockFont); - - GetThemeColor(clockTheme, - CLP_TIME, - 0, - TMT_TEXTCOLOR, - &textColor); - - if (this->hFont != NULL) - DeleteObject(this->hFont); - - SetFont(hFont, FALSE); - } - else - { - /* We don't need to set a font here, our parent will use - * WM_SETFONT to set the right one when themes are not enabled. */ - textColor = RGB(0, 0, 0); - } - - CloseThemeData(clockTheme); - - return TRUE; - } - - LRESULT OnThemeChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - return OnThemeChanged(); - } - - BOOL MeasureLines() - { - HDC hDC; - HFONT hPrevFont; - UINT c, i; - BOOL bRet = TRUE; - - hDC = GetDC(); - if (hDC != NULL) - { - if (hFont) - hPrevFont = (HFONT) SelectObject(hDC, hFont); - - for (i = 0; i < CLOCKWND_FORMAT_COUNT && bRet; i++) - { - if (szLines[i][0] != L'\0' && - !GetTextExtentPointW(hDC, szLines[i], wcslen(szLines[i]), - &LineSizes[i])) - { - bRet = FALSE; - break; - } - } - - if (hFont) - SelectObject(hDC, hPrevFont); - - ReleaseDC(hDC); - - if (bRet) - { - LineSpacing = 0; - - /* calculate the line spacing */ - for (i = 0, c = 0; i < CLOCKWND_FORMAT_COUNT; i++) - { - if (LineSizes[i].cx > 0) - { - LineSpacing += LineSizes[i].cy; - c++; - } - } - - if (c > 0) - { - /* We want a spacing of 1/2 line */ - LineSpacing = (LineSpacing / c) / 2; - } - - return TRUE; - } - } - - return FALSE; - } - - WORD GetMinimumSize(IN BOOL Horizontal, IN OUT PSIZE pSize) - { - WORD iLinesVisible = 0; - UINT i; - SIZE szMax = { 0, 0 }; - - if (!LinesMeasured) - LinesMeasured = MeasureLines(); - - if (!LinesMeasured) - return 0; - - for (i = 0; i < CLOCKWND_FORMAT_COUNT; i++) - { - if (LineSizes[i].cx != 0) - { - if (iLinesVisible > 0) - { - if (Horizontal) - { - if (szMax.cy + LineSizes[i].cy + (LONG) LineSpacing > - pSize->cy - (2 * TRAY_CLOCK_WND_SPACING_Y)) - { - break; - } - } - else - { - if (LineSizes[i].cx > pSize->cx - (2 * TRAY_CLOCK_WND_SPACING_X)) - break; - } - - /* Add line spacing */ - szMax.cy += LineSpacing; - } - - iLinesVisible++; - - /* Increase maximum rectangle */ - szMax.cy += LineSizes[i].cy; - if (LineSizes[i].cx > szMax.cx - (2 * TRAY_CLOCK_WND_SPACING_X)) - szMax.cx = LineSizes[i].cx + (2 * TRAY_CLOCK_WND_SPACING_X); - } - } - - szMax.cx += 2 * TRAY_CLOCK_WND_SPACING_X; - szMax.cy += 2 * TRAY_CLOCK_WND_SPACING_Y; - - *pSize = szMax; - - return iLinesVisible; - } - - - VOID UpdateWnd() - { - SIZE szPrevCurrent; - UINT BufSize, i; - INT iRet; - RECT rcClient; - - ZeroMemory(LineSizes, sizeof(LineSizes)); - - szPrevCurrent = CurrentSize; - - for (i = 0; i < CLOCKWND_FORMAT_COUNT; i++) - { - szLines[i][0] = L'\0'; - BufSize = _countof(szLines[0]); - - if (ClockWndFormats[i].IsTime) - { - iRet = GetTimeFormat(LOCALE_USER_DEFAULT, - g_TaskbarSettings.bShowSeconds ? ClockWndFormats[i].dwFormatFlags : TIME_NOSECONDS, - &LocalTime, - ClockWndFormats[i].lpFormat, - szLines[i], - BufSize); - } - else - { - iRet = GetDateFormat(LOCALE_USER_DEFAULT, - ClockWndFormats[i].dwFormatFlags, - &LocalTime, - ClockWndFormats[i].lpFormat, - szLines[i], - BufSize); - } - - if (iRet != 0 && i == 0) - { - /* Set the window text to the time only */ - SetWindowText(szLines[i]); - } - } - - LinesMeasured = MeasureLines(); - - if (LinesMeasured && - GetClientRect(&rcClient)) - { - SIZE szWnd; - - szWnd.cx = rcClient.right; - szWnd.cy = rcClient.bottom; - - VisibleLines = GetMinimumSize(IsHorizontal, &szWnd); - CurrentSize = szWnd; - } - - if (IsWindowVisible()) - { - InvalidateRect(NULL, TRUE); - - if (hWndNotify != NULL && - (szPrevCurrent.cx != CurrentSize.cx || - szPrevCurrent.cy != CurrentSize.cy)) - { - NMHDR nmh; - - nmh.hwndFrom = m_hWnd; - nmh.idFrom = GetWindowLongPtr(GWLP_ID); - nmh.code = NTNWM_REALIGN; - - SendMessage(hWndNotify, - WM_NOTIFY, - (WPARAM) nmh.idFrom, - (LPARAM) &nmh); - } - } - } - - VOID Update() - { - GetLocalTime(&LocalTime); - UpdateWnd(); - } - - UINT CalculateDueTime() - { - UINT uiDueTime; - - /* Calculate the due time */ - GetLocalTime(&LocalTime); - uiDueTime = 1000 - (UINT) LocalTime.wMilliseconds; - if (g_TaskbarSettings.bShowSeconds) - uiDueTime += (UINT) LocalTime.wSecond * 100; - else - uiDueTime += (59 - (UINT) LocalTime.wSecond) * 1000; - - if (uiDueTime < USER_TIMER_MINIMUM || uiDueTime > USER_TIMER_MAXIMUM) - uiDueTime = 1000; - else - { - /* Add an artificial delay of 0.05 seconds to make sure the timer - doesn't fire too early*/ - uiDueTime += 50; - } - - return uiDueTime; - } - - BOOL ResetTime() - { - UINT uiDueTime; - BOOL Ret; - - /* Disable all timers */ - if (IsTimerEnabled) - { - KillTimer(ID_TRAYCLOCK_TIMER); - IsTimerEnabled = FALSE; - } - - if (IsInitTimerEnabled) - { - KillTimer(ID_TRAYCLOCK_TIMER_INIT); - } - - uiDueTime = CalculateDueTime(); - - /* Set the new timer */ - Ret = SetTimer(ID_TRAYCLOCK_TIMER_INIT, uiDueTime, NULL) != 0; - IsInitTimerEnabled = Ret; - - /* Update the time */ - Update(); - - return Ret; - } - - VOID CalibrateTimer() - { - UINT uiDueTime; - BOOL Ret; - UINT uiWait1, uiWait2; - - /* Kill the initialization timer */ - KillTimer(ID_TRAYCLOCK_TIMER_INIT); - IsInitTimerEnabled = FALSE; - - uiDueTime = CalculateDueTime(); - - if (g_TaskbarSettings.bShowSeconds) - { - uiWait1 = 1000 - 200; - uiWait2 = 1000; - } - else - { - uiWait1 = 60 * 1000 - 200; - uiWait2 = 60 * 1000; - } - - if (uiDueTime > uiWait1) - { - /* The update of the clock will be up to 200 ms late, but that's - acceptable. We're going to setup a timer that fires depending - uiWait2. */ - Ret = SetTimer(ID_TRAYCLOCK_TIMER, uiWait2, NULL) != 0; - IsTimerEnabled = Ret; - - /* Update the time */ - Update(); - } - else - { - /* Recalibrate the timer and recalculate again when the current - minute/second ends. */ - ResetTime(); - } - } - - LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - /* Disable all timers */ - if (IsTimerEnabled) - { - KillTimer(ID_TRAYCLOCK_TIMER); - } - - if (IsInitTimerEnabled) - { - KillTimer(ID_TRAYCLOCK_TIMER_INIT); - } - - return TRUE; - } - - LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - RECT rcClient; - HFONT hPrevFont; - INT iPrevBkMode; - UINT i, line; - - PAINTSTRUCT ps; - HDC hDC = (HDC) wParam; - - if (wParam == 0) - { - hDC = BeginPaint(&ps); - } - - if (hDC == NULL) - return FALSE; - - if (LinesMeasured && - GetClientRect(&rcClient)) - { - iPrevBkMode = SetBkMode(hDC, TRANSPARENT); - - SetTextColor(hDC, textColor); - - hPrevFont = (HFONT) SelectObject(hDC, hFont); - - rcClient.left = (rcClient.right / 2) - (CurrentSize.cx / 2); - rcClient.top = (rcClient.bottom / 2) - (CurrentSize.cy / 2); - rcClient.right = rcClient.left + CurrentSize.cx; - rcClient.bottom = rcClient.top + CurrentSize.cy; - - for (i = 0, line = 0; - i < CLOCKWND_FORMAT_COUNT && line < VisibleLines; - i++) - { - if (LineSizes[i].cx != 0) - { - TextOut(hDC, - rcClient.left + (CurrentSize.cx / 2) - (LineSizes[i].cx / 2) + - TRAY_CLOCK_WND_SPACING_X, - rcClient.top + TRAY_CLOCK_WND_SPACING_Y, - szLines[i], - wcslen(szLines[i])); - - rcClient.top += LineSizes[i].cy + LineSpacing; - line++; - } - } - - SelectObject(hDC, hPrevFont); - - SetBkMode(hDC, iPrevBkMode); - } - - if (wParam == 0) - { - EndPaint(&ps); - } - - return TRUE; - } - - VOID SetFont(IN HFONT hNewFont, IN BOOL bRedraw) - { - hFont = hNewFont; - LinesMeasured = MeasureLines(); - if (bRedraw) - { - InvalidateRect(NULL, TRUE); - } - } - - LRESULT DrawBackground(HDC hdc) - { - RECT rect; - - GetClientRect(&rect); - DrawThemeParentBackground(m_hWnd, hdc, &rect); - - return TRUE; - } - - LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - HDC hdc = (HDC) wParam; - - if (!IsAppThemed()) - { - bHandled = FALSE; - return 0; - } - - return DrawBackground(hdc); - } - - LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - switch (wParam) - { - case ID_TRAYCLOCK_TIMER: - Update(); - break; - - case ID_TRAYCLOCK_TIMER_INIT: - CalibrateTimer(); - break; - } - return TRUE; - } - - LRESULT OnGetMinimumSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - IsHorizontal = (BOOL) wParam; - - return (LRESULT) GetMinimumSize((BOOL) wParam, (PSIZE) lParam) != 0; - } - - LRESULT OnUpdateTime(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - return (LRESULT) ResetTime(); - } - - LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - return HTTRANSPARENT; - } - - LRESULT OnSetFont(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - SetFont((HFONT) wParam, (BOOL) LOWORD(lParam)); - return TRUE; - } - - LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - ResetTime(); - return TRUE; - } - - LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - SIZE szClient; - - szClient.cx = LOWORD(lParam); - szClient.cy = HIWORD(lParam); - - VisibleLines = GetMinimumSize(IsHorizontal, &szClient); - CurrentSize = szClient; - - InvalidateRect(NULL, TRUE); - return TRUE; - } - - DECLARE_WND_CLASS_EX(szTrayClockWndClass, CS_DBLCLKS, COLOR_3DFACE) - - BEGIN_MSG_MAP(CTrayClockWnd) - MESSAGE_HANDLER(WM_CREATE, OnCreate) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) - MESSAGE_HANDLER(WM_SIZE, OnSize) - MESSAGE_HANDLER(WM_PAINT, OnPaint) - MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) - MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged) - MESSAGE_HANDLER(WM_TIMER, OnTimer) - MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest) - MESSAGE_HANDLER(WM_SETFONT, OnSetFont) - MESSAGE_HANDLER(TCWM_GETMINIMUMSIZE, OnGetMinimumSize) - MESSAGE_HANDLER(TCWM_UPDATETIME, OnUpdateTime) - - END_MSG_MAP() - - HWND _Init(IN HWND hWndParent, IN BOOL bVisible) - { - IsHorizontal = TRUE; - - hWndNotify = hWndParent; - - /* Create the window. The tray window is going to move it to the correct - position and resize it as needed. */ - DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS; - if (bVisible) - dwStyle |= WS_VISIBLE; - - Create(hWndParent, 0, NULL, dwStyle); - - if (m_hWnd != NULL) - SetWindowTheme(m_hWnd, L"TrayNotify", NULL); - - return m_hWnd; - - } -}; - /* * TrayNotifyWnd */
6 years, 11 months
1
0
0
0
← Newer
1
...
7
8
9
10
11
12
13
...
38
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Results per page:
10
25
50
100
200