Skip to content

Commit

Permalink
Fix Windows 7 button missing glyphs
Browse files Browse the repository at this point in the history
  • Loading branch information
fdwr committed Dec 25, 2022
1 parent 96479f9 commit 1dcfa3e
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 35 deletions.
6 changes: 3 additions & 3 deletions resource/MainWindow.manifest
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
<!--This Id value indicates the application supports Windows 8/Server 2012 functionality-->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- This Id value indicates the application supports Windows 8.1 Blue/Server 2012 R2 functionality-->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- This Id value indicates the application supports Windows Threshold functionality-->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- This Id value indicates the application supports Windows 10 (Threshold) functionality-->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
Expand Down
Binary file modified resource/MainWindow.rc
Binary file not shown.
54 changes: 35 additions & 19 deletions source/Common.AutoResource.Windows.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
//----------------------------------------------------------------------------
//
// 2015-12-16 dwayner Split Windows specific stuff from AutoResource.h
//
//----------------------------------------------------------------------------
#pragma once

template <
typename ResourceType, // underlying type of the resource held onto (e.g. HGDIOBJ instead of HFONT)
typename ResourceReleaserSignature, // function prototype of the releasing function
ResourceReleaserSignature ResourceReleaser // address of function to release object
>
struct HandleResourceTypePolicy : public DefaultResourceTypePolicy<ResourceType>
struct AutoResourceHandlePolicy : public AutoResourceDefaultPolicy<ResourceType>
{
inline static void Release(ResourceType resource) noexcept
{
Expand All @@ -19,7 +24,6 @@ struct HandleResourceTypePolicy : public DefaultResourceTypePolicy<ResourceType>
static const bool AllowsMultipleReferences = false;
};


// Releasing function for WaitHandleResource to pass to use with HandleResourceTypePolicy.
inline void WaitHandleUnregister(HANDLE handle) noexcept
{
Expand All @@ -29,28 +33,40 @@ inline void WaitHandleUnregister(HANDLE handle) noexcept
}
}

using GdiDeviceContext = AutoResource<HDC, AutoResourceHandlePolicy<HDC, BOOL (WINAPI*)(HDC), &DeleteDC>, HDC>;
using GdiPenHandle = AutoResource<HPEN, AutoResourceHandlePolicy<HGDIOBJ, BOOL (WINAPI*)(HGDIOBJ), &DeleteObject>, HGDIOBJ>;
using GdiFontHandle = AutoResource<HFONT, AutoResourceHandlePolicy<HGDIOBJ, BOOL (WINAPI*)(HGDIOBJ), &DeleteObject>, HGDIOBJ>;
using GdiBitmapHandle = AutoResource<HBITMAP, AutoResourceHandlePolicy<HGDIOBJ, BOOL (WINAPI*)(HGDIOBJ), &DeleteObject>, HGDIOBJ>;
using GdiRegionHandle = AutoResource<HRGN, AutoResourceHandlePolicy<HGDIOBJ, BOOL (WINAPI*)(HGDIOBJ), &DeleteObject>, HGDIOBJ>;
using GlobalMemoryResource = AutoResource<HGLOBAL, AutoResourceHandlePolicy<HGLOBAL, HGLOBAL (WINAPI*)(HGLOBAL), &GlobalFree>, HGLOBAL>;
using LocalMemoryResource = AutoResource<HLOCAL, AutoResourceHandlePolicy<HLOCAL, HLOCAL (WINAPI*)(HLOCAL), &LocalFree>, HLOCAL>;
using FileHandle = AutoResource<HANDLE, AutoResourceHandlePolicy<HANDLE, BOOL (WINAPI*)(HANDLE), &CloseHandle>, HANDLE>;
using CstdioFileHandle = AutoResource<FILE*, AutoResourceHandlePolicy<FILE*, int (__cdecl *)(FILE*), &fclose>, FILE*>;
using ScopedMemory = AutoResource<FILE*, AutoResourceHandlePolicy<void*, void (__cdecl *)(void*), &free>, FILE*>;
using ModuleHandle = AutoResource<HMODULE, AutoResourceHandlePolicy<HMODULE, BOOL (WINAPI*)(HMODULE), &FreeLibrary>, HMODULE>;
using WindowHandle = AutoResource<HWND, AutoResourceHandlePolicy<HWND, BOOL (WINAPI*)(HWND), &DestroyWindow>, HWND>;
using MemoryViewResource = AutoResource<void*, AutoResourceHandlePolicy<void*, BOOL (WINAPI*)(void const*), &UnmapViewOfFile>, void*>;
using MemorySectionResource = AutoResource<HANDLE, AutoResourceHandlePolicy<HANDLE, BOOL (WINAPI*)(HANDLE), &CloseHandle>, HANDLE>;

