0

I am dealing with win32. I have created a window. What I want is a transparent window for clicked area but nontransparent for border. Additionaly with no title bar. It should seem like an empty rectangle. When I add the following code I, my whole window becomes transparent (borders are also tranparent.)

    SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
    SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), 75, LWA_ALPHA);
    SetWindowLong(hwnd, GWL_STYLE, 0);

The output of my code by adding the above code is like following:

When opacity value is 255:

When opacity value is 75

enter image description here

As you can see that the borders also transparent. How can I prevent becoming transparent border, but obtain transparent clicked area like a rectange? Thanks...

Latif Uluman
  • 257
  • 3
  • 13
  • Do you want the client area to be fully transparent (i.e. with an alpha value of 0), or do you want it to be translucent (i.e. and alpha value greater than 0)? – IInspectable Apr 16 '20 at 10:04
  • I want fully transparent. Actullay I am trying to do a tool like micrososf accesibility it is like https://www.youtube.com/watch?v=BEQ-wfJisBA#t=2m3s I determine ui element then I want to rectangle the element. When I use the Rectange() fucntion of the win32, the rectangle is appearing, then disapearing(when window rendered). So it becomes very bad. So I tried to create a window which is fully transparent except it's borders. So it should seem like a rectangle. Also it does not disapper. Thanks – Latif Uluman Apr 16 '20 at 10:24

1 Answers1

2

It looks like you want to make part of the window transparent.For this, you need to create two windows to complete.

  • Use SetWindowRgn to create a window with a hole

  • Use the WS_EX_LAYERED and WS_EX_TRANSPARENT style to place another transparent window in the hole.

Like this:

enter image description here

The whole code:

// Test_transparent.cpp : Defines the entry point for the application.
//

#include "framework.h"
#include "Test_transparent.h"

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;                                // current instance
WCHAR szTitle[MAX_LOADSTRING];                  // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name

// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
HWND hWnd;
HWND child;


int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: Place code here.

    // Initialize global strings
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_TESTTRANSPARENT, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TESTTRANSPARENT));

    MSG msg;

    // Main message loop:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TESTTRANSPARENT));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_TESTTRANSPARENT);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hWnd = CreateWindowEx(0, szWindowClass, L" ", WS_POPUP, 100, 100, 800, 600, NULL, NULL, hInst, 0);
   child = CreateWindowEx(WS_EX_LAYERED, szWindowClass, szTitle, WS_POPUP | WS_VISIBLE | WS_CHILD, 300, 300, 200, 200, hWnd, NULL, hInst, 0);
   SetLayeredWindowAttributes(child, 0, 50, LWA_ALPHA);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE: Processes messages for the main window.
//
//  WM_COMMAND  - process the application menu
//  WM_PAINT    - Paint the main window
//  WM_DESTROY  - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    RECT rect;
    RECT rc;
    COLORREF    brColor;
    static HRGN     hRgnWnd;
    static HRGN     hRgnWnd1;
    static HBRUSH   hBr;
    switch (message)
    {       
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // Parse the menu selections:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: Add any drawing code that uses hdc here...           
            brColor = RGB(51, 143, 178);
            hBr = CreateSolidBrush(brColor);     
            GetClientRect(hWnd, &rect);
            rc.left = 200;
            rc.top = 200;
            rc.right = 400;
            rc.bottom = 400;
            hRgnWnd = CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom);
            hRgnWnd1 = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
            CombineRgn(hRgnWnd1, hRgnWnd1, hRgnWnd, RGN_XOR);
            SetWindowRgn(hWnd, hRgnWnd1, true);
            FillRect(hdc, &rect, hBr);

            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}

To get a borderless window, you need to comment the MENU code in the .rc file.

.rc cpp

//Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE resource.
//
#ifndef APSTUDIO_INVOKED
#include "targetver.h"
#endif
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE 9, 1

/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.

IDI_TESTTRANSPARENT       ICON         "Test_transparent.ico"
IDI_SMALL               ICON         "small.ico"

/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
//
//IDC_TESTTRANSPARENT MENU
//BEGIN
//    POPUP "&File"
//    BEGIN
//        MENUITEM "E&xit",                IDM_EXIT
//    END
//    POPUP "&Help"
//    BEGIN
//        MENUITEM "&About ...",           IDM_ABOUT
//    END
//END


/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//

IDC_TESTTRANSPARENT ACCELERATORS
BEGIN
    "?",            IDM_ABOUT,              ASCII,  ALT
    "/",            IDM_ABOUT,              ASCII,  ALT
END


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About Test_transparent"
FONT 8, "MS Shell Dlg"
BEGIN
    ICON            IDR_MAINFRAME,IDC_STATIC,14,14,21,20
    LTEXT           "Test_transparent, Version 1.0",IDC_STATIC,42,14,114,8,SS_NOPREFIX
    LTEXT           "Copyright (c) 2020",IDC_STATIC,42,26,114,8
    DEFPUSHBUTTON   "OK",IDOK,113,41,50,14,WS_GROUP
END

/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
    IDD_ABOUTBOX, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 163
        TOPMARGIN, 7
        BOTTOMMARGIN, 55
    END
END
#endif    // APSTUDIO_INVOKED

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE
BEGIN
    "#ifndef APSTUDIO_INVOKED\r\n"
    "#include ""targetver.h""\r\n"
    "#endif\r\n"
    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
    "#include ""windows.h""\r\n"
    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
    "\0"
END

3 TEXTINCLUDE
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED

/////////////////////////////////////////////////////////////////////////////
//
// String Table
//

STRINGTABLE
BEGIN
   IDC_TESTTRANSPARENT   "TESTTRANSPARENT"
   IDS_APP_TITLE       "Test_transparent"
END

#endif
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE resource.
//

/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED
Strive Sun
  • 5,988
  • 1
  • 9
  • 26
  • Actually I tried very similar idea to your suggestion. I create 2 windows. One of them is transparent other is not. So since other is not transparent, the background of the transparent window becomes the nontransparent window. I could misunderstand your idea, please can you extend your idea a little bit. Thanks.. – Latif Uluman Apr 16 '20 at 10:29
  • 2
    @LatifUluman Making a window with a hold is the secret - the hold is not part of the window. Then if you want a transparent window in the hole you can create it. – Jerry Jeremiah Apr 16 '20 at 10:37
  • 1
    @StriveSun-MSFT thank you so much for your work, and spending time. I tried to add your code to a sample window code. It did not work. It is probably my fault. If it is not problem for you, can you share full code of the above program? Thanks. – Latif Uluman Apr 16 '20 at 10:50
  • @LatifUluman Yes, please see my updated. You can start by creating a new windows desktop app. – Strive Sun Apr 17 '20 at 02:13