|
I am creating a memory game in C# that flashes a pattern on 4 buttons by changing the background images. Then the user repeats the pattern on the same buttons.
My problem is getting a delay to occur between the flashes. The Sleep delays between the calls of flash() seem to all pile up at the beginning of the loop. The last call of flash() is all i see occuring. I run this loop:
//IN Game class code
for(int i = 0; i < buttonTrack.Count; i++) {
flash((int)buttonTrack[i]);
System.Threading.Thread.Sleep(1000);
}
public void flash(int n){
// convert number to button
switch(n) {
case 1 :
form1.redB();
break;
case 2 :
form1.blueB();
break;
case 3 :
form1.yellowB();
break;
case 4 :
form1.greenB();
break;
}
}
//End Game class code
//In Form1 class code
public void redButton() {
button4.BackgroundImage = redOn;
button5.BackgroundImage = blueOff;
button6.BackgroundImage = yelOff;
button7.BackgroundImage = greenOff;
}
public void blueButton() {
//same idea as above
button5.BackgroundImage = blueOn;
button4.BackgroundImage = redOff;
button6.BackgroundImage = yelOff;
button7.BackgroundImage = greenOff;
//ditto for other color methods
}
//End Form1 class code
|
|
|
|
|
Use the WinForms timer component instead. Pausing the thread will make the GUI non-responsive, which very bad for WinForms apps.
Regards,
Björn Morén
Stockholm, Sweden
|
|
|
|
|
You're not allowing the Paint event to fire. You should call Refresh() on each loop after the switch statement.
"You can have everything in life you want if you will just help enough other people get what they want." --Zig Ziglar
The Second EuroCPian Event will be in Brussels on the 4th of September
Can't manage to P/Invoke that Win32 API in .NET? Why not do interop the wiki way!
|
|
|
|
|
Calling Application.DoEvents() is probably better than Refresh(), because it processes all the events in the queue, not just the paint ones. BTW, you may also need to call Invalidate for each of the buttons. Not sure though.
Marc
Microsoft MVP, Visual C#
MyXaml
MyXaml Blog
|
|
|
|
|
dotnet provides a way cool StackFrame class that can be used to get Reflection information about the call stack, the methods and their parameters. however i don't see how to get the actual values of these parameters, for example the instance of the class defining a method on the call stack.
is that because interpreting the actual data on the call stack is language dependent, or something like that? suppose i am a method and want to know the instance of the class calling me, can i do that? ((c'mon, no cheating by passing Sender as a parameter!!))
Tia.
________________________________________
Gosh, it would be awful pleas'n, to reason out the reason, for things I can't explain.
Then perhaps I'd deserve ya, and be even worthy of ya..
if I only had a brain!
|
|
|
|
|
Why not pass sender as a parameter if your method needs that information?
One obvious detail is that the callee may know nothing about the caller. For example, in a third party component that your program calls. The third party component won't know anything about your objects so what can it do with them? If it is all your own code then I think its time to step back and re-examine the design.
"You can have everything in life you want if you will just help enough other people get what they want." --Zig Ziglar
The Second EuroCPian Event will be in Brussels on the 4th of September
Can't manage to P/Invoke that Win32 API in .NET? Why not do interop the wiki way!
|
|
|
|
|
TuringTest1 wrote:
suppose i am a method and want to know the instance of the class calling me
OK, here goes. Obviously, the instance is available because, when using the debugger, you can click on the prior calls in the stack. That takes you to the caller code, and then you can inspect variables in that instance.
However, what exactly would you do with the instance yourself? The way the debugger gets it is because the class instance is either stored in a CPU register or is somehow obtainable by inspecting the stack (I can't remember if "this" gets pushed or not). Anyways, it's just an address. The debugger is doing some magic by converting the pointer to a class. In C++, that's easy, but in C#, I'm not sure it's possible.
Marc
Microsoft MVP, Visual C#
MyXaml
MyXaml Blog
|
|
|
|
|
Marc, Colin, thanks. Here is a brazen plug-- anyone reading this thread should read MyXaml-- it's way cool.
Responding to Colin's question, if "sender" is only used in very odd cases i want to put the plumbing underground where it belongs. I admit that this is an asthetic judgement, but it makes sense to me. Your code might detect an unusual condition several levels down and want to know the value of something at the top level-- certainly you could percolate this data or create some sort of global variables etc, but in my asthetic sense it's much more appealing to go and grovel for the data in the rare cases when it's needed rather than forcing everybody to look at your dirty laundry all the time. Imho it's exactly analogous the exception handling, you *could* achieve the same effect by passing all kinds of return flags around, but popping the stack is so much more comprehensible.
Back to the question, as Marc asks, how does the debugger do it? the debugger has no problem displaying all the local variables etc. I *assume* the values or pointers are simply coming from the stack. It's also clear that the debugger sometimes gets confused, so examining the stack isn't a slam dunk. What i don't know for a fact that external information gotten from compiling "Debug" isn't required. Also as Marc points out, what i really want isn't exactly the class instance but rather the contents of the field instance.Foobar-- i'm assuming that c# internally uses some sort of pointer and that if i'm either in the correct namespace or able to use reflection that given the instance pointer or whatever it should be easy to get the value of Foobar.
Anyway why would StackFrame return all the cool type information if it wasn't useful? I have to believe Stackframe is intended for more than just getting the NAMES/ signatures of the methods on the stack.
Again, thanks, and thanks in advance for any more hints.
_______________________________________________
Go see Shrek2. Tell me if it isnt the best movie ever. Then read the credits at the end of the movie and estimate the animation budget.
|
|
|
|
|
run tlbimp on cordebug.tlb in the lib dir of the SDK root. That should give you enough to play with (unfortunately its still in my to look at list, so gimme a shout if it works well).
top secret xacc-ide 0.0.1
|
|
|
|
|
Thanks be to Leppie! (can't claim i understand it quite yet but google cordebug seems to be the place to look).
Again, thanks!
________________________________________
Gosh, it would be awful pleas'n, to reason out the reason, for things I can't explain.
Then perhaps I'd deserve ya, and be even worthy of ya..
if I only had a brain!
|
|
|
|
|
TuringTest1 wrote:
is that because interpreting the actual data on the call stack is language dependent,
No, because all languages targeting the CLR compile to Intermediate Language, or IL. The source language you use to write an assembly has little to do with the compiled code (though some compilers support different features of the CLI and compiler optimizations can change the IL a small amount).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Is there a function which given a pathname will return the size of that file in bytes?
Thanks.
|
|
|
|
|
well, use the fileinfo class.
|
|
|
|
|
Thanks, I was looking at that class but missed "Length" - sometimes I can't see the wood for the trees.
Rugby League: The Greatest Game Of All.
|
|
|
|
|
new FileInfo("myPath").Length
|
|
|
|
|
Hi guys
Here is my problem without further ado :-
Let's say I have a COM method as follows -
HRESULT GetHerName([in] LONG id,
[out,retval] BSTR* namestr);
And I've implemented it as -
STDMETHODIMP MyClassHere::GetHerName(LONG id, BSTR* namestr)
{
wchar_t str[100];
*namestr = SysAllocString(str);
return S_OK;
}
Now C# sees this method as -
string GetHerName(int)
and I can use it from C# as :-
string s1 = obj.GetHerName(22);
string s2 = obj.GetHerName(14);
Now my problem is as follows - I have allocated a new BSTR using SysAllocString in my COM method, but this BSTR gets copied into a new String object by the RCW layer. All that's nice for me - but the original BSTR now leaks.
When I originally designed my COM method, my idea would probably have been that the client should free the BSTR using SysFreeString after using it.
But now I do not have such an option.
Anyone knows if RCW handles this for me in some way? Or will memory keep leaking every time GetHerName is called?
Now with my own blog - void Nish(char* szBlog);
My MVP tips, tricks and essays web site - www.voidnish.com
|
|
|
|
|
Hey, Nish...
When working with COM interop, be sure to check out the System.Runtime.InteropServices.Marshal class. It can be very helpful.
For example, there is a Marshal.FreeBSTR method. All this does is call SysFreeBSTR for you, but saves you from having to P/Invoke it yourself which saves you from requiring an extra code access permission or two (unless you P/Invoke'd other APIs). The trick is that Marshal.FreeBSTR requires an IntPtr - the address to the BSTR . You can get the address like so:
private void FreeBSTR(string bstr)
{
GCHandle handle = GCHandle.Alloc(bstr);
try
{
Marshal.FreeBSTR(handle.AddrOfPinnedObject());
}
finally
{
if (handle.IsAllocated) handle.Free();
}
}
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hey Heath,
Thanks for the reply.
So are you saying that, the string object that the RCW layer returns to the C# client will still internally refer the BSTR memory?
I'd have thought that the original BSTR returned from the COM method is ignored once its contents are used to construct a new string object.
Heath, are there any MSDN links or articles that explain how RCW internally works?
Thanks once again for some really interesting info
Nish
Now with my own blog - void Nish(char* szBlog);
My MVP tips, tricks and essays web site - www.voidnish.com
|
|
|
|
|
Internally, no. The best you could do is search Microsoftie blogs and see what you can find. In the .NET Framework SDK and other articles I've seen on MSDN, it's mostly higher level stuff.
Instead of having your method return a marshaled string have it return an IntPtr (may require hand-coding the RCW) and use Marshal.PtrToStringBSTR . After calling it, use Marshal.FreeBSTR with the IntPtr return value since Marshal.PtrToStringBSTR creates a copy, which implies you are indeed right. Guess I didn't consider that, though it does make complete sense. Maybe I should've slept in longer on this Saturday morning.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanks a heap, Heath
I was writing a blog entry for my blog on this RCW issue of returning a BSTR and was just wondering if perhaps RCW internally solves this issue. So I didn't want to write something without first confirming that the issue does exist.
I'll remember to thank you in my blog entry
Heath Stewart wrote:
Maybe I should've slept in longer on this Saturday morning.
Sleep does you a world of good Get as much of it as possible as you'll probably get busier in the near future as you land up lucrative sub-contracts and stuff.
Nish
Now with my own blog - void Nish(char* szBlog);
My MVP tips, tricks and essays web site - www.voidnish.com
|
|
|
|
|
Nishant S wrote:
...as you land up lucrative sub-contracts and stuff.
Man, I wish...
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
i took two listbox web server controls..ok
In My Listbox1 there is some data which comes from database
on client side i added some elements from listbox1 to listbox2 i have done this by using javascript ok...
Now on some event my page is going to refresh.. so what ever the data i have add on client side in listbox2 vanishes as page get refresh..
what i think as .Net provide a view state so how it get vanishes ....
so can u tell me where i m wrong...
the reason behind to think so, is that (if we add some data in text box through javascript or we just enter through our key board) and when it do the server trip it remains there ,then why not for list box.. so please help me and tell me where i m wrong...
thanks in advance...
|
|
|
|
|
|
Hai all...
I was trying to pass a class to an Unmanaged function. The class has a member of type, of the same class. Is it possible to pass a Managed class(Class having a member of it's own type) to an Unmanaged function.
Thanks in advance
Below is what i did...
This is the class i created to pass into an Unmanaged function as parameter
[StructLayout(LayoutKind.Explicit )]
public class MyWindow
{
[FieldOffset (0)]
public String className;
[FieldOffset (16)]
public String caption;
[FieldOffset (32)]
public MyWindow child ;
}
But if i remove the class member 'child' from the class it works well.
Unmanaged function Decleration
[DllImport("user32")]
public static extern bool EnumChildWindows(int hwndParent, EnumChildDelegare lpEnumFunc, MyWindow lParam) ;
This is the way how i call the unmanaged function
MyWindow m = new MyWindow ();
Win32Calls.EnumChildWindows (winHandle,w.enumChildDlgate ,m);
And i am getting this error.
An unhandled exception of type 'System.TypeLoadException' occurred in CSRecorder.exe
Additional information: Can not marshal field child of type CSRecorder.MyWindow: This type can not be marshaled as a structure field.
Shaju Mathew
|
|
|
|
|
First, change the class to a struct. This allocates the data on the stack so it will not be moved. While this isn't the direct cause of your problem, it may lead to them. If it's a class - which is allocated on the heap - the GC (Garbage Collector) may move it when necessary and your handle that your enumerator is using would be invalid. Declaring this as a struct should also fix the other error.
There is a problem with your EnumChildWindows as well. An HWND is a processor-dependent type. You should really declare this as IntPtr , which works well since P/Invoking other unmanaged Windows APIs will use IntPtr and Control.Handle (the HWND for the control) is also of type IntPtr . Any native int or unsigned int should be declared as an IntPtr .
Also, for your struct, just use LayoutKind.Sequential . You really don't even need that, however, since the memory address to your struct's instance is being passed to your enumerator so it doesn't need to be marshaled for use with unmanaged code. Just a couple of tips.
Microsoft MVP, Visual C#
My Articles
|
|
|
|