[SNDVOL32] Add the small master dialog

- Add the small master dialog.
- Add support for tray (/t), small (/s) and normal (/n) dialog sizes.
- Fix the font size calculation for the dialogs.
- Fix the dialog unit to pixel conversion.
- Fix the client window size calculation.
- Do not leak font handles.
This commit is contained in:
Eric Kohl 2018-03-10 21:10:40 +01:00
parent 8bdebb1fed
commit 849fdca3f9
32 changed files with 514 additions and 115 deletions

View file

@ -7,11 +7,15 @@
#include "sndvol32.h"
#include <wingdi.h>
#define XLEFT (30)
#define XTOP (20)
#define DIALOG_VOLUME_SIZE (150)
VOID
ConvertRect(LPRECT lpRect, UINT xBaseUnit, UINT yBaseUnit)
{
lpRect->left = MulDiv(lpRect->left, xBaseUnit, 4);
lpRect->right = MulDiv(lpRect->right, xBaseUnit, 4);
lpRect->top = MulDiv(lpRect->top, yBaseUnit, 8);
lpRect->bottom = MulDiv(lpRect->bottom, yBaseUnit, 8);
}
LPVOID
LoadDialogResource(
@ -66,7 +70,9 @@ AddDialogControl(
IN LPRECT DialogOffset,
IN PDLGITEMTEMPLATE DialogItem,
IN DWORD DialogIdMultiplier,
IN HFONT hFont)
IN HFONT hFont,
UINT xBaseUnit,
UINT yBaseUnit)
{
RECT rect;
LPWORD Offset;
@ -75,12 +81,18 @@ AddDialogControl(
DWORD wID;
/* initialize client rectangle */
rect.left = DialogItem->x + DialogOffset->left;
rect.top = DialogItem->y + DialogOffset->top;
rect.right = DialogItem->cx;
rect.bottom = DialogItem->cy;
rect.left = DialogItem->x;
rect.top = DialogItem->y;
rect.right = DialogItem->x + DialogItem->cx;
rect.bottom = DialogItem->y + DialogItem->cy;
//MapDialogRect(hwndDialog, &rect);
/* Convert Dialog units to pixes */
ConvertRect(&rect, xBaseUnit, yBaseUnit);
rect.left += DialogOffset->left;
rect.right += DialogOffset->left;
rect.top += DialogOffset->top;
rect.bottom += DialogOffset->top;
/* move offset after dialog item */
Offset = (LPWORD)(DialogItem + 1);
@ -140,8 +152,8 @@ AddDialogControl(
DialogItem->style,
rect.left,
rect.top,
rect.right,
rect.bottom,
rect.right - rect.left,
rect.bottom - rect.top,
hwndDialog,
(HMENU)(wID),
hAppInstance,
@ -207,35 +219,75 @@ VOID
LoadDialogControls(
IN PMIXER_WINDOW MixerWindow,
LPRECT DialogOffset,
LPVOID DlgResource,
DWORD DialogIdMultiplier)
WORD ItemCount,
PDLGITEMTEMPLATE DialogItem,
DWORD DialogIdMultiplier,
UINT xBaseUnit,
UINT yBaseUnit)
{
LPDLGTEMPLATE DialogHeader;
PDLGITEMTEMPLATE DialogItem;
LPWORD Offset;
WORD FontSize;
WCHAR FontName[100];
WORD Length, Index;
HFONT Font;
/* get dialog header */
DialogHeader = (LPDLGTEMPLATE)DlgResource;
WORD Index;
/* sanity check */
assert(DialogHeader->cdit);
assert(ItemCount);
if (MixerWindow->Window)
MixerWindow->Window = (HWND*)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MixerWindow->Window, (MixerWindow->WindowCount + DialogHeader->cdit) * sizeof(HWND));
MixerWindow->Window = (HWND*)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MixerWindow->Window, (MixerWindow->WindowCount + ItemCount) * sizeof(HWND));
else
MixerWindow->Window = (HWND*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, DialogHeader->cdit * sizeof(HWND));
MixerWindow->Window = (HWND*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ItemCount * sizeof(HWND));
if (!MixerWindow->Window)
{
/* no memory */
return;
}
/* now walk past the dialog header */
Offset = (LPWORD)(DialogHeader + 1);
/* enumerate now all controls */
for (Index = 0; Index < ItemCount; Index++)
{
/* add controls */
Offset = AddDialogControl(MixerWindow->hWnd, &MixerWindow->Window[MixerWindow->WindowCount], DialogOffset, DialogItem, DialogIdMultiplier, MixerWindow->hFont, xBaseUnit, yBaseUnit);
/* sanity check */
assert(Offset);
/* move dialog item to new offset */
DialogItem =(PDLGITEMTEMPLATE)Offset;
/* increment window count */
MixerWindow->WindowCount++;
}
}
VOID
LoadDialog(
IN HMODULE hModule,
IN PMIXER_WINDOW MixerWindow,
IN LPCWSTR DialogResId,
IN DWORD Index)
{
LPDLGTEMPLATE DlgTemplate;
PDLGITEMTEMPLATE DlgItem;
RECT dialogRect;
LPWORD Offset;
WORD FontSize;
WCHAR FontName[100];
WORD Length;
int width;
DWORD units = GetDialogBaseUnits();
UINT xBaseUnit = LOWORD(units);
UINT yBaseUnit = HIWORD(units);
/* first load the dialog resource */
DlgTemplate = (LPDLGTEMPLATE)LoadDialogResource(hModule, DialogResId, NULL);
if (!DlgTemplate)
{
/* failed to load resource */
return;
}
/* Now walk past the dialog header */
Offset = (LPWORD)(DlgTemplate + 1);
/* FIXME: support menu */
assert(*Offset == 0);
@ -260,61 +312,62 @@ LoadDialogControls(
/* copy font */
wcscpy(FontName, (LPWSTR)Offset);
Font = CreateFontW(FontSize+8, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, FontName);
assert(Font);
if (DlgTemplate->style & DS_SETFONT)
{
HDC hDC;
hDC = GetDC(0);
if (!MixerWindow->hFont)
{
int pixels = MulDiv(FontSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
MixerWindow->hFont = CreateFontW(-pixels, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, FontName);
}
if (MixerWindow->hFont)
{
SIZE charSize;
HFONT hOldFont;
hOldFont = SelectObject(hDC, MixerWindow->hFont);
charSize.cx = GdiGetCharDimensions(hDC, NULL, &charSize.cy);
if (charSize.cx)
{
xBaseUnit = charSize.cx;
yBaseUnit = charSize.cy;
}
SelectObject(hDC, hOldFont);
}
}
// assert(MixerWindow->hFont);
/* move offset after font name */
Offset += Length;
/* offset is now at first dialog item control */
DialogItem = (PDLGITEMTEMPLATE)Offset;
DlgItem = (PDLGITEMTEMPLATE)Offset;
/* enumerate now all controls */
for(Index = 0; Index < DialogHeader->cdit; Index++)
{
/* add controls */
Offset = AddDialogControl(MixerWindow->hWnd, &MixerWindow->Window[MixerWindow->WindowCount], DialogOffset, DialogItem, DialogIdMultiplier, Font);
dialogRect.left = 0;
dialogRect.right = DlgTemplate->cx;
dialogRect.top = 0;
dialogRect.bottom = DlgTemplate->cy;
/* sanity check */
assert(Offset);
ConvertRect(&dialogRect, xBaseUnit, yBaseUnit);
/* move dialog item to new offset */
DialogItem =(PDLGITEMTEMPLATE)Offset;
width = dialogRect.right - dialogRect.left;
/* increment window count */
MixerWindow->WindowCount++;
}
}
VOID
LoadDialog(
IN HMODULE hModule,
IN PMIXER_WINDOW MixerWindow,
IN LPCWSTR DialogResId,
IN DWORD Index)
{
LPVOID DlgResource;
RECT rect;
/* first load the dialog resource */
DlgResource = LoadDialogResource(hModule, DialogResId, NULL);
if (!DlgResource)
{
/* failed to load resource */
return;
}
/* get window size */
GetClientRect(MixerWindow->hWnd, &rect);
/* adjust client position */
rect.left += (Index * DIALOG_VOLUME_SIZE);
dialogRect.left += MixerWindow->rect.right;
dialogRect.right += MixerWindow->rect.right;
dialogRect.top += MixerWindow->rect.top;
dialogRect.bottom += MixerWindow->rect.top;
MixerWindow->rect.right += width;
if ((dialogRect.bottom - dialogRect.top) > (MixerWindow->rect.bottom - MixerWindow->rect.top))
MixerWindow->rect.bottom = MixerWindow->rect.top + dialogRect.bottom - dialogRect.top;
/* now add the controls */
LoadDialogControls(MixerWindow, &rect, DlgResource, Index);
LoadDialogControls(MixerWindow, &dialogRect, DlgTemplate->cdit, DlgItem, Index, xBaseUnit, yBaseUnit);
}
BOOL
@ -328,7 +381,6 @@ EnumConnectionsCallback(
WCHAR LineName[MIXER_LONG_NAME_CHARS];
DWORD Flags;
DWORD wID;
RECT rect;
UINT ControlCount = 0, Index;
LPMIXERCONTROL Control = NULL;
HWND hDlgCtrl;
@ -352,8 +404,10 @@ EnumConnectionsCallback(
/* is it selected */
if (Flags != 0x4)
{
int dlgId = (PrefContext->MixerWindow->Mode == SMALL_MODE) ? IDD_SMALL_MASTER : IDD_VOLUME_CTRL;
/* load dialog resource */
LoadDialog(hAppInstance, PrefContext->MixerWindow, MAKEINTRESOURCE(IDD_VOLUME_CTRL), PrefContext->Count);
LoadDialog(hAppInstance, PrefContext->MixerWindow, MAKEINTRESOURCE(dlgId), PrefContext->Count);
/* get id */
wID = (PrefContext->Count + 1) * IDC_LINE_NAME;
@ -431,12 +485,6 @@ EnumConnectionsCallback(
/* increment dialog count */
PrefContext->Count++;
/* get application rectangle */
GetWindowRect(PrefContext->MixerWindow->hWnd, &rect);
/* now move the window */
MoveWindow(PrefContext->MixerWindow->hWnd, rect.left, rect.top, (PrefContext->Count * DIALOG_VOLUME_SIZE), rect.bottom - rect.top, TRUE);
}
}
}
@ -448,13 +496,26 @@ LoadDialogCtrls(
PPREFERENCES_CONTEXT PrefContext)
{
HWND hDlgCtrl;
RECT statusRect;
/* set dialog count to zero */
PrefContext->Count = 0;
SetRectEmpty(&PrefContext->MixerWindow->rect);
/* enumerate controls */
SndMixerEnumConnections(PrefContext->MixerWindow->Mixer, PrefContext->SelectedLine, EnumConnectionsCallback, (PVOID)PrefContext);
if (PrefContext->MixerWindow->hStatusBar)
{
GetWindowRect(PrefContext->MixerWindow->hStatusBar, &statusRect);
PrefContext->MixerWindow->rect.bottom += (statusRect.bottom - statusRect.top);
}
/* now move the window */
AdjustWindowRect(&PrefContext->MixerWindow->rect, WS_DLGFRAME | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE, TRUE);
SetWindowPos(PrefContext->MixerWindow->hWnd, HWND_TOP, PrefContext->MixerWindow->rect.left, PrefContext->MixerWindow->rect.top, PrefContext->MixerWindow->rect.right - PrefContext->MixerWindow->rect.left, PrefContext->MixerWindow->rect.bottom - PrefContext->MixerWindow->rect.top, SWP_NOMOVE | SWP_NOZORDER);
/* get last line separator */
hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, IDC_LINE_SEP * PrefContext->Count);
@ -463,7 +524,6 @@ LoadDialogCtrls(
/* hide last separator */
ShowWindow(hDlgCtrl, SW_HIDE);
}
}
VOID