using GdiDeviceContext = AutoResource<HDC, HandleResourceTypePolicy<HDC, BOOL(WINAPI*)(HDC), &DeleteDC> >;
using GdiPenHandle = AutoResource<HPEN, HandleResourceTypePolicy<HGDIOBJ, BOOL(WINAPI*)(HGDIOBJ), &DeleteObject>, HGDIOBJ>;
using GdiFontHandle = AutoResource<HFONT, HandleResourceTypePolicy<HGDIOBJ, BOOL(WINAPI*)(HGDIOBJ), &DeleteObject>, HGDIOBJ>;
using GdiBitmapHandle = AutoResource<HBITMAP, HandleResourceTypePolicy<HGDIOBJ, BOOL(WINAPI*)(HGDIOBJ), &DeleteObject>, HGDIOBJ>;
using GdiRegionHandle = AutoResource<HRGN, HandleResourceTypePolicy<HGDIOBJ, BOOL(WINAPI*)(HGDIOBJ), &DeleteObject>, HGDIOBJ>;
using GlobalMemoryResource = AutoResource<HGLOBAL, HandleResourceTypePolicy<HGLOBAL, HGLOBAL(WINAPI*)(HGLOBAL), &GlobalFree> >;
using LocalMemoryResource = AutoResource<HLOCAL, HandleResourceTypePolicy<HLOCAL, HLOCAL(WINAPI*)(HLOCAL), &LocalFree> >;
using FileHandle = AutoResource<HANDLE, HandleResourceTypePolicy<HANDLE, BOOL(WINAPI*)(HANDLE), &CloseHandle> >;
using CstdioFileHandle = AutoResource<FILE*, HandleResourceTypePolicy<FILE*, int(__cdecl *)(FILE*), &fclose> >;
using ScopedMemory = AutoResource<void*, HandleResourceTypePolicy<void*, void(__cdecl *)(void*), &free> >;
using ModuleHandle = AutoResource<HMODULE, HandleResourceTypePolicy<HMODULE, BOOL(WINAPI*)(HMODULE), &FreeLibrary> >;
using WindowHandle = AutoResource<HWND, HandleResourceTypePolicy<HWND, BOOL(WINAPI*)(HWND), &DestroyWindow> >;
using MemoryViewResource = AutoResource<void*, HandleResourceTypePolicy<void*, BOOL(WINAPI*)(void const*), &UnmapViewOfFile> >;
using MemorySectionResource = AutoResource<HANDLE, HandleResourceTypePolicy<HANDLE, BOOL(WINAPI*)(HANDLE), &CloseHandle> >;
using WaitHandleResource = AutoResource<HANDLE, HandleResourceTypePolicy<HANDLE, void(*)(HANDLE), &WaitHandleUnregister>>;

using GdiDeviceContext = AutoResource<HDC, AutoResourceHandlePolicy<HDC, BOOL (WINAPI*)(HDC), &DeleteDC>, HDC>;
using GdiPenHandle = AutoResource<HPEN, AutoResourceHandlePolicy<HGDIOBJ, BOOL (WINAPI*)(HGDIOBJ), &DeleteObject>, HGDIOBJ>;
using GdiFontHandle = AutoResource<HFONT, AutoResourceHandlePolicy<HGDIOBJ, BOOL (WINAPI*)(HGDIOBJ), &DeleteObject>, HGDIOBJ>;
using GdiBitmapHandle = AutoResource<HBITMAP, AutoResourceHandlePolicy<HGDIOBJ, BOOL (WINAPI*)(HGDIOBJ), &DeleteObject>, HGDIOBJ>;
using GdiRegionHandle = AutoResource<HRGN, AutoResourceHandlePolicy<HGDIOBJ, BOOL (WINAPI*)(HGDIOBJ), &DeleteObject>, HGDIOBJ>;
using GlobalMemoryResource = AutoResource<HGLOBAL, AutoResourceHandlePolicy<HGLOBAL, HGLOBAL (WINAPI*)(HGLOBAL), &GlobalFree>, HGLOBAL>;
using LocalMemoryResource = AutoResource<HLOCAL, AutoResourceHandlePolicy<HLOCAL, HLOCAL (WINAPI*)(HLOCAL), &LocalFree>, HLOCAL>;
using FileHandle = AutoResource<HANDLE, AutoResourceHandlePolicy<HANDLE, BOOL (WINAPI*)(HANDLE), &CloseHandle>, HANDLE>;
using CstdioFileHandle = AutoResource<FILE*, AutoResourceHandlePolicy<FILE*, int (__cdecl *)(FILE*), &fclose>, FILE*>;
using ScopedMemory = AutoResource<FILE*, AutoResourceHandlePolicy<void*, void (__cdecl *)(void*), &free>, FILE*>;
using ModuleHandle = AutoResource<HMODULE, AutoResourceHandlePolicy<HMODULE, BOOL (WINAPI*)(HMODULE), &FreeLibrary>, HMODULE>;
using WindowHandle = AutoResource<HWND, AutoResourceHandlePolicy<HWND, BOOL (WINAPI*)(HWND), &DestroyWindow>, HWND>;
using MemoryViewResource = AutoResource<void*, AutoResourceHandlePolicy<void*, BOOL (WINAPI*)(void const*), &UnmapViewOfFile>, void*>;
using MemorySectionResource = AutoResource<HANDLE, AutoResourceHandlePolicy<HANDLE, BOOL (WINAPI*)(HANDLE), &CloseHandle>, HANDLE>;

