📄 ntse95r.c
字号:
demenu = submenu; goto Error;
}
ANDrv refresh_start_type(submenu);
ANDrv AppendMenu(hPopupGlobal, MF_SEPARATOR, 0, "");
submenu = CreatePopupMenu();
if (!submenu ||
!AppendMenu(hPopupGlobal, MF_POPUP|MF_STRING,
(UINT_PTR)submenu, "Special"))
{
demenu = submenu; goto Error;
}
ANDrv AppendMenu(submenu, MF_STRING, nwCmdWmHIDE, "Hide");
ANDrv AppendMenu(submenu, MF_STRING, nwCmdWmEXIT, "Exit");
if (!rv)
{
Error:
rv = GetLastError();
if (demenu) DestroyMenu(demenu);
UL_ERROR((NSLOG, "%!l ntse::AppendMenu() FAILED", rv));
return rv? rv: -1;
}
return 0;
}
static BOOL taskbar_icon(HWND hWnd, const char *title)
{
BOOL rv;
NOTIFYICONDATA pnid;
memset(&pnid, 0, sizeof pnid);
#if defined(NOTIFYICONDATA_V1_SIZE)
pnid.cbSize = NOTIFYICONDATA_V1_SIZE;
#elif !defined(NIF_STATE)
pnid.cbSize = sizeof(NOTIFYICONDATA);
if (sizeof(pnid.szTip) > 64)
pnid.cbSize = offsetof(NOTIFYICONDATA, szTip[64]);
#else
// pnid.cbSize = offsetof(NOTIFYICONDATA, dwState);
pnid.cbSize = offsetof(NOTIFYICONDATA, szTip) +
sizeof(pnid.szTip) < 64? sizeof(pnid.szTip): 64;
#endif
if (hWnd)
{
pnid.hWnd = hWnd;
pnid.uID = NTSE_ID_TASKBAR;
pnid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
pnid.uCallbackMessage = NTSE_WM_TASKBAR;
pnid.hIcon = hIconGlobal16;
strncpy (pnid.szTip, title, sizeof(pnid.szTip));
rv = Shell_NotifyIcon(NIM_ADD, &pnid);
UL_DEBUG((NSLOG, "%!L ntse::Shell_NotifyIcon() = %d ", rv));
}
else
{
pnid.uFlags = 0;
pnid.cbSize = sizeof (NOTIFYICONDATA);
pnid.hWnd = hWndGlobal;
pnid.uID = NTSE_ID_TASKBAR;
rv = Shell_NotifyIcon(NIM_DELETE, &pnid);
}
DrawMenuBar(pnid.hWnd);
// UpdateWindow(pnid.hWnd);
return rv;
}
static BOOL CALLBACK enum_icon(HMODULE hModule, // module handle
LPCTSTR lpszType, // resource type
LPTSTR lpszName, // resource name
LPARAM/*LONG_PTR*/ lParam) // application-defined parameter
{
//UL_DEBUG((NSLOG, "%!L ---- EnumResource (%x)(%d)", hModule, lpszName));
#if 0
hIconGlobal = LoadIcon(hModule, lpszName);
#else
hIconGlobal16 = LoadImage(hModule, lpszName,
IMAGE_ICON, 16, 16, LR_SHARED);
hIconGlobal32 = LoadImage(hModule, lpszName,
IMAGE_ICON, 0, 0, LR_SHARED|LR_DEFAULTSIZE);
#endif
// UL_DEBUG((NSLOG, "%!L EnumResource %p(%d)", hIconGlobal, lpszName));
return !hIconGlobal16;
}
static int InitInstance(int nCmdShow, const char *title)
{
HWND hWnd;
WNDCLASSEX wcex;
int rv;
#if 1
if (!hIconGlobal16)
EnumResourceNames(hInstGlobal, RT_GROUP_ICON, enum_icon, 0);
#endif
if (!hIconGlobal16) hIconGlobal16 = LoadIcon(NULL, IDI_APPLICATION);
if (!hIconGlobal32) hIconGlobal32 = hIconGlobal16;//LoadIcon(NULL, IDI_APPLICATION);
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstGlobal;
wcex.hIcon = hIconGlobal32;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = ntse_classname;
wcex.hIconSm = hIconGlobal16;
if (!RegisterClassEx(&wcex))
{
rv = GetLastError();
UL_ERROR((NSLOG, "%!l ntse::RegisterClassEx() FAILED", rv));
/* return rv? rv: -1;
Let's try without class registerd... */
}
hWnd = FindWindow(ntse_classname, title);
UL_MESSAGE((NSLOG, "%!L ntse::FindWindow()=%p", hWnd));
if (hWnd)
{
taskbar_icon(hWnd, title);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
PostMessage(hWnd, WM_COMMAND, nwCmdWmSHOW, 0); /* for Wine only */
return ERROR_SERVICE_ALREADY_RUNNING;
}
/* We can live without menus... But we willn't */
hPopupGlobal = CreatePopupMenu();
if (!hPopupGlobal)
{
rv = GetLastError();
UL_ERROR((NSLOG, "%!l ntse::CreatePopupMenu() FAILED", rv));
return rv? rv: -1;
}
if (rv = InitMenus())
{
DestroyMenu(hPopupGlobal);
hPopupGlobal = 0;
return rv;
}
hWnd = CreateWindow(ntse_classname, title, /*WS_OVERLAPPEDWINDOW*/ WS_POPUP,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // parent
hPopupGlobal, //NULL,
hInstGlobal, NULL);
if (!hWnd)
{
rv = GetLastError();
UL_ERROR((NSLOG, "%!l ntse::CreateWindow() FAILED", rv));
DestroyMenu(hPopupGlobal);
hPopupGlobal = 0;
return rv? rv: -1;
}
else UL_DEBUG((NSLOG, "ntse::CreateWindow()=%p"));
hWndGlobal = hWnd;
if (!taskbar_icon(hWnd, title))
{
rv = GetLastError();
UL_WARNING((NSLOG, "%!l ntse::Shell_NotifyIcon() FAILED", rv));
/* May be there is no shell/taskbar? */
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return 0;
}
static void ExitInstance (void)
{
if (!wndDestroyed && hWndGlobal)
UL_WARNING((NSLOG, "ntse95::ExitInstance()... Hmm..."));
else UL_DEBUG((NSLOG, "ntse95::ExitInstance()..."));
taskbar_icon(0, 0);
// Window does destroy itself...
// if (!DestroyWindow(hWndGlobal))
// UL_NOTICE((NSLOG, "%!L ntse::ExitInstance()DestroyWindow..."));
// Is the menu bound to window?
// if (hPopupGlobal && !DestroyMenu (hPopupGlobal))
// UL_NOTICE((NSLOG, "%!L ntse::ExitInstance()DestroyMenu..."));
if (!UnregisterClass(ntse_classname, hInstGlobal))
UL_NOTICE((NSLOG, "%!L ntse::UnRegisterClass() FAILED"));
hPopupGlobal = 0;
hWndGlobal = 0;
}
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int exit_pending;
unsigned wmId, wmEvent;
unsigned stt;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case nwCmdWmEXIT:
exit_pending++;
UL_DEBUG((NSLOG, "ntse::nwCmdWmEXIT %p", &wmId));
if ( 0 == command_for_all(-1) ||
IDCANCEL != MessageBox(hWnd,
"The service will be stopped", ntse_servlist->niSe->nsName,
MB_OKCANCEL/*|MB_ICONQUESTION/*/|MB_ICONWARNING))
{
UL_DEBUG((NSLOG, "ntse95::process exit"));
if (0 == command_for_all(nwCmdCtlSTOP))
{
wndDestroyed = 1;
DestroyWindow(hWnd);
}
else { wndShouldExit = 1; /* Ignore, Let's user click it again */ }
}
UL_DEBUG((NSLOG, "ntse::nwCmdWmEXIT finish %p", &wmId));
exit_pending--;
break;
case nwCmdWmQUIETEXIT:
UL_DEBUG((NSLOG, "ntse::nwCmdWmQUIETEXIT"));
wndShouldExit = 1;
if (0 == command_for_all(-1))
{
wndDestroyed = 1;
DestroyWindow(hWnd);
}
break;
case nwCmdWmHIDE:
UL_DEBUG((NSLOG, "ntse::nwCmdWmHIDE"));
if (wndSvcConf &&
wndSvcConf->dwStartType != SERVICE_DEMAND_START)
ntseAutoRun95(wndNC, ntse_servlist->niSe->nsName, NULL);
taskbar_icon(0, 0);
break;
case nwCmdWmSHOW: /* for Wine only */
UL_DEBUG((NSLOG, "ntse::nwCmdWmSHOW"));
taskbar_icon(hWndGlobal, ntse_servlist->niSe->nsName);
break;
case nwCmdStAUTO:
stt = SERVICE_AUTO_START; goto StartType;
case nwCmdStDEMAND:
stt = SERVICE_DEMAND_START; goto StartType;
case nwCmdStDISABLED:
stt = SERVICE_DISABLED;
StartType:
if (wndSvcConf && !(wndSvcConf->dwStartType == SERVICE_DISABLED?
ntseCreate95(wndNC, ntse_servlist->niSe->nsName,
wndSvcConf->dwServiceType, stt, wndSvcConf->lpBinaryPathName):
ntseChange95(wndNC, ntse_servlist->niSe->nsName,
wndSvcConf->dwServiceType, stt, wndSvcConf->lpBinaryPathName)))
{
wndSvcConf->dwStartType = stt;
refresh_start_type(0);
}
else MessageBox(hWnd, "Failed to change start type",
ntse_servlist->niSe->nsName, MB_OK|MB_ICONERROR);
break;
default:
UL_DEBUG((NSLOG, "WM_COMMAND{ 0x%X %d }/%p", wmId, wmId, &wmId));
if (wmId >= nwCmdBASE)
process_command(wmId, 1/*verbose*/);
else if (wmId >= nwCmdFORALL)
command_for_all(wmId - nwCmdFORALL);
else return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case NTSE_WM_TASKBAR: //wParam = NTSE_ID_TASKBAR; lParam = mouse notify
wmId = LOWORD(lParam);
wmEvent = HIWORD(lParam);
switch (wmId)
{
case WM_LBUTTONDOWN:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN:
{
POINT pt;
GetCursorPos (&pt);
if (exit_pending)
SetForegroundWindow(hWnd);
else
{
#if 1
static unsigned last_refresh;
unsigned time_now = GetTickCount();
if (time_now - last_refresh > (/*!wndSvcConf? 3000u:*/ 6000u))
{
QUERY_SERVICE_CONFIG *sc = 0;
stt = wndSvcConf? wndSvcConf->dwStartType: SERVICE_DISABLED;
if (ntseQueryConf95(wndNC, ntse_servlist->niSe->nsName, &sc))
{
if (wndSvcConf) wndSvcConf->dwStartType = SERVICE_DISABLED;
}
else
{
QUERY_SERVICE_CONFIG *tsc = wndSvcConf;
wndSvcConf = sc; sc = tsc;
}
if (sc) ntseFree(wndNC, sc);
if (stt != (wndSvcConf? wndSvcConf->dwStartType: SERVICE_DISABLED))
refresh_start_type(0);
last_refresh = time_now;
}
#endif
if (SetForegroundWindow(hWnd) ||
wmId == WM_LBUTTONDBLCLK)
{
TrackPopupMenu(hPopupGlobal, TPM_RIGHTBUTTON,
pt.x, pt.y, 0, hWnd, NULL);
PostMessage(hWnd, WM_NULL, 0, 0);
}
else
{
// PostMessage(hWnd, NTSE_WM_TASKBAR, wParam, lParam);
}
}
}
break;
}
break;
case WM_DESTROY:
UL_MESSAGE((NSLOG, "ntse::WM_DESTROY received"));
//?? ExitInstance (hInstGlobal);
// command_for_all(nwCmdCtlSTOP);
// DrawMenuBar(hWnd);
PostQuitMessage(0);
break;
case WM_ENDSESSION:
UL_TRACE((NSLOG, "ntse::WM_ENDSESSION received %x", lParam));
//wndShouldExit = 1;
if (lParam == 0) // real shutdown
{
unsigned nn = 32;
do if (command_for_all(nwCmdCtlSHUTDOWN)) Sleep(200);
else // real SCM doesn't translate SHUTDOWN to STOP
{
if (!command_for_all(-1))
{
wndDestroyed = 1;
DestroyWindow(hWnd);
}
break;
}
while(--nn > 0);
}
break;
default:
if (wm_TaskbarCreated && wm_TaskbarCreated == message)
taskbar_icon(hWndGlobal, ntse_servlist->niSe->nsName);
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
static int ntseRegServProc95(int reg)
{
DWORD (WINAPI *regservproc)(DWORD dwProcessId, DWORD dwType);
HMODULE kernel;
int rv;
kernel = GetModuleHandle("KERNEL32.DLL");
if (!kernel)
{
rv = GetLastError();
UL_NOTICE((NSLOG, "%!l ntseRegServProc(%d):GetModuleHandle()", rv, reg));
goto Error;
}
regservproc = (DWORD (WINAPI *)(DWORD, DWORD))
GetProcAddress(kernel, "RegisterServiceProcess");
if (!regservproc)
{
rv = GetLastError();
UL_NOTICE((NSLOG, "%!l ntseRegServProc(%d):GetProcAddress()", rv, reg));
goto Error;
}
rv = regservproc(0, reg);
if (!rv)
{
rv = GetLastError();
UL_NOTICE((NSLOG, "%!l ntseRegServProc(%d):RegisterServiceProcess()", rv, reg));
goto Error;
}
UL_TRACE((NSLOG, "ntseRegServProc(%d): Ok", reg));
return 0;
Error:
return rv? rv: -1;
}
/********************************************************************************/
/* end of ntse95r.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -