【问题标题】:c++ remove pixels from dialog round cornersc ++从对话框圆角中删除像素
【发布时间】:2017-09-25 11:48:34
【问题描述】:

我想删除一些在带有圆角的对话框窗口中可见的像素,但我在 c++ 中找不到任何解决方案

这是我使用的代码,据我搜索,我认为我需要在 WS_EX_LAYERED 窗口中使用 UpdateLayeredWindow 函数而不是 SetLayeredWindowAttributes,但我找不到这样做的方法。

有谁知道如何从我的对话框的圆角移除这些像素?

代码:

INT_PTR CALLBACK WinProc(HWND hh,UINT mm,WPARAM ww,LPARAM)
    {
    HWND hX = GetDlgItem(hh,123);

    switch(mm)
        {
        case WM_INITDIALOG:
            {
            // No Dialog Title Bar 
            SetWindowLong(hh, GWL_STYLE, 0); // With no border around the window 
            // Transparent Dialog In Selected Color
            LONG ExtendedStyle = GetWindowLong(hh, GWL_EXSTYLE);
            SetWindowLong(hh, GWL_EXSTYLE, ExtendedStyle | WS_EX_LAYERED);
            SetLayeredWindowAttributes(hh, RGB(255, 128, 255), 0, LWA_COLORKEY);
            //UpdateLayeredWindow(hh, NULL, NULL, NULL, NULL, NULL, RGB(255, 128, 255), 0, ULW_COLORKEY);

            // Load the swf from our resources, extract first to temp path
            TCHAR dx[1000] = {0};
            GetTempPath(1000,dx);
            TCHAR df[1000] = {0};
            GetTempFileName(dx,L"swf",0,df);
            DeleteFile(df);
            wcscat_s(df,1000,L".swf");
            DeleteFile(df);
            ExtractDefaultFile(df,L"flash",0,0,L"data");

            SendMessage(hX,AX_INPLACE,1,0);
            SendMessage(hh,WM_SIZE,0,0);

            // Set the object
            IShockwaveFlash* p = 0;
            CLSID iidx = __uuidof(IShockwaveFlash);
            HRESULT hr = (HRESULT)SendMessage(hX,AX_QUERYINTERFACE,(WPARAM)&iidx,(LPARAM)&p);
            if (p)
                {
                _bstr_t x(df);
                hr = p->put_WMode(L"transparent");
                hr = p->put_BackgroundColor(RGB(255,128,255));
                hr = p->put_Movie(x);

                // Notification
                AX* iax = (AX*)SendMessage(hX,AX_GETAXINTERFACE,0,0);
                if (iax)
                    {
                    axCookie = AXConnectObject(iax->OleObject,__uuidof(_IShockwaveFlashEvents),(IUnknown*)&fn,&cpc,&cp);
                    }


                p->Release();
                }

            break;
            }
        case WM_SIZE:
            {
            RECT rc;
            GetClientRect(hh,&rc);
            SetWindowPos(hX,0,0,0,rc.right,rc.bottom,SWP_SHOWWINDOW);
            return 0;
            }

        case WM_CLOSE:
            {
            EndDialog(hh,0);
            return 0;
            }
        }
    return 0;
    }

int __stdcall WinMain( HINSTANCE hInstance,HINSTANCE,LPSTR,int)
    {
    OleInitialize(0);
    AXRegister();

    DialogBox(hInstance,L"DIALOG_MAIN",0,WinProc);
    return 0;
    }

我使用的是 RGB(255, 128, 255) 的颜色,它在 Flash 内部不用作颜色,否则它也会从 Flash 播放器内部擦除颜色。

提前致谢

【问题讨论】:

  • 查看 WinAPI 的“蒙版”或“剪辑区域”。你会想要使用:CreateRoundRectRgn
  • 如果您在窗口边缘看到额外的像素,这意味着这些像素与您指定的透明度颜色不匹配。例如,如果边缘模糊或消除锯齿,或者与其他颜色或阴影混合。
  • 是的,雷米,你也是对的。似乎具有透明度并删除 WS_EX_LAYERED 颜色映射的 activex 存在一些问题,尤其是在圆角处,我发现了两种方法,一种是 Brandon 和 xMRi 建议的 CreateRoundRectRgn,另一种是避免在加载的 activex 内使用不透明度或 alpha 混合。不使用阴影、alpha 混合和其他有颜色映射问题的效果是一个很好的解决方案,如果没有它们,可能会出现圆形边缘的一些像素,最好的方法是使用这两种方法,直到现在为止。

标签: c++ winapi dialog


【解决方案1】:
  1. 使用 win32 函数创建区域。即 CreateEllipticRegion、CreateRectRgn...
  2. 你必须使用 SetWindowRgn。

这是一个link 纯Win32 讨论。这里是一个 link 到 MFC 示例。应该很容易将其转移到 WinAPI pure

【讨论】:

  • 感谢 Brandon 和 xMRi 的链接,是的,它通过在 flash hwnd 设置一个带圆角的区域来工作,它删除了坏像素,但结果是有点像素化的角落,但至少它确实做到了工作:) 谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-18
  • 2011-08-12
  • 2016-01-31
  • 1970-01-01
  • 2018-02-05
  • 1970-01-01
相关资源
最近更新 更多