////////////////////////////////////////
// Basic COM pointer.

struct ComResourceTypePolicy : public DefaultResourceTypePolicy<IUnknown*>
struct ComResourceTypePolicy : public AutoResourceDefaultPolicy<IUnknown*>
{
inline static void Acquire(_Inout_opt_ IUnknown* resource) noexcept
{
Expand Down
31 changes: 19 additions & 12 deletions source/Common.AutoResource.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
//+---------------------------------------------------------------------------
// Automatic resource management helper class.
//
// History: 2007-07-30 Dwayne Robinson - Created
// 2014-10-06 Dwayne Robinson - Changed to template typedefs
// History: 2007-07-30 Dwayne Robinson - created
// 2009-12-16 Dwayne Robinson - Updated to support __cdecl too (fclose)
// 2010-07-08 Dwayne Robinson - Updated to handle ref counting policies
// 2014-10-06 Dwayne Robinson - changed to template typedefs
//
//----------------------------------------------------------------------------
#pragma once

Expand All @@ -17,9 +20,9 @@
// a reference to it, or zero-initialized. The resource type itself should generally be a simple
// trivially copyable thing such as a pointer or handle type.
template <typename ResourceType = void*> // type of the resource held onto
struct DefaultResourceTypePolicy
struct AutoResourceDefaultPolicy
{
inline static void InitializeEmpty(_Out_ ResourceType* resource) noexcept
inline static void InitializeEmpty(/*out*/ ResourceType* resource) noexcept
{
// Most resources (pointers to memory, HGLOBALS, HGDIOBJ...)
// are indicated as empty by setting to 0/NULL. If a resource
Expand Down Expand Up @@ -63,7 +66,7 @@ struct DefaultResourceTypePolicy
// depending on the policy implementation).
template <
typename ResourceType = void*, // type of the resource held onto
typename ResourceTypePolicy = DefaultResourceTypePolicy<ResourceType>,
typename ResourceTypePolicy = AutoResourceDefaultPolicy<ResourceType>,
typename BaseResourceType = ResourceType // type as known by the resource releaser (like HGDIOBJ vs HBITMAP)
>
class AutoResource
Expand All @@ -86,9 +89,11 @@ class AutoResource
ResourceTypePolicy::Acquire(resource_);
}

AutoResource(Self&& other)
AutoResource(Self&& /*moveable*/ other)
: resource_(other.resource_)
{
resource_ = other.resource_;
// Just reset the other resource without changing the initialization
// state or reference count.
ResourceTypePolicy::InitializeEmpty(Cast(&other.resource_));
}

Expand Down Expand Up @@ -206,7 +211,7 @@ class AutoResource
return *this;
}

inline Self& operator=(const Self& other)
inline Self& operator=(Self const& other)
{
static_assert(ResourceTypePolicy::AllowsMultipleReferences, "This function is only useable on resource types that allow multiple strong references.");
Set(other.resource_);
Expand Down Expand Up @@ -300,7 +305,7 @@ class AutoResource
Set(resource);
}

// there is no 'release' alias, since the C++ auto_ptr does something
// There is no release() function, since the C++ auto_ptr does something
// different than typically expected (detaches rather than frees).

protected:
Expand All @@ -320,7 +325,9 @@ class AutoResource
return reinterpret_cast<BaseResourceType*>(resource);
}

ResourceType resource_; // could be void*, HANDLE, FILE*, GDIOBJ...
// Specific resource type, such as void*, HANDLE, FILE*, GDIOBJ...
// It is expected to be a simple data type with no copy constructors.
ResourceType resource_;
};


