windows-nt/Source/XPSP1/NT/multimedia/media/mplayer2/ctrls.c
2020-09-26 16:20:57 +08:00

530 lines
15 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*-----------------------------------------------------------------------------+
| TOOLBAR.C |
| |
| Contains the code which implements the toolbar and its buttons. |
| |
| (C) Copyright Microsoft Corporation 1991. All rights reserved. |
| |
| Revision History |
| Oct-1992 MikeTri Ported to WIN32 / WIN16 common code |
| |
+-----------------------------------------------------------------------------*/
#include <windows.h>
#include <string.h>
#include <shellapi.h>
#include "toolbar.h"
#include "mpole.h"
#include "mplayer.h"
#ifndef COLOR_BTNFACE
#define COLOR_BTNFACE 15
#define COLOR_BTNSHADOW 16
#define COLOR_BTNTEXT 18
#endif
extern void FAR cdecl dprintf(LPSTR szFormat, ...);
extern HWND ghwndApp;
extern HWND ghwndToolbar;
extern HWND ghwndFSArrows;
/*
Variables
*/
HBRUSH hbrGray = NULL; // Gray for text
HBRUSH hbrButtonFace;
HBRUSH hbrButtonShadow;
HBRUSH hbrButtonText;
HBRUSH hbrButtonHighLight;
HBRUSH hbrWindowFrame;
HBRUSH hbrWindowColour;
DWORD rgbButtonHighLight;
DWORD rgbButtonFocus;
DWORD rgbButtonFace;
DWORD rgbButtonText;
DWORD rgbButtonShadow;
DWORD rgbWindowFrame;
DWORD rgbWindowColour;
TBBUTTON tbBtns[TB_NUM_BTNS + MARK_NUM_BTNS + ARROW_NUM_BTNS] =
{
{BTN_PLAY, IDT_PLAY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
{BTN_PAUSE, IDT_PAUSE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
{BTN_STOP, IDT_STOP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
{BTN_EJECT, IDT_EJECT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
{BTN_HOME, IDT_HOME, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
{BTN_RWD, IDT_RWD, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
{BTN_FWD, IDT_FWD, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
{BTN_END, IDT_END, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
{-1, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0},
{BTN_MARKIN, IDT_MARKIN, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
{BTN_MARKOUT, IDT_MARKOUT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
{ARROW_PREV, IDT_ARROWPREV, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
{ARROW_NEXT, IDT_ARROWNEXT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0}
};
int BtnIndex[TB_NUM_BTNS + MARK_NUM_BTNS + ARROW_NUM_BTNS];
static int iBtnOffset[3] = {0,TB_NUM_BTNS, TB_NUM_BTNS+MARK_NUM_BTNS};
WNDPROC fnTBWndProc = NULL;
WNDPROC fnStatusWndProc = NULL;
/*
ControlInit( hInst )
This is called when the application is first loaded into
memory. It performs all initialization.
Arguments:
hInst instance handle of current instance
Returns:
TRUE if successful, FALSE if not
*/
BOOL
FAR PASCAL
ControlInit(
HANDLE hInst)
{
long patGray[4];
HBITMAP hbmGray;
int i;
/* initialize the brushes */
for (i=0; i < 4; i++)
patGray[i] = 0xAAAA5555L; // 0x11114444L; // lighter gray
hbmGray = CreateBitmap(8, 8, 1, 1, patGray);
hbrGray = CreatePatternBrush(hbmGray);
if (hbmGray)
DeleteObject(hbmGray);
rgbButtonFace = GetSysColor(COLOR_BTNFACE);
rgbButtonShadow = GetSysColor(COLOR_BTNSHADOW);
rgbButtonText = GetSysColor(COLOR_BTNTEXT);
rgbButtonHighLight = GetSysColor(COLOR_BTNHIGHLIGHT);
rgbButtonFocus = GetSysColor(COLOR_BTNTEXT);
rgbWindowFrame = GetSysColor(COLOR_WINDOWFRAME);
rgbWindowColour = GetSysColor(COLOR_WINDOW);
if (rgbButtonFocus == rgbButtonFace)
rgbButtonFocus = rgbButtonText;
hbrButtonFace = CreateSolidBrush(rgbButtonFace);
hbrButtonShadow = CreateSolidBrush(rgbButtonShadow);
hbrButtonText = CreateSolidBrush(rgbButtonText);
hbrButtonHighLight = CreateSolidBrush(rgbButtonHighLight);
hbrWindowFrame = CreateSolidBrush(rgbWindowFrame);
hbrWindowColour = CreateSolidBrush(rgbWindowColour);
if (((UINT_PTR)hbrWindowFrame & // fail if any of them are NULL ???
(UINT_PTR)hbrButtonShadow &
(UINT_PTR)hbrButtonText &
(UINT_PTR)hbrButtonHighLight &
(UINT_PTR)hbrWindowFrame) == (UINT_PTR)0)
return FALSE;
return TRUE;
}
/*
ControlCleanup()
Delete the brushes we've been using
*/
void FAR PASCAL ControlCleanup(void)
{
DeleteObject(hbrGray);
DeleteObject(hbrButtonFace);
DeleteObject(hbrButtonShadow);
DeleteObject(hbrButtonText);
DeleteObject(hbrButtonHighLight);
DeleteObject(hbrWindowFrame);
DeleteObject(hbrWindowColour);
#if 0
DeleteObject(hbTBMain);
DeleteObject(hbTBMark);
DeleteObject(hbTBArrows);
#endif
}
BOOL FAR PASCAL toolbarInit(void)
{
int i;
InitCommonControls();
for(i = 0; i < TB_NUM_BTNS + MARK_NUM_BTNS + ARROW_NUM_BTNS; i++)
BtnIndex[i] = -1;
return TRUE;
}
LONG_PTR FAR PASCAL SubClassedTBWndProc(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
switch(wMsg)
{
case WM_SIZE:
return 0;
case WM_STARTTRACK:
switch(wParam)
{
case IDT_RWD:
case IDT_FWD:
case IDT_ARROWPREV:
case IDT_ARROWNEXT:
PostMessage(ghwndApp, WM_COMMAND, wParam, REPEAT_ID);
SetTimer(hwnd, (UINT_PTR)ghwndApp, MSEC_BUTTONREPEAT, NULL);
}
return 0;
case WM_ENDTRACK:
switch(wParam)
{
case IDT_RWD:
case IDT_FWD:
case IDT_ARROWPREV:
case IDT_ARROWNEXT:
KillTimer(hwnd, wParam);
SendMessage(ghwndApp, WM_HSCROLL, (WPARAM)TB_ENDTRACK, (LPARAM)hwnd);
}
return 0;
case WM_TIMER:
{
WPARAM cmd;
if (wParam != (WPARAM)ghwndApp)
break;
if (hwnd == ghwndToolbar)
{
if(SendMessage(hwnd, TB_ISBUTTONPRESSED, tbBtns[BTN_RWD].idCommand, 0L))
cmd = IDT_RWD;
else if(SendMessage(hwnd, TB_ISBUTTONPRESSED, tbBtns[BTN_FWD].idCommand, 0L))
cmd = IDT_FWD;
else
return 0;
PostMessage(ghwndApp, WM_COMMAND, cmd, REPEAT_ID);
return 0;
}
else
if (hwnd == ghwndFSArrows)
{
if(SendMessage(hwnd, TB_ISBUTTONPRESSED, tbBtns[TB_NUM_BTNS+MARK_NUM_BTNS+ARROW_PREV].idCommand, 0L))
cmd = IDT_ARROWPREV;
else if(SendMessage(hwnd, TB_ISBUTTONPRESSED, tbBtns[TB_NUM_BTNS+MARK_NUM_BTNS+ARROW_NEXT].idCommand, 0L))
cmd = IDT_ARROWNEXT;
else
return 0;
PostMessage(ghwndApp, WM_COMMAND, cmd, REPEAT_ID);
return 0;
}
KillTimer(hwnd, wParam);
return 0;
}
}
return CallWindowProc(fnTBWndProc, hwnd, wMsg, wParam, lParam);
}
void SubClassTBWindow(HWND hwnd)
{
if (!fnTBWndProc)
fnTBWndProc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC);
if (hwnd)
SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)SubClassedTBWndProc);
}
#ifndef CCS_NODIVIDER
/* For NT: */
#define CCS_NODIVIDER 0
#endif
HWND FAR PASCAL toolbarCreateMain(HWND hwndParent)
{
HWND hwnd;
hwnd = CreateToolbarEx(hwndParent,
WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|TBSTYLE_BUTTON|TBSTYLE_TOOLTIPS|
CCS_NODIVIDER,
IDT_TBMAINCID, 8,
ghInst, IDR_TOOLBAR, NULL, 0, 16, 16, 16, 16, sizeof(TBBUTTON));
if (hwnd)
SubClassTBWindow(hwnd);
return hwnd;
}
HWND FAR PASCAL toolbarCreateMark(HWND hwndParent)
{
HWND hwnd;
hwnd = CreateToolbarEx(hwndParent,
WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|TBSTYLE_BUTTON|TBSTYLE_TOOLTIPS|
CCS_NODIVIDER,
IDT_TBMARKCID, 2,
ghInst, IDR_MARK, NULL, 0, 17, 16, 17, 16, sizeof(TBBUTTON));
if (hwnd)
SubClassTBWindow(hwnd);
return hwnd;
}
HWND FAR PASCAL toolbarCreateArrows(HWND hwndParent)
{
HWND hwnd;
hwnd = CreateToolbarEx(hwndParent,
WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|TBSTYLE_BUTTON|TBSTYLE_TOOLTIPS|
CCS_NODIVIDER,
IDT_TBARROWSCID,
2,
ghInst,
IDR_ARROWS,
NULL,
0,
4,
7,
4,
7,
sizeof(TBBUTTON));
if (hwnd)
SubClassTBWindow(hwnd);
return hwnd;
}
/***************************************************************************/
/* toolbarStateFromButton: This fn is called by the parent application */
/* to get the state of a button. It will only */
/* return DOWN, or UP or GRAYED as opposed to */
/* toolbarFullStateFromButton which could return */
/* FULLDOWN. */
/***************************************************************************/
BOOL FAR PASCAL toolbarStateFromButton(HWND hwnd, int iButton, int tbIndex)
{
int idBtn;
int pos;
pos = BtnIndex[iBtnOffset[tbIndex] + iButton];
if (pos == -1)
return FALSE;
idBtn = tbBtns[iBtnOffset[tbIndex] + iButton].idCommand;
return (BOOL)SendMessage(hwnd, TB_ISBUTTONENABLED, (WPARAM)idBtn, 0L);
}
/***************************************************************************/
/* toolbarAddTool: Add a button to this toolbar. Sort them by leftmost */
/* position in the window (for tabbing order). */
/* Return FALSE for an error. */
/***************************************************************************/
BOOL FAR PASCAL toolbarAddTool(HWND hwnd, int iButton, int tbIndex, int iState)
{
TBBUTTON tb;
tb = tbBtns[iBtnOffset[tbIndex] + iButton];
if (iState)
tb.fsState |= TBSTATE_ENABLED;
else
tb.fsState &= ~TBSTATE_ENABLED;
if(!SendMessage(hwnd, TB_ADDBUTTONS, (WPARAM)1, (LPARAM)(const TBBUTTON FAR *)&tb))
return FALSE;
BtnIndex[iBtnOffset[tbIndex] + iButton] =
(int)SendMessage(hwnd, TB_BUTTONCOUNT, 0, 0L) - 1;
return TRUE;
}
BOOL FAR PASCAL toolbarSwapTools(HWND hwnd, int iButton, int jButton, int tbIndex)
{
int pos;
TBBUTTON tb;
int newBut, oldBut;
pos = BtnIndex[iBtnOffset[tbIndex] + iButton];
if (pos == -1)
{
pos = BtnIndex[iBtnOffset[tbIndex] + jButton];
if (pos == -1)
return FALSE;
newBut = iButton;
oldBut = jButton;
}
else
{
newBut = jButton;
oldBut = iButton;
}
SendMessage(hwnd, TB_DELETEBUTTON, (WPARAM)pos, 0L);
BtnIndex[iBtnOffset[tbIndex] + oldBut] = -1;
tb = tbBtns[iBtnOffset[tbIndex] + newBut];
if(!SendMessage(hwnd, TB_INSERTBUTTON, (WPARAM)pos, (LPARAM)(const TBBUTTON FAR *)&tb))
return FALSE;
BtnIndex[iBtnOffset[tbIndex] + newBut] = pos;
return TRUE;
}
/***************************************************************************/
/* toolbarModifyState: Given a button ID on the toolbar, change its */
/* state. */
/* returns FALSE for an error or if no such button */
/***************************************************************************/
BOOL FAR PASCAL toolbarModifyState(HWND hwnd, int iButton, int tbIndex, int iState)
{
int idBtn;
int pos;
pos = BtnIndex[iBtnOffset[tbIndex] + iButton];
if (pos == -1)
return FALSE;
idBtn = tbBtns[iBtnOffset[tbIndex] + iButton].idCommand;
SendMessage(hwnd, TB_PRESSBUTTON, (WPARAM)idBtn, 0L); //unpress button first. commctrl bug
if (idBtn == IDT_STOP)
{
SendMessage(hwnd, TB_PRESSBUTTON, (WPARAM)IDT_HOME, 0L);
SendMessage(hwnd, TB_PRESSBUTTON, (WPARAM)IDT_END, 0L);
SendMessage(hwnd, TB_PRESSBUTTON, (WPARAM)IDT_FWD, 0L);
SendMessage(hwnd, TB_PRESSBUTTON, (WPARAM)IDT_RWD, 0L);
}
if (!iState)
SendMessage(hwnd, TB_PRESSBUTTON, (WPARAM)IDT_EJECT, 0L);
SendMessage(hwnd, TB_ENABLEBUTTON, (WPARAM)idBtn, (LPARAM)MAKELONG(iState, 0));
return TRUE;
}
/***************************************************************************/
/* toolbarSetFocus : Set the focus in the toolbar to the specified button.*/
/* If it's gray, it'll set focus to next ungrayed btn. */
/***************************************************************************/
BOOL FAR PASCAL toolbarSetFocus(HWND hwnd, int iButton)
{
int pos;
if ((hwnd != ghwndToolbar) || (iButton != BTN_PLAY && iButton != BTN_PAUSE))
return TRUE;
pos = BtnIndex[iButton];
if (pos != -1)
return TRUE;
toolbarSwapTools(hwnd, iButton, 1-iButton, TBINDEX_MAIN);
return TRUE;
}
LONG_PTR FAR PASCAL SubClassedStatusWndProc(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
switch(wMsg)
{
case WM_SIZE:
return 0;
}
return CallWindowProc(fnStatusWndProc, hwnd, wMsg, wParam, lParam);
}
void SubClassStatusWindow(HWND hwnd)
{
if (!fnStatusWndProc)
fnStatusWndProc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC);
if (hwnd)
SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)SubClassedStatusWndProc);
}
/* SBS_SIZEGRIP isn't defined for NT!! */
#ifndef SBS_SIZEGRIP
#define SBS_SIZEGRIP 0
#endif
HWND CreateStaticStatusWindow(HWND hwndParent, BOOL fSizeGrip)
{
HWND hwnd;
hwnd = CreateStatusWindow(WS_CHILD|WS_VISIBLE|(fSizeGrip ? 0 : CCS_NOMOVEY),
TEXT(""), hwndParent, IDT_STATUSWINDOWCID);
if (hwnd)
SubClassStatusWindow(hwnd);
return hwnd;
}
BOOL WriteStatusMessage(HWND hwnd, LPTSTR szMsg)
{
TCHAR Text[64];
SIZE StatusTextExtent;
LONG StatusTextWidth;
BOOL rc;
Text[0] = TEXT('\0');
GetWindowText(hwnd, Text, CHAR_COUNT(Text));
if (lstrcmp(szMsg, Text) == 0)
return TRUE;
GetStatusTextExtent(ghwndStatic, &StatusTextExtent);
StatusTextWidth = StatusTextExtent.cy;
rc = (BOOL)SendMessage(hwnd, SB_SETTEXT, (WPARAM)0, (LPARAM)szMsg);
GetStatusTextExtent(ghwndStatic, &StatusTextExtent);
if (StatusTextWidth != StatusTextExtent.cy)
Layout();
return rc;
}
BOOL GetStatusTextExtent(HWND hwnd, LPSIZE pTextExtent)
{
HDC hdc;
HFONT hfontOld;
TCHAR Text[64];
hdc = GetDC(NULL);
if (hdc == NULL)
return FALSE;
Text[0] = TEXT('\0');
GetWindowText(hwnd, Text, CHAR_COUNT(Text));
hfontOld = SelectObject(hdc, (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0));
GetTextExtentPoint32(hdc, Text, STRLEN(Text), pTextExtent);
SelectObject(hdc, hfontOld);
ReleaseDC(NULL, hdc);
return TRUE;
}