سؤال

لدي تطبيق Windows يستخدم APPBAR API لتثبيت كشرح تطبيق في الجزء العلوي من الشاشة (على غرار شريط مهام Windows نفسه). يعمل هذا بشكل رائع ويتم ضبط حجم سطح المكتب وفقا لذلك، لذلك تطبيقي مرئي دائما.

ومع ذلك، إذا اختر المستخدم "إظهار سطح المكتب" (Windows + D)، فإن طلبي مخفي. لا أحد يعرف وسيلة لفخ "إظهار سطح المكتب" حتى أتمكن من ضمان يبقى طلبي مرئيا (أفترض أن Windows يعوم جميع النوافذ ذات المستوى الأعلى ويختبئها مع ShowWindow (SW_Hide).

هل كانت مفيدة؟

المحلول

استخدم التعليمات البرمجية التالية وتمرير مقبض النافذة إلى الوظيفة أثناء تحميل النموذج. نأمل أن يحل هذا مشكلتك.

public void SetFormOnDesktop(IntPtr hwnd)
{
    IntPtr hwndf = hwnd;
    IntPtr hwndParent = FindWindow("ProgMan", null);
    SetParent(hwndf, hwndParent);
}

نصائح أخرى

كنت تحت الانطباع الذي وضع النافذة كأكبر أعلى (عبر setwindowpos. ويمنع معظم العلم hwnd_toppoy) سطح المكتب من تغطية ذلك. يتقدم Windows + D من خلال تقليل جميع النوافذ، ثم قم بتغطية تلك التي لا يمكن تقليلها عن طريق رفع سطح المكتب في ترتيب Z (حسنا، فعلت في نقطة واحدة على أي حال). أعتقد أنه يمكنك إنشاء نافذة غير قابلة للتطبيق من خلال عدم اجتياز WS_MINIMIZEBOX إلى إنشاء WS_MINIMIZEEX، أو باستخدام WS_EX_TOOLWindow على الرغم من أنني لست 100٪ على هذا الجزء.

سيكون نهج الوفالي أثقل بكثير هو ربط لوحة المفاتيح العالمية باستخدام setwindowshookex و keyboardProc. سيكون لهذا تأثير ضار على تجربة المستخدم.


ذهبت وترميز مثال بسيط حقا على ما أتحدث عنه. يجعل التعليمات البرمجية التالية نافذة غير تقليص أو مغطاة من قبل مستخدم يضرب Windows + D. لاحظ أنه على نظام التشغيل Windows 7، لا يزال من الممكن إحضار الأدوات على سطح المكتب فوقها؛ التي لا أستطيع أن أشرح حقا.

#include <windows.h>
#include <tchar.h>

#define WIN_TITLE _T("Resists Win+D Window")
#define WIN_CLASS _T("Resists Win+D Class")

LRESULT CALLBACK CustomWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    //Special behavior goes here

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

HWND CreateMainWindow(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = CustomWndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = WIN_CLASS;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

    if (!RegisterClassEx(&wcex))
    {
        exit(1);
    }

    HWND hWnd = CreateWindowEx(
        WS_EX_TOOLWINDOW,
        WIN_CLASS,
        WIN_TITLE,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        500,
        100,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hWnd)
    {
        exit(1);
    }

    return hWnd;
}

/*
  Main entry point
*/
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    HWND hwnd = CreateMainWindow(hInstance);

    ShowWindow(hwnd, nCmdShow);
    SetWindowPos(hwnd, HWND_TOPMOST, -1, -1, -1, -1, SWP_NOMOVE | SWP_NOSIZE);
    UpdateWindow(hwnd);

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int) msg.wParam;
}

في إخطار ABN_FULLSCREENAPP الخاص بك، تحتاج إلى تحديد ما إذا كانت النافذة التي تحتلها منطقة العمل هي سطح المكتب، وإذا كان الأمر كذلك، فتجاهل رسالة ABN_FullScreenApp.

PS كتنفيذ بديل، والنظر في التجاري Shellappbar. عنصر.

بالإضافة الى إجابة jks., ، إليك رمز العمل ل VB.NET، على افتراض أنك حولت نموذجك بالفعل إلى AppBar. تحتاج إلى P / استدعاء الوظائف FindWindow و SetFormOnDesktop.

'In your form
Public Sub New()
    'Stuff
    SetFormOnDesktop(Me.Handle)
    'More stuff
End Sub

'In your form or somewhere else.
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindow( _
 ByVal lpClassName As String, _
 ByVal lpWindowName As String) As IntPtr
End Function

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Public Shared Function SetParent(_
 ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr
End Function

Public Sub SetFormOnDesktop(hwnd As IntPtr)
    Dim hwndf As IntPtr = hwnd
    Dim hwndParent As IntPtr = FindWindow("ProgMan", Nothing)
    SetParent(hwndf, hwndParent)
End Sub
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top