|
I have a form and a png image file (with a transparent shadow in its border) and what I want is to make a drop shadow effect on the form. I know there are CS_DROPSHADOW solution for this, but I think it doesn't look too good. So I create a "fake" form using CreateWindowEx (via DllImport), and draw the png image file into the fake form.
void CreateFakeForm()
{
WNDCLASSEX wndClsEx = new WNDCLASSEX();
wndClsEx.Init();
wndClsEx.style = CS_VREDRAW | CS_HREDRAW;
wndClsEx.lpfnWndProc = m_DefWndProcDelegate;
wndClsEx.cbClsExtra = 0;
wndClsEx.cbWndExtra = 0;
wndClsEx.hInstance = GetModuleHandle(null);
wndClsEx.hIcon = IntPtr.Zero;
wndClsEx.hIconSm = IntPtr.Zero;
wndClsEx.hCursor = IntPtr.Zero;
wndClsEx.hbrBackground = IntPtr.Zero;
wndClsEx.lpszClassName = m_WndClsName;
wndClsEx.lpszMenuName = null;
bool success = RegisterClassEx(ref wndClsEx) != 0;
UInt32 dwExStyle = WS_EX_LAYERED |
WS_EX_TRANSPARENT |
WS_EX_NOACTIVATE |
WS_EX_LEFT;
UInt32 dwStyle = WS_VISIBLE | WS_OVERLAPPED;
FakeWndHandle = CreateWindowEx(dwExStyle
, m_WndClsName
, null
, dwStyle
, X
, Y
, PngImg.Width
, PngImg.Height
, MainFormHandle
, IntPtr.Zero
, GetModuleHandle(null)
, IntPtr.Zero
);
}
The problem is my fake form always in the topmost position. Is there a way to put the fake form behind the main form?
In other words, how do I set z-order between the main form and the fake form so that the fake form placed at the bottom of the Z order?
How to hide the fake form whenever the main form minimized or maximized, and move or resize the fake form whenever the main form moved or resized?
Thanks.
|
|
|
|
|
Why don't you override CreateParams instead of creating FakeWindow?
This example overrides default border and replace it with AERO. to get WS_ numbers, go to your Windows SDK and look under window.h for decleration
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
unchecked
{
cp.Style |= (int)0x80000000;
cp.Style |= 0x40000;
}
return cp;
}
}
|
|
|
|
|
Thanks for the reply,
I'm using Windows XP, so I think there are no WS_ for AERO.
|
|
|
|
|
when i said WS_ i meant WS_EX_NOACTIVATE and other. The one I post was uses AERO. It isn't limited for aero. It has all same as unmanaged code
|
|
|
|
|
When you say override CreateParams, did you refer to the main form's CreateParams? But then, where do I draw the png image files into?. Sorry, but I'm new in this so I'm still confused.
|
|
|
|
|
for painting try look into OnPaint event or you can even ovverride
roshihans wrote: When you say override CreateParams, did you refer to the main form's CreateParams?
That is correct
|
|
|
|
|
Saksida Bojan wrote: for painting try look into OnPaint event or you can even ovverride
I thought if I paint form's border with a transparent-shadow background (using png file), it will not become transparent unless I set the main form transparent too. And how to paint the shadow into the border which is located in non-client area?
|
|
|
|
|
roshihans wrote: And how to paint the shadow into the border which is located in non-client area?
Special 'Graphics' Objects to Draw Anywhere on your Window[^]
roshihans wrote: it will not become transparent unless I set the main form transparent too
To enable Form transparecy you need to enable transparent color.
this.SetStyle(ControlStyles.SupportsTransparentBackColor | ControlStyles.DoubleBuffer, true);
|
|
|
|
|
Thanks a lot for your help. I will try your suggestion
|
|
|
|
|
Saksida Bojan wrote:
this.SetStyle(ControlStyles.SupportsTransparentBackColor | ControlStyles.DoubleBuffer, true);
It seems that SetStyle only applied in client area. I can't make the non-client area transparent. Any suggestion?
|
|
|
|
|
In a book i am reading, this is formula for getting transparecy
displayColor = sourceColor × alpha / 255 + backgroundColor × (255 - alpha) / 255
ImageTraverser[^]
This link is very good. Create a snapshot and you can get pixel. Image.GetPixel is super slow, this example is very fast.
|
|
|
|
|
how can i use the function 'CreateFakeForm'? could you give me the full project?
I 1 2 create a nice shadow behind a customized form... Thanks
|
|
|
|
|
Alright guys, here's what I'm trying to do. I have an integer called rollcount1 in a class called Class2.cs. When I call upon a method in Class2.cs from Class3.cs to increase the value of rollcount1 by one (rollcount1++;), the moment it finishes increasing the value of rollcount1 and goes back go Class3.cs, and from there to Form1.cs, rollcount1 gets reset to a value of 0.
Does anybody know what's going on? Really frustrating >_<
modified on Friday, January 8, 2010 10:43 PM
|
|
|
|
|
Hi,
you really should spend some time and come up with realistic class names, you may not believe it right away, but it will help you in making fewer mistakes.
Without seeing any of the code, my best guess is you somewhere have an extraneous new Class2() and are suddenly facing the rollcount1 of a new class2 instance, which obviously is not holding the same value rollcount1 has in an earlier class2 instance.
|
|
|
|
|
Hey Luc Pattyn,
you had a good guess and based on your answer I was able to fix the problem, but it's slightly more complex than simply turning the ints into static ints.
And, Yeah I usually set the name of my classes to something appropriate, but this is a friends' project and he needed help on it, and I couldn't help so I decided to come to the professionals
Thanks again!
|
|
|
|
|
Make rollcount1 static.
There are only 10 types of people in this world — those who understand binary, and those who don't. |
|
|
|
|
|
Wow that worked . Now, if you don't mind, could you please go into detail on what exactly static is or what it does? Pleassse
|
|
|
|
|
Some more info on static here [^]. Warning - static is not always the best way to do things. I would suggest you also look at restructuring your code as has been mentioned in the other post.
Also, vote for an answer if it helps .
There are only 10 types of people in this world — those who understand binary, and those who don't. |
|
|
|
|
|
Hi,
static members of a class get shared by all instances of that class, so they each get allocated memory only once, and all instances read and write that single instance. A typical example would be a counter to keep track how many instances of some class have been created, or are in existence; such count, by its very nature, does not belong to any such instance, it oversees all instances. That is what static is for.
"solving" a problem by adding static to some variables is very bad practice in general, it does not conform to best practices in object-oriented programming.
In your case, again assuming you had two instances of class2 where you really only wanted one, it is definitely the wrong way to solve the problem. You should:
- not create a second class2 instance;
- instead pass the first instance to interested parties, or better yet pass delegates to execute the operation you want to happen inside class2.
It is my impression you are not really qualified to help your friend; I suggest you buy and study an introductory book on C# before passing advice to others...
|
|
|
|
|
Thanks for the help :P
Thing is, we're both in grade 11, and our teachers don't exactly, you know, teach.
I have to figure everything out for myself pretty much, and solving it by adding static is a good solution for now in my opinion.
He had his whole classroom attempt to solve his problem, but nobody succeeded, so he's pretty desperate.
Plus, it's a simple snakes and ladders game that he's attempting, not anything professional.
But once again, thanks for your help, I learned something new today ^.^
|
|
|
|
|
Raztor0 wrote: solving it by adding static is a good solution
That depends on the purpose of rollcount .
If it's counting the number of ALL rolls in the game, then static is fine as it's not directly related to an instance of the class. If the class had proper names that would belong to a Dice class. It would be better to have a public static (readonly) property with a private static field. Even in this situation, it may be better to have a Game class and the value would be an instance member of that.
If it's counting the number of throws per player then it would need to be an instance member - of a Player class, this class should raise an event to tell the main form (or any other interested party) that the value has changed.
It's really quite easy to do and worth doing properly. Once you've done it the correct way once, you'll never take the nasty 'static' approach again unless it's the correct solution.
If you want further help you'll need to post some relavent code snippets as so far we are just guessing!
Dave
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Why are you using VB6? Do you hate yourself? (Christian Graus)
|
|
|
|
|
I could post some code, but do you think I should post ALL the code?
It's 690 lines spread out into Form1, and two other classes, but they're really just a ton of if statements and methods through which I return variables.
Keep in mind this isn't my code, it's a friends' code who needed help with this problem so I don't really fully understand how it's working either.
So, should I post it all? I think it might be necessary for you to see it all
modified on Saturday, January 9, 2010 10:26 AM
|
|
|
|
|
No - there's no need to post all that!
Your friend may be better off working out the plan on paper first and doing some recoding afterwards. This often gives a clearer indication of what classes, properties, methods and events are needed without writing a line of code.
Coding is then just a matter of implenting the above which should then be trivial. Starting by coding often causes problems like he has now as the classes and communication between them are not clearly defined.
Dave
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Why are you using VB6? Do you hate yourself? (Christian Graus)
|
|
|
|
|
Alright, thanks to everyone who helped I've learned something that will help me in the future
|
|
|
|
|
will u please explain the code ?
|
|
|
|