Expand Down Expand Up @@ -350,7 +357,7 @@ namespace std
static_assert(sizeof(int*) == sizeof(void*), "Expect all pointers have same size, such as void* and resourceType*");

template <typename ResourceType>
struct UnownedMemoryPointerPolicy : public DefaultResourceTypePolicy<ResourceType>
struct UnownedMemoryPointerPolicy : public AutoResourceDefaultPolicy<ResourceType>
{
// Allow multiple references because the non-owning AutoResource does not strongly hold it anyway.
static const bool AllowsMultipleReferences = true;
Expand All @@ -367,7 +374,7 @@ using UnownedMemoryPointer = AutoResource<ResourceType*, UnownedMemoryPointerPol
// Steal'ing from another, or by Detach/Attach.

template <typename ResourceType>
struct OwnedMemoryPointerPolicy : public DefaultResourceTypePolicy<ResourceType>
struct OwnedMemoryPointerPolicy : public AutoResourceDefaultPolicy<ResourceType>
{
inline static void Release(ResourceType resource) noexcept
{
Expand Down
2 changes: 1 addition & 1 deletion source/DrawingCanvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ inline float Lerp(float first, float last, float fraction)

////////////////////

using GdiPlusStartupAutoResource = AutoResource<ULONG_PTR, HandleResourceTypePolicy<ULONG_PTR, void (WINAPI*)(ULONG_PTR), &Gdiplus::GdiplusShutdown>, ULONG_PTR>;
using GdiPlusStartupAutoResource = AutoResource<ULONG_PTR, AutoResourceHandlePolicy<ULONG_PTR, void (WINAPI*)(ULONG_PTR), &Gdiplus::GdiplusShutdown>, ULONG_PTR>;


class __declspec(uuid("74868E11-F1CF-461A-AEAF-175216DFF0BA")) DrawingCanvas : public ComObject
Expand Down
32 changes: 32 additions & 0 deletions source/MainWindow.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,38 @@ INT_PTR MainWindow::InitializeMainDialog()
}
SetFocus(GetWindowFromId(hwnd_, controlIdToSetFocusTo));

// For Windows 7, set toolbar button labels to older font characters before Segoe UI Symbol.
DWORD majorWindowsVersion = LOBYTE(LOWORD(GetVersion()));
// GetVersion() is deprecated because it was badly designed and error-prone, but then they messed up and replaced
// a *slightly* error-prone function with a *much more* complicated function like VerifyVersionInfo, where far more
// can go wrong. Yeah, forget you, whoever poorly designed the versioning API's. We're sticking with the simpler
// one here.
if (majorWindowsVersion <= 7)
{
struct ControlIdAndText
{
int id;
wchar_t const* text;
};
ControlIdAndText idsAndText[] =
{
{IdcDrawableObjectListLoad, L"Load"},
{IdcDrawableObjectListStore, L"Save"},
{IdcDrawableObjectCreate, L"+"},
{IdcDrawableObjectDelete, L"-"},
{IdcDrawableObjectCreatePermutations, L"Pm"},
{IdcSelectFontFile, L"File"},
// Already okay:
// IdcDrawableObjectMoveUp
// IdcDrawableObjectMoveDown
// IdcSelectFontFamily
};
for (auto& idAndText : idsAndText)
{
SetWindowText(GetWindowFromId(hwnd_, idAndText.id), idAndText.text);
}
}

#if 0 // hack for debugging animating objects.
SetTimer(hwnd_, IdcUpdateUi + 1, 10, nullptr);
#endif
Expand Down
2 changes: 2 additions & 0 deletions source/precomp.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
#define NOIME
#endif

#define BUILD_WINDOWS

#define _ENABLE_EXTENDED_ALIGNED_STORAGE // For the SseSizedType case, which is > max_align_t.
#define _SCL_SECURE_NO_WARNINGS // I hate doing this, but Visual Studio offers no substitute for std::uninitialized_copy.

Expand Down

0 comments on commit 1dcfa3e

Please sign in to comment.