 |
|
 |
why using old win32 with .net and c#...? get rid of those old gdi handles...
|
|
|
|
 |
|
 |
because you cant update a layered window using a gdi+ bitmap....
|
|
|
|
 |
|
 |
How would I get this working with VB.Net 2005?
|
|
|
|
 |
|
 |
Class:
Imports System
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
'Translation from C# by Dj Den4ik
Public Class PerPixelAlphaForm
'Implements Windows.Forms.IWin32Window
Public Structure ARGB
Public Blue As Byte
Public Green As Byte
Public Red As Byte
Public Alpha As Byte
End Structure
Public Structure BLENDFUNCTION
Public BlendOp As Byte
Public BlendFlags As Byte
Public SourceConstantAlpha As Byte
Public AlphaFormat As Byte
End Structure
Public Const ULW_COLORKEY As Int32 = &H1
Public Const ULW_ALPHA As Int32 = &H2
Public Const ULW_OPAQUE As Int32 = &H4
Public Const AC_SRC_OVER As Byte = &H0
Public Const AC_SRC_ALPHA As Byte = &H1
Public Declare Function UpdateLayeredWindow Lib "user32" Alias "UpdateLayeredWindow" (ByVal hwnd As IntPtr, ByVal hdcDst As IntPtr, ByRef pptDst As Point, ByRef psize As Size, ByVal hdcSrc As IntPtr, ByRef pprSrc As Point, ByVal crKey As Int32, ByRef pblend As BLENDFUNCTION, ByVal dwFlags As Int32) As Boolean
Public Declare Function GetDC Lib "user32" Alias "GetDC" (ByVal hWnd As IntPtr) As IntPtr
Public Declare Function ReleaseDC Lib "user32" Alias "ReleaseDC" (ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As Integer
Public Declare Function CreateCompatibleDC Lib "gdi32.dll" Alias "CreateCompatibleDC" (ByVal hDC As IntPtr) As IntPtr
Public Declare Function DeleteDC Lib "gdi32.dll" Alias "DeleteDC" (ByVal hDC As IntPtr) As Boolean
Public Declare Function SelectObject Lib "gdi32.dll" Alias "SelectObject" (ByVal hDC As IntPtr, ByVal hObject As IntPtr) As IntPtr
Public Declare Function DeleteObject Lib "gdi32.dll" Alias "DeleteObject" (ByVal hObject As IntPtr) As Boolean
Public Sub SetBitmap(ByVal bitmap As Bitmap, ByVal opacity As Byte, ByVal frm As Form)
If bitmap.PixelFormat <> PixelFormat.Format32bppArgb Then Throw New ApplicationException("The bitmap must be 32ppp with alpha-channel.")
' The ideia of this is very simple,
' 1. Create a compatible DC with screen;
' 2. Select the bitmap with 32bpp with alpha-channel in the compatible DC;
' 3. Call the UpdateLayeredWindow.
Dim screenDc As IntPtr = GetDC(IntPtr.Zero)
Dim memDc As IntPtr = CreateCompatibleDC(screenDc)
Dim hBitmap As IntPtr = IntPtr.Zero
Dim oldBitmap As IntPtr = IntPtr.Zero
Try
hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)) ' grab a GDI handle from this GDI+ bitmap
oldBitmap = SelectObject(memDc, hBitmap)
Dim size As New Size(bitmap.Width, bitmap.Height)
Dim pointSource As New Point(0, 0)
Dim topPos As New Point(frm.Left, frm.Top)
Dim blend As New BLENDFUNCTION
blend.BlendOp = AC_SRC_OVER
blend.BlendFlags = 0
blend.SourceConstantAlpha = opacity
blend.AlphaFormat = AC_SRC_ALPHA
UpdateLayeredWindow(frm.Handle, screenDc, topPos, size, memDc, pointSource, 0, blend, ULW_ALPHA)
Finally
ReleaseDC(IntPtr.Zero, screenDc)
If hBitmap <> IntPtr.Zero Then
SelectObject(memDc, oldBitmap)
DeleteObject(hBitmap)
End If
DeleteDC(memDc)
End Try
End Sub
Form:
Dim ppaf As New PerPixelAlphaForm
Dim bmp As New Bitmap("D:\Audio\FL Studio 7\Artwork\FL Studio Producer Edition\Title_.png")
Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
Get
Dim SecPerm As New Security.Permissions.SecurityPermission(Security.Permissions.PermissionState.Unrestricted)
SecPerm.Demand()
' Extend the CreateParams property of the Button class.
Dim cp As System.Windows.Forms.CreateParams = MyBase.CreateParams
' Update the button Style.
cp.ExStyle = &H80000
Return cp
End Get
End Property
Private Sub frmTest_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
Me.TopMost = True
For Each ctrl As Control In Me.Controls
ctrl.DrawToBitmap(bmp, ctrl.Bounds)
Next
Me.Region = New Region()
ppaf.SetBitmap(bmp, 240, Me)
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Const WM_MOUSEMOVE As Int32 = &H200
Const WM_NCLBUTTONDOWN As Int32 = &HA1
Const HTCAPTION As Int32 = 2
'// ????????????? WM_MOUSEMOVE
If m.Msg = WM_MOUSEMOVE Then
'// ???????? ReleaseCapture
MyBase.Capture = False
'// ??????? ???? ?????????
Dim message As New Message
With message
.HWnd = Me.Handle
.Msg = WM_NCLBUTTONDOWN
.WParam = HTCAPTION
.LParam = 0&
End With
'// ?????????? ???? ????????? ????
MyBase.WndProc(message)
End If
MyBase.WndProc(m)
End Sub
|
|
|
|
 |
