Win32 分割器控件

发布于 2024-10-30 01:37:36 字数 264 浏览 5 评论 0原文

在 Win32 的所有不同控件中,是否有任何基本的、轻量可用的 Splitter/Splitcontainer 控件(意味着一两个 C/C++ 文件最多)?

我似乎无法在 Visual Studio 中显示的默认控件中找到任何内容,并且我在网上找到的所有内容似乎都是针对 MFC 的,而我在项目中没有使用它...

无分离器??

Of all the different controls that there are for Win32, is there any basic, lightweight Splitter/Splitcontainer control available (meaning one or two C/C++ files max)?

I can't seem to find any in the default controls shown in Visual Studio, and everything I find online seems to be for MFC, which I'm not using in my project...

No splitter??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

请帮我爱他 2024-11-06 01:37:36

不,没有本机 win32 拆分器,您必须使用框架或编写自己的框架。 Codeproject 甚至有自己的分割器类别

如果你自己编写,你基本上有两个选择:

  • 窗口 A 和 B 的父窗口是分割器(分割器边框来自窗口 A 和 B 上的 WS_EX_CLIENTEDGE)
  • A 和 B 由第三个窗口分隔;分离器

No there is no native win32 splitter, you have to use a framework or write your own. Codeproject even has its own splitter category.

If you write your own you basically have two options:

  • The parent of window A and B is the splitter (The splitter border comes from WS_EX_CLIENTEDGE on windows A and B)
  • A and B are separated by a third window; the splitter
夏夜暖风 2024-11-06 01:37:36

Win32 中有一个原生的分割器,
在本例中,它基本上只是将鼠标图标转换为IDC_SIZENS,并跟踪鼠标移动,然后根据鼠标移动调整控件的大小。

请参阅此处:使用 Win32 API 分割窗口

There's a native splitter in Win32,
it's basically just transform mouse icon to IDC_SIZENS in this example, and tracking mouse movement and then resizing the control based on mouse movement.

See here: Split Window using Win32 API

魂ガ小子 2024-11-06 01:37:36

没有原生的 win32 拆分器,我在一个 cpp 文件中使用纯 win32 api 制作了一个。

    // Win32test2.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "Win32test2.h"

LRESULT CALLBACK windowprocessforwindow1(HWND handleforwindow1, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow2, UINT message, WPARAM wParam, LPARAM lParam);

bool window1closed = false;
bool window2closed = false;

//child hwnd 小子窗口,非弹出式子窗口,是CreateWindowEx设置了parent
HWND cHwnd[5]; //0 左窗口 1 右窗口或右上窗口  2 竖分隔符窗口 spiltter 3 右下窗口  4 横分隔符窗口 spiltter
//main hwnd
HWND mHwnd;

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd)
{
    bool endprogram = false;

    //create window 1

    WNDCLASSEX windowclassforwindow1;
    ZeroMemory(&windowclassforwindow1, sizeof(WNDCLASSEX));
    windowclassforwindow1.cbClsExtra = NULL;
    windowclassforwindow1.cbSize = sizeof(WNDCLASSEX);
    windowclassforwindow1.cbWndExtra = NULL;
    windowclassforwindow1.hbrBackground = (HBRUSH)COLOR_WINDOW;
    windowclassforwindow1.hCursor = LoadCursor(NULL, IDC_ARROW);
    windowclassforwindow1.hIcon = NULL;
    windowclassforwindow1.hIconSm = NULL;
    windowclassforwindow1.hInstance = hInst;
    windowclassforwindow1.lpfnWndProc = (WNDPROC)windowprocessforwindow1;
    windowclassforwindow1.lpszClassName = L"windowclass 1";
    windowclassforwindow1.lpszMenuName = NULL;
    windowclassforwindow1.style = CS_HREDRAW | CS_VREDRAW;

    if (!RegisterClassEx(&windowclassforwindow1))
    {
        int nResult = GetLastError();
        MessageBox(NULL,
            L"Window class creation failed",
            L"Window Class Failed",
            MB_ICONERROR);
    }

    HWND handleforwindow1 = CreateWindowEx(NULL,
        windowclassforwindow1.lpszClassName,
        L"Parent Window",
        WS_OVERLAPPEDWINDOW,
        200,
        200,
        640,
        480,
        NULL,
        NULL,
        hInst,
        NULL                /* No Window Creation data */
    );

    if (!handleforwindow1)
    {
        int nResult = GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }

    ShowWindow(handleforwindow1, nShowCmd);
    mHwnd = handleforwindow1;


    // create window 2

    WNDCLASSEX windowclassforwindow2;
    ZeroMemory(&windowclassforwindow2, sizeof(WNDCLASSEX));
    windowclassforwindow2.cbClsExtra = NULL;
    windowclassforwindow2.cbSize = sizeof(WNDCLASSEX);
    windowclassforwindow2.cbWndExtra = NULL;
    windowclassforwindow2.hbrBackground = (HBRUSH)COLOR_WINDOW;
    windowclassforwindow2.hCursor = LoadCursor(NULL, IDC_ARROW);
    windowclassforwindow2.hIcon = NULL;
    windowclassforwindow2.hIconSm = NULL;
    windowclassforwindow2.hInstance = hInst;
    windowclassforwindow2.lpfnWndProc = (WNDPROC)windowprocessforwindow2;
    windowclassforwindow2.lpszClassName = L"window class2";
    windowclassforwindow2.lpszMenuName = NULL;
    windowclassforwindow2.style = CS_HREDRAW | CS_VREDRAW;

    if (!RegisterClassEx(&windowclassforwindow2))
    {
        int nResult = GetLastError();
        MessageBox(NULL,
            L"Window class creation failed for window 2",
            L"Window Class Failed",
            MB_ICONERROR);
    }

    HWND handleforwindow2 = CreateWindowEx(NULL,
        windowclassforwindow2.lpszClassName,
        L"Child Window",
        WS_CHILD 
        ,
        0,
        0,
        195,
        480,
        handleforwindow1,
        NULL,
        hInst,
        NULL);

    if (!handleforwindow2)
    {
        int nResult = GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }

    ShowWindow(handleforwindow2, nShowCmd);
    cHwnd[0] = handleforwindow2;

    // create window 3

    HWND handleforwindow3 = CreateWindowEx(NULL,
        windowclassforwindow2.lpszClassName,
        L"Child Window",
        WS_CHILD 
        ,
        200,
        0,
        440,
        275,
        handleforwindow1,
        NULL,
        hInst,
        NULL);

    if (!handleforwindow3)
    {
        int nResult = GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }

    ShowWindow(handleforwindow3, nShowCmd);
    cHwnd[1] = handleforwindow3;

    // create window 4 spiltter

    WNDCLASSEX windowclassforwindow4;
    ZeroMemory(&windowclassforwindow4, sizeof(WNDCLASSEX));
    windowclassforwindow4.cbClsExtra = NULL;
    windowclassforwindow4.cbSize = sizeof(WNDCLASSEX);
    windowclassforwindow4.cbWndExtra = NULL;
    windowclassforwindow4.hbrBackground = (HBRUSH)COLOR_WINDOW;
    windowclassforwindow4.hCursor = LoadCursor(NULL, IDC_SIZEWE);
    windowclassforwindow4.hIcon = NULL;
    windowclassforwindow4.hIconSm = NULL;
    windowclassforwindow4.hInstance = hInst;
    windowclassforwindow4.lpfnWndProc = (WNDPROC)windowprocessforwindow2;
    windowclassforwindow4.lpszClassName = L"window class4";
    windowclassforwindow4.lpszMenuName = NULL;
    windowclassforwindow4.style = CS_HREDRAW | CS_VREDRAW;

    if (!RegisterClassEx(&windowclassforwindow4))
    {
        int nResult = GetLastError();
        MessageBox(NULL,
            L"Window class creation failed for window 2",
            L"Window Class Failed",
            MB_ICONERROR);
    }

    HWND handleforwindow4 = CreateWindowEx(NULL,
        windowclassforwindow4.lpszClassName,
        L"Child Window",
        WS_CHILD \
        | WS_BORDER
        ,
        195,
        0,
        5,
        480,
        handleforwindow1,
        NULL,
        hInst,
        NULL);

    if (!handleforwindow4)
    {
        int nResult = GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }

    ShowWindow(handleforwindow4, nShowCmd);
    cHwnd[2] = handleforwindow4;

    // create window 5 有窗口下面窗口

    HWND handleforwindow5 = CreateWindowEx(NULL,
        windowclassforwindow2.lpszClassName,
        L"Child Window",
        WS_CHILD
        ,
        200,
        280,
        440,
        200,
        handleforwindow1,
        NULL,
        hInst,
        NULL);

    if (!handleforwindow5)
    {
        int nResult = GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }
    ShowWindow(handleforwindow5, nShowCmd);
    cHwnd[3] = handleforwindow5;

    // create window 6 spiltter 右窗口spiltter

    WNDCLASSEX windowclassforwindow6;
    ZeroMemory(&windowclassforwindow6, sizeof(WNDCLASSEX));
    windowclassforwindow6.cbClsExtra = NULL;
    windowclassforwindow6.cbSize = sizeof(WNDCLASSEX);
    windowclassforwindow6.cbWndExtra = NULL;
    windowclassforwindow6.hbrBackground = (HBRUSH)COLOR_WINDOW;
    windowclassforwindow6.hCursor = LoadCursor(NULL, IDC_SIZENS);
    windowclassforwindow6.hIcon = NULL;
    windowclassforwindow6.hIconSm = NULL;
    windowclassforwindow6.hInstance = hInst;
    windowclassforwindow6.lpfnWndProc = (WNDPROC)windowprocessforwindow2;
    windowclassforwindow6.lpszClassName = L"window class6";
    windowclassforwindow6.lpszMenuName = NULL;
    windowclassforwindow6.style = CS_HREDRAW | CS_VREDRAW;

    if (!RegisterClassEx(&windowclassforwindow6))
    {
        int nResult = GetLastError();
        MessageBox(NULL,
            L"Window class creation failed for window 2",
            L"Window Class Failed",
            MB_ICONERROR);
    }

    HWND handleforwindow6 = CreateWindowEx(NULL,
        windowclassforwindow6.lpszClassName,
        L"Child Window",
        WS_CHILD \
        | WS_BORDER
        ,
        200,
        275,
        480,
        5,
        handleforwindow1,
        NULL,
        hInst,
        NULL);

    if (!handleforwindow6)
    {
        int nResult = GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }

    ShowWindow(handleforwindow6, nShowCmd);
    cHwnd[4] = handleforwindow6;

    MSG msg;
    ZeroMemory(&msg, sizeof(MSG));
    while (endprogram == false) {
        if (GetMessage(&msg, NULL, 0, 0));
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        if (window1closed == true && window2closed == true) {
            endprogram = true;
        }
    }

    return 0;
}

LRESULT CALLBACK windowprocessforwindow1(HWND handleforwindow, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_DESTROY: {

        window1closed = true;
        return 0;
    }
                     break;
    }

    return DefWindowProc(handleforwindow, msg, wParam, lParam);
}

