Здравствуйте, <Аноним>, Вы писали:
А>Я думаю, для многих не секрет, что в библиотеке shell32.dll есть функция под номером 60. Но не каждый знает, что эта функция выводит диалог завершения работы ОС. А>Так вот, когда я её вызываю — диалог завершения работы выводится, но когда выбираю какое-нибудь действие, то диалог просто закрывается и ничего не происходит. А>Почему?
Наверное потому, что эта функция просто выводит диалог.
Здравствуйте, Аноним, Вы писали:
А>Я думаю, для многих не секрет, что в библиотеке shell32.dll есть функция под номером 60. Но не каждый знает, что эта функция выводит диалог завершения работы ОС. А>Так вот, когда я её вызываю — диалог завершения работы выводится, но когда выбираю какое-нибудь действие, то диалог просто закрывается и ничего не происходит. А>Почему? А>Вот код: А>
A> ......
А>
На самом деле функция работает нормально и компутер выключает как надо. Просто по неизвестным причинам вызов FreeLibrary непосредственно после этой волшебной функции прерывает процесс выключения. Если поставить там задержку, то все работает.
Вот еще вариант:
PostMessage(FindWindow('Shell_TrayWnd', nil), WM_close, 0, 0);
Проверял на 98 и ХР.
Диалог завершения работы
От:
Аноним
Дата:
18.08.04 04:33
Оценка:
Я думаю, для многих не секрет, что в библиотеке shell32.dll есть функция под номером 60. Но не каждый знает, что эта функция выводит диалог завершения работы ОС.
Так вот, когда я её вызываю — диалог завершения работы выводится, но когда выбираю какое-нибудь действие, то диалог просто закрывается и ничего не происходит.
Почему?
Вот код:
typedef void (_stdcall *SHShutDownDialogProc)(HWND);
if(Надо вывести диалог завершения работы)
{
// получаем версию
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
// если 9x, то просто запоминаем в глобальной переменнойif(osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
WinVer = VER_PLATFORM_WIN32_WINDOWS;
}
// если NT, то устанавливаем привилегии на завершение работыelse if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
WinVer = VER_PLATFORM_WIN32_NT;
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
if(!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
PrintError("OpenProcessToken");
if(!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
&tkp.Privileges[0].Luid))
PrintError("LookupPrivilegeValue");
tkp.PrivilegeCount = 1; // one privilege to set
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
(PTOKEN_PRIVILEGES)NULL, 0))
PrintError("AdjustTokenPrivileges");
}
//иначе ошибкаelse
{
MessageBox(0,"Данная версия ОС не поддерживает эту операцию.",
0,MB_OK|MB_ICONSTOP);
return 1;
}
// ищем в shell32.dll функцию, которая выводит диалог завершения работы
// и вызываем её
SHShutDownDialogProc SHShutDownDialog;
HMODULE hDll;
hDll = LoadLibrary("shell32.dll");
if(!hDll)PrintError("LoadLibrary");
SHShutDownDialog = (SHShutDownDialogProc)GetProcAddress(hDll,(LPCSTR)60);
if(!SHShutDownDialog)PrintError("GetProcAddress");
SHShutDownDialog(GetDesktopWindow());
FreeLibrary(hDll);
}
Здравствуйте, Аноним, Вы писали:
А>Я думаю, для многих не секрет, что в библиотеке shell32.dll есть функция под номером 60. Но не каждый знает, что эта функция выводит диалог завершения работы ОС. А>Так вот, когда я её вызываю — диалог завершения работы выводится, но когда выбираю какое-нибудь действие, то диалог просто закрывается и ничего не происходит. А>Почему? А> ...
А я откуда знаю? Фича недокументированная!
Хотя, rockandroll по-моему правильно сказал...
Здравствуйте, <Аноним>, Вы писали:
А>Я думаю, для многих не секрет, что в библиотеке shell32.dll есть функция под номером 60. Но не каждый знает, что эта функция выводит диалог завершения работы ОС. А>Так вот, когда я её вызываю — диалог завершения работы выводится, но когда выбираю какое-нибудь действие, то диалог просто закрывается и ничего не происходит. А>Почему?
Вообще-то лучше юзать RestartDialogEx — он все возвращает и сам вызывает ExitWindowsEx
А>Вот код:
А>
А>typedef void (_stdcall *SHShutDownDialogProc)(HWND);
А>if(Надо вывести диалог завершения работы)
А>{
А> // получаем версию
А> OSVERSIONINFO osvi;
А> osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
А> GetVersionEx(&osvi);
А> // если 9x, то просто запоминаем в глобальной переменной
А> if(osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
А> {
А> WinVer = VER_PLATFORM_WIN32_WINDOWS;
А> }
А> // если NT, то устанавливаем привилегии на завершение работы
А> else if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
А> {
А> WinVer = VER_PLATFORM_WIN32_NT;
А> HANDLE hToken;
А> TOKEN_PRIVILEGES tkp;
А> if(!OpenProcessToken(GetCurrentProcess(),
А> TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
А> PrintError("OpenProcessToken");
А> if(!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
А> &tkp.Privileges[0].Luid))
А> PrintError("LookupPrivilegeValue");
А> tkp.PrivilegeCount = 1; // one privilege to set
А> tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
А> if(!AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
А> (PTOKEN_PRIVILEGES)NULL, 0))
А> PrintError("AdjustTokenPrivileges");
А> }
А> //иначе ошибка
А> else
А> {
А> MessageBox(0,"Данная версия ОС не поддерживает эту операцию.",
А> 0,MB_OK|MB_ICONSTOP);
А> return 1;
А> }
А> // ищем в shell32.dll функцию, которая выводит диалог завершения работы
А> // и вызываем её
А> SHShutDownDialogProc SHShutDownDialog;
А> HMODULE hDll;
А> hDll = LoadLibrary("shell32.dll");
А> if(!hDll)PrintError("LoadLibrary");
А> SHShutDownDialog = (SHShutDownDialogProc)GetProcAddress(hDll,(LPCSTR)60);
А> if(!SHShutDownDialog)PrintError("GetProcAddress");
А> SHShutDownDialog(GetDesktopWindow());
А> FreeLibrary(hDll);
А>}
А>
Здравствуйте, <Аноним>, Вы писали:
R>>Наверное потому, что эта функция просто выводит диалог.
А>Но эта функция ничего не возвращает.
Как ты это узнал?
А>Как мне узнать, какую кнопку юзер тыкнул? Неужели хуки?
Как тебе советовали, не пользуйся недокументированными функциями. Нарисуй свой диалог.
... << RSDN@Home 1.1.4 >>
Re[4]: Диалог завершения работы
От:
Аноним
Дата:
18.08.04 10:34
Оценка:
Здравствуйте, rockandroll, Вы писали:
R>Как ты это узнал?
В нете, умные люди пишут.
R>Как тебе советовали, не пользуйся недокументированными функциями. Нарисуй свой диалог.
Так в разных виндах он разный, а дясять штук делать неохота и ващще...
Re[2]: Диалог завершения работы
От:
Аноним
Дата:
18.08.04 10:36
Оценка:
Здравствуйте, dv2004, Вы писали:
D>Вообще-то лучше юзать RestartDialogEx — он все возвращает и сам вызывает ExitWindowsEx
А подробнее можно, а то я что-то такого не слышал и не видел.
Здравствуйте, <Аноним>, Вы писали:
А>Здравствуйте, dv2004, Вы писали:
D>>Вообще-то лучше юзать RestartDialogEx — он все возвращает и сам вызывает ExitWindowsEx
А>А подробнее можно, а то я что-то такого не слышал и не видел.
Вот кусок из MSDN:
RestartDialogEx Function
Displays a dialog box that asks the user to restart Microsoft® Windows®. When the user clicks the button, the function calls ExitWindowsEx to attempt to restart Windows.
Syntax
int RestartDialogEx(
HWND hParent,
LPCWSTR pszPrompt,
DWORD dwFlags,
HWND dwReasonCode
);
Parameters
hParent
[in] A handle to the parent window.
pszPrompt
[in] A null-terminated string that contains the text that displays in the dialog box to prompt the user.
dwFlags
[in] Flags that specifies the type of shutdown.
This parameter must include one of the following values.
EWX_LOGOFF
Shuts down all processes running in the security context of the process that called this function. Then it logs the user off.
EWX_POWEROFF
Shuts down the system and turns off the power. The system must support the power-off feature. The calling process must have the SE_SHUTDOWN_NAME privilege. For more information, see ExitWindowsEx.
EWX_REBOOT
Shuts down the system and then restarts the system. The calling process must have the SE_SHUTDOWN_NAME privilege. For more information, see ExitWindowsEx.
EWX_SHUTDOWN
Shuts down the system to a point at which it is safe to turn off the power. At this point, all file buffers have been flushed to disk, and all running processes have stopped. If the system supports the power-off feature, the power is also turned off. The calling process must have the SE_SHUTDOWN_NAME privilege. For more information, see ExitWindowsEx.
This parameter can optionally include the following values.
EWX_FORCE
Forces processes to terminate. When this flag is set, the system does not send the WM_QUERYENDSESSION and WM_ENDSESSION messages. This can cause the applications to lose data. Therefore, you should only use this flag in an emergency.
EWX_FORCEIFHUNG
Forces processes to terminate if they do not respond to the WM_QUERYENDSESSION or WM_ENDSESSION message. This flag is ignored if EWX_FORCE is used.
dwReasonCode
[in]
Windows XP:Specifies the reason for initiating the shutdown. For more information, see System Shutdown Reason Codes.
Windows 2000: This parameter is ignored.
Return Value
Returns the identifier of the button that was pressed to close the dialog box.
Function Information
Minimum DLL Version shell32.dll version 5.0 or later
Custom Implementation No
Header shlobj.h
Import library shell32.lib
Minimum operating systems Windows 2000
G>Похоже, просто не надо использовать FreeLibrary() для shell32.dll...
А прога после этого сразу завершается и Виновззз сам Освобождает ресурсы, т.е. билу тоже. Короче, не получается так. А вот если задержку сделать, то, действительно вырубает.
Re[2]: Диалог завершения работы
От:
Аноним
Дата:
20.08.04 10:26
Оценка:
Здравствуйте, aGrey, Вы писали:
G>Ловите еще вариант, СОМ-ненавистники
G>
Здравствуйте, <Аноним>, Вы писали:
А>Я думаю, для многих не секрет, что в библиотеке shell32.dll есть функция под номером 60. Но не каждый знает, что эта функция выводит диалог завершения работы ОС. А>Так вот, когда я её вызываю — диалог завершения работы выводится, но когда выбираю какое-нибудь действие, то диалог просто закрывается и ничего не происходит.
пришел digest за неделю с codeproject: а может здесь статья в тему ложится?
... << RSDN@Home 1.1.4 @@subversion >>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.