255 lines
6.8 KiB
C
255 lines
6.8 KiB
C
|
/*****************************************************************************
|
||
|
*
|
||
|
* UI.c
|
||
|
*
|
||
|
* Copyright (c) 1997 Microsoft Corporation. All Rights Reserved.
|
||
|
*
|
||
|
* Abstract:
|
||
|
*
|
||
|
* The thing that does UI.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#include "msnspa.h"
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* Overview:
|
||
|
*
|
||
|
* UI for the app is done on the main thread. The app itself
|
||
|
* is not in the taskbar or in the tray. The only way to get to
|
||
|
* it is to Alt+Tab to it. When you minimize it, it vanishes again.
|
||
|
*
|
||
|
* FEATURE -- someday create an optional tray icon
|
||
|
*
|
||
|
* Details:
|
||
|
*
|
||
|
* The main window
|
||
|
* is just a dialog box. The window we create is just a
|
||
|
* subclassed static control.
|
||
|
*
|
||
|
* By stealing an existing control, we don't need to register
|
||
|
* our own bogus class.
|
||
|
*
|
||
|
* We hide from the taskbar by having a hidden owner.
|
||
|
*
|
||
|
* We show up in Alt+Tab because the hidden owner is
|
||
|
* not marked WS_EX_TOOLWINDOW.
|
||
|
*
|
||
|
* We vanish on minimization by hiding ourselves, parking
|
||
|
* the minimized window "in outer space" so it doesn't bother
|
||
|
* the user. Then re-show it so it can take part in Alt+Tab.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
/*
|
||
|
* These are the co-ordinates of outer space. Note that we can't base
|
||
|
* this on GetSystemMetrics(SM_C[XY]SCREEN) because the user might be
|
||
|
* running multiple monitors, and we need to be sure we are outside all
|
||
|
* monitors. So we pick a really absurd value for outer space.
|
||
|
*/
|
||
|
#define XOUTERSPACE (-32000)
|
||
|
#define YOUTERSPACE (-32000)
|
||
|
|
||
|
HWND g_hwndMain;
|
||
|
HWND g_hwndDlg;
|
||
|
int g_cMailUsers;
|
||
|
int g_cNewsUsers;
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* @func void | UI_UpdateCounts |
|
||
|
*
|
||
|
* Update the counts of things.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
void INTERNAL
|
||
|
UI_UpdateCounts(void)
|
||
|
{
|
||
|
SetDlgItemInt(g_hwndDlg, IDC_MAIL, g_cMailUsers, FALSE);
|
||
|
SetDlgItemInt(g_hwndDlg, IDC_NEWS, g_cNewsUsers, FALSE);
|
||
|
|
||
|
EnableWindow(GetDlgItem(g_hwndDlg, IDOK), !(g_cMailUsers | g_cNewsUsers));
|
||
|
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* @func BOOL | UI_OnSysCommand |
|
||
|
*
|
||
|
* Munge some commands around.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
BOOL INTERNAL
|
||
|
UI_OnSysCommand(HWND hdlg, WPARAM wp)
|
||
|
{
|
||
|
switch (wp & ~0xF) {
|
||
|
case SC_CLOSE:
|
||
|
FORWARD_WM_COMMAND(hdlg, IDCANCEL, 0, 0, PostMessage);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* @func BOOL | UI_OnCommand |
|
||
|
*
|
||
|
* Munge some commands around.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
BOOL INTERNAL
|
||
|
UI_OnCommand(HWND hdlg, WPARAM wp)
|
||
|
{
|
||
|
ANIMATIONINFO aniOld, aniNew;
|
||
|
|
||
|
switch (wp) {
|
||
|
case IDCANCEL:
|
||
|
/*
|
||
|
* There is no way to minimize a hidden window.
|
||
|
*/
|
||
|
|
||
|
aniOld.cbSize = sizeof(aniOld);
|
||
|
SystemParametersInfo(SPI_GETANIMATION, sizeof(aniOld), &aniOld, 0);
|
||
|
|
||
|
aniNew.cbSize = sizeof(aniNew);
|
||
|
aniNew.iMinAnimate = 0;
|
||
|
SystemParametersInfo(SPI_SETANIMATION, sizeof(aniNew), &aniNew, 0);
|
||
|
|
||
|
ShowWindow(hdlg, SW_MINIMIZE);
|
||
|
|
||
|
SystemParametersInfo(SPI_SETANIMATION, sizeof(aniOld), &aniOld, 0);
|
||
|
|
||
|
SetWindowPos(hdlg, HWND_BOTTOM,
|
||
|
XOUTERSPACE, YOUTERSPACE, 0, 0,
|
||
|
SWP_NOACTIVATE | SWP_NOSIZE | SWP_SHOWWINDOW);
|
||
|
return TRUE;
|
||
|
|
||
|
case IDOK:
|
||
|
FORWARD_WM_CLOSE(hdlg, PostMessage);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* @func BOOL | UI_OnClose |
|
||
|
*
|
||
|
* Note that various weird conditions can lead to us getting
|
||
|
* here while there are active sessions, so re-check before
|
||
|
* leaving.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
void INTERNAL
|
||
|
UI_OnClose(HWND hdlg)
|
||
|
{
|
||
|
if (IsWindowEnabled(GetDlgItem(hdlg, IDOK))) {
|
||
|
DestroyWindow(hdlg);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* @func INT_PTR | UI_DlgProc |
|
||
|
*
|
||
|
* Our dialog procedure.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
INT_PTR CALLBACK
|
||
|
UI_DlgProc(HWND hdlg, UINT wm, WPARAM wp, LPARAM lp)
|
||
|
{
|
||
|
switch (wm) {
|
||
|
case WM_SYSCOMMAND:
|
||
|
return UI_OnSysCommand(hdlg, wp);
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
return UI_OnCommand(hdlg, wp);
|
||
|
|
||
|
case WM_NCPAINT:
|
||
|
if (IsIconic(hdlg)) {
|
||
|
return TRUE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_CLOSE:
|
||
|
UI_OnClose(hdlg);
|
||
|
return TRUE;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
PostQuitMessage(0);
|
||
|
break;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* @func HWND | UI_Init |
|
||
|
*
|
||
|
* Initialize the UI stuff.
|
||
|
*
|
||
|
* @returns
|
||
|
*
|
||
|
* Nonzero on success.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
HWND INTERNAL
|
||
|
UI_Init(void)
|
||
|
{
|
||
|
g_hwndMain = CreateWindow(
|
||
|
"static", /* Class Name */
|
||
|
"", /* Title */
|
||
|
WS_OVERLAPPEDWINDOW | WS_MINIMIZE,
|
||
|
/* Style (note: not visible) */
|
||
|
CW_USEDEFAULT, CW_USEDEFAULT, /* Position */
|
||
|
CW_USEDEFAULT, CW_USEDEFAULT, /* Size */
|
||
|
NULL, /* Parent */
|
||
|
NULL, /* Use class menu */
|
||
|
g_hinst, /* Instance */
|
||
|
0); /* No special parameters */
|
||
|
|
||
|
// SubclassWindow(g_hwndMain, Main_WndProc);
|
||
|
|
||
|
SendMessage(g_hwndMain, WM_SETICON, ICON_BIG,
|
||
|
(LPARAM)LoadIcon(g_hinst, MAKEINTRESOURCE(IDI_MAIN)));
|
||
|
|
||
|
/*
|
||
|
* Create the dialog not visible because we're going to be shoving
|
||
|
* it around.
|
||
|
*/
|
||
|
g_hwndDlg = CreateDialog(g_hinst, MAKEINTRESOURCE(IDD_MAIN),
|
||
|
g_hwndMain, UI_DlgProc);
|
||
|
|
||
|
/*
|
||
|
* Tell the system that the window should be parked in outer space.
|
||
|
*/
|
||
|
SetWindowPos(g_hwndDlg, HWND_BOTTOM,
|
||
|
XOUTERSPACE, YOUTERSPACE, 0, 0,
|
||
|
SWP_NOACTIVATE | SWP_NOSIZE | SWP_SHOWWINDOW);
|
||
|
|
||
|
return g_hwndDlg;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* @func void | UI_Term |
|
||
|
*
|
||
|
* Clean up the UI stuff.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
void INTERNAL
|
||
|
UI_Term(void)
|
||
|
{
|
||
|
DestroyWindow(g_hwndMain);
|
||
|
}
|