//子窗口处理
LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow, UINT msg, WPARAM wParam, LPARAM lParam)
{
    //鼠标拖动spiltter时,相对于主窗口的x
    int spos,border;
    //鼠标左键单击spiltter时,在spiltter内部的偏移长度
    int posinspiltter = 0;
    static BOOL bSplitterMoving;

    RECT rectMain,rectSpiltterH,rectRightUp;

    switch (msg)
    {
    case WM_DESTROY: {


        window2closed = true;
        return 0;
    }
    case WM_LBUTTONDOWN:

        if (handleforwindow == cHwnd[0])
        {
            MessageBox(NULL, TEXT("1鼠标左键点击"), TEXT("Win32_Mouse"), MB_OK);
        }else if (handleforwindow == cHwnd[1])
        {
            MessageBox(NULL, TEXT("2鼠标左键点击"), TEXT("Win32_Mouse"), MB_OK);
        }
        else if (handleforwindow == cHwnd[3])
        {
            MessageBox(NULL, TEXT("3鼠标左键点击"), TEXT("Win32_Mouse"), MB_OK);
        }
        else if (handleforwindow == cHwnd[2])
        {
            //MessageBox(NULL, TEXT("3鼠标左键点击"), TEXT("Win32_Mouse"), MB_OK);
            bSplitterMoving = TRUE;
            //抓住左窗口,WM_MOUSEMOVE得到的就是鼠标相对于左窗口移动距离
            SetCapture(cHwnd[0]);
            posinspiltter = GET_X_LPARAM(lParam);
            return 0;
        }
        else if (handleforwindow == cHwnd[4])
        {
            //MessageBox(NULL, TEXT("3鼠标左键点击"), TEXT("Win32_Mouse"), MB_OK);
            bSplitterMoving = TRUE;
            //抓住右上窗口
            SetCapture(cHwnd[1]);
            posinspiltter = GET_Y_LPARAM(lParam);
            return 0;
        }

        break;
    case WM_LBUTTONUP:
        ReleaseCapture();
        bSplitterMoving = FALSE;
        return 0;
    case WM_MOUSEMOVE:
        if ((wParam == MK_LBUTTON) && bSplitterMoving && (handleforwindow == cHwnd[0]))
        {
            spos = GET_X_LPARAM(lParam);
            //spos- posinspiltter  鼠标的相对于主窗口的x - 在spiltter内的偏移 就是左窗口的宽度
            MoveWindow(cHwnd[0], 0, 0, spos- posinspiltter, 480, TRUE); //左窗口
            //spos+(5- posinspiltter)  5- posinspiltter是点击位置到spiltter有边框的距离, 鼠标的相对于主窗口的x + 点击位置到spiltter有边框的距离就是 有窗口的x起始位置
            //640-(spos + (5 - posinspiltter))  640是主窗口宽度 - 有窗口的起始位置,就是宽度

            MoveWindow(cHwnd[2], spos, 0, 5, 480, TRUE); //spiltter

            GetWindowRect(mHwnd, &rectMain);
            GetWindowRect(cHwnd[1], &rectRightUp);

            MoveWindow(cHwnd[1], spos + (5 - posinspiltter), 0, 640 - (spos + (5 - posinspiltter)), rectRightUp.bottom - rectMain.top - 31, TRUE); //右窗口

            MoveWindow(cHwnd[3], spos + (5 - posinspiltter), rectRightUp.bottom- rectMain.top-31+5, 640 - (spos + (5 - posinspiltter)), 480 - (rectRightUp.bottom -     rectMain.top - 31 + 5), TRUE); //右下
            MoveWindow(cHwnd[4], spos + (5 - posinspiltter), rectRightUp.bottom - rectMain.top - 31, 640 - (spos + (5 - posinspiltter)), 5, TRUE); //spiltter
        }
        else if ((wParam == MK_LBUTTON) && bSplitterMoving && (handleforwindow == cHwnd[1]))
        {
            border = GetSystemMetrics(SM_CXBORDER);
            spos = GET_Y_LPARAM(lParam);

            GetWindowRect(mHwnd, &rectMain);
            GetWindowRect(cHwnd[2], &rectSpiltterH);
            GetWindowRect(cHwnd[1], &rectRightUp);

            MoveWindow(cHwnd[1], rectRightUp.left - rectMain.left-8, 0, rectRightUp.right-rectRightUp.left, spos - posinspiltter, TRUE); //右上
            MoveWindow(cHwnd[3], rectRightUp.left - rectMain.left-8, spos + (5-posinspiltter), rectRightUp.right - rectRightUp.left, 480-(spos + (5 -     posinspiltter)), TRUE); //右下
            MoveWindow(cHwnd[4], rectRightUp.left - rectMain.left-8, spos - posinspiltter, rectRightUp.right - rectRightUp.left, 5, TRUE); //spiltter

        }
        return 0;
    }

    return DefWindowProc(handleforwindow, msg, wParam, lParam);
}

There is no native win32 splitter, I made one using pure win32 api in one cpp file.

    // Win32test2.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "Win32test2.h"

LRESULT CALLBACK windowprocessforwindow1(HWND handleforwindow1, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow2, UINT message, WPARAM wParam, LPARAM lParam);

bool window1closed = false;
bool window2closed = false;

//child hwnd 小子窗口,非弹出式子窗口,是CreateWindowEx设置了parent
HWND cHwnd[5]; //0 左窗口 1 右窗口或右上窗口  2 竖分隔符窗口 spiltter 3 右下窗口  4 横分隔符窗口 spiltter
//main hwnd
HWND mHwnd;

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd)
{
    bool endprogram = false;

    //create window 1

    WNDCLASSEX windowclassforwindow1;
    ZeroMemory(&windowclassforwindow1, sizeof(WNDCLASSEX));
    windowclassforwindow1.cbClsExtra = NULL;
    windowclassforwindow1.cbSize = sizeof(WNDCLASSEX);
    windowclassforwindow1.cbWndExtra = NULL;
    windowclassforwindow1.hbrBackground = (HBRUSH)COLOR_WINDOW;
    windowclassforwindow1.hCursor = LoadCursor(NULL, IDC_ARROW);
    windowclassforwindow1.hIcon = NULL;
    windowclassforwindow1.hIconSm = NULL;
    windowclassforwindow1.hInstance = hInst;
    windowclassforwindow1.lpfnWndProc = (WNDPROC)windowprocessforwindow1;
    windowclassforwindow1.lpszClassName = L"windowclass 1";
    windowclassforwindow1.lpszMenuName = NULL;
    windowclassforwindow1.style = CS_HREDRAW | CS_VREDRAW;

    if (!RegisterClassEx(&windowclassforwindow1))
    {
        int nResult = GetLastError();
        MessageBox(NULL,
            L"Window class creation failed",
            L"Window Class Failed",
            MB_ICONERROR);
    }

    HWND handleforwindow1 = CreateWindowEx(NULL,
        windowclassforwindow1.lpszClassName,
        L"Parent Window",
        WS_OVERLAPPEDWINDOW,
        200,
        200,
        640,
        480,
        NULL,
        NULL,
        hInst,
        NULL                /* No Window Creation data */
    );

    if (!handleforwindow1)
    {
        int nResult = GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }

    ShowWindow(handleforwindow1, nShowCmd);
    mHwnd = handleforwindow1;


    // create window 2

    WNDCLASSEX windowclassforwindow2;
    ZeroMemory(&windowclassforwindow2, sizeof(WNDCLASSEX));
    windowclassforwindow2.cbClsExtra = NULL;
    windowclassforwindow2.cbSize = sizeof(WNDCLASSEX);
    windowclassforwindow2.cbWndExtra = NULL;
    windowclassforwindow2.hbrBackground = (HBRUSH)COLOR_WINDOW;
    windowclassforwindow2.hCursor = LoadCursor(NULL, IDC_ARROW);
    windowclassforwindow2.hIcon = NULL;
    windowclassforwindow2.hIconSm = NULL;
    windowclassforwindow2.hInstance = hInst;
    windowclassforwindow2.lpfnWndProc = (WNDPROC)windowprocessforwindow2;
    windowclassforwindow2.lpszClassName = L"window class2";
    windowclassforwindow2.lpszMenuName = NULL;
    windowclassforwindow2.style = CS_HREDRAW | CS_VREDRAW;

    if (!RegisterClassEx(&windowclassforwindow2))
    {
        int nResult = GetLastError();
        MessageBox(NULL,
            L"Window class creation failed for window 2",
            L"Window Class Failed",
            MB_ICONERROR);
    }

    HWND handleforwindow2 = CreateWindowEx(NULL,
        windowclassforwindow2.lpszClassName,
        L"Child Window",
        WS_CHILD 
        ,
        0,
        0,
        195,
        480,
        handleforwindow1,
        NULL,
        hInst,
        NULL);

    if (!handleforwindow2)
    {
        int nResult = GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }

    ShowWindow(handleforwindow2, nShowCmd);
    cHwnd[0] = handleforwindow2;

    // create window 3

    HWND handleforwindow3 = CreateWindowEx(NULL,
        windowclassforwindow2.lpszClassName,
        L"Child Window",
        WS_CHILD 
        ,
        200,
        0,
        440,
        275,
        handleforwindow1,
        NULL,
        hInst,
        NULL);

    if (!handleforwindow3)
    {
        int nResult = GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }

    ShowWindow(handleforwindow3, nShowCmd);
    cHwnd[1] = handleforwindow3;

    // create window 4 spiltter

    WNDCLASSEX windowclassforwindow4;
    ZeroMemory(&windowclassforwindow4, sizeof(WNDCLASSEX));
    windowclassforwindow4.cbClsExtra = NULL;
    windowclassforwindow4.cbSize = sizeof(WNDCLASSEX);
    windowclassforwindow4.cbWndExtra = NULL;
    windowclassforwindow4.hbrBackground = (HBRUSH)COLOR_WINDOW;
    windowclassforwindow4.hCursor = LoadCursor(NULL, IDC_SIZEWE);
    windowclassforwindow4.hIcon = NULL;
    windowclassforwindow4.hIconSm = NULL;
    windowclassforwindow4.hInstance = hInst;
    windowclassforwindow4.lpfnWndProc = (WNDPROC)windowprocessforwindow2;
    windowclassforwindow4.lpszClassName = L"window class4";
    windowclassforwindow4.lpszMenuName = NULL;
    windowclassforwindow4.style = CS_HREDRAW | CS_VREDRAW;

    if (!RegisterClassEx(&windowclassforwindow4))
    {
        int nResult = GetLastError();
        MessageBox(NULL,
            L"Window class creation failed for window 2",
            L"Window Class Failed",
            MB_ICONERROR);
    }

    HWND handleforwindow4 = CreateWindowEx(NULL,
        windowclassforwindow4.lpszClassName,
        L"Child Window",
        WS_CHILD \
        | WS_BORDER
        ,
        195,
        0,
        5,
        480,
        handleforwindow1,
        NULL,
        hInst,
        NULL);

    if (!handleforwindow4)
    {
        int nResult = GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }

    ShowWindow(handleforwindow4, nShowCmd);
    cHwnd[2] = handleforwindow4;

    // create window 5 有窗口下面窗口

    HWND handleforwindow5 = CreateWindowEx(NULL,
        windowclassforwindow2.lpszClassName,
        L"Child Window",
        WS_CHILD
        ,
        200,
        280,
        440,
        200,
        handleforwindow1,
        NULL,
        hInst,
        NULL);

    if (!handleforwindow5)
    {
        int nResult = GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }
    ShowWindow(handleforwindow5, nShowCmd);
    cHwnd[3] = handleforwindow5;

    // create window 6 spiltter 右窗口spiltter

    WNDCLASSEX windowclassforwindow6;
    ZeroMemory(&windowclassforwindow6, sizeof(WNDCLASSEX));
    windowclassforwindow6.cbClsExtra = NULL;
    windowclassforwindow6.cbSize = sizeof(WNDCLASSEX);
    windowclassforwindow6.cbWndExtra = NULL;
    windowclassforwindow6.hbrBackground = (HBRUSH)COLOR_WINDOW;
    windowclassforwindow6.hCursor = LoadCursor(NULL, IDC_SIZENS);
    windowclassforwindow6.hIcon = NULL;
    windowclassforwindow6.hIconSm = NULL;
    windowclassforwindow6.hInstance = hInst;
    windowclassforwindow6.lpfnWndProc = (WNDPROC)windowprocessforwindow2;
    windowclassforwindow6.lpszClassName = L"window class6";
    windowclassforwindow6.lpszMenuName = NULL;
    windowclassforwindow6.style = CS_HREDRAW | CS_VREDRAW;

    if (!RegisterClassEx(&windowclassforwindow6))
    {
        int nResult = GetLastError();
        MessageBox(NULL,
            L"Window class creation failed for window 2",
            L"Window Class Failed",
            MB_ICONERROR);
    }

    HWND handleforwindow6 = CreateWindowEx(NULL,
        windowclassforwindow6.lpszClassName,
        L"Child Window",
        WS_CHILD \
        | WS_BORDER
        ,
        200,
        275,
        480,
        5,
        handleforwindow1,
        NULL,
        hInst,
        NULL);

    if (!handleforwindow6)
    {
        int nResult = GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }

    ShowWindow(handleforwindow6, nShowCmd);
    cHwnd[4] = handleforwindow6;

    MSG msg;
    ZeroMemory(&msg, sizeof(MSG));
    while (endprogram == false) {
        if (GetMessage(&msg, NULL, 0, 0));
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        if (window1closed == true && window2closed == true) {
            endprogram = true;
        }
    }

    return 0;
}

LRESULT CALLBACK windowprocessforwindow1(HWND handleforwindow, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_DESTROY: {

        window1closed = true;
        return 0;
    }
                     break;
    }

    return DefWindowProc(handleforwindow, msg, wParam, lParam);
}