|
 |
Simply the BEST!! Many thanks, Rui!!!
|
|
|
|
 |
|
 |
Add some controls to overlay transparent form and avoid refreshing it's content with common Refresh()/Invalidate() methods,
use UpdateLayeredWindow() instead. For correct controls rendering add code like
Bitmap temp_bmp = new Bitmap(bitmap);
foreach (Control ctrl in this.Controls)
{
ctrl.DrawToBitmap(temp_bmp, ctrl.Bounds);
}
hBitmap = temp_bmp.GetHbitmap(Color.FromArgb(0)); // grab a GDI handle from this GDI+ bitmap
to the PerPixelAlphaForm::SetBitmap() method. Every System.Windows.Forms controlhas method DrawToBitmap().
Actually, i used this way to render simple controls - labels, i don't know would it work with more complex
user controls, but i can't see why it should not
|
|
|
|
 |
|
 |
Thanks, I was wondering about this.
Works perfectly
Edit: Ok, I take that back sorta.. The actual clickable region is MUCH smaller than the visible control (a button in this case)...
modified on Sunday, August 24, 2008 2:37 PM
|
|
|
|
 |
|
 |
Thanks, this is just what I needed to complete my design. It appeared that the bitmap was not getting refreshed each time the procedure was called. The actual Form.BackgroundImage needs to be present underneath so the region cut out from your controls, e.g. so this background image can bleed through around the controls.
In order to achieve transparency of the form controls, just override the controls in question and make sure that the regions are set to the way you need along with the ctrl.BackColor = Color.Transparent.
Without spending too much time on this, ensure that the 'bitmap' you are using originated from the 'this.BackgroundImage' build-in Form property.
public void SetBitmap(Bitmap bitmap, byte opacity = 255) {
}
So just I just changed all references outside this function and used the pre-existing container for the Bitmap/Image with one already build into the Form control itself.
So what you get is something like this:
partial class MainForm: Form
{
Bitmap bkgrnd = null;
...
// Constructor
public MainForm()
{
InitializeComponent();
bkgrnd = lib.LoadBitmapResource(2005); // Assign your Bitmap loaded from .dll
this.BackgroundImage = bkgrnd;
// StartPosition has no affect so use this instead.
this.CenterToScreen();
}
...
private void RefreshFormTimer_Tick(object sender, EventArgs e)
{
if (bkgrnd != null)
SetBitmap(bkgrnd);
}
-Latency
modified on Monday, January 24, 2011 5:52 AM
|
|
|
|
 |
|
 |
I want mesure a length of a line by using pixel.Can u send me C# coding for that
fbgsd asgtdfg
|
|
|
|
 |
|
 |
I've compiled the source by using the bat file but I'm still not able to get the Images to show up. What am I missing?
|
|
|
|
 |
|
 |
Check point 1...'Drag & Drop an image file from windows...", just drag one of the images in the sample zip onto the compiled window or call the following when the application is loaded:
SetBitmap(New Bitmap("full path to your image.png"))
Cheers
|
|
|
|
 |
|
 |
(Sorry for the poor English)
Hi,
I got a strange problem.
In my form i add something like :
[DllImport("user32.dll")]
private static extern int SetParent(IntPtr hWndChild, int hwndNewParent);
[DllImport("user32.dll", EntryPoint="FindWindowA")]
private static extern int FindWindow(string lpClassName, string lpWindowName);
private int GetDesktopWnd() {
return FindWindow("Progman", null);
}
private void button1_click(object sender, System.EventArgs e) {
SetParent(pngForm_.Handle, GetDesktopWnd);
}
So when I click button1 my pngForm_ is now drawed on the desktop.
This worked great with 1 monitor.. But now I'm dual-monitoring and I got a bug when I try to move the pngForm_ when it's on the desktop. By example I hit the form when it's on monitor 1, and the form go on monitor 2 at the same position, and after it's impossible to move it.
I have made a lot of test, and i thinks it's due to the cp.ExStyle. In Fact when I remove the WS_EX_LAYERED it works..
Any idea to repair that ?
-- modified at 8:51 Saturday 7th October, 2006
|
|
|
|
 |
|
 |
Isn't it easier to use Forms.Opacity?
|
|
|
|
 |
|
 |
Đm, moebiusproject đúng là thằng ngu chẳng hiểu cái đ*'o gì cả!
|
|
|
|
 |
|
 |
No....because that won't give you an alphablended gui. it will just have 1 level of transparency
|
|
|
|
 |
|
 |
Hi,
This is some great code, I pissed around for ages trying to get this working before I stumbled across this page.
Now, it works just fine, the only thing is that forms descended from a PerPixelAlphaForm don't work in the VS2005 designer, you just get:
One or more errors encountered while loading the designer. The errors are listed below. Some errors can be fixed by rebuilding your project, while others may require code changes.
Error creating window handle.
This doesn't stop the project from building or running though, but it's a pain not being able to use the designer.
Any ideas?
Thanks!
|
|
|
|
 |
|
 |
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
if(Site != null)
{
if(!Site.DesignMode)
{
cp.ExStyle |= 0x00080000; // This form has to have the WS_EX_LAYERED extended style
}
}
else
{
cp.ExStyle |= 0x00080000; // This form has to have the WS_EX_LAYERED extended style
}
return cp;
}
}
This will let you view the form in design mode. Not much use though as i havn't wokred out how to add controls yet.
|
|
|
|
 |
