Recent

Author Topic: [Solved] Problem with Controls being Unselectable in Win 10 Transparent Forms !  (Read 1773 times)

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2069
  • Fifty shades of code.
    • Delphi & FreePascal
Updated to be able to work better for different BorderStyle settings.
Make this method part of your form and call it in OnCreate and OnResize.
Code: Pascal  [Select][+][-]
  1. procedure TForm1.MakeTransparent;
  2. var
  3.   AControl: TControl;
  4.   A, Margin, X, Y, CtlX, CtlY: Integer;
  5.   FullRgn, ClientRgn, CtlRgn: THandle;
  6.   cXBorder, cYBorder, cWidth, cHeight: LongInt;
  7. begin
  8.   // calculate different border styles
  9.   case Self.BorderStyle of
  10.     bsDialog:
  11.       begin
  12.         cXBorder := 0;
  13.         cYBorder := GetSystemMetrics(SM_CYCAPTION);
  14.       end;
  15.     bsNone:
  16.       begin
  17.         cXBorder := GetSystemMetrics(SM_CXBORDER);
  18.         cYBorder := GetSystemMetrics(SM_CYBORDER);
  19.       end;
  20.     bsSingle:
  21.       begin
  22.         cXBorder := 0;
  23.         cYBorder := GetSystemMetrics(SM_CYCAPTION);
  24.       end;
  25.     bsSizeable:
  26.       begin
  27.         cXBorder := GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CXEDGE) + GetSystemMetrics(SM_CXFOCUSBORDER);
  28.         cYBorder := GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYEDGE) + GetSystemMetrics(SM_CYFOCUSBORDER) + GetSystemMetrics(SM_CYCAPTION);
  29.       end;
  30.     bsSizeToolWin:
  31.       begin
  32.         cXBorder := GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CXEDGE) + GetSystemMetrics(SM_CXFOCUSBORDER);
  33.         cYBorder := GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYEDGE) + GetSystemMetrics(SM_CYFOCUSBORDER) + GetSystemMetrics(SM_CYCAPTION);
  34.       end;
  35.     bsToolWindow:
  36.       begin
  37.         cXBorder := 0;
  38.         cYBorder := GetSystemMetrics(SM_CYCAPTION);
  39.       end;
  40.   end;
  41.  
  42.   // set client dimension
  43.   cWidth := Self.ClientRect.Width - cXBorder;
  44.   cHeight:= Self.ClientRect.Height - cYBorder;
  45.   Margin := (Self.Width - cWidth) div 2;
  46.  
  47.   // get form and client area region
  48.   X := Margin;
  49.   case Self.BorderStyle of
  50.     bsDialog:
  51.       begin
  52.         FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Self.Height + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
  53.         Y := Self.Height - cHeight - Margin + GetSystemMetrics(SM_CYDLGFRAME);
  54.         ClientRgn := CreateRectRgn(X, Y, X + cWidth + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Y + cHeight + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
  55.       end;
  56.     bsNone:
  57.       begin
  58.         FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder, Self.Height + cYBorder);
  59.         Y := Self.Height - cHeight - Margin - GetSystemMetrics(SM_CYBORDER);
  60.         ClientRgn := CreateRectRgn(X, Y, X + cWidth + GetSystemMetrics(SM_CXBORDER), Y + cHeight + GetSystemMetrics(SM_CYBORDER));
  61.       end;
  62.     bsSingle:
  63.       begin
  64.         FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Self.Height + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
  65.         Y := Self.Height - cHeight - Margin + GetSystemMetrics(SM_CYDLGFRAME);
  66.         ClientRgn := CreateRectRgn(X, Y, X + cWidth + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Y + cHeight + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
  67.       end;
  68.     bsSizeable:
  69.       begin
  70.         FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder, Self.Height + cYBorder);
  71.         Y := Self.Height - cHeight - Margin - GetSystemMetrics(SM_CYBORDER);
  72.         ClientRgn := CreateRectRgn( X, Y, X + cWidth + cXBorder, Y + cHeight + cYBorder);
  73.       end;
  74.     bsSizeToolWin:
  75.       begin
  76.         FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder, Self.Height + cYBorder);
  77.         Y := Self.Height - cHeight - Margin - GetSystemMetrics(SM_CYBORDER);
  78.         ClientRgn := CreateRectRgn( X, Y, X + cWidth + cXBorder, Y + cHeight + cYBorder);
  79.       end;
  80.     bsToolWindow:
  81.       begin
  82.         FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Self.Height + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
  83.         Y := Self.Height - cHeight - Margin + GetSystemMetrics(SM_CYDLGFRAME);
  84.         ClientRgn := CreateRectRgn(X, Y, X + cWidth + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Y + cHeight + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
  85.       end;
  86.   end;
  87.  
  88.   // 'Mask' out all but non-client areas
  89.   CombineRgn(FullRgn, FullRgn, ClientRgn, RGN_DIFF);
  90.  
  91.   // Now, walk through all the controls on the form and 'OR' them into the existing Full region.
  92.   for A := 0 to Pred(ControlCount) do
  93.     begin
  94.       AControl := Controls[A];
  95.       if ((AControl is TWinControl) or (AControl is TGraphicControl) or (AControl is TControl)) then
  96.         if AControl.Visible then
  97.           begin
  98.             CtlX := X + AControl.Left;
  99.             CtlY := Y + AControl.Top;
  100.             case Self.BorderStyle of
  101.               bsDialog:
  102.                 begin
  103.                   CtlRgn := CreateRectRgn(CtlX + GetSystemMetrics(SM_CXDLGFRAME), CtlY, CtlX + AControl.Width + GetSystemMetrics(SM_CXDLGFRAME), CtlY + AControl.Height);
  104.                 end;
  105.               bsNone:
  106.                 begin
  107.                   CtlRgn := CreateRectRgn(CtlX, CtlY, CtlX + AControl.Width, CtlY + AControl.Height);
  108.                 end;
  109.               bsSingle:
  110.                 begin
  111.                   CtlRgn := CreateRectRgn(CtlX + GetSystemMetrics(SM_CXDLGFRAME), CtlY, CtlX + AControl.Width + GetSystemMetrics(SM_CXDLGFRAME), CtlY + AControl.Height);
  112.                 end;
  113.               bsSizeable:
  114.                 begin
  115.                   CtlRgn := CreateRectRgn(CtlX, CtlY, CtlX + AControl.Width + GetSystemMetrics(SM_CXEDGE), CtlY + AControl.Height + GetSystemMetrics(SM_CYEDGE));
  116.                 end;
  117.               bsSizeToolWin:
  118.                 begin
  119.                   CtlRgn := CreateRectRgn(CtlX, CtlY, CtlX + AControl.Width + GetSystemMetrics(SM_CXEDGE), CtlY + AControl.Height + GetSystemMetrics(SM_CYEDGE));
  120.                 end;
  121.               bsToolWindow:
  122.                 begin
  123.                   CtlRgn := CreateRectRgn(CtlX + GetSystemMetrics(SM_CXDLGFRAME), CtlY, CtlX + AControl.Width + GetSystemMetrics(SM_CXDLGFRAME), CtlY + AControl.Height);
  124.                 end;
  125.             end;
  126.             CombineRgn(FullRgn, FullRgn, CtlRgn, RGN_OR);
  127.           end;
  128.     end;
  129.  
  130.   // When the region is all ready, put it into effect:
  131.   SetWindowRgn(Handle, FullRgn, TRUE);
  132.  
  133.   // clean up the mess
  134.   DeleteObject(ClientRgn);
  135.   DeleteObject(FullRgn);
  136.   DeleteObject(CtlRgn);
  137. end;
Enjoy transparent forms for Windows  O:-)
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

loaded

  • Hero Member
  • *****
  • Posts: 825
Yes this code is better. I can't thank you enough for your hard work. Respects.
Check out  loaded on Strava
https://www.strava.com/athletes/109391137

 

TinyPortal © 2005-2018