//子窗口处理
LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow, UINT msg, WPARAM wParam, LPARAM lParam)
{
    //鼠标拖动spiltter时,相对于主窗口的x
    int spos,border;
    //鼠标左键单击spiltter时,在spiltter内部的偏移长度
    int posinspiltter = 0;
    static BOOL bSplitterMoving;

    RECT rectMain,rectSpiltterH,rectRightUp;

    switch (msg)
    {
    case WM_DESTROY: {


        window2closed = true;
        return 0;
    }
    case WM_LBUTTONDOWN:

        if (handleforwindow == cHwnd[0])
        {
            MessageBox(NULL, TEXT("1鼠标左键点击"), TEXT("Win32_Mouse"), MB_OK);
        }else if (handleforwindow == cHwnd[1])
        {
            MessageBox(NULL, TEXT("2鼠标左键点击"), TEXT("Win32_Mouse"), MB_OK);
        }
        else if (handleforwindow == cHwnd[3])
        {
            MessageBox(NULL, TEXT("3鼠标左键点击"), TEXT("Win32_Mouse"), MB_OK);
        }
        else if (handleforwindow == cHwnd[2])
        {
            //MessageBox(NULL, TEXT("3鼠标左键点击"), TEXT("Win32_Mouse"), MB_OK);
            bSplitterMoving = TRUE;
            //抓住左窗口,WM_MOUSEMOVE得到的就是鼠标相对于左窗口移动距离
            SetCapture(cHwnd[0]);
            posinspiltter = GET_X_LPARAM(lParam);
            return 0;
        }
        else if (handleforwindow == cHwnd[4])
        {
            //MessageBox(NULL, TEXT("3鼠标左键点击"), TEXT("Win32_Mouse"), MB_OK);
            bSplitterMoving = TRUE;
            //抓住右上窗口
            SetCapture(cHwnd[1]);
            posinspiltter = GET_Y_LPARAM(lParam);
            return 0;
        }

        break;
    case WM_LBUTTONUP:
        ReleaseCapture();
        bSplitterMoving = FALSE;
        return 0;
    case WM_MOUSEMOVE:
        if ((wParam == MK_LBUTTON) && bSplitterMoving && (handleforwindow == cHwnd[0]))
        {
            spos = GET_X_LPARAM(lParam);
            //spos- posinspiltter  鼠标的相对于主窗口的x - 在spiltter内的偏移 就是左窗口的宽度
            MoveWindow(cHwnd[0], 0, 0, spos- posinspiltter, 480, TRUE); //左窗口
            //spos+(5- posinspiltter)  5- posinspiltter是点击位置到spiltter有边框的距离, 鼠标的相对于主窗口的x + 点击位置到spiltter有边框的距离就是 有窗口的x起始位置
            //640-(spos + (5 - posinspiltter))  640是主窗口宽度 - 有窗口的起始位置,就是宽度

            MoveWindow(cHwnd[2], spos, 0, 5, 480, TRUE); //spiltter

            GetWindowRect(mHwnd, &rectMain);
            GetWindowRect(cHwnd[1], &rectRightUp);

            MoveWindow(cHwnd[1], spos + (5 - posinspiltter), 0, 640 - (spos + (5 - posinspiltter)), rectRightUp.bottom - rectMain.top - 31, TRUE); //右窗口

            MoveWindow(cHwnd[3], spos + (5 - posinspiltter), rectRightUp.bottom- rectMain.top-31+5, 640 - (spos + (5 - posinspiltter)), 480 - (rectRightUp.bottom -     rectMain.top - 31 + 5), TRUE); //右下
            MoveWindow(cHwnd[4], spos + (5 - posinspiltter), rectRightUp.bottom - rectMain.top - 31, 640 - (spos + (5 - posinspiltter)), 5, TRUE); //spiltter
        }
        else if ((wParam == MK_LBUTTON) && bSplitterMoving && (handleforwindow == cHwnd[1]))
        {
            border = GetSystemMetrics(SM_CXBORDER);
            spos = GET_Y_LPARAM(lParam);

            GetWindowRect(mHwnd, &rectMain);
            GetWindowRect(cHwnd[2], &rectSpiltterH);
            GetWindowRect(cHwnd[1], &rectRightUp);

            MoveWindow(cHwnd[1], rectRightUp.left - rectMain.left-8, 0, rectRightUp.right-rectRightUp.left, spos - posinspiltter, TRUE); //右上
            MoveWindow(cHwnd[3], rectRightUp.left - rectMain.left-8, spos + (5-posinspiltter), rectRightUp.right - rectRightUp.left, 480-(spos + (5 -     posinspiltter)), TRUE); //右下
            MoveWindow(cHwnd[4], rectRightUp.left - rectMain.left-8, spos - posinspiltter, rectRightUp.right - rectRightUp.left, 5, TRUE); //spiltter

        }
        return 0;
    }

    return DefWindowProc(handleforwindow, msg, wParam, lParam);
}
一抹苦笑 2024-11-06 01:37:36

试试这个,它是一个本机 win32 分割器控件,只有 2 个文件。

// Splitter.h

#pragma once

#include <windows.h>

constexpr WCHAR UC_SPLITTER[]{ L"UserControl_Splitter" };

constexpr DWORD SPS_HORZ{ 0b1u };
constexpr DWORD SPS_VERT{ 0b10u };
constexpr DWORD SPS_PARENTWIDTH{ 0b100u };
constexpr DWORD SPS_PARENTHEIGHT{ 0b1000u };
constexpr DWORD SPS_AUTODRAG{ 0b10000u };
constexpr DWORD SPS_NOCAPTURE{ 0b100000u };
constexpr DWORD SPS_NONOTIFY{ 0b1000000u };

enum SPLITTERMESSAGE : UINT { SPM_ROTATE = WM_USER + 1, SPM_SETRANGE, SPM_GETRANGE, SPM_SETMARGIN, SPM_GETMARGIN, SPM_SETLINKEDCTL, SPM_GETLINKEDCTL, SPM_ADDLINKEDCTL, SPM_REMOVELINKEDCTL };
enum SETLINKEDCONTROL : WORD { SLC_TOP = 1, SLC_BOTTOM, SLC_LEFT, SLC_RIGHT };

typedef struct tagNMSPLITTER
{
    NMHDR hdr;
    POINT ptCursor;
    POINT ptCursorOffset;
} NMSPLITTER, *PNMSPLITTER, *LPNMSPLITTER;

ATOM InitSplitter();
// Splitter.cpp

#include <windows.h>
#include <windowsx.h>
#include <vector>
#include <array>
#include <algorithm>
#include <cassert>
#include "Splitter.h"

LRESULT CALLBACK SplitterProc(HWND hWndSplitter, UINT Message, WPARAM wParam, LPARAM lParam);

ATOM InitSplitter()
{
    WNDCLASS wc{ 0, SplitterProc, 0, 0, static_cast<HINSTANCE>(GetModuleHandle(NULL)), NULL, NULL, NULL, NULL, UC_SPLITTER };

    return RegisterClass(&wc);
}