|
 |
try to recompile sources, then designer should handle it. If not try using VS 2008 Express, in my case it works fine.
|
|
|
|
 |
|
 |
Someone said "make the main form's Owner the shadow form",but I don't kown how to do this,Please help me!
thanks a lot!
|
|
|
|
 |
|
 |
I can't add Controls.Please help me.
my MSN:wangsongqing2003@hotmail.com Mail:wang.songqing@staples.sh.cn
|
|
|
|
 |
|
 |
Hi dear
Can you recognition coordinate of circle in bitmap?
i searching a algorithm for do this task but i cann't find
I want search a sample picture in another picture .
for example I give a circle picture to program then program search this picture in another picture ,if find get me coordinate of circle picture.
Thank
|
|
|
|
 |
|
 |
I was wondering if there was a way to get the same functionality using direct X. I see how you can use alpha blending for 3d objects, but how would you do it for a 2d png image and the desktop?
#teve
|
|
|
|
 |
|
 |
Since you called it "Form" (PerPixelAlphaForm) shouldn't we be able to add controls to it like labels and stuff?
Right now its only use seems to be the display of pictures over the desktop with full alpha support which is good, but rather limiting.
Is there any other project which implements full alpha support as a form background?
Luís Ferrão
|
|
|
|
 |
|
 |
Alpha blend windows don't support controls, so I don't support them either.
Not that I'm aware of, but feel free to implement it yourself and share it with us!
----
Rui Lopes
|
|
|
|
 |
|
 |
Actualy i did, by seemlessly creating another form on top of yours with a transparency key. The later form works as a placeholder for every control. The result is close to perfect but with only one issue:
If the user clicks outside a control on the top form, it activates your form. I can't find a way to avoid mouse clicking getting the focus to your form.
I do try to catch the mouse click event but when I do so, it's already too late as the background form already got the focus.
There is also another strange behaviour to your form. I have a form that inherits from yours. If i set the "ShowInTaskBar" to false, it actualy hides the entire form!
The workaround I found is to set it to false directly in the PerPixelForm constructor.
Thank god, code-project and yourself I have the source code =P
Luis Ferrao
|
|
|
|
 |