Desktop disabel - aber wie ?
-
Hallo,
ich will die Rechnerverwendung während eines Programmvorgangs verhindern. Wie z.B. wenn man den "Herunterfahren" Dialog bei WinXP öffnet und bestimmt jeder auch kennt. Da wird der kmpl. Desktop grau und nur der Dialog ist aktiv.
Leider weiß ich nicht welche Funktion oder welches Vorgehen dazu nötig ist...Hat jemand eine Idee oder ein Tip...
Besten Dank,
mit freundlichem Gruß
Marcus
-
Versuch es doch mit BlockInput. Ist nur schlecht wenn dann nach dem
BlockInput dein Programm abschmieren sollte.
-
Dabei wird ein zusätzliches Fenster über den Desktio gelegt. ALT+Tab und Konsorten musst Du abfagen. Es wird Dir nur nicht nmit Strg+Alt+Entf gelingen.
-
Okay besten Dank für die Antowrten,
hab mir mal ein Beispiel Programm angesehen, leider eine Mischung auf managed und unmanaged Code.Es ist sind nicht viel Zeilen, hier der Source Code
/*** DimmerDialog - A .NET class to show a modal dialog that dims the background. Author : Nishant Sivakumar Email : voidnish@gmail.com Blog : http://blog.voidnish.com Web : http://www.voidnish.com You may freely use this class as long as you include this copyright. You may freely modify and use this class as long as you include this copyright in your modified version. This code is provided "as is" without express or implied warranty. Copyright © Nishant Sivakumar, 2006. All Rights Reserved. ***/ #pragma once #include <windows.h> #include <tchar.h> using namespace System; using namespace System::Threading; using namespace System::Windows::Forms; using namespace System::Drawing; using namespace System::Drawing::Imaging; using namespace System::Timers; LPCTSTR g_desktopname = _T("{F375AF67-22ED-4ba2-928E-B9DB633AA79C}"); public ref class DimmerDialog { private: HDESK m_hOrigDesktop; HDESK m_hDimmerDesktop; Bitmap^ m_Image; System::Timers::Timer^ m_Timer; Form^ m_BackgroundForm; Form^ m_MainForm; bool m_bShowForm; String^ m_text; String^ m_title; MessageBoxIcon m_icon; int m_ColorReductionStep; void OnTimer(Object^ source, ElapsedEventArgs^ e) { if(++m_ColorReductionStep > 4) m_Timer->Enabled = false; else { m_Timer->Enabled = false; ((PictureBox^)m_BackgroundForm->Controls[0])->Image = DimBitmap(); m_BackgroundForm->Controls[0]->Invalidate(); m_BackgroundForm->Controls[0]->Update(); m_Timer->Enabled = true; } } void SwitchToDimmerDesktop() { m_hOrigDesktop = GetThreadDesktop(GetCurrentThreadId()); m_hDimmerDesktop = CreateDesktop(g_desktopname, NULL,NULL,0,GENERIC_ALL,NULL); if(m_hDimmerDesktop) { if(SetThreadDesktop(m_hDimmerDesktop)) { SwitchDesktop(m_hDimmerDesktop); m_ColorReductionStep = 0; m_Timer = gcnew System::Timers::Timer; m_Timer->Elapsed += gcnew ElapsedEventHandler(this, &DimmerDialog::OnTimer ); m_Timer->Interval = 100; m_BackgroundForm = gcnew Form(); m_BackgroundForm->FormBorderStyle = FormBorderStyle::None; m_BackgroundForm->WindowState = FormWindowState::Maximized; PictureBox picbox; picbox.Dock = DockStyle::Fill; picbox.Image = DimBitmap(); m_BackgroundForm->Controls->Add(%picbox); m_BackgroundForm->Show(); m_Timer->Enabled = true; if(m_bShowForm) { m_MainForm->StartPosition = FormStartPosition::CenterParent; m_MainForm->ShowDialog(); } else { MessageBox::Show(m_text, m_title, MessageBoxButtons::OK, m_icon); } SwitchDesktop(m_hOrigDesktop); SetThreadDesktop(m_hOrigDesktop); } } CloseDesktop(m_hDimmerDesktop); } void Show() { HDC hDC = GetDC(NULL); HDC hMemDC = CreateCompatibleDC(hDC); SIZE size; size.cx = GetSystemMetrics(SM_CXSCREEN); size.cy = GetSystemMetrics(SM_CYSCREEN); HBITMAP hBitmap = CreateCompatibleBitmap(hDC, size.cx, size.cy); if (hBitmap) { HBITMAP hOld = (HBITMAP) SelectObject(hMemDC, hBitmap); BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, SRCCOPY); SelectObject(hMemDC, hOld); DeleteDC(hMemDC); ReleaseDC(NULL, hDC); m_Image = Image::FromHbitmap((IntPtr)hBitmap); DeleteObject(hBitmap); } Thread^ switchthread = gcnew Thread( gcnew ThreadStart(this,&DimmerDialog::SwitchToDimmerDesktop)); switchthread->Start(); } Bitmap^ DimBitmap() { if(m_ColorReductionStep == 0) return m_Image; Bitmap^ imagecopy = (Bitmap^)m_Image->Clone(); BitmapData^ bmData = imagecopy->LockBits( System::Drawing::Rectangle(0, 0, imagecopy->Width, imagecopy->Height), ImageLockMode::ReadWrite, PixelFormat::Format24bppRgb); BYTE* p = (BYTE*)bmData->Scan0.ToPointer(); int nOffset = bmData->Stride - imagecopy->Width * 3; BYTE red, green, blue; for(int y=0; y < imagecopy->Height; y++) { for(int x=0; x < imagecopy->Width; x++) { blue = p[0]; green = p[1]; red = p[2]; switch(m_ColorReductionStep) { case 1: p[0] = (BYTE)(.001 * red + .286 * green + .713 * blue); p[1] = (BYTE)(.001 * red + .986 * green + .013 * blue); p[2] = (BYTE)(.899 * red + .087 * green + .013 * blue); break; case 2: p[0] = (BYTE)(.099 * red + .387 * green + .514 * blue); p[1] = (BYTE)(.099 * red + .887 * green + .014 * blue); p[2] = (BYTE)(.699 * red + .287 * green + .013 * blue); break; case 3: p[0] = (BYTE)(.199 * red + .487 * green + .314 * blue); p[1] = (BYTE)(.199 * red + .787 * green + .014 * blue); p[2] = (BYTE)(.499 * red + .487 * green + .014 * blue); break; case 4: p[0] = p[1] = p[2] = (BYTE)(.299 * red + .587 * green + .114 * blue); break; } p += 3; } p += nOffset; } imagecopy->UnlockBits(bmData); return imagecopy; } public: DimmerDialog() { m_hOrigDesktop = nullptr; m_hDimmerDesktop = nullptr; } void ShowForm(Form^ form) { m_bShowForm = true; m_MainForm = form; Show(); } void ShowMessageBox(String^ text, String^ title, MessageBoxIcon icon) { m_bShowForm = false; m_MainForm = nullptr; m_text = text; m_title = title; m_icon = icon; Show(); } };Leider steig ich da nicht ganz durch, ich brauch das ganze in einem reinen VC6 Projekt mit einem Dialog Basierenden Programm.
Hab schon mal etwas mit dem "SetThreadDesktop", "SwitchDesktop" experimientiert, bekomm ab immer den Fehler "170 The requested resource is in use.". Hier mein Testcode, jemand eine Idee wie ich weiter komme, soweit ich das verstehe kann man damit eine zusätzlichen Desktop anlegen und den Desktop Thread darauf setzen, somit ist der vorherige Desktop "disabled"..._AFX_THREAD_STATE *pState = AfxGetThreadState(); bool blUnhookOk = UnhookWindowsHookEx(pState->m_hHookOldMsgFilter); pState->m_hHookOldMsgFilter = NULL; LPTSTR g_desktopname = _T("{F375AF67-22ED-4ba2-928E-B9sdfasdfasdfasdf3AA79C}"); HDESK m_hOrigDesktop; HDESK m_hDimmerDesktop; m_hOrigDesktop = GetThreadDesktop(GetCurrentThreadId()); m_hDimmerDesktop = CreateDesktop(g_desktopname, NULL,NULL,0,GENERIC_ALL,NULL); if(m_hDimmerDesktop) { if(SetThreadDesktop(m_hDimmerDesktop)) { SwitchDesktop(m_hDimmerDesktop); AfxMessageBox(_T("Anderer Desktop")); SwitchDesktop(m_hOrigDesktop); SetThreadDesktop(m_hOrigDesktop); } else { DWORD dwError = GetLastError(); CString sOut; sOut.Format(_T("%d"),dwError); AfxMessageBox(sOut); } }Besten Dank,
gruss
Marcus
-
Könnte vielleicht daran liegen:
MSDN schrieb:
The SetThreadDesktop function will fail if the calling thread has any windows or hooks on its current desktop (unless the hDesktop parameter is a handle to the current desktop).
-
Hab ich auch schon gesehen, deshalb hab ich dieses Zeilen eingefügt :
_AFX_THREAD_STATE *pState = AfxGetThreadState(); bool blUnhookOk = UnhookWindowsHookEx(pState->m_hHookOldMsgFilter); pState->m_hHookOldMsgFilter = NULL;Aber scheint keine Verbesserung zu bringen.
gruss
Marcus