LRESULT CALLBACK SplitterProc(HWND hWndSplitter, UINT Message, WPARAM wParam, LPARAM lParam)
{
    LRESULT ret{};

    static DWORD dwSplitterStyle{};
    static WORD idSplitter{};
    static POINT ptSplitterRange{};
    static DWORD dwLineMargin{};
    static POINT ptCursorOffset{};
    static std::array<std::vector<HWND>, 2> LinkedControl;

    switch (Message)
    {
    case SPM_ROTATE:
        {
            DWORD dwSplitterStyleNew{ (dwSplitterStyle & (~(SPS_HORZ | SPS_VERT))) | ((dwSplitterStyle & (SPS_HORZ | SPS_VERT)) ^ (SPS_HORZ | SPS_VERT)) };
            if (dwSplitterStyleNew & SPS_PARENTWIDTH)
            {
                dwSplitterStyle = (dwSplitterStyleNew & (~SPS_PARENTWIDTH)) | SPS_PARENTHEIGHT;
            }
            if (dwSplitterStyleNew & SPS_PARENTHEIGHT)
            {
                dwSplitterStyle = (dwSplitterStyleNew & (~SPS_PARENTHEIGHT)) | SPS_PARENTWIDTH;
            }
            SetWindowLongPtr(hWndSplitter, GWL_STYLE, static_cast<LONG>(dwSplitterStyleNew));

            InvalidateRect(hWndSplitter, NULL, FALSE);
        }
        break;
    case SPM_SETRANGE:
        {
            if (wParam)
            {
                HWND hWndSplitterParent{ GetAncestor(hWndSplitter, GA_PARENT) };
                RECT rcSplitter{};
                GetWindowRect(hWndSplitter, &rcSplitter);
                MapWindowRect(HWND_DESKTOP, hWndSplitterParent, &rcSplitter);
                if (dwSplitterStyle & SPS_HORZ)
                {
                    ptSplitterRange = { LOWORD(wParam), HIWORD(wParam) - (rcSplitter.bottom - rcSplitter.top) };
                }
                else if (dwSplitterStyle & SPS_VERT)
                {
                    ptSplitterRange = { LOWORD(wParam), HIWORD(wParam) - (rcSplitter.right - rcSplitter.left) };
                }
                if (ptSplitterRange.y >= ptSplitterRange.x)
                {
                    ret = static_cast<LRESULT>(TRUE);
                }
                else
                {
                    ptSplitterRange = {};

                    ret = static_cast<LRESULT>(FALSE);
                }
            }
            else
            {
                ptSplitterRange = {};

                ret = static_cast<LRESULT>(TRUE);
            }
        }
        break;
    case SPM_GETRANGE:
        {
            ret = MAKELRESULT(ptSplitterRange.x, ptSplitterRange.y);
        }
        break;
    case SPM_SETMARGIN:
        {
            dwLineMargin = static_cast<DWORD>(wParam);
            RECT rcSplitterClient{};
            GetClientRect(hWndSplitter, &rcSplitterClient);
            if (dwSplitterStyle & SPS_HORZ)
            {
                POINT ptLineStart{ rcSplitterClient.left + static_cast<LONG>(dwLineMargin), rcSplitterClient.top + (rcSplitterClient.bottom - rcSplitterClient.top) / 2 };
                RECT rcSplitterClientLeftPart{ rcSplitterClient.left, rcSplitterClient.top, rcSplitterClient.left + (rcSplitterClient.right - rcSplitterClient.left) / 2, rcSplitterClient.bottom };
                if (!PtInRect(&rcSplitterClientLeftPart, ptLineStart))
                {
                    dwLineMargin = 0;

                    ret = static_cast<LRESULT>(FALSE);
                    break;
                }
            }
            else if (dwSplitterStyle & SPS_VERT)
            {
                POINT ptLineStart{ rcSplitterClient.left + (rcSplitterClient.right - rcSplitterClient.left) / 2, rcSplitterClient.top + static_cast<LONG>(dwLineMargin) };
                RECT rcSplitterClientUpperPart{ rcSplitterClient.left, rcSplitterClient.top, rcSplitterClient.right, rcSplitterClient.top + (rcSplitterClient.bottom - rcSplitterClient.top) / 2 };
                if (!PtInRect(&rcSplitterClientUpperPart, ptLineStart))
                {
                    dwLineMargin = 0;

                    ret = static_cast<LRESULT>(FALSE);
                    break;
                }
            }
            else
            {
                dwLineMargin = 0;

                ret = static_cast<LRESULT>(FALSE);
                break;
            }

            InvalidateRect(hWndSplitter, NULL, FALSE);

            ret = static_cast<LRESULT>(TRUE);
        }
        break;
    case SPM_GETMARGIN:
        {
            ret = static_cast<LRESULT>(dwLineMargin);
        }
        break;
    case SPM_SETLINKEDCTL:
        {
            switch (HIWORD(wParam))
            {
            case SLC_TOP:
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        LinkedControl[0].clear();
                        try
                        {
                            for (WORD i = 0; i < LOWORD(wParam); i++)
                            {
                                if (IsWindow(reinterpret_cast<HWND*>(lParam)[i]) && (GetAncestor(reinterpret_cast<HWND*>(lParam)[i], GA_PARENT) == GetAncestor(hWndSplitter, GA_PARENT)))
                                {
                                    LinkedControl[0].push_back(reinterpret_cast<HWND*>(lParam)[i]);
                                }
                            }
                            std::sort(LinkedControl[0].begin(), LinkedControl[0].end());
                            LinkedControl[0].erase(std::unique(LinkedControl[0].begin(), LinkedControl[0].end()), LinkedControl[0].end());
                        }
                        catch (...)
                        {
                            LinkedControl[0].clear();

                            ret = 0;
                            break;
                        }

                        ret = static_cast<LRESULT>(LinkedControl[0].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_BOTTOM:
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        LinkedControl[1].clear();
                        try
                        {
                            for (WORD i = 0; i < LOWORD(wParam); i++)
                            {
                                if (IsWindow(reinterpret_cast<HWND*>(lParam)[i]) && (GetAncestor(reinterpret_cast<HWND*>(lParam)[i], GA_PARENT) == GetAncestor(hWndSplitter, GA_PARENT)))
                                {
                                    LinkedControl[1].push_back(reinterpret_cast<HWND*>(lParam)[i]);
                                }
                            }
                            std::sort(LinkedControl[1].begin(), LinkedControl[1].end());
                                                        LinkedControl[1].erase(std::unique(LinkedControl[1].begin(), LinkedControl[1].end()), LinkedControl[1].end());
                        }
                        catch (...)
                        {
                            LinkedControl[1].clear();

                            ret = 0;
                            break;
                        }

                        ret = static_cast<LRESULT>(LinkedControl[1].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_LEFT:
                {
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        LinkedControl[0].clear();
                        try
                        {
                            for (WORD i = 0; i < LOWORD(wParam); i++)
                            {
                                if (IsWindow(reinterpret_cast<HWND*>(lParam)[i]) && (GetAncestor(reinterpret_cast<HWND*>(lParam)[i], GA_PARENT) == GetAncestor(hWndSplitter, GA_PARENT)))
                                {
                                    LinkedControl[0].push_back(reinterpret_cast<HWND*>(lParam)[i]);
                                }
                            }
                            std::sort(LinkedControl[0].begin(), LinkedControl[0].end());
                            LinkedControl[0].erase(std::unique(LinkedControl[0].begin(), LinkedControl[0].end()), LinkedControl[0].end());
                        }
                        catch (...)
                        {
                            LinkedControl[0].clear();

                            ret = 0;
                            break;
                        }

                        ret = static_cast<LRESULT>(LinkedControl[0].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_RIGHT:
                {
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        LinkedControl[1].clear();
                        try
                        {
                            for (WORD i = 0; i < LOWORD(wParam); i++)
                            {
                                if (IsWindow(reinterpret_cast<HWND*>(lParam)[i]) && (GetAncestor(reinterpret_cast<HWND*>(lParam)[i], GA_PARENT) == GetAncestor(hWndSplitter, GA_PARENT)))
                                {
                                    LinkedControl[1].push_back(reinterpret_cast<HWND*>(lParam)[i]);
                                }
                            }
                            std::sort(LinkedControl[1].begin(), LinkedControl[1].end());
                            LinkedControl[1].erase(std::unique(LinkedControl[1].begin(), LinkedControl[1].end()), LinkedControl[1].end());
                        }
                        catch (...)
                        {
                            LinkedControl[1].clear();

                            ret = 0;
                            break;
                        }

                        ret = static_cast<LRESULT>(LinkedControl[1].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            default:
                {
                    ret = 0;
                }
                break;
            }
        }
        break;
    case SPM_GETLINKEDCTL:
        {
            switch (HIWORD(wParam))
            {
            case SLC_TOP:
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        if (lParam)
                        {
                            for (WORD i = 0; i < static_cast<WORD>(LinkedControl[0].size()); i++)
                            {
                                reinterpret_cast<HWND*>(lParam)[i] = LinkedControl[0][i];
                            }
                        }

                        ret = static_cast<LRESULT>(LinkedControl[0].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_BOTTOM:
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        if (lParam)
                        {
                            for (WORD i = 0; i < static_cast<WORD>(LinkedControl[1].size()); i++)
                            {
                                reinterpret_cast<HWND*>(lParam)[i] = LinkedControl[1][i];
                            }
                        }

                        ret = static_cast<LRESULT>(LinkedControl[1].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_LEFT:
                {
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        if (lParam)
                        {
                            for (WORD i = 0; i < static_cast<WORD>(LinkedControl[0].size()); i++)
                            {
                                reinterpret_cast<HWND*>(lParam)[i] = LinkedControl[0][i];
                            }
                        }

                        ret = static_cast<LRESULT>(LinkedControl[0].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_RIGHT:
                {
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        if (lParam)
                        {
                            for (WORD i = 0; i < static_cast<WORD>(LinkedControl[1].size()); i++)
                            {
                                reinterpret_cast<HWND*>(lParam)[i] = LinkedControl[1][i];
                            }
                        }

                        ret = static_cast<LRESULT>(LinkedControl[1].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            default:
                {
                    ret = 0;
                }
                break;
            }
        }
        break;
    case SPM_ADDLINKEDCTL:
        {
            std::vector<HWND> LinkedControlTemp{};

            switch (HIWORD(wParam))
            {
            case SLC_TOP:
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        try
                        {
                            for (WORD i = 0; i < LOWORD(wParam); i++)
                            {
                                if (IsWindow(reinterpret_cast<HWND*>(lParam)[i]) && (GetAncestor(reinterpret_cast<HWND*>(lParam)[i], GA_PARENT) == GetAncestor(hWndSplitter, GA_PARENT)))
                                {
                                    LinkedControlTemp.push_back(reinterpret_cast<HWND*>(lParam)[i]);
                                }
                            }
                            std::sort(LinkedControlTemp.begin(), LinkedControlTemp.end());
                            LinkedControlTemp.erase(std::unique(LinkedControlTemp.begin(), LinkedControlTemp.end()), LinkedControlTemp.end());
                            LinkedControl[0].reserve(LinkedControl[0].size() + LinkedControlTemp.size());
                        }
                        catch (...)
                        {
                            ret = 0;
                            break;
                        }
                        LinkedControl[0].insert(LinkedControl[0].end(), LinkedControlTemp.begin(), LinkedControlTemp.end());

                        ret = static_cast<LRESULT>(LinkedControlTemp.size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_BOTTOM:
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        try
                        {
                            for (WORD i = 0; i < LOWORD(wParam); i++)
                            {
                                if (IsWindow(reinterpret_cast<HWND*>(lParam)[i]) && (GetAncestor(reinterpret_cast<HWND*>(lParam)[i], GA_PARENT) == GetAncestor(hWndSplitter, GA_PARENT)))
                                {
                                    LinkedControlTemp.push_back(reinterpret_cast<HWND*>(lParam)[i]);
                                }
                            }
                            std::sort(LinkedControlTemp.begin(), LinkedControlTemp.end());
                            LinkedControlTemp.erase(std::unique(LinkedControlTemp.begin(), LinkedControlTemp.end()), LinkedControlTemp.end());
                            LinkedControl[1].reserve(LinkedControl[1].size() + LinkedControlTemp.size());
                        }
                        catch (...)
                        {
                            ret = 0;
                            break;
                        }
                        LinkedControl[1].insert(LinkedControl[1].end(), LinkedControlTemp.begin(), LinkedControlTemp.end());

                        ret = static_cast<LRESULT>(LinkedControlTemp.size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_LEFT:
                {
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        try
                        {
                            for (WORD i = 0; i < LOWORD(wParam); i++)
                            {
                                if (IsWindow(reinterpret_cast<HWND*>(lParam)[i]) && (GetAncestor(reinterpret_cast<HWND*>(lParam)[i], GA_PARENT) == GetAncestor(hWndSplitter, GA_PARENT)))
                                {
                                    LinkedControlTemp.push_back(reinterpret_cast<HWND*>(lParam)[i]);
                                }
                            }
                            std::sort(LinkedControlTemp.begin(), LinkedControlTemp.end());
                            LinkedControlTemp.erase(std::unique(LinkedControlTemp.begin(), LinkedControlTemp.end()), LinkedControlTemp.end());
                            LinkedControl[0].reserve(LinkedControl[0].size() + LinkedControlTemp.size());
                        }
                        catch (...)
                        {
                            ret = 0;
                            break;
                        }
                        LinkedControl[0].insert(LinkedControl[0].end(), LinkedControlTemp.begin(), LinkedControlTemp.end());

                        ret = static_cast<LRESULT>(LinkedControlTemp.size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_RIGHT:
                {
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        try
                        {
                            for (WORD i = 0; i < LOWORD(wParam); i++)
                            {
                                if (IsWindow(reinterpret_cast<HWND*>(lParam)[i]) && (GetAncestor(reinterpret_cast<HWND*>(lParam)[i], GA_PARENT) == GetAncestor(hWndSplitter, GA_PARENT)))
                                {
                                    LinkedControlTemp.push_back(reinterpret_cast<HWND*>(lParam)[i]);
                                }
                            }
                            std::sort(LinkedControlTemp.begin(), LinkedControlTemp.end());
                            LinkedControlTemp.erase(std::unique(LinkedControlTemp.begin(), LinkedControlTemp.end()), LinkedControlTemp.end());
                            LinkedControl[1].reserve(LinkedControl[1].size() + LinkedControlTemp.size());
                        }
                        catch (...)
                        {
                            ret = 0;
                            break;
                        }
                        LinkedControl[1].insert(LinkedControl[1].end(), LinkedControlTemp.begin(), LinkedControlTemp.end());

                        ret = static_cast<LRESULT>(LinkedControlTemp.size());
                    }
                }
                break;
            default:
                {
                    ret = 0;
                }
                break;
            }
        }
        break;
    case SPM_REMOVELINKEDCTL:
        {
            switch (HIWORD(wParam))
            {
            case SLC_TOP:
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        std::size_t LinkedControlOriginalSize{ LinkedControl[0].size() };
                        for (WORD i = 0; i < LOWORD(wParam); i++)
                        {
                            LinkedControl[0].erase(std::find(LinkedControl[0].begin(), LinkedControl[0].end(), reinterpret_cast<HWND*>(lParam)[i]));
                        }

                        ret = static_cast<LRESULT>(LinkedControlOriginalSize - LinkedControl[0].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_BOTTOM:
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        std::size_t LinkedControlOriginalSize{ LinkedControl[1].size() };
                        for (WORD i = 0; i < LOWORD(wParam); i++)
                        {
                            LinkedControl[1].erase(std::find(LinkedControl[1].begin(), LinkedControl[1].end(), reinterpret_cast<HWND*>(lParam)[i]));
                        }

                        ret = static_cast<LRESULT>(LinkedControlOriginalSize - LinkedControl[1].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_LEFT:
                {
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        std::size_t LinkedControlOriginalSize{ LinkedControl[0].size() };
                        for (WORD i = 0; i < LOWORD(wParam); i++)
                        {
                            LinkedControl[0].erase(std::find(LinkedControl[0].begin(), LinkedControl[0].end(), reinterpret_cast<HWND*>(lParam)[i]));
                        }

                        ret = static_cast<LRESULT>(LinkedControlOriginalSize - LinkedControl[0].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_RIGHT:
                {
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        std::size_t LinkedControlOriginalSize{ LinkedControl[1].size() };
                        for (WORD i = 0; i < LOWORD(wParam); i++)
                        {
                            LinkedControl[1].erase(std::find(LinkedControl[1].begin(), LinkedControl[1].end(), reinterpret_cast<HWND*>(lParam)[i]));
                        }

                        ret = static_cast<LRESULT>(LinkedControlOriginalSize - LinkedControl[1].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            default:
                {
                    ret = 0;
                }
                break;
            }
        }
        break;
    case WM_CREATE:
        {
            dwSplitterStyle = static_cast<DWORD>(reinterpret_cast<LPCREATESTRUCT>(lParam)->style);
            idSplitter = static_cast<WORD>(reinterpret_cast<UINT_PTR>(reinterpret_cast<LPCREATESTRUCT>(lParam)->hMenu) & 0xFFFF);

            if (static_cast<bool>(dwSplitterStyle & SPS_HORZ) == static_cast<bool>(dwSplitterStyle & SPS_VERT))
            {
                dwSplitterStyle = dwSplitterStyle & (~(SPS_HORZ | SPS_VERT));
            }
            if ((dwSplitterStyle & SPS_PARENTWIDTH) && (dwSplitterStyle & SPS_PARENTHEIGHT))
            {
                dwSplitterStyle = dwSplitterStyle & (~(SPS_PARENTWIDTH | SPS_PARENTHEIGHT));
            }
            if ((dwSplitterStyle & SPS_HORZ) && (dwSplitterStyle & SPS_PARENTHEIGHT))
            {
                dwSplitterStyle = dwSplitterStyle & (~(SPS_PARENTHEIGHT));
            }
            if ((dwSplitterStyle & SPS_VERT) && (dwSplitterStyle & SPS_PARENTWIDTH))
            {
                dwSplitterStyle = dwSplitterStyle & (~(SPS_PARENTWIDTH));
            }
            SetWindowLongPtr(hWndSplitter, GWL_STYLE, static_cast<LONG>(dwSplitterStyle));

            ret = 0;
        }
        break;
    case WM_ERASEBKGND:
        {
            ret = static_cast<LRESULT>(TRUE);
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps{};
            HDC hDCSplitter{ BeginPaint(hWndSplitter, &ps) };

            HWND hWndSplitterParent{ GetAncestor(hWndSplitter, GA_PARENT) };
            HBRUSH hBrSplitterBackground{ FORWARD_WM_CTLCOLORSTATIC(hWndSplitterParent, hDCSplitter, hWndSplitter, SendMessage) };

            RECT rcSplitterClient{};
            GetClientRect(hWndSplitter, &rcSplitterClient);
            if (!hBrSplitterBackground)
            {
                hBrSplitterBackground = GetSysColorBrush(COLOR_3DFACE);
            }
            FillRect(hDCSplitter, &rcSplitterClient, hBrSplitterBackground);

            if (dwSplitterStyle & SPS_HORZ)
            {
                MoveToEx(hDCSplitter, rcSplitterClient.left + dwLineMargin, rcSplitterClient.top + (rcSplitterClient.bottom - rcSplitterClient.top) / 2, NULL);
                LineTo(hDCSplitter, rcSplitterClient.right - dwLineMargin, rcSplitterClient.top + (rcSplitterClient.bottom - rcSplitterClient.top) / 2);
            }
            else if (dwSplitterStyle & SPS_VERT)
            {
                MoveToEx(hDCSplitter, rcSplitterClient.left + (rcSplitterClient.right - rcSplitterClient.left) / 2, rcSplitterClient.top + dwLineMargin, NULL);
                LineTo(hDCSplitter, rcSplitterClient.left + (rcSplitterClient.right - rcSplitterClient.left) / 2, rcSplitterClient.bottom - dwLineMargin);
            }

            EndPaint(hWndSplitter, &ps);
        }
        break;
    case WM_LBUTTONDOWN:
        {
            if (!(dwSplitterStyle & SPS_NOCAPTURE))
            {
                SetCapture(hWndSplitter);
            }

            if (!(dwSplitterStyle & SPS_NONOTIFY))
            {
                HWND hWndSplitterParent{ GetAncestor(hWndSplitter, GA_PARENT) };
                RECT rcSplitter{}, rcSplitterClient{};
                GetWindowRect(hWndSplitter, &rcSplitter);
                GetClientRect(hWndSplitter, &rcSplitterClient);
                MapWindowRect(hWndSplitter, HWND_DESKTOP, &rcSplitterClient);
                POINT ptCursor{ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
                ptCursorOffset = { ptCursor.x + (rcSplitterClient.left - rcSplitter.left), ptCursor.y + (rcSplitterClient.top - rcSplitter.top) };
                MapWindowPoints(hWndSplitter, hWndSplitterParent, &ptCursor, 1);
                NMSPLITTER nms{ { hWndSplitter, static_cast<UINT_PTR>(idSplitter), static_cast<UINT>(SPN_DRAGBEGIN) }, ptCursor, ptCursorOffset };
                SendMessage(hWndSplitterParent, WM_NOTIFY, static_cast<WPARAM>(idSplitter), reinterpret_cast<LPARAM>(&nms));
            }
        }
        break;
    case WM_MOUSEMOVE:
        {
            if ((wParam == MK_LBUTTON))
            {
                HWND hWndSplitterParent{ GetAncestor(hWndSplitter, GA_PARENT) };
                POINT ptCursor{ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }, ptSplitter{}, ptCursorOffsetNew{ ptCursorOffset };
                MapWindowPoints(hWndSplitter, hWndSplitterParent, &ptCursor, 1);
                ptSplitter = { ptCursor.x - ptCursorOffsetNew.x, ptCursor.y - ptCursorOffsetNew.y };
                if ((ptSplitterRange.x != 0) || (ptSplitterRange.y != 0))
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        if (ptSplitter.y < ptSplitterRange.x)
                        {
                            ptSplitter.y = ptSplitterRange.x;
                            ptCursorOffsetNew.y = ptCursor.y - ptSplitterRange.x;
                        }
                        if (ptSplitter.y > ptSplitterRange.y)
                        {
                            ptSplitter.y = ptSplitterRange.y;
                            ptCursorOffsetNew.y = ptCursor.y - ptSplitterRange.y;
                        }
                    }
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        if (ptSplitter.x < ptSplitterRange.x)
                        {
                            ptSplitter.x = ptSplitterRange.x;
                            ptCursorOffsetNew.x = ptCursor.x - ptSplitterRange.x;
                        }
                        if (ptSplitter.x > ptSplitterRange.y)
                        {
                            ptSplitter.x = ptSplitterRange.y;
                            ptCursorOffsetNew.x = ptCursor.x - ptSplitterRange.y;
                        }
                    }
                }

                if (dwSplitterStyle & SPS_AUTODRAG)
                {
                    FORWARD_WM_MOVE(hWndSplitter, ptSplitter.x, ptSplitter.y, SendMessage);
                }

                if (!(dwSplitterStyle & SPS_NONOTIFY))
                {
                    NMSPLITTER nms{ { hWndSplitter, static_cast<UINT_PTR>(idSplitter), static_cast<UINT>(SPN_DRAGGING) }, ptCursor, ptCursorOffsetNew };
                    SendMessage(hWndSplitterParent, WM_NOTIFY, static_cast<WPARAM>(idSplitter), reinterpret_cast<LPARAM>(&nms));
                }
            }
        }
        break;
    case WM_LBUTTONUP:
        {
            if (!(dwSplitterStyle & SPS_NOCAPTURE))
            {
                ReleaseCapture();
            }

            if (!(dwSplitterStyle & SPS_NONOTIFY))
            {
                HWND hWndSplitterParent{ GetAncestor(hWndSplitter, GA_PARENT) };
                POINT ptCursor{ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
                MapWindowPoints(hWndSplitter, hWndSplitterParent, &ptCursor, 1);
                NMSPLITTER nms{ { hWndSplitter, static_cast<UINT_PTR>(idSplitter), static_cast<UINT>(SPN_DRAGEND) }, ptCursor, ptCursorOffset };
                SendMessage(hWndSplitterParent, WM_NOTIFY, static_cast<WPARAM>(idSplitter), reinterpret_cast<LPARAM>(&nms));
            }
        }
        break;
    case WM_SETCURSOR:
        {
            if (reinterpret_cast<HWND>(wParam) == hWndSplitter)
            {
                if (dwSplitterStyle & SPS_HORZ)
                {
                    SetCursor(LoadCursor(NULL, IDC_SIZENS));

                    ret = static_cast<LRESULT>(TRUE);
                }
                else if (dwSplitterStyle & SPS_VERT)
                {
                    SetCursor(LoadCursor(NULL, IDC_SIZEWE));

                    ret = static_cast<LRESULT>(TRUE);
                }
                else
                {
                    ret = static_cast<LRESULT>(FALSE);
                }
            }
        }
        break;
    case WM_MOVE:
        {
            HWND hWndSplitterParent{ GetAncestor(hWndSplitter, GA_PARENT) };
            RECT rcSplitter{}, rcSplitterParentClient{};
            GetWindowRect(hWndSplitter, &rcSplitter);
            GetClientRect(hWndSplitterParent, &rcSplitterParentClient);
            int xPosSplitter{}, yPosSplitter{}, cxSplitter{}, cySplitter{};
            UINT uFlags{ SWP_NOZORDER | SWP_NOACTIVATE };
            if (dwSplitterStyle & SPS_PARENTWIDTH)
            {
                xPosSplitter = rcSplitterParentClient.left;
                yPosSplitter = GET_Y_LPARAM(lParam);
                cxSplitter = rcSplitterParentClient.right - rcSplitterParentClient.left;
                cySplitter = rcSplitter.bottom - rcSplitter.top;
            }
            else if (dwSplitterStyle & SPS_PARENTHEIGHT)
            {
                xPosSplitter = GET_X_LPARAM(lParam);
                yPosSplitter = rcSplitterParentClient.top;
                cxSplitter = rcSplitter.right - rcSplitter.left;
                cySplitter = rcSplitterParentClient.bottom - rcSplitterParentClient.top;
            }
            else
            {
                xPosSplitter = GET_X_LPARAM(lParam);
                yPosSplitter = GET_Y_LPARAM(lParam);
                uFlags |= SWP_NOSIZE;
            }
            SetWindowPos(hWndSplitter, NULL, xPosSplitter, yPosSplitter, cxSplitter, cySplitter, uFlags);

            MapWindowRect(HWND_DESKTOP, hWndSplitterParent, &rcSplitter);
            for (const auto& i : LinkedControl[0])
            {
                RECT rcLinkedWindow{};
                GetWindowRect(i, &rcLinkedWindow);
                MapWindowRect(HWND_DESKTOP, hWndSplitterParent, &rcLinkedWindow);
                if (dwSplitterStyle & SPS_HORZ)
                {
                    SetWindowPos(i, NULL, 0, 0, rcLinkedWindow.right - rcLinkedWindow.left, yPosSplitter - rcLinkedWindow.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
                }
                else if (dwSplitterStyle & SPS_VERT)
                {
                    SetWindowPos(i, NULL, 0, 0, xPosSplitter - rcLinkedWindow.left, rcLinkedWindow.bottom - rcLinkedWindow.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
                }
            }
            for (const auto& i : LinkedControl[1])
            {
                RECT rcLinkedWindow{};
                GetWindowRect(i, &rcLinkedWindow);
                MapWindowRect(HWND_DESKTOP, hWndSplitterParent, &rcLinkedWindow);
                if (dwSplitterStyle & SPS_HORZ)
                {
                    SetWindowPos(i, NULL, rcLinkedWindow.left, yPosSplitter + cySplitter, rcLinkedWindow.right - rcLinkedWindow.left, rcLinkedWindow.bottom - (yPosSplitter + cySplitter), SWP_NOZORDER | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
                }
                else if (dwSplitterStyle & SPS_VERT)
                {
                    SetWindowPos(i, NULL, xPosSplitter + cxSplitter, rcLinkedWindow.top, rcLinkedWindow.right - (xPosSplitter + cxSplitter), rcLinkedWindow.bottom - rcLinkedWindow.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
                }
            }
        }
        break;
    case WM_SIZE:
        {
            HWND hWndSplitterParent{ GetAncestor(hWndSplitter, GA_PARENT) };
            RECT rcSplitter{}, rcSplitterParentClient{};
            GetWindowRect(hWndSplitter, &rcSplitter);
            MapWindowRect(HWND_DESKTOP, hWndSplitterParent, &rcSplitter);
            GetClientRect(hWndSplitterParent, &rcSplitterParentClient);
            int xPosSplitter{}, yPosSplitter{}, cxSplitter{}, cySplitter{};
            UINT uFlags{ SWP_NOZORDER | SWP_NOACTIVATE };
            if (dwSplitterStyle & SPS_PARENTWIDTH)
            {
                xPosSplitter = rcSplitterParentClient.left;
                yPosSplitter = rcSplitter.top;
                cxSplitter = rcSplitterParentClient.right - rcSplitterParentClient.left;
                cySplitter = HIWORD(lParam);
            }
            else if (dwSplitterStyle & SPS_PARENTHEIGHT)
            {
                xPosSplitter = rcSplitter.left;
                yPosSplitter = rcSplitterParentClient.top;
                cxSplitter = LOWORD(lParam);
                cySplitter = rcSplitterParentClient.bottom - rcSplitterParentClient.top;
            }
            else
            {
                cxSplitter = LOWORD(lParam);
                cySplitter = HIWORD(lParam);
                uFlags |= SWP_NOMOVE;
            }
            SetWindowPos(hWndSplitter, NULL, xPosSplitter, yPosSplitter, cxSplitter, cySplitter, uFlags);

            MapWindowRect(HWND_DESKTOP, hWndSplitterParent, &rcSplitter);
            for (const auto& i : LinkedControl[0])
            {
                RECT rcLinkedWindow{};
                GetWindowRect(i, &rcLinkedWindow);
                MapWindowRect(HWND_DESKTOP, hWndSplitterParent, &rcLinkedWindow);
                if (dwSplitterStyle & SPS_HORZ)
                {
                    SetWindowPos(i, NULL, 0, 0, rcLinkedWindow.right - rcLinkedWindow.left, yPosSplitter - rcLinkedWindow.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
                }
                else if (dwSplitterStyle & SPS_VERT)
                {
                    SetWindowPos(i, NULL, 0, 0, xPosSplitter - rcLinkedWindow.left, rcLinkedWindow.bottom - rcLinkedWindow.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
                }
            }
            for (const auto& i : LinkedControl[1])
            {
                RECT rcLinkedWindow{};
                GetWindowRect(i, &rcLinkedWindow);
                MapWindowRect(HWND_DESKTOP, hWndSplitterParent, &rcLinkedWindow);
                if (dwSplitterStyle & SPS_HORZ)
                {
                    SetWindowPos(i, NULL, rcLinkedWindow.left, yPosSplitter + cySplitter, rcLinkedWindow.right - rcLinkedWindow.left, rcLinkedWindow.bottom - (yPosSplitter + cySplitter), SWP_NOZORDER | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
                }
                else if (dwSplitterStyle & SPS_VERT)
                {
                    SetWindowPos(i, NULL, xPosSplitter + cxSplitter, rcLinkedWindow.top, rcLinkedWindow.right - (xPosSplitter + cxSplitter), rcLinkedWindow.bottom - rcLinkedWindow.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
                }
            }
        }
        break;
    case WM_STYLECHANGING:
        {
            if (wParam == GWL_STYLE)
            {
                if (static_cast<bool>(reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & SPS_HORZ) == static_cast<bool>(reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & SPS_VERT))
                {
                    reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew = reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & (~(SPS_HORZ | SPS_VERT));
                }
                if ((reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & SPS_PARENTWIDTH) && (reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & SPS_PARENTHEIGHT))
                {
                    reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew = reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & (~(SPS_PARENTWIDTH | SPS_PARENTHEIGHT));
                }
                if ((reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & SPS_HORZ) && (reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & SPS_PARENTHEIGHT))
                {
                    reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew = reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & (~(SPS_PARENTHEIGHT));
                }
                if ((reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & SPS_VERT) && (reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & SPS_PARENTWIDTH))
                {
                    reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew = reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & (~(SPS_PARENTWIDTH));
                }

                if (reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew != reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleOld)
                {
                    InvalidateRect(hWndSplitter, NULL, FALSE);
                }
            }
        }
        break;
    default:
        {
            ret = DefWindowProc(hWndSplitter, Message, wParam, lParam);
        }
        break;
    }

    return ret;
}

Try this one, it's a native win32 splitter control with just 2 files.

// Splitter.h

#pragma once

#include <windows.h>

constexpr WCHAR UC_SPLITTER[]{ L"UserControl_Splitter" };

constexpr DWORD SPS_HORZ{ 0b1u };
constexpr DWORD SPS_VERT{ 0b10u };
constexpr DWORD SPS_PARENTWIDTH{ 0b100u };
constexpr DWORD SPS_PARENTHEIGHT{ 0b1000u };
constexpr DWORD SPS_AUTODRAG{ 0b10000u };
constexpr DWORD SPS_NOCAPTURE{ 0b100000u };
constexpr DWORD SPS_NONOTIFY{ 0b1000000u };

enum SPLITTERMESSAGE : UINT { SPM_ROTATE = WM_USER + 1, SPM_SETRANGE, SPM_GETRANGE, SPM_SETMARGIN, SPM_GETMARGIN, SPM_SETLINKEDCTL, SPM_GETLINKEDCTL, SPM_ADDLINKEDCTL, SPM_REMOVELINKEDCTL };
enum SETLINKEDCONTROL : WORD { SLC_TOP = 1, SLC_BOTTOM, SLC_LEFT, SLC_RIGHT };

typedef struct tagNMSPLITTER
{
    NMHDR hdr;
    POINT ptCursor;
    POINT ptCursorOffset;
} NMSPLITTER, *PNMSPLITTER, *LPNMSPLITTER;

ATOM InitSplitter();
// Splitter.cpp

#include <windows.h>
#include <windowsx.h>
#include <vector>
#include <array>
#include <algorithm>
#include <cassert>
#include "Splitter.h"

LRESULT CALLBACK SplitterProc(HWND hWndSplitter, UINT Message, WPARAM wParam, LPARAM lParam);

ATOM InitSplitter()
{
    WNDCLASS wc{ 0, SplitterProc, 0, 0, static_cast<HINSTANCE>(GetModuleHandle(NULL)), NULL, NULL, NULL, NULL, UC_SPLITTER };

    return RegisterClass(&wc);
}

LRESULT CALLBACK SplitterProc(HWND hWndSplitter, UINT Message, WPARAM wParam, LPARAM lParam)
{
    LRESULT ret{};

    static DWORD dwSplitterStyle{};
    static WORD idSplitter{};
    static POINT ptSplitterRange{};
    static DWORD dwLineMargin{};
    static POINT ptCursorOffset{};
    static std::array<std::vector<HWND>, 2> LinkedControl;

    switch (Message)
    {
    case SPM_ROTATE:
        {
            DWORD dwSplitterStyleNew{ (dwSplitterStyle & (~(SPS_HORZ | SPS_VERT))) | ((dwSplitterStyle & (SPS_HORZ | SPS_VERT)) ^ (SPS_HORZ | SPS_VERT)) };
            if (dwSplitterStyleNew & SPS_PARENTWIDTH)
            {
                dwSplitterStyle = (dwSplitterStyleNew & (~SPS_PARENTWIDTH)) | SPS_PARENTHEIGHT;
            }
            if (dwSplitterStyleNew & SPS_PARENTHEIGHT)
            {
                dwSplitterStyle = (dwSplitterStyleNew & (~SPS_PARENTHEIGHT)) | SPS_PARENTWIDTH;
            }
            SetWindowLongPtr(hWndSplitter, GWL_STYLE, static_cast<LONG>(dwSplitterStyleNew));

            InvalidateRect(hWndSplitter, NULL, FALSE);
        }
        break;
    case SPM_SETRANGE:
        {
            if (wParam)
            {
                HWND hWndSplitterParent{ GetAncestor(hWndSplitter, GA_PARENT) };
                RECT rcSplitter{};
                GetWindowRect(hWndSplitter, &rcSplitter);
                MapWindowRect(HWND_DESKTOP, hWndSplitterParent, &rcSplitter);
                if (dwSplitterStyle & SPS_HORZ)
                {
                    ptSplitterRange = { LOWORD(wParam), HIWORD(wParam) - (rcSplitter.bottom - rcSplitter.top) };
                }
                else if (dwSplitterStyle & SPS_VERT)
                {
                    ptSplitterRange = { LOWORD(wParam), HIWORD(wParam) - (rcSplitter.right - rcSplitter.left) };
                }
                if (ptSplitterRange.y >= ptSplitterRange.x)
                {
                    ret = static_cast<LRESULT>(TRUE);
                }
                else
                {
                    ptSplitterRange = {};

                    ret = static_cast<LRESULT>(FALSE);
                }
            }
            else
            {
                ptSplitterRange = {};

                ret = static_cast<LRESULT>(TRUE);
            }
        }
        break;
    case SPM_GETRANGE:
        {
            ret = MAKELRESULT(ptSplitterRange.x, ptSplitterRange.y);
        }
        break;
    case SPM_SETMARGIN:
        {
            dwLineMargin = static_cast<DWORD>(wParam);
            RECT rcSplitterClient{};
            GetClientRect(hWndSplitter, &rcSplitterClient);
            if (dwSplitterStyle & SPS_HORZ)
            {
                POINT ptLineStart{ rcSplitterClient.left + static_cast<LONG>(dwLineMargin), rcSplitterClient.top + (rcSplitterClient.bottom - rcSplitterClient.top) / 2 };
                RECT rcSplitterClientLeftPart{ rcSplitterClient.left, rcSplitterClient.top, rcSplitterClient.left + (rcSplitterClient.right - rcSplitterClient.left) / 2, rcSplitterClient.bottom };
                if (!PtInRect(&rcSplitterClientLeftPart, ptLineStart))
                {
                    dwLineMargin = 0;

                    ret = static_cast<LRESULT>(FALSE);
                    break;
                }
            }
            else if (dwSplitterStyle & SPS_VERT)
            {
                POINT ptLineStart{ rcSplitterClient.left + (rcSplitterClient.right - rcSplitterClient.left) / 2, rcSplitterClient.top + static_cast<LONG>(dwLineMargin) };
                RECT rcSplitterClientUpperPart{ rcSplitterClient.left, rcSplitterClient.top, rcSplitterClient.right, rcSplitterClient.top + (rcSplitterClient.bottom - rcSplitterClient.top) / 2 };
                if (!PtInRect(&rcSplitterClientUpperPart, ptLineStart))
                {
                    dwLineMargin = 0;

                    ret = static_cast<LRESULT>(FALSE);
                    break;
                }
            }
            else
            {
                dwLineMargin = 0;

                ret = static_cast<LRESULT>(FALSE);
                break;
            }

            InvalidateRect(hWndSplitter, NULL, FALSE);

            ret = static_cast<LRESULT>(TRUE);
        }
        break;
    case SPM_GETMARGIN:
        {
            ret = static_cast<LRESULT>(dwLineMargin);
        }
        break;
    case SPM_SETLINKEDCTL:
        {
            switch (HIWORD(wParam))
            {
            case SLC_TOP:
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        LinkedControl[0].clear();
                        try
                        {
                            for (WORD i = 0; i < LOWORD(wParam); i++)
                            {
                                if (IsWindow(reinterpret_cast<HWND*>(lParam)[i]) && (GetAncestor(reinterpret_cast<HWND*>(lParam)[i], GA_PARENT) == GetAncestor(hWndSplitter, GA_PARENT)))
                                {
                                    LinkedControl[0].push_back(reinterpret_cast<HWND*>(lParam)[i]);
                                }
                            }
                            std::sort(LinkedControl[0].begin(), LinkedControl[0].end());
                            LinkedControl[0].erase(std::unique(LinkedControl[0].begin(), LinkedControl[0].end()), LinkedControl[0].end());
                        }
                        catch (...)
                        {
                            LinkedControl[0].clear();

                            ret = 0;
                            break;
                        }

                        ret = static_cast<LRESULT>(LinkedControl[0].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_BOTTOM:
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        LinkedControl[1].clear();
                        try
                        {
                            for (WORD i = 0; i < LOWORD(wParam); i++)
                            {
                                if (IsWindow(reinterpret_cast<HWND*>(lParam)[i]) && (GetAncestor(reinterpret_cast<HWND*>(lParam)[i], GA_PARENT) == GetAncestor(hWndSplitter, GA_PARENT)))
                                {
                                    LinkedControl[1].push_back(reinterpret_cast<HWND*>(lParam)[i]);
                                }
                            }
                            std::sort(LinkedControl[1].begin(), LinkedControl[1].end());
                                                        LinkedControl[1].erase(std::unique(LinkedControl[1].begin(), LinkedControl[1].end()), LinkedControl[1].end());
                        }
                        catch (...)
                        {
                            LinkedControl[1].clear();

                            ret = 0;
                            break;
                        }

                        ret = static_cast<LRESULT>(LinkedControl[1].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_LEFT:
                {
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        LinkedControl[0].clear();
                        try
                        {
                            for (WORD i = 0; i < LOWORD(wParam); i++)
                            {
                                if (IsWindow(reinterpret_cast<HWND*>(lParam)[i]) && (GetAncestor(reinterpret_cast<HWND*>(lParam)[i], GA_PARENT) == GetAncestor(hWndSplitter, GA_PARENT)))
                                {
                                    LinkedControl[0].push_back(reinterpret_cast<HWND*>(lParam)[i]);
                                }
                            }
                            std::sort(LinkedControl[0].begin(), LinkedControl[0].end());
                            LinkedControl[0].erase(std::unique(LinkedControl[0].begin(), LinkedControl[0].end()), LinkedControl[0].end());
                        }
                        catch (...)
                        {
                            LinkedControl[0].clear();

                            ret = 0;
                            break;
                        }

                        ret = static_cast<LRESULT>(LinkedControl[0].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_RIGHT:
                {
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        LinkedControl[1].clear();
                        try
                        {
                            for (WORD i = 0; i < LOWORD(wParam); i++)
                            {
                                if (IsWindow(reinterpret_cast<HWND*>(lParam)[i]) && (GetAncestor(reinterpret_cast<HWND*>(lParam)[i], GA_PARENT) == GetAncestor(hWndSplitter, GA_PARENT)))
                                {
                                    LinkedControl[1].push_back(reinterpret_cast<HWND*>(lParam)[i]);
                                }
                            }
                            std::sort(LinkedControl[1].begin(), LinkedControl[1].end());
                            LinkedControl[1].erase(std::unique(LinkedControl[1].begin(), LinkedControl[1].end()), LinkedControl[1].end());
                        }
                        catch (...)
                        {
                            LinkedControl[1].clear();

                            ret = 0;
                            break;
                        }

                        ret = static_cast<LRESULT>(LinkedControl[1].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            default:
                {
                    ret = 0;
                }
                break;
            }
        }
        break;
    case SPM_GETLINKEDCTL:
        {
            switch (HIWORD(wParam))
            {
            case SLC_TOP:
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        if (lParam)
                        {
                            for (WORD i = 0; i < static_cast<WORD>(LinkedControl[0].size()); i++)
                            {
                                reinterpret_cast<HWND*>(lParam)[i] = LinkedControl[0][i];
                            }
                        }

                        ret = static_cast<LRESULT>(LinkedControl[0].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_BOTTOM:
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        if (lParam)
                        {
                            for (WORD i = 0; i < static_cast<WORD>(LinkedControl[1].size()); i++)
                            {
                                reinterpret_cast<HWND*>(lParam)[i] = LinkedControl[1][i];
                            }
                        }

                        ret = static_cast<LRESULT>(LinkedControl[1].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_LEFT:
                {
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        if (lParam)
                        {
                            for (WORD i = 0; i < static_cast<WORD>(LinkedControl[0].size()); i++)
                            {
                                reinterpret_cast<HWND*>(lParam)[i] = LinkedControl[0][i];
                            }
                        }

                        ret = static_cast<LRESULT>(LinkedControl[0].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_RIGHT:
                {
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        if (lParam)
                        {
                            for (WORD i = 0; i < static_cast<WORD>(LinkedControl[1].size()); i++)
                            {
                                reinterpret_cast<HWND*>(lParam)[i] = LinkedControl[1][i];
                            }
                        }

                        ret = static_cast<LRESULT>(LinkedControl[1].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            default:
                {
                    ret = 0;
                }
                break;
            }
        }
        break;
    case SPM_ADDLINKEDCTL:
        {
            std::vector<HWND> LinkedControlTemp{};

            switch (HIWORD(wParam))
            {
            case SLC_TOP:
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        try
                        {
                            for (WORD i = 0; i < LOWORD(wParam); i++)
                            {
                                if (IsWindow(reinterpret_cast<HWND*>(lParam)[i]) && (GetAncestor(reinterpret_cast<HWND*>(lParam)[i], GA_PARENT) == GetAncestor(hWndSplitter, GA_PARENT)))
                                {
                                    LinkedControlTemp.push_back(reinterpret_cast<HWND*>(lParam)[i]);
                                }
                            }
                            std::sort(LinkedControlTemp.begin(), LinkedControlTemp.end());
                            LinkedControlTemp.erase(std::unique(LinkedControlTemp.begin(), LinkedControlTemp.end()), LinkedControlTemp.end());
                            LinkedControl[0].reserve(LinkedControl[0].size() + LinkedControlTemp.size());
                        }
                        catch (...)
                        {
                            ret = 0;
                            break;
                        }
                        LinkedControl[0].insert(LinkedControl[0].end(), LinkedControlTemp.begin(), LinkedControlTemp.end());

                        ret = static_cast<LRESULT>(LinkedControlTemp.size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_BOTTOM:
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        try
                        {
                            for (WORD i = 0; i < LOWORD(wParam); i++)
                            {
                                if (IsWindow(reinterpret_cast<HWND*>(lParam)[i]) && (GetAncestor(reinterpret_cast<HWND*>(lParam)[i], GA_PARENT) == GetAncestor(hWndSplitter, GA_PARENT)))
                                {
                                    LinkedControlTemp.push_back(reinterpret_cast<HWND*>(lParam)[i]);
                                }
                            }
                            std::sort(LinkedControlTemp.begin(), LinkedControlTemp.end());
                            LinkedControlTemp.erase(std::unique(LinkedControlTemp.begin(), LinkedControlTemp.end()), LinkedControlTemp.end());
                            LinkedControl[1].reserve(LinkedControl[1].size() + LinkedControlTemp.size());
                        }
                        catch (...)
                        {
                            ret = 0;
                            break;
                        }
                        LinkedControl[1].insert(LinkedControl[1].end(), LinkedControlTemp.begin(), LinkedControlTemp.end());

                        ret = static_cast<LRESULT>(LinkedControlTemp.size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_LEFT:
                {
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        try
                        {
                            for (WORD i = 0; i < LOWORD(wParam); i++)
                            {
                                if (IsWindow(reinterpret_cast<HWND*>(lParam)[i]) && (GetAncestor(reinterpret_cast<HWND*>(lParam)[i], GA_PARENT) == GetAncestor(hWndSplitter, GA_PARENT)))
                                {
                                    LinkedControlTemp.push_back(reinterpret_cast<HWND*>(lParam)[i]);
                                }
                            }
                            std::sort(LinkedControlTemp.begin(), LinkedControlTemp.end());
                            LinkedControlTemp.erase(std::unique(LinkedControlTemp.begin(), LinkedControlTemp.end()), LinkedControlTemp.end());
                            LinkedControl[0].reserve(LinkedControl[0].size() + LinkedControlTemp.size());
                        }
                        catch (...)
                        {
                            ret = 0;
                            break;
                        }
                        LinkedControl[0].insert(LinkedControl[0].end(), LinkedControlTemp.begin(), LinkedControlTemp.end());

                        ret = static_cast<LRESULT>(LinkedControlTemp.size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_RIGHT:
                {
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        try
                        {
                            for (WORD i = 0; i < LOWORD(wParam); i++)
                            {
                                if (IsWindow(reinterpret_cast<HWND*>(lParam)[i]) && (GetAncestor(reinterpret_cast<HWND*>(lParam)[i], GA_PARENT) == GetAncestor(hWndSplitter, GA_PARENT)))
                                {
                                    LinkedControlTemp.push_back(reinterpret_cast<HWND*>(lParam)[i]);
                                }
                            }
                            std::sort(LinkedControlTemp.begin(), LinkedControlTemp.end());
                            LinkedControlTemp.erase(std::unique(LinkedControlTemp.begin(), LinkedControlTemp.end()), LinkedControlTemp.end());
                            LinkedControl[1].reserve(LinkedControl[1].size() + LinkedControlTemp.size());
                        }
                        catch (...)
                        {
                            ret = 0;
                            break;
                        }
                        LinkedControl[1].insert(LinkedControl[1].end(), LinkedControlTemp.begin(), LinkedControlTemp.end());

                        ret = static_cast<LRESULT>(LinkedControlTemp.size());
                    }
                }
                break;
            default:
                {
                    ret = 0;
                }
                break;
            }
        }
        break;
    case SPM_REMOVELINKEDCTL:
        {
            switch (HIWORD(wParam))
            {
            case SLC_TOP:
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        std::size_t LinkedControlOriginalSize{ LinkedControl[0].size() };
                        for (WORD i = 0; i < LOWORD(wParam); i++)
                        {
                            LinkedControl[0].erase(std::find(LinkedControl[0].begin(), LinkedControl[0].end(), reinterpret_cast<HWND*>(lParam)[i]));
                        }

                        ret = static_cast<LRESULT>(LinkedControlOriginalSize - LinkedControl[0].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_BOTTOM:
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        std::size_t LinkedControlOriginalSize{ LinkedControl[1].size() };
                        for (WORD i = 0; i < LOWORD(wParam); i++)
                        {
                            LinkedControl[1].erase(std::find(LinkedControl[1].begin(), LinkedControl[1].end(), reinterpret_cast<HWND*>(lParam)[i]));
                        }

                        ret = static_cast<LRESULT>(LinkedControlOriginalSize - LinkedControl[1].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_LEFT:
                {
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        std::size_t LinkedControlOriginalSize{ LinkedControl[0].size() };
                        for (WORD i = 0; i < LOWORD(wParam); i++)
                        {
                            LinkedControl[0].erase(std::find(LinkedControl[0].begin(), LinkedControl[0].end(), reinterpret_cast<HWND*>(lParam)[i]));
                        }

                        ret = static_cast<LRESULT>(LinkedControlOriginalSize - LinkedControl[0].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            case SLC_RIGHT:
                {
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        std::size_t LinkedControlOriginalSize{ LinkedControl[1].size() };
                        for (WORD i = 0; i < LOWORD(wParam); i++)
                        {
                            LinkedControl[1].erase(std::find(LinkedControl[1].begin(), LinkedControl[1].end(), reinterpret_cast<HWND*>(lParam)[i]));
                        }

                        ret = static_cast<LRESULT>(LinkedControlOriginalSize - LinkedControl[1].size());
                    }
                    else
                    {
                        ret = 0;
                    }
                }
                break;
            default:
                {
                    ret = 0;
                }
                break;
            }
        }
        break;
    case WM_CREATE:
        {
            dwSplitterStyle = static_cast<DWORD>(reinterpret_cast<LPCREATESTRUCT>(lParam)->style);
            idSplitter = static_cast<WORD>(reinterpret_cast<UINT_PTR>(reinterpret_cast<LPCREATESTRUCT>(lParam)->hMenu) & 0xFFFF);

            if (static_cast<bool>(dwSplitterStyle & SPS_HORZ) == static_cast<bool>(dwSplitterStyle & SPS_VERT))
            {
                dwSplitterStyle = dwSplitterStyle & (~(SPS_HORZ | SPS_VERT));
            }
            if ((dwSplitterStyle & SPS_PARENTWIDTH) && (dwSplitterStyle & SPS_PARENTHEIGHT))
            {
                dwSplitterStyle = dwSplitterStyle & (~(SPS_PARENTWIDTH | SPS_PARENTHEIGHT));
            }
            if ((dwSplitterStyle & SPS_HORZ) && (dwSplitterStyle & SPS_PARENTHEIGHT))
            {
                dwSplitterStyle = dwSplitterStyle & (~(SPS_PARENTHEIGHT));
            }
            if ((dwSplitterStyle & SPS_VERT) && (dwSplitterStyle & SPS_PARENTWIDTH))
            {
                dwSplitterStyle = dwSplitterStyle & (~(SPS_PARENTWIDTH));
            }
            SetWindowLongPtr(hWndSplitter, GWL_STYLE, static_cast<LONG>(dwSplitterStyle));

            ret = 0;
        }
        break;
    case WM_ERASEBKGND:
        {
            ret = static_cast<LRESULT>(TRUE);
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps{};
            HDC hDCSplitter{ BeginPaint(hWndSplitter, &ps) };

            HWND hWndSplitterParent{ GetAncestor(hWndSplitter, GA_PARENT) };
            HBRUSH hBrSplitterBackground{ FORWARD_WM_CTLCOLORSTATIC(hWndSplitterParent, hDCSplitter, hWndSplitter, SendMessage) };

            RECT rcSplitterClient{};
            GetClientRect(hWndSplitter, &rcSplitterClient);
            if (!hBrSplitterBackground)
            {
                hBrSplitterBackground = GetSysColorBrush(COLOR_3DFACE);
            }
            FillRect(hDCSplitter, &rcSplitterClient, hBrSplitterBackground);

            if (dwSplitterStyle & SPS_HORZ)
            {
                MoveToEx(hDCSplitter, rcSplitterClient.left + dwLineMargin, rcSplitterClient.top + (rcSplitterClient.bottom - rcSplitterClient.top) / 2, NULL);
                LineTo(hDCSplitter, rcSplitterClient.right - dwLineMargin, rcSplitterClient.top + (rcSplitterClient.bottom - rcSplitterClient.top) / 2);
            }
            else if (dwSplitterStyle & SPS_VERT)
            {
                MoveToEx(hDCSplitter, rcSplitterClient.left + (rcSplitterClient.right - rcSplitterClient.left) / 2, rcSplitterClient.top + dwLineMargin, NULL);
                LineTo(hDCSplitter, rcSplitterClient.left + (rcSplitterClient.right - rcSplitterClient.left) / 2, rcSplitterClient.bottom - dwLineMargin);
            }

            EndPaint(hWndSplitter, &ps);
        }
        break;
    case WM_LBUTTONDOWN:
        {
            if (!(dwSplitterStyle & SPS_NOCAPTURE))
            {
                SetCapture(hWndSplitter);
            }

            if (!(dwSplitterStyle & SPS_NONOTIFY))
            {
                HWND hWndSplitterParent{ GetAncestor(hWndSplitter, GA_PARENT) };
                RECT rcSplitter{}, rcSplitterClient{};
                GetWindowRect(hWndSplitter, &rcSplitter);
                GetClientRect(hWndSplitter, &rcSplitterClient);
                MapWindowRect(hWndSplitter, HWND_DESKTOP, &rcSplitterClient);
                POINT ptCursor{ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
                ptCursorOffset = { ptCursor.x + (rcSplitterClient.left - rcSplitter.left), ptCursor.y + (rcSplitterClient.top - rcSplitter.top) };
                MapWindowPoints(hWndSplitter, hWndSplitterParent, &ptCursor, 1);
                NMSPLITTER nms{ { hWndSplitter, static_cast<UINT_PTR>(idSplitter), static_cast<UINT>(SPN_DRAGBEGIN) }, ptCursor, ptCursorOffset };
                SendMessage(hWndSplitterParent, WM_NOTIFY, static_cast<WPARAM>(idSplitter), reinterpret_cast<LPARAM>(&nms));
            }
        }
        break;
    case WM_MOUSEMOVE:
        {
            if ((wParam == MK_LBUTTON))
            {
                HWND hWndSplitterParent{ GetAncestor(hWndSplitter, GA_PARENT) };
                POINT ptCursor{ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }, ptSplitter{}, ptCursorOffsetNew{ ptCursorOffset };
                MapWindowPoints(hWndSplitter, hWndSplitterParent, &ptCursor, 1);
                ptSplitter = { ptCursor.x - ptCursorOffsetNew.x, ptCursor.y - ptCursorOffsetNew.y };
                if ((ptSplitterRange.x != 0) || (ptSplitterRange.y != 0))
                {
                    if (dwSplitterStyle & SPS_HORZ)
                    {
                        if (ptSplitter.y < ptSplitterRange.x)
                        {
                            ptSplitter.y = ptSplitterRange.x;
                            ptCursorOffsetNew.y = ptCursor.y - ptSplitterRange.x;
                        }
                        if (ptSplitter.y > ptSplitterRange.y)
                        {
                            ptSplitter.y = ptSplitterRange.y;
                            ptCursorOffsetNew.y = ptCursor.y - ptSplitterRange.y;
                        }
                    }
                    if (dwSplitterStyle & SPS_VERT)
                    {
                        if (ptSplitter.x < ptSplitterRange.x)
                        {
                            ptSplitter.x = ptSplitterRange.x;
                            ptCursorOffsetNew.x = ptCursor.x - ptSplitterRange.x;
                        }
                        if (ptSplitter.x > ptSplitterRange.y)
                        {
                            ptSplitter.x = ptSplitterRange.y;
                            ptCursorOffsetNew.x = ptCursor.x - ptSplitterRange.y;
                        }
                    }
                }

                if (dwSplitterStyle & SPS_AUTODRAG)
                {
                    FORWARD_WM_MOVE(hWndSplitter, ptSplitter.x, ptSplitter.y, SendMessage);
                }

                if (!(dwSplitterStyle & SPS_NONOTIFY))
                {
                    NMSPLITTER nms{ { hWndSplitter, static_cast<UINT_PTR>(idSplitter), static_cast<UINT>(SPN_DRAGGING) }, ptCursor, ptCursorOffsetNew };
                    SendMessage(hWndSplitterParent, WM_NOTIFY, static_cast<WPARAM>(idSplitter), reinterpret_cast<LPARAM>(&nms));
                }
            }
        }
        break;
    case WM_LBUTTONUP:
        {
            if (!(dwSplitterStyle & SPS_NOCAPTURE))
            {
                ReleaseCapture();
            }

            if (!(dwSplitterStyle & SPS_NONOTIFY))
            {
                HWND hWndSplitterParent{ GetAncestor(hWndSplitter, GA_PARENT) };
                POINT ptCursor{ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
                MapWindowPoints(hWndSplitter, hWndSplitterParent, &ptCursor, 1);
                NMSPLITTER nms{ { hWndSplitter, static_cast<UINT_PTR>(idSplitter), static_cast<UINT>(SPN_DRAGEND) }, ptCursor, ptCursorOffset };
                SendMessage(hWndSplitterParent, WM_NOTIFY, static_cast<WPARAM>(idSplitter), reinterpret_cast<LPARAM>(&nms));
            }
        }
        break;
    case WM_SETCURSOR:
        {
            if (reinterpret_cast<HWND>(wParam) == hWndSplitter)
            {
                if (dwSplitterStyle & SPS_HORZ)
                {
                    SetCursor(LoadCursor(NULL, IDC_SIZENS));

                    ret = static_cast<LRESULT>(TRUE);
                }
                else if (dwSplitterStyle & SPS_VERT)
                {
                    SetCursor(LoadCursor(NULL, IDC_SIZEWE));

                    ret = static_cast<LRESULT>(TRUE);
                }
                else
                {
                    ret = static_cast<LRESULT>(FALSE);
                }
            }
        }
        break;
    case WM_MOVE:
        {
            HWND hWndSplitterParent{ GetAncestor(hWndSplitter, GA_PARENT) };
            RECT rcSplitter{}, rcSplitterParentClient{};
            GetWindowRect(hWndSplitter, &rcSplitter);
            GetClientRect(hWndSplitterParent, &rcSplitterParentClient);
            int xPosSplitter{}, yPosSplitter{}, cxSplitter{}, cySplitter{};
            UINT uFlags{ SWP_NOZORDER | SWP_NOACTIVATE };
            if (dwSplitterStyle & SPS_PARENTWIDTH)
            {
                xPosSplitter = rcSplitterParentClient.left;
                yPosSplitter = GET_Y_LPARAM(lParam);
                cxSplitter = rcSplitterParentClient.right - rcSplitterParentClient.left;
                cySplitter = rcSplitter.bottom - rcSplitter.top;
            }
            else if (dwSplitterStyle & SPS_PARENTHEIGHT)
            {
                xPosSplitter = GET_X_LPARAM(lParam);
                yPosSplitter = rcSplitterParentClient.top;
                cxSplitter = rcSplitter.right - rcSplitter.left;
                cySplitter = rcSplitterParentClient.bottom - rcSplitterParentClient.top;
            }
            else
            {
                xPosSplitter = GET_X_LPARAM(lParam);
                yPosSplitter = GET_Y_LPARAM(lParam);
                uFlags |= SWP_NOSIZE;
            }
            SetWindowPos(hWndSplitter, NULL, xPosSplitter, yPosSplitter, cxSplitter, cySplitter, uFlags);

            MapWindowRect(HWND_DESKTOP, hWndSplitterParent, &rcSplitter);
            for (const auto& i : LinkedControl[0])
            {
                RECT rcLinkedWindow{};
                GetWindowRect(i, &rcLinkedWindow);
                MapWindowRect(HWND_DESKTOP, hWndSplitterParent, &rcLinkedWindow);
                if (dwSplitterStyle & SPS_HORZ)
                {
                    SetWindowPos(i, NULL, 0, 0, rcLinkedWindow.right - rcLinkedWindow.left, yPosSplitter - rcLinkedWindow.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
                }
                else if (dwSplitterStyle & SPS_VERT)
                {
                    SetWindowPos(i, NULL, 0, 0, xPosSplitter - rcLinkedWindow.left, rcLinkedWindow.bottom - rcLinkedWindow.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
                }
            }
            for (const auto& i : LinkedControl[1])
            {
                RECT rcLinkedWindow{};
                GetWindowRect(i, &rcLinkedWindow);
                MapWindowRect(HWND_DESKTOP, hWndSplitterParent, &rcLinkedWindow);
                if (dwSplitterStyle & SPS_HORZ)
                {
                    SetWindowPos(i, NULL, rcLinkedWindow.left, yPosSplitter + cySplitter, rcLinkedWindow.right - rcLinkedWindow.left, rcLinkedWindow.bottom - (yPosSplitter + cySplitter), SWP_NOZORDER | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
                }
                else if (dwSplitterStyle & SPS_VERT)
                {
                    SetWindowPos(i, NULL, xPosSplitter + cxSplitter, rcLinkedWindow.top, rcLinkedWindow.right - (xPosSplitter + cxSplitter), rcLinkedWindow.bottom - rcLinkedWindow.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
                }
            }
        }
        break;
    case WM_SIZE:
        {
            HWND hWndSplitterParent{ GetAncestor(hWndSplitter, GA_PARENT) };
            RECT rcSplitter{}, rcSplitterParentClient{};
            GetWindowRect(hWndSplitter, &rcSplitter);
            MapWindowRect(HWND_DESKTOP, hWndSplitterParent, &rcSplitter);
            GetClientRect(hWndSplitterParent, &rcSplitterParentClient);
            int xPosSplitter{}, yPosSplitter{}, cxSplitter{}, cySplitter{};
            UINT uFlags{ SWP_NOZORDER | SWP_NOACTIVATE };
            if (dwSplitterStyle & SPS_PARENTWIDTH)
            {
                xPosSplitter = rcSplitterParentClient.left;
                yPosSplitter = rcSplitter.top;
                cxSplitter = rcSplitterParentClient.right - rcSplitterParentClient.left;
                cySplitter = HIWORD(lParam);
            }
            else if (dwSplitterStyle & SPS_PARENTHEIGHT)
            {
                xPosSplitter = rcSplitter.left;
                yPosSplitter = rcSplitterParentClient.top;
                cxSplitter = LOWORD(lParam);
                cySplitter = rcSplitterParentClient.bottom - rcSplitterParentClient.top;
            }
            else
            {
                cxSplitter = LOWORD(lParam);
                cySplitter = HIWORD(lParam);
                uFlags |= SWP_NOMOVE;
            }
            SetWindowPos(hWndSplitter, NULL, xPosSplitter, yPosSplitter, cxSplitter, cySplitter, uFlags);

            MapWindowRect(HWND_DESKTOP, hWndSplitterParent, &rcSplitter);
            for (const auto& i : LinkedControl[0])
            {
                RECT rcLinkedWindow{};
                GetWindowRect(i, &rcLinkedWindow);
                MapWindowRect(HWND_DESKTOP, hWndSplitterParent, &rcLinkedWindow);
                if (dwSplitterStyle & SPS_HORZ)
                {
                    SetWindowPos(i, NULL, 0, 0, rcLinkedWindow.right - rcLinkedWindow.left, yPosSplitter - rcLinkedWindow.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
                }
                else if (dwSplitterStyle & SPS_VERT)
                {
                    SetWindowPos(i, NULL, 0, 0, xPosSplitter - rcLinkedWindow.left, rcLinkedWindow.bottom - rcLinkedWindow.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
                }
            }
            for (const auto& i : LinkedControl[1])
            {
                RECT rcLinkedWindow{};
                GetWindowRect(i, &rcLinkedWindow);
                MapWindowRect(HWND_DESKTOP, hWndSplitterParent, &rcLinkedWindow);
                if (dwSplitterStyle & SPS_HORZ)
                {
                    SetWindowPos(i, NULL, rcLinkedWindow.left, yPosSplitter + cySplitter, rcLinkedWindow.right - rcLinkedWindow.left, rcLinkedWindow.bottom - (yPosSplitter + cySplitter), SWP_NOZORDER | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
                }
                else if (dwSplitterStyle & SPS_VERT)
                {
                    SetWindowPos(i, NULL, xPosSplitter + cxSplitter, rcLinkedWindow.top, rcLinkedWindow.right - (xPosSplitter + cxSplitter), rcLinkedWindow.bottom - rcLinkedWindow.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
                }
            }
        }
        break;
    case WM_STYLECHANGING:
        {
            if (wParam == GWL_STYLE)
            {
                if (static_cast<bool>(reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & SPS_HORZ) == static_cast<bool>(reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & SPS_VERT))
                {
                    reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew = reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & (~(SPS_HORZ | SPS_VERT));
                }
                if ((reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & SPS_PARENTWIDTH) && (reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & SPS_PARENTHEIGHT))
                {
                    reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew = reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & (~(SPS_PARENTWIDTH | SPS_PARENTHEIGHT));
                }
                if ((reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & SPS_HORZ) && (reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & SPS_PARENTHEIGHT))
                {
                    reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew = reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & (~(SPS_PARENTHEIGHT));
                }
                if ((reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & SPS_VERT) && (reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & SPS_PARENTWIDTH))
                {
                    reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew = reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew & (~(SPS_PARENTWIDTH));
                }

                if (reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleNew != reinterpret_cast<LPSTYLESTRUCT>(lParam)->styleOld)
                {
                    InvalidateRect(hWndSplitter, NULL, FALSE);
                }
            }
        }
        break;
    default:
        {
            ret = DefWindowProc(hWndSplitter, Message, wParam, lParam);
        }
        break;
    }

    return ret;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文