From 81f31280b40dfd5e412438743cd5ffd0c4297ecb Mon Sep 17 00:00:00 2001 From: Ratin Gao Date: Thu, 28 Nov 2024 07:11:30 +0800 Subject: [PATCH] Update --- .../KNSoft.MakeLifeEasier.vcxproj | 15 +- .../KNSoft.MakeLifeEasier.vcxproj.filters | 36 +++- .../KNSoft.MakeLifeEasier/KNSoft/DialogBox.h | 11 +- Source/KNSoft.MakeLifeEasier/MakeLifeEasier.h | 8 +- Source/KNSoft.MakeLifeEasier/UI/Control.c | 194 ------------------ .../KNSoft.MakeLifeEasier/UI/Control/Dialog.h | 24 +++ .../UI/Control/ListView.c | 53 +++++ .../UI/Control/ListView.h | 15 ++ .../KNSoft.MakeLifeEasier/UI/Control/Menu.c | 71 +++++++ .../UI/{Control.h => Control/Menu.h} | 42 +--- .../UI/Control/PropSheet.c | 92 +++++++++ .../UI/Control/PropSheet.h | 34 +++ .../UI/Control/TreeView.c | 57 +++++ .../UI/Control/TreeView.h | 29 +++ Source/KNSoft.MakeLifeEasier/UI/Message.c | 8 +- Source/KNSoft.MakeLifeEasier/UI/Message.h | 4 +- Source/KNSoft.MakeLifeEasier/UI/Window.c | 34 +++ Source/KNSoft.MakeLifeEasier/UI/Window.h | 41 ++++ Source/KNSoft.MakeLifeEasier/packages.config | 2 +- Source/Test/Test.vcxproj | 4 +- Source/Test/packages.config | 2 +- 21 files changed, 512 insertions(+), 264 deletions(-) delete mode 100644 Source/KNSoft.MakeLifeEasier/UI/Control.c create mode 100644 Source/KNSoft.MakeLifeEasier/UI/Control/Dialog.h create mode 100644 Source/KNSoft.MakeLifeEasier/UI/Control/ListView.c create mode 100644 Source/KNSoft.MakeLifeEasier/UI/Control/ListView.h create mode 100644 Source/KNSoft.MakeLifeEasier/UI/Control/Menu.c rename Source/KNSoft.MakeLifeEasier/UI/{Control.h => Control/Menu.h} (67%) create mode 100644 Source/KNSoft.MakeLifeEasier/UI/Control/PropSheet.c create mode 100644 Source/KNSoft.MakeLifeEasier/UI/Control/PropSheet.h create mode 100644 Source/KNSoft.MakeLifeEasier/UI/Control/TreeView.c create mode 100644 Source/KNSoft.MakeLifeEasier/UI/Control/TreeView.h diff --git a/Source/KNSoft.MakeLifeEasier/KNSoft.MakeLifeEasier.vcxproj b/Source/KNSoft.MakeLifeEasier/KNSoft.MakeLifeEasier.vcxproj index eee1e06..688fcc9 100644 --- a/Source/KNSoft.MakeLifeEasier/KNSoft.MakeLifeEasier.vcxproj +++ b/Source/KNSoft.MakeLifeEasier/KNSoft.MakeLifeEasier.vcxproj @@ -188,7 +188,10 @@ - + + + + @@ -238,7 +241,11 @@ - + + + + + @@ -263,7 +270,7 @@ - + @@ -271,6 +278,6 @@ - + \ No newline at end of file diff --git a/Source/KNSoft.MakeLifeEasier/KNSoft.MakeLifeEasier.vcxproj.filters b/Source/KNSoft.MakeLifeEasier/KNSoft.MakeLifeEasier.vcxproj.filters index 96808e1..fce9d67 100644 --- a/Source/KNSoft.MakeLifeEasier/KNSoft.MakeLifeEasier.vcxproj.filters +++ b/Source/KNSoft.MakeLifeEasier/KNSoft.MakeLifeEasier.vcxproj.filters @@ -46,6 +46,9 @@ {c33347fe-2000-4c97-bd09-132385981b94} + + {2aeeba04-9117-436c-ab83-36a0eed7434a} + @@ -101,9 +104,6 @@ UI - - UI - System @@ -153,6 +153,18 @@ Process + + UI\Control + + + UI\Control + + + UI\Control + + + UI\Control + @@ -219,9 +231,6 @@ UI - - UI - System @@ -278,6 +287,21 @@ NT + + UI\Control + + + UI\Control + + + UI\Control + + + UI\Control + + + UI\Control + diff --git a/Source/KNSoft.MakeLifeEasier/KNSoft/DialogBox.h b/Source/KNSoft.MakeLifeEasier/KNSoft/DialogBox.h index 9533813..5332c99 100644 --- a/Source/KNSoft.MakeLifeEasier/KNSoft/DialogBox.h +++ b/Source/KNSoft.MakeLifeEasier/KNSoft/DialogBox.h @@ -8,19 +8,12 @@ EXTERN_C_START FORCEINLINE HRESULT -KNS_DlgBox( - _In_opt_ HINSTANCE Instance, - _In_opt_ HWND Owner, - _In_ LPCDLGTEMPLATEW DialogTemplate, - _In_opt_ HACCEL Accelerator, - _In_opt_ DLGPROC DlgProc, - _In_opt_ LPARAM InitParam) +KNS_DlgMessageLoop( + _In_opt_ HACCEL Accelerator) { INT DlgRet; W32ERROR Ret; - CreateDialogIndirectParamW(Instance, DialogTemplate, Owner, DlgProc, InitParam); - Ret = UI_MessageLoop(NULL, TRUE, Accelerator, &DlgRet); return Ret == ERROR_SUCCESS ? (HRESULT)DlgRet : HRESULT_FROM_WIN32(Ret); } diff --git a/Source/KNSoft.MakeLifeEasier/MakeLifeEasier.h b/Source/KNSoft.MakeLifeEasier/MakeLifeEasier.h index 23e6949..abc62ca 100644 --- a/Source/KNSoft.MakeLifeEasier/MakeLifeEasier.h +++ b/Source/KNSoft.MakeLifeEasier/MakeLifeEasier.h @@ -46,6 +46,7 @@ typedef _Return_type_success_(return == 0) ULONG W32ERROR; #include "System/Library.h" #include "System/Registry.h" #include "UI/GDI.h" +#include "UI/Message.h" /* L2 Header: No dependencies yet */ #include "Crypt/Cert.h" @@ -61,10 +62,12 @@ typedef _Return_type_success_(return == 0) ULONG W32ERROR; #include "String/Encoding.h" #include "String/Hash.h" #include "System/Info.h" -#include "UI/Control.h" +#include "UI/Control/ListView.h" +#include "UI/Control/Menu.h" +#include "UI/Control/PropSheet.h" +#include "UI/Control/TreeView.h" #include "UI/DialogBox/DialogBox.h" #include "UI/DPI.h" -#include "UI/Message.h" #include "UI/Paint.h" #include "UI/Window.h" @@ -72,6 +75,7 @@ typedef _Return_type_success_(return == 0) ULONG W32ERROR; #include "Error/Message.h" #include "IO/File.h" #include "Process/Process.h" +#include "UI/Control/Dialog.h" /* KNSoft specification, do not use */ #if defined(_KNSOFT_) diff --git a/Source/KNSoft.MakeLifeEasier/UI/Control.c b/Source/KNSoft.MakeLifeEasier/UI/Control.c deleted file mode 100644 index db46319..0000000 --- a/Source/KNSoft.MakeLifeEasier/UI/Control.c +++ /dev/null @@ -1,194 +0,0 @@ -#include "../MakeLifeEasier.inl" - -VOID -NTAPI -UI_SetDialogFont( - _In_ HWND Dialog, - _In_opt_ HFONT Font) -{ - HWND hWnd = GetWindow(Dialog, GW_CHILD); - while (hWnd) - { - UI_SetWindowFont(hWnd, Font, FALSE); - hWnd = GetWindow(hWnd, GW_HWNDNEXT); - } - UI_Redraw(Dialog); -} - -LOGICAL -NTAPI -UI_ListViewSort( - _In_ HWND List, - _In_ PFNLVCOMPARE CompareFn, - _In_ INT ColumnIndex) -{ - HWND hHeader; - INT i; - UINT Flag; - HDITEMW stHDI; - - hHeader = ListView_GetHeader(List); - stHDI.mask = HDI_FORMAT; - if (!Header_GetItem(hHeader, ColumnIndex, &stHDI)) - { - return FALSE; - } - Flag = FlagOn(stHDI.fmt, HDF_SORTUP) ? HDF_SORTDOWN : HDF_SORTUP; - ClearFlag(stHDI.fmt, HDF_SORTDOWN | HDF_SORTUP); - SetFlag(stHDI.fmt, Flag); - if (!Header_SetItem(hHeader, ColumnIndex, &stHDI)) - { - return FALSE; - } - - i = Header_GetItemCount(hHeader); - while (--i >= 0) - { - if (Header_GetItem(hHeader, i, &stHDI)) - { - if (i != ColumnIndex) - { - ClearFlag(stHDI.fmt, HDF_SORTDOWN | HDF_SORTUP); - } - Header_SetItem(hHeader, i, &stHDI); - } - } - - if (Flag == HDF_SORTDOWN) - { - if (ColumnIndex != 0) - { - ColumnIndex = -ColumnIndex; - } else - { - ColumnIndex = INT_MIN; - } - } - return ListView_SortItems(List, CompareFn, ColumnIndex); -} - -W32ERROR -NTAPI -UI_CreateMenuItemsEx( - _In_ HMENU Parent, - _Inout_updates_(Count) PUI_MENU_ITEM Items, - _In_ UINT Count) -{ - W32ERROR eRet; - UINT i, j, Index; - UINT_PTR uIDNewItem; - - Index = 0; - for (i = 0; i < Count; i++) - { - if (Items[i].Invalid) - { - continue; - } - if (Items[i].SubMenusCount > 0) - { - Items[i].Handle = CreatePopupMenu(); - if (Items[i].Handle == NULL) - { - break; - } - eRet = UI_CreateMenuItemsEx(Items[i].Handle, Items[i].SubMenus, Items[i].SubMenusCount); - if (eRet != ERROR_SUCCESS) - { - NtSetLastError(eRet); - break; - } - Items[i].Flags |= MF_POPUP; - uIDNewItem = (UINT_PTR)Items[i].Handle; - } else - { - Items[i].Handle = NULL; - uIDNewItem = Items[i].Id; - } - if (!AppendMenuW(Parent, Items[i].Flags, uIDNewItem, Items[i].Text)) - { - break; - } - if (Items[i].Icon != NULL) - { - SetMenuItemBitmaps(Parent, Index, MF_BYPOSITION, Items[i].Icon, Items[i].Icon); - } - if (Items[i].Flags & MF_DEFAULT) - { - SetMenuDefaultItem(Parent, Index, MF_BYPOSITION); - } - Index++; - } - - if (i < Count) - { - eRet = NtGetLastError(); - for (j = 0; j <= i; j++) - { - if (Items[j].Handle != NULL) - { - DestroyMenu(Items[i].Handle); - } - UI_DestroyMenuItemsEx(Items[j].SubMenus, Items[j].SubMenusCount); - } - return eRet; - } - - return ERROR_SUCCESS; -} - -HRESULT -NTAPI -UI_TreeViewEnumItems( - _In_ HWND TreeView, - _In_ LOGICAL BFS, - _In_ __callback PUI_TREEVIEW_ENUMITEM_FN TreeItemEnumProc, - _In_opt_ PVOID Context) -{ - UINT uDepth; - HTREEITEM hItem, hItemTemp; - - if (BFS) - { - // TODO: Implement BFS - return E_NOTIMPL; - } - - uDepth = 0; - hItem = (HTREEITEM)SendMessageW(TreeView, TVM_GETNEXTITEM, TVGN_ROOT, 0); - do - { - if (!TreeItemEnumProc(TreeView, hItem, uDepth, Context)) - { - return S_FALSE; - } - - hItemTemp = hItem; - hItem = (HTREEITEM)SendMessageW(TreeView, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItemTemp); - if (hItem != NULL) - { - uDepth++; - continue; - } - hItem = (HTREEITEM)SendMessageW(TreeView, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItemTemp); - if (hItem != NULL) - { - continue; - } - while (--uDepth) - { - hItem = (HTREEITEM)SendMessageW(TreeView, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItemTemp); - hItemTemp = (HTREEITEM)SendMessageW(TreeView, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem); - if (hItemTemp != NULL) - { - hItem = hItemTemp; - break; - } else - { - hItemTemp = hItem; - } - } - } while (uDepth != 0); - - return S_OK; -} diff --git a/Source/KNSoft.MakeLifeEasier/UI/Control/Dialog.h b/Source/KNSoft.MakeLifeEasier/UI/Control/Dialog.h new file mode 100644 index 0000000..ef09928 --- /dev/null +++ b/Source/KNSoft.MakeLifeEasier/UI/Control/Dialog.h @@ -0,0 +1,24 @@ +#pragma once + +#include "../../MakeLifeEasier.h" + +#include "../Message.h" + +EXTERN_C_START + +FORCEINLINE +VOID +UI_SetDialogFont( + _In_ HWND Dialog, + _In_opt_ HFONT Font) +{ + HWND hWnd = GetWindow(Dialog, GW_CHILD); + while (hWnd) + { + UI_SetWindowFont(hWnd, Font, FALSE); + hWnd = GetWindow(hWnd, GW_HWNDNEXT); + } + UI_Redraw(Dialog); +} + +EXTERN_C_END diff --git a/Source/KNSoft.MakeLifeEasier/UI/Control/ListView.c b/Source/KNSoft.MakeLifeEasier/UI/Control/ListView.c new file mode 100644 index 0000000..5c047b1 --- /dev/null +++ b/Source/KNSoft.MakeLifeEasier/UI/Control/ListView.c @@ -0,0 +1,53 @@ +#include "../../MakeLifeEasier.inl" + +LOGICAL +NTAPI +UI_ListViewSort( + _In_ HWND List, + _In_ PFNLVCOMPARE CompareFn, + _In_ INT ColumnIndex) +{ + HWND hHeader; + INT i; + UINT Flag; + HDITEMW stHDI; + + hHeader = ListView_GetHeader(List); + stHDI.mask = HDI_FORMAT; + if (!Header_GetItem(hHeader, ColumnIndex, &stHDI)) + { + return FALSE; + } + Flag = FlagOn(stHDI.fmt, HDF_SORTUP) ? HDF_SORTDOWN : HDF_SORTUP; + ClearFlag(stHDI.fmt, HDF_SORTDOWN | HDF_SORTUP); + SetFlag(stHDI.fmt, Flag); + if (!Header_SetItem(hHeader, ColumnIndex, &stHDI)) + { + return FALSE; + } + + i = Header_GetItemCount(hHeader); + while (--i >= 0) + { + if (Header_GetItem(hHeader, i, &stHDI)) + { + if (i != ColumnIndex) + { + ClearFlag(stHDI.fmt, HDF_SORTDOWN | HDF_SORTUP); + } + Header_SetItem(hHeader, i, &stHDI); + } + } + + if (Flag == HDF_SORTDOWN) + { + if (ColumnIndex != 0) + { + ColumnIndex = -ColumnIndex; + } else + { + ColumnIndex = INT_MIN; + } + } + return ListView_SortItems(List, CompareFn, ColumnIndex); +} diff --git a/Source/KNSoft.MakeLifeEasier/UI/Control/ListView.h b/Source/KNSoft.MakeLifeEasier/UI/Control/ListView.h new file mode 100644 index 0000000..401fa1a --- /dev/null +++ b/Source/KNSoft.MakeLifeEasier/UI/Control/ListView.h @@ -0,0 +1,15 @@ +#pragma once + +#include "../../MakeLifeEasier.h" + +EXTERN_C_START + +MLE_API +LOGICAL +NTAPI +UI_ListViewSort( + _In_ HWND List, + _In_ PFNLVCOMPARE CompareFn, + _In_ INT ColumnIndex); + +EXTERN_C_END diff --git a/Source/KNSoft.MakeLifeEasier/UI/Control/Menu.c b/Source/KNSoft.MakeLifeEasier/UI/Control/Menu.c new file mode 100644 index 0000000..5ad580a --- /dev/null +++ b/Source/KNSoft.MakeLifeEasier/UI/Control/Menu.c @@ -0,0 +1,71 @@ +#include "../../MakeLifeEasier.inl" + +W32ERROR +NTAPI +UI_CreateMenuItemsEx( + _In_ HMENU Parent, + _Inout_updates_(Count) UI_MENU_ITEM Items[], + _In_ UINT Count) +{ + W32ERROR eRet; + UINT i, j, Index; + UINT_PTR uIDNewItem; + + Index = 0; + for (i = 0; i < Count; i++) + { + if (Items[i].Invalid) + { + continue; + } + if (Items[i].SubMenusCount > 0) + { + Items[i].Handle = CreatePopupMenu(); + if (Items[i].Handle == NULL) + { + break; + } + eRet = UI_CreateMenuItemsEx(Items[i].Handle, Items[i].SubMenus, Items[i].SubMenusCount); + if (eRet != ERROR_SUCCESS) + { + NtSetLastError(eRet); + break; + } + Items[i].Flags |= MF_POPUP; + uIDNewItem = (UINT_PTR)Items[i].Handle; + } else + { + Items[i].Handle = NULL; + uIDNewItem = Items[i].Id; + } + if (!AppendMenuW(Parent, Items[i].Flags, uIDNewItem, Items[i].Text)) + { + break; + } + if (Items[i].Icon != NULL) + { + SetMenuItemBitmaps(Parent, Index, MF_BYPOSITION, Items[i].Icon, Items[i].Icon); + } + if (Items[i].Flags & MF_DEFAULT) + { + SetMenuDefaultItem(Parent, Index, MF_BYPOSITION); + } + Index++; + } + + if (i < Count) + { + eRet = NtGetLastError(); + for (j = 0; j <= i; j++) + { + if (Items[j].Handle != NULL) + { + DestroyMenu(Items[i].Handle); + } + UI_DestroyMenuItemsEx(Items[j].SubMenus, Items[j].SubMenusCount); + } + return eRet; + } + + return ERROR_SUCCESS; +} diff --git a/Source/KNSoft.MakeLifeEasier/UI/Control.h b/Source/KNSoft.MakeLifeEasier/UI/Control/Menu.h similarity index 67% rename from Source/KNSoft.MakeLifeEasier/UI/Control.h rename to Source/KNSoft.MakeLifeEasier/UI/Control/Menu.h index b47c942..f37a0ef 100644 --- a/Source/KNSoft.MakeLifeEasier/UI/Control.h +++ b/Source/KNSoft.MakeLifeEasier/UI/Control/Menu.h @@ -1,24 +1,9 @@ #pragma once -#include "../MakeLifeEasier.h" +#include "../../MakeLifeEasier.h" EXTERN_C_START -MLE_API -VOID -NTAPI -UI_SetDialogFont( - _In_ HWND Dialog, - _In_opt_ HFONT Font); - -MLE_API -LOGICAL -NTAPI -UI_ListViewSort( - _In_ HWND List, - _In_ PFNLVCOMPARE CompareFn, - _In_ INT ColumnIndex); - typedef struct _UI_MENU_ITEM UI_MENU_ITEM, *PUI_MENU_ITEM; struct _UI_MENU_ITEM { @@ -42,7 +27,7 @@ W32ERROR NTAPI UI_CreateMenuItemsEx( _In_ HMENU Parent, - _Inout_updates_(Count) PUI_MENU_ITEM Items, + _Inout_updates_(Count) UI_MENU_ITEM Items[], _In_ UINT Count); #define UI_CreateMenuItems(Parent, Items) UI_CreateMenuItemsEx(Parent, Items, ARRAYSIZE(Items)) @@ -50,7 +35,7 @@ UI_CreateMenuItemsEx( FORCEINLINE VOID UI_DestroyMenuItemsEx( - _In_reads_(Count) PUI_MENU_ITEM Items, + _In_reads_(Count) UI_MENU_ITEM Items[], _In_ UINT Count) { UINT i; @@ -111,25 +96,4 @@ UI_ToggleMenuCheckItem( return mii.fState & MFS_CHECKED ? S_OK : S_FALSE; } -// Return FALSE to stop enumeration, UI_EnumTreeViewItems will returns S_FALSE -typedef -_Function_class_(UI_TREEVIEW_ENUMITEM_FN) -LOGICAL -CALLBACK -UI_TREEVIEW_ENUMITEM_FN( - _In_ HWND TreeView, - _In_ HTREEITEM TreeItem, - _In_ UINT Level, - _In_opt_ PVOID Context); -typedef UI_TREEVIEW_ENUMITEM_FN *PUI_TREEVIEW_ENUMITEM_FN; - -MLE_API -HRESULT -NTAPI -UI_TreeViewEnumItems( - _In_ HWND TreeView, - _In_ LOGICAL BFS, - _In_ __callback PUI_TREEVIEW_ENUMITEM_FN TreeItemEnumProc, - _In_opt_ PVOID Context); - EXTERN_C_END diff --git a/Source/KNSoft.MakeLifeEasier/UI/Control/PropSheet.c b/Source/KNSoft.MakeLifeEasier/UI/Control/PropSheet.c new file mode 100644 index 0000000..e701e13 --- /dev/null +++ b/Source/KNSoft.MakeLifeEasier/UI/Control/PropSheet.c @@ -0,0 +1,92 @@ +#include "../../MakeLifeEasier.inl" + +INT_PTR +CALLBACK +UI_PropSheetWndProc( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam, + INT iTabControlId) +{ + if (uMsg == WM_NOTIFY) + { + LPNMHDR lpnmhdr = (LPNMHDR)lParam; + INT iSelected; + TCITEMW tci; + RECT rc; + if (lpnmhdr->idFrom == iTabControlId) + { + if (lpnmhdr->code == TCN_SELCHANGING || lpnmhdr->code == TCN_SELCHANGE) + { + iSelected = (INT)SendMessageW(lpnmhdr->hwndFrom, TCM_GETCURSEL, 0, 0); + if (iSelected != -1) + { + tci.mask = TCIF_PARAM; + if (SendMessageW(lpnmhdr->hwndFrom, TCM_GETITEMW, iSelected, (LPARAM)&tci)) + { + if (lpnmhdr->code == TCN_SELCHANGING) + { + ShowWindow((HWND)tci.lParam, SW_HIDE); + } else + { + if (SUCCEEDED(UI_GetRelativeRect(lpnmhdr->hwndFrom, hWnd, &rc))) + { + SendMessageW(lpnmhdr->hwndFrom, TCM_ADJUSTRECT, FALSE, (LPARAM)&rc); + SetWindowPos((HWND)tci.lParam, + NULL, + rc.left, + rc.top, + rc.right - rc.left, + rc.bottom - rc.top, + SWP_NOZORDER | SWP_SHOWWINDOW); + } + } + } + } + } + } + } + + return 0; +} + +LOGICAL +NTAPI +UI_InitPropSheetEx( + _In_ HWND Dialog, + _In_ INT TabControlId, + _In_reads_(PageCount) UI_PROPSHEET_PAGE Pages[], + _In_ UINT PageCount) +{ + HWND TabControl; + UINT i; + TCITEMW tci; + NMHDR nmhdr; + + TabControl = GetDlgItem(Dialog, TabControlId); + tci.mask = TCIF_TEXT | TCIF_PARAM; + SendMessageW(TabControl, TCM_DELETEALLITEMS, 0, 0); + for (i = 0; i < PageCount; i++) + { + tci.pszText = (PWSTR)Pages[i].TabTitle; + tci.lParam = (LPARAM)Pages[i].PageWindow; + if (SendMessageW(TabControl, TCM_INSERTITEMW, i, (LPARAM)&tci) == -1) + { + SendMessageW(TabControl, TCM_DELETEALLITEMS, 0, 0); + return FALSE; + } + UI_SetDialogTextureTheme(Pages[i].PageWindow, ETDT_ENABLETAB); + } + if (PageCount) + { + SetWindowPos(TabControl, Pages[i - 1].PageWindow, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); + SendMessageW(TabControl, TCM_SETCURSEL, 0, 0); + nmhdr.hwndFrom = TabControl; + nmhdr.idFrom = TabControlId; + nmhdr.code = TCN_SELCHANGE; + SendMessageW(Dialog, WM_NOTIFY, TabControlId, (LPARAM)&nmhdr); + } + + return TRUE; +} diff --git a/Source/KNSoft.MakeLifeEasier/UI/Control/PropSheet.h b/Source/KNSoft.MakeLifeEasier/UI/Control/PropSheet.h new file mode 100644 index 0000000..34ffb08 --- /dev/null +++ b/Source/KNSoft.MakeLifeEasier/UI/Control/PropSheet.h @@ -0,0 +1,34 @@ +#pragma once + +#include "../../MakeLifeEasier.h" + +EXTERN_C_START + +typedef struct _UI_PROPSHEET_PAGE +{ + HWND PageWindow; + PCWSTR TabTitle; +} UI_PROPSHEET_PAGE, *PUI_PROPSHEET_PAGE; + +MLE_API +LOGICAL +NTAPI +UI_InitPropSheetEx( + _In_ HWND Dialog, + _In_ INT TabControlId, + _In_reads_(PageCount) UI_PROPSHEET_PAGE Pages[], + _In_ UINT PageCount); + +#define UI_InitPropSheet(Dialog, TabControlId, Pages) UI_InitPropSheetEx(Dialog, TabControlId, Pages, ARRAYSIZE(Pages)) + +MLE_API +INT_PTR +CALLBACK +UI_PropSheetWndProc( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam, + INT iTabControlId); + +EXTERN_C_END diff --git a/Source/KNSoft.MakeLifeEasier/UI/Control/TreeView.c b/Source/KNSoft.MakeLifeEasier/UI/Control/TreeView.c new file mode 100644 index 0000000..2ff3dd5 --- /dev/null +++ b/Source/KNSoft.MakeLifeEasier/UI/Control/TreeView.c @@ -0,0 +1,57 @@ +#include "../../MakeLifeEasier.inl" + +HRESULT +NTAPI +UI_TreeViewEnumItems( + _In_ HWND TreeView, + _In_ LOGICAL BFS, + _In_ __callback PUI_TREEVIEW_ENUMITEM_FN TreeItemEnumProc, + _In_opt_ PVOID Context) +{ + UINT uDepth; + HTREEITEM hItem, hItemTemp; + + if (BFS) + { + // TODO: Implement BFS + return E_NOTIMPL; + } + + uDepth = 0; + hItem = (HTREEITEM)SendMessageW(TreeView, TVM_GETNEXTITEM, TVGN_ROOT, 0); + do + { + if (!TreeItemEnumProc(TreeView, hItem, uDepth, Context)) + { + return S_FALSE; + } + + hItemTemp = hItem; + hItem = (HTREEITEM)SendMessageW(TreeView, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItemTemp); + if (hItem != NULL) + { + uDepth++; + continue; + } + hItem = (HTREEITEM)SendMessageW(TreeView, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItemTemp); + if (hItem != NULL) + { + continue; + } + while (--uDepth) + { + hItem = (HTREEITEM)SendMessageW(TreeView, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItemTemp); + hItemTemp = (HTREEITEM)SendMessageW(TreeView, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem); + if (hItemTemp != NULL) + { + hItem = hItemTemp; + break; + } else + { + hItemTemp = hItem; + } + } + } while (uDepth != 0); + + return S_OK; +} diff --git a/Source/KNSoft.MakeLifeEasier/UI/Control/TreeView.h b/Source/KNSoft.MakeLifeEasier/UI/Control/TreeView.h new file mode 100644 index 0000000..4782dd3 --- /dev/null +++ b/Source/KNSoft.MakeLifeEasier/UI/Control/TreeView.h @@ -0,0 +1,29 @@ +#pragma once + +#include "../../MakeLifeEasier.h" + +EXTERN_C_START + +// Return FALSE to stop enumeration, UI_EnumTreeViewItems will returns S_FALSE +typedef +_Function_class_(UI_TREEVIEW_ENUMITEM_FN) +LOGICAL +CALLBACK +UI_TREEVIEW_ENUMITEM_FN( + _In_ HWND TreeView, + _In_ HTREEITEM TreeItem, + _In_ UINT Level, + _In_opt_ PVOID Context); +typedef UI_TREEVIEW_ENUMITEM_FN *PUI_TREEVIEW_ENUMITEM_FN; + +/* BFS (Breadth-First-Search) must be FALSE (unimplemented), support DFS (Depth-First-Search) only */ +MLE_API +HRESULT +NTAPI +UI_TreeViewEnumItems( + _In_ HWND TreeView, + _In_ LOGICAL BFS, + _In_ __callback PUI_TREEVIEW_ENUMITEM_FN TreeItemEnumProc, + _In_opt_ PVOID Context); + +EXTERN_C_END diff --git a/Source/KNSoft.MakeLifeEasier/UI/Message.c b/Source/KNSoft.MakeLifeEasier/UI/Message.c index 7eda94b..0fa16f6 100644 --- a/Source/KNSoft.MakeLifeEasier/UI/Message.c +++ b/Source/KNSoft.MakeLifeEasier/UI/Message.c @@ -34,7 +34,7 @@ UI_GetWindowTextExA( return cCh; } -#define UI_NONOTIFYPROP L"KNSoft.MakeLifeEasier.UI.NoNotify" +#define UI_NONOTIFY_PROP L"KNSoft.MakeLifeEasier.UI.NoNotify" W32ERROR NTAPI @@ -44,10 +44,10 @@ UI_SetNoNotifyFlag( { if (EnableState) { - return SetPropW(Window, UI_NONOTIFYPROP, (HANDLE)TRUE) ? ERROR_SUCCESS : NtGetLastError(); + return SetPropW(Window, UI_NONOTIFY_PROP, (HANDLE)TRUE) ? ERROR_SUCCESS : NtGetLastError(); } else { - return RemovePropW(Window, UI_NONOTIFYPROP) != NULL ? ERROR_SUCCESS : NtGetLastError(); + return RemovePropW(Window, UI_NONOTIFY_PROP) != NULL ? ERROR_SUCCESS : NtGetLastError(); } } @@ -56,7 +56,7 @@ NTAPI UI_GetNoNotifyFlag( _In_ HWND Window) { - return GetPropW(Window, UI_NONOTIFYPROP) == (HANDLE)TRUE; + return GetPropW(Window, UI_NONOTIFY_PROP) == (HANDLE)TRUE; } LRESULT diff --git a/Source/KNSoft.MakeLifeEasier/UI/Message.h b/Source/KNSoft.MakeLifeEasier/UI/Message.h index 5f2d36e..71fbae2 100644 --- a/Source/KNSoft.MakeLifeEasier/UI/Message.h +++ b/Source/KNSoft.MakeLifeEasier/UI/Message.h @@ -70,8 +70,8 @@ UI_EnableDlgItem( #define UI_LocalSetDlgButtonCheck(Dialog, ButtonID, CheckState) DefWindowProcW(GetDlgItem(Dialog, ButtonID), BM_SETCHECK, (WPARAM)(CheckState), 0) /// -#define UI_SetWindowTextW(Window, Text) SendMessageW(Window, WM_SETTEXT, 0, (LPARAM)(Text)) -#define UI_SetWindowTextA(Window, Text) SendMessageA(Window, WM_SETTEXT, 0, (LPARAM)(Text)) +#define UI_SetWindowTextW(Window, Text) SetWindowTextW(Window, Text) +#define UI_SetWindowTextA(Window, Text) SetWindowTextA(Window, Text) #define UI_LocalSetWindowTextW(Window, Text) DefWindowProcW(Window, WM_SETTEXT, 0, (LPARAM)(Text)) #define UI_LocalSetWindowTextA(Window, Text) DefWindowProcA(Window, WM_SETTEXT, 0, (LPARAM)(Text)) diff --git a/Source/KNSoft.MakeLifeEasier/UI/Window.c b/Source/KNSoft.MakeLifeEasier/UI/Window.c index 480a8ac..0e76e9a 100644 --- a/Source/KNSoft.MakeLifeEasier/UI/Window.c +++ b/Source/KNSoft.MakeLifeEasier/UI/Window.c @@ -1,5 +1,39 @@ #include "../MakeLifeEasier.inl" +HRESULT +NTAPI +UI_GetRelativeRect( + _In_ HWND Window, + _In_ HWND RefWindow, + _Out_ PRECT Rect) +{ + POINT pt; + HANDLE hParent; + RECT rc; + HRESULT hr; + + hr = UI_GetWindowRect(Window, &rc); + if (FAILED(hr)) + { + return hr; + } + + pt.x = rc.left; + pt.y = rc.top; + hParent = RefWindow ? RefWindow : GetParent(Window); + if (!ScreenToClient(hParent ? hParent : GetDesktopWindow(), &pt)) + { + return E_UNEXPECTED; + } + + Rect->right = rc.right + pt.x - rc.left; + Rect->bottom = rc.bottom + pt.y - rc.top; + Rect->left = pt.x; + Rect->top = pt.y; + + return S_OK; +} + static VOID UI_UpdateResizeWndDPI( diff --git a/Source/KNSoft.MakeLifeEasier/UI/Window.h b/Source/KNSoft.MakeLifeEasier/UI/Window.h index b7c567c..a1d1480 100644 --- a/Source/KNSoft.MakeLifeEasier/UI/Window.h +++ b/Source/KNSoft.MakeLifeEasier/UI/Window.h @@ -16,6 +16,14 @@ UI_TruncateHandle( #endif } +FORCEINLINE +ULONG +UI_TruncateHandle32( + _In_ PVOID Handle32) +{ + return (ULONG)(ULONG_PTR)Handle32; +} + /// FORCEINLINE LOGICAL @@ -50,6 +58,14 @@ UI_GetScreenPos( } } +MLE_API +HRESULT +NTAPI +UI_GetRelativeRect( + _In_ HWND Window, + _In_ HWND RefWindow, + _Out_ PRECT Rect); + /// /// Implemented by GetWindow FORCEINLINE @@ -139,6 +155,7 @@ UI_SetWindowThemeProperty( _In_ HWND Window, _In_opt_ PCWSTR Property); +/* See also SetWindowTheme */ FORCEINLINE LOGICAL UI_SetWindowTheme( @@ -155,6 +172,30 @@ UI_SetWindowTheme( return Ret; } +/* See also EnableThemeDialogTexture */ +FORCEINLINE +HRESULT +UI_SetDialogTextureTheme( + _In_ HWND Dialog, + _In_ DWORD Flags) +{ + DWORD OldFlags; + + if (Flags & ETDT_DISABLE) + { + RemovePropW(Dialog, (PCWSTR)UXTHEME_ATOM_DLGTEXTURE); + return S_OK; + } + + OldFlags = (DWORD)(DWORD_PTR)GetPropW(Dialog, (PCWSTR)UXTHEME_ATOM_DLGTEXTURE); + if (!SetPropW(Dialog, (PCWSTR)UXTHEME_ATOM_DLGTEXTURE, (HANDLE)(DWORD_PTR)(OldFlags | (Flags & ETDT_VALIDBITS)))) + { + return HRESULT_FROM_WIN32(NtGetLastError()); + } + + return S_OK; +} + /* Windows Explorer visual style can be applied to Tree-View, List-View, ... controls */ FORCEINLINE LOGICAL diff --git a/Source/KNSoft.MakeLifeEasier/packages.config b/Source/KNSoft.MakeLifeEasier/packages.config index f284121..f503ef8 100644 --- a/Source/KNSoft.MakeLifeEasier/packages.config +++ b/Source/KNSoft.MakeLifeEasier/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/Source/Test/Test.vcxproj b/Source/Test/Test.vcxproj index 0aaa206..59e1d4e 100644 --- a/Source/Test/Test.vcxproj +++ b/Source/Test/Test.vcxproj @@ -189,12 +189,12 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/Source/Test/packages.config b/Source/Test/packages.config index 85ffa18..ed9f293 100644 --- a/Source/Test/packages.config +++ b/Source/Test/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file