Окно с прозрачным фоном - C ++ / CLI .net - PullRequest
2 голосов
/ 08 февраля 2012

Это действительно стресс,

Мне нужно создать форму с прозрачным фоном или даже нарисовать на экране, я хочу иметь возможность рисовать на экране все, что захочу, но она все равно должна действовать как форма, чтобы я мог получать все события из этого .. Кто-нибудь знает, почему я получаю 0 при вызове UpdateLayeredWindow?

У меня есть следующие структуры

[StructLayout(LayoutKind::Sequential)]
public ref struct wPoint

[StructLayout(LayoutKind::Sequential)]
public ref struct wSize

[StructLayout(LayoutKind::Sequential, Pack = 1)]
public ref struct BLENDFUNCTION

I И это те функции, которые я импортировал из нативного c ++

        [DllImport("user32.dll")]
    static IntPtr GetDC(IntPtr hWnd);
    [DllImport("user32.dll")]
    static int ReleaseDC(IntPtr hWnd, IntPtr dc);   
    [DllImport("Kernel32.dll")]
    static unsigned long GetLastError(void);
    [DllImport("user32.dll")]
    static bool ShowWindow(unsigned long hWnd, int nCmdShow);
    [DllImport("user32.dll", CharSet = CharSet::Auto, SetLastError = true)]
    static int UpdateLayeredWindow(
        IntPtr hwnd,
        IntPtr hdcDst,
        [System::Runtime::InteropServices::In()]
        wPoint ^ pptDst,
        [System::Runtime::InteropServices::In()]
        wSize ^ psize,
        IntPtr hdcSrc,
        [System::Runtime::InteropServices::In()]
        wPoint ^ pptSrc,
        int crKey,
        [System::Runtime::InteropServices::In()]
        BLENDFUNCTION ^ pblend,
        int dwFlags);
    [DllImport("gdi32.dll")]
    static IntPtr CreateCompatibleDC(IntPtr hDC);
    [DllImport("gdi32.dll")]
    static int DeleteDC(IntPtr hdc);
    [DllImport("gdi32.dll")]
    static int DeleteObject(IntPtr hObject);
    [DllImport("gdi32.dll")]
    static IntPtr SelectObject(IntPtr hDC, IntPtr hObject);

Я очищаю функцию OnPaint (переопределяю ее) и переопределяю функцию OnShow, чтобы вызвать следующую функцию с растровым изображением, которое будет отображаться на экране.

void SmartToolTips::SetLayeredBitmap(Bitmap^ bitmap, Byte opacity){
IntPtr dc = Win32::GetDC(IntPtr::Zero);
IntPtr memorydc = Win32::CreateCompatibleDC(IntPtr::Zero);
IntPtr bitmaphandle = IntPtr::Zero;
IntPtr bitmaphandleold = IntPtr::Zero;
try
{
    bitmaphandle = bitmap->GetHbitmap(Color::FromArgb(0));
    bitmaphandleold = Win32::SelectObject(memorydc, bitmaphandle);

    wSize^ size = gcnew wSize(bitmap->Width, bitmap->Height);
    wPoint^ pointSource = gcnew wPoint(0, 0);
    wPoint^ topPos = gcnew wPoint(Left, Top);
    BLENDFUNCTION^ blend = gcnew BLENDFUNCTION();
    blend->BlendOp = AC_SRC_OVER;
    blend->BlendFlags = 0;
    blend->SourceConstantAlpha = opacity;
    blend->AlphaFormat = AC_SRC_ALPHA;
    int res = Win32::UpdateLayeredWindow(Handle, dc, topPos, size, memorydc, pointSource, 0, blend, ULW_ALPHA);
    if (!res)
    {
        Debug::WriteLine("Failed to update layered window");
        Debug::WriteLine(Win32::GetLastError());
    }
}
finally
{
    if (bitmaphandle != IntPtr::Zero)
    {
        Win32::SelectObject(memorydc, bitmaphandleold);
        Win32::DeleteObject(bitmaphandle);
    }
    Win32::DeleteDC(memorydc);
    Win32::ReleaseDC(IntPtr::Zero, dc); 
}

}

Еще одна вещь, которую я переопределил:

        property System::Windows::Forms::CreateParams^ CreateParams 
    {
        virtual System::Windows::Forms::CreateParams^ get()override
        {
            System::Windows::Forms::CreateParams^ createParams = __super::CreateParams;
            createParams->ExStyle |= WS_EX_LAYERED | WS_EX_TRANSPARENT;
            return createParams;
        }
    }

Кто-нибудь знает, почему ничего не появляется? и UpdateLayeredWindow возвращает код ошибки 87: неверный параметр?

Спасибо !!

...