diff --git a/src/fs/DirectoryReader.hxx b/src/fs/DirectoryReader.hxx
index abf63957e..3ee1fd876 100644
--- a/src/fs/DirectoryReader.hxx
+++ b/src/fs/DirectoryReader.hxx
@@ -24,7 +24,7 @@
 
 #ifdef _WIN32
 
-#include <windows.h>
+#include <fileapi.h>
 #include <tchar.h>
 
 /**
diff --git a/src/fs/io/FileOutputStream.hxx b/src/fs/io/FileOutputStream.hxx
index d377f08ea..10c614831 100644
--- a/src/fs/io/FileOutputStream.hxx
+++ b/src/fs/io/FileOutputStream.hxx
@@ -42,7 +42,10 @@
 #include <cstdint>
 
 #ifdef _WIN32
-#include <windows.h>
+#include <fileapi.h>
+#include <windef.h> // for HWND (needed by winbase.h)
+#include <handleapi.h> // for INVALID_HANDLE_VALUE
+#include <winbase.h> // for FILE_END
 #endif
 
 #if defined(__linux__) && !defined(ANDROID)
diff --git a/src/fs/io/FileReader.hxx b/src/fs/io/FileReader.hxx
index bee39cc9a..5be332b72 100644
--- a/src/fs/io/FileReader.hxx
+++ b/src/fs/io/FileReader.hxx
@@ -35,7 +35,10 @@
 #include "util/Compiler.h"
 
 #ifdef _WIN32
-#include <windows.h>
+#include <fileapi.h>
+#include <handleapi.h> // for INVALID_HANDLE_VALUE
+#include <windef.h> // for HWND (needed by winbase.h)
+#include <winbase.h> // for FILE_CURRENT
 #else
 #include "io/UniqueFileDescriptor.hxx"
 #endif
diff --git a/src/output/plugins/WinmmOutputPlugin.cxx b/src/output/plugins/WinmmOutputPlugin.cxx
index 1f4f180d8..66b3dc3b5 100644
--- a/src/output/plugins/WinmmOutputPlugin.cxx
+++ b/src/output/plugins/WinmmOutputPlugin.cxx
@@ -28,6 +28,10 @@
 #include <array>
 #include <iterator>
 
+#include <handleapi.h>
+#include <synchapi.h>
+#include <winbase.h> // for INFINITE
+
 #include <stdlib.h>
 #include <string.h>
 
diff --git a/src/output/plugins/WinmmOutputPlugin.hxx b/src/output/plugins/WinmmOutputPlugin.hxx
index e5d249f38..5e29121b8 100644
--- a/src/output/plugins/WinmmOutputPlugin.hxx
+++ b/src/output/plugins/WinmmOutputPlugin.hxx
@@ -26,7 +26,7 @@
 
 #include "util/Compiler.h"
 
-#include <windows.h>
+#include <windef.h>
 #include <mmsystem.h>
 
 struct WinmmOutput;
diff --git a/src/system/Error.hxx b/src/system/Error.hxx
index ea2f31d69..e539306fd 100644
--- a/src/system/Error.hxx
+++ b/src/system/Error.hxx
@@ -49,7 +49,9 @@ FormatSystemError(std::error_code code, const char *fmt,
 
 #ifdef _WIN32
 
-#include <windows.h>
+#include <errhandlingapi.h> // for GetLastError()
+#include <windef.h> // for HWND (needed by winbase.h)
+#include <winbase.h> // for FormatMessageA()
 
 static inline std::system_error
 MakeLastError(DWORD code, const char *msg) noexcept
diff --git a/src/system/FatalError.cxx b/src/system/FatalError.cxx
index e892c5472..c8473bb69 100644
--- a/src/system/FatalError.cxx
+++ b/src/system/FatalError.cxx
@@ -27,7 +27,9 @@
 #include <cstring>
 
 #ifdef _WIN32
-#include <windows.h>
+#include <errhandlingapi.h> // for GetLastError()
+#include <windef.h> // for HWND (needed by winbase.h)
+#include <winbase.h> // for FormatMessageA()
 #else
 #include <cerrno>
 #endif
diff --git a/src/thread/CriticalSection.hxx b/src/thread/CriticalSection.hxx
index 3e311738e..4cc140739 100644
--- a/src/thread/CriticalSection.hxx
+++ b/src/thread/CriticalSection.hxx
@@ -30,7 +30,7 @@
 #ifndef THREAD_CRITICAL_SECTION_HXX
 #define THREAD_CRITICAL_SECTION_HXX
 
-#include <windows.h>
+#include <synchapi.h>
 
 /**
  * Wrapper for a CRITICAL_SECTION, backend for the Mutex class.
diff --git a/src/thread/Id.hxx b/src/thread/Id.hxx
index aadb51a50..1cf11abb3 100644
--- a/src/thread/Id.hxx
+++ b/src/thread/Id.hxx
@@ -23,7 +23,7 @@
 #include "util/Compiler.h"
 
 #ifdef _WIN32
-#include <windows.h>
+#include <processthreadsapi.h>
 #else
 #include <pthread.h>
 #endif
diff --git a/src/thread/Thread.hxx b/src/thread/Thread.hxx
index ff9abbdd4..071f9d7bd 100644
--- a/src/thread/Thread.hxx
+++ b/src/thread/Thread.hxx
@@ -26,7 +26,7 @@
 #include <cassert>
 
 #ifdef _WIN32
-#include <windows.h>
+#include <processthreadsapi.h>
 #else
 #include <pthread.h>
 #endif
diff --git a/src/thread/WindowsCond.hxx b/src/thread/WindowsCond.hxx
index 7c0b19a1f..0f49f71d5 100644
--- a/src/thread/WindowsCond.hxx
+++ b/src/thread/WindowsCond.hxx
@@ -32,6 +32,9 @@
 
 #include "CriticalSection.hxx"
 
+#include <windef.h> // for HWND (needed by winbase.h)
+#include <winbase.h> // for INFINITE
+
 #include <chrono>
 #include <mutex>
 
diff --git a/src/util/HugeAllocator.hxx b/src/util/HugeAllocator.hxx
index bb6a12726..786a2a722 100644
--- a/src/util/HugeAllocator.hxx
+++ b/src/util/HugeAllocator.hxx
@@ -77,7 +77,7 @@ void
 HugeDiscard(void *p, size_t size) noexcept;
 
 #elif defined(_WIN32)
-#include <windows.h>
+#include <memoryapi.h>
 
 WritableBuffer<void>
 HugeAllocate(size_t size);
diff --git a/src/win32/Com.hxx b/src/win32/Com.hxx
index 173b0fcc9..a9e58761a 100644
--- a/src/win32/Com.hxx
+++ b/src/win32/Com.hxx
@@ -21,8 +21,8 @@
 #define MPD_WIN32_COM_HXX
 
 #include "HResult.hxx"
-#include <objbase.h>
-#include <windows.h>
+
+#include <combaseapi.h>
 
 // RAII for Microsoft Component Object Model(COM)
 // https://docs.microsoft.com/en-us/windows/win32/api/_com/
diff --git a/src/win32/ComHeapPtr.hxx b/src/win32/ComHeapPtr.hxx
index 737bc6551..08d4401f6 100644
--- a/src/win32/ComHeapPtr.hxx
+++ b/src/win32/ComHeapPtr.hxx
@@ -23,7 +23,8 @@
 #include <cstddef>
 #include <objbase.h>
 #include <utility>
-#include <windows.h>
+
+#include <combaseapi.h>
 
 // RAII for CoTaskMemAlloc and CoTaskMemFree
 // https://docs.microsoft.com/zh-tw/windows/win32/api/combaseapi/nf-combaseapi-cotaskmemalloc
diff --git a/src/win32/ComPtr.hxx b/src/win32/ComPtr.hxx
index c7efa88b8..3c652e2f3 100644
--- a/src/win32/ComPtr.hxx
+++ b/src/win32/ComPtr.hxx
@@ -21,10 +21,12 @@
 #define MPD_WIN32_COMPTR_HXX
 
 #include "win32/HResult.hxx"
+
 #include <cstddef>
 #include <objbase.h>
 #include <utility>
-#include <windows.h>
+
+#include <combaseapi.h>
 
 // RAII for Object in Microsoft Component Object Model(COM)
 // https://docs.microsoft.com/zh-tw/windows/win32/api/_com/
diff --git a/src/win32/ComWorker.hxx b/src/win32/ComWorker.hxx
index d4c410652..4016d9939 100644
--- a/src/win32/ComWorker.hxx
+++ b/src/win32/ComWorker.hxx
@@ -26,8 +26,6 @@
 
 #include <boost/lockfree/spsc_queue.hpp>
 
-#include <windows.h>
-
 // Worker thread for all COM operation
 class COMWorker {
 	Thread thread{BIND_THIS_METHOD(Work)};
diff --git a/src/win32/WinEvent.hxx b/src/win32/WinEvent.hxx
index 7b3305c37..e757fbbae 100644
--- a/src/win32/WinEvent.hxx
+++ b/src/win32/WinEvent.hxx
@@ -20,7 +20,10 @@
 #ifndef MPD_WIN32_WINEVENT_HXX
 #define MPD_WIN32_WINEVENT_HXX
 
-#include <windows.h>
+#include <handleapi.h>
+#include <synchapi.h>
+#include <windef.h> // for HWND (needed by winbase.h)
+#include <winbase.h> // for INFINITE
 
 // RAII for Windows unnamed event object
 // https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createeventw