C++ 将窗口设置为透明

C++ 将窗口设置为透明,c++,winapi,C++,Winapi,我一直在尝试设置蓝钉窗口透明: DWORD MakeWindowTransparent(HWND hWnd, unsigned char factor) { /* First, see if we can get the API call we need. If we've tried * once, we don't need to try again. */ if (!initialized) { HMODULE hDLL = LoadLib

我一直在尝试设置蓝钉窗口透明:

DWORD MakeWindowTransparent(HWND hWnd, unsigned char factor)
{
    /* First, see if we can get the API call we need. If we've tried
     * once, we don't need to try again. */
    if (!initialized)
    {
        HMODULE hDLL = LoadLibrary(L"user32");

        pSetLayeredWindowAttributes =
            (PSLWA)GetProcAddress(hDLL, "SetLayeredWindowAttributes");

        initialized = TRUE;
    }

    if (pSetLayeredWindowAttributes == NULL)
        return FALSE;

    /* Windows need to be layered to be made transparent. This is done
     * by modifying the extended style bits to contain WS_EX_LAYARED. */
    SetLastError(0);

    auto winlong = SetWindowLong(hWnd,
    GWL_EXSTYLE,
    GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);

    if ((winlong == 0) && (GetLastError() != 0)) { 
        auto error = GetLastErrorAsString(); 
        return FALSE;
    } 

    if (!pSetLayeredWindowAttributes(hWnd,RGB(255, 255, 255),factor, LWA_COLORKEY | LWA_ALPHA))
    { 
        auto error = GetLastErrorAsString(); 
        return FALSE; 
    } 

    return TRUE;
}


int main() {
  HWND hWnd = FindWindowA(NULL, L"BlueStacks");
  MakeWindowTransparent(hWnd, 0);
}
Bluestack可以在
opengl
directx
中运行,我已经使用这两种模式测试了上面的代码

MakeWindowTransparent
正在返回0

pSetLayeredWindowAttributes
auto error=GetLastErrorAsString()错误为:
参数错误

我已经用其他OpenGL窗口测试了代码,它没有在任何错误中暂停,而且窗口正确透明

我收集的有关窗口的一些信息:


感谢您的帮助。

您为什么同时使用这两个标志
LWA_COLORKEY | LWA_ALPHA
?如果要指定颜色
RGB(255、255、255)
,只需使用
LWA\u COLORKEY

还有,你为什么要处理
GetProcAddress
SetLayeredWindowAttributes
从Windows 2000开始提供;你的目标是比这更老的平台吗

我不熟悉Bluestack,但建议
SetLayeredWindowAttributes
不适用于
Direct3D
;你知道Bluestack是否使用Direct3D吗

有关
OpenGL
的信息,请参见:

更新 我在玩那个蓝钉,我想你可以将它重新设置为另一个窗口的父窗口(不建议这样做,因为你需要处理一些边缘情况)。无论如何,我使用了一个现有的
记事本
窗口,并能够在其上设置alpha,这影响了子BlueStacks窗口:

int main() {
  HWND hWnd = FindWindow(NULL, L"BlueStacks");
  HWND hWndN = FindWindow(NULL, L"Untitled - Notepad");
  ::SetParent(hWnd, hWndN);

  auto winlong1 = SetWindowLongPtr(hWnd, GWL_EXSTYLE, 0);
  auto winlong2 = SetWindowLongPtr(hWnd, GWL_STYLE, WS_CHILD | WS_VISIBLE);
  ::SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE);

  MakeWindowTransparent(hWndN, 200);
}
我还清理了您的函数以摆脱
GetProcAddress

DWORD MakeWindowTransparent(HWND hWnd, unsigned char factor)
{
  auto winlong = SetWindowLong(hWnd,
    GWL_EXSTYLE,
    GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);

  if ((winlong == 0) && (GetLastError() != 0)) {
    return FALSE;
  }

  if (!SetLayeredWindowAttributes(hWnd, 0, factor, LWA_ALPHA))
  {
    return FALSE;
  }

  return TRUE;
}

什么是
MakeWindowTransparent
返回?根据文档,调用
GetLastError
查看系统可能告诉您的信息:实际故障在哪里
MakeWindowTransparent()
在3种不同条件下返回false-1)如果
SetLayeredWindowAttributes
user32.dll
中不可用;2) 如果
SetWindowLong()
失败;3) 如果
SetLayeredWindowAttributes()
失败。那么,到底发生了什么样的失败呢?当故障发生时,
GetLastError()
实际返回什么?另外,仅供参考,在
SetWindowLong()
之后调用
GetLastError()
仅在
SetWindowLong()
返回0时有效,而您没有检查该值。如果
SetWindowLong()
返回非零,则
GetLastError()
的值为indeterminate@Caio这不是我问的。以下哪一个API函数完全失败-
LoadLibrary()
GetProcAddress()
SetWindowLong()
,或
SetLayeredWindowAttribute()
?对于特定的失败函数,
GetLastError()
会返回什么?您仅在该代码的4个可能故障点中的1个检查
GetLastError()
。如果要发现故障的根本原因,您需要编写更好的错误处理逻辑。@Caio显示
SetWindowLong()
返回非零,这意味着需要跳过后续的
GetLastError()
。我们无法看到
SetWindowLong()
之后的
GetLastError()
是否返回非零,使
MakeWindowTransparent()
在调用
SetLayeredWindowAttributes()
之前过早退出。不要在
SetWindowLong()
之后检查
GetLastError()
,除非且仅当
SetWindowLong()
返回0,例如:
LONG winlong=SetWindowLong(…);if((winlong==0)和(&(GetLastError()!=0))返回FALSE
这将允许正确调用
SetLayeredWindowAttributes()
。@Caio如果在此之后,您发现实际上正在调用
SetLayeredWindowAttributes()
,并且它返回0,那么您需要再次检查
GetLastError()
,以了解它返回0.Windows10的原因,关于调用函数
MakeWindowTransparent(hWnd,0)时的颜色我目前正在使用opengl@Vlad Feinsteini试图遵循这个示例:但我的代码在添加后没有编译。我添加了#include和代码,在编译时出现了以下错误:
LNK2019未解析的外部符号uu imp\u dwmenablebluebehindWindow在函数“private:enum ResultType u cdecl Line::Launcher(wchar\u t*,wchar\u t*,bool)”中引用
@Caio(1)请您删除
LWA\u ALPHA
并传递
LWA\u COLORKEY
?(2) 请确保
hWnd
不为
NULL
?Vlad,感谢您的时间,(1)我已删除
LWA_ALPHA
,只传递
LWA_COLORKEY
,但它仍然不透明,(2)我确认句柄不为NULL,还收集了一些有关窗口的信息,我希望这能有所帮助: