Vankwysha |
Posted - Jun 14 2005 : 04:02:39 AM I'm restarting the project that I've been developing over the past couple of months (using DirectDraw) with Direct3D as I've encountered several limitations *everybody sighs* yeah yeah, I know, but the learning part is more important than the end product to me.
So, I'm writing my engine in VB.NET using the managed DirectX runtimes and Direct3D. While this is a 2D game, I think Direct3D makes my intended outcomes easier to achieve (no spoilers yet ).
I'm trying to make a DLL with all my code, featuring support for graphics, sound, music, networking code, and the problem that I'm currently having, replicated VB.NET controls such as buttons, text boxes etc.
The problem that I'm having currently is so:
I have a Button class which basically takes the function of the VB.NET button control and wraps it for DirectX. During my main render loop, I run methods to see if the Button.Click() event has been raised. However, the hitch I have it is; as I am trying to make an independant engine that cannot be edited, how do I link the Button's event to a user written sub? I was thinking of taking an IntPtr as a parameter and then pointing to a specific, unwritten method in the form that is passed, but I'm not sure if this will work. In an attempt to help you all understand this better (I don't want to use real code, it will take to long):
DECLARE Button as Class ....... ....... DECLARE Click() as Event ????? (Here I need to link to a subprogram that will run the user(of the engine)'s button code) END Event END Class BEGIN Render IF Button.Clicked THEN Button.RaiseEvent(Click) END IF END
Basically, I want the user to be able to write some code that will execute on the Button.click event. How do I tell the DLL "When this happens go here for some code"?
As you can see, for a DLL this is a definite problem. I would appreciate any help. Hmm, now that I look back, this is a pretty big post.... |
Struan |
Posted - Jul 14 2005 : 12:19:21 AM Here is the button-click-event part of a simplified button class. It handles the mouseup/mousedown events of its parent form (which I don't set in this code, I'll let you handle referencing the parent form) You can also handle creating the bounds whatever way you prefer, it was just easy for this example to do it this way
You make this class public to the user of the DLL so they can create new instances of the button.
Public Class Button Public Event Click() Private Bounds As Rectangle Private WithEvents ParentForm As Form Private MouseDownInButton As Boolean Sub New(ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer) Bounds = New Rectangle(x, y, width, height) End Sub Private Sub parentForm_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles parentForm.MouseDown MouseDownInButton = Bounds.Contains(e.X, e.Y) End Sub Private Sub parentForm_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles parentForm.MouseUp If MouseDownInButton And Bounds.Contains(e.X, e.Y) Then RaiseEvent Click() End If MouseDownInButton = False End Sub End Class
When the mousedown event happens you check to see if it is within the bounds of the button. Then when the mouseup event happens you check to see if both the original bounds test returned true and the new bounds test returns true. This makes sure they "Clicked" the button. Then if they did mousedown and mouseup in the button you raise the Click event of your control.
The user can then create their own UserInterface class and handle the click event you raised the same way they would with a windows form button click.
Example code of an exit button that would be made by a user:
Class UserInterface Private WithEvents ExitButton As New Button(10, 10, 30, 30) Sub ExitButton_Click() Handles ExitButton.Click Application.Exit() End Sub End Class
You could also raise MouseEnter and MouseLeave events so the user can easily do button rollover effects.
Note: I haven't really tested this code (other than typing it in Visual Studio) but it should give you a general idea of what you need to do.
I hope this is what you were looking for. It should make it really easy for the user of your DLL.
EDIT: The color coding only seems to work with VB6 code but if you cut and paste it into .NET it should work fine. |
Vankwysha |
Posted - Jun 21 2005 : 4:41:00 PM I think this problem will work best if I create the DLL as a whole and then create a template VB.NET project which includes things such as the main game loop, an empty sub to put the button code in etc. Thanks everybody for your help. |
ryusten |
Posted - Jun 20 2005 : 7:19:09 PM quote: Originally posted by Vankwysha
3) I need to point the engine to a point in space that doesn't actually exist and say "here's the code, go get it."
4) HOW!!?!
Answer: I dont know the exact syntax myself since I dont use it. But you could use the AddressOf keyword. example: myVariable = AddressOf Foo() or something similar to that. However, you cant point to anything that doesnt exist. So the engine will have to fully initialize itself and create all the necessary functions before you can use the AddressOf Foo(). |
Dan |
Posted - Jun 20 2005 : 09:02:42 AM When you are declaring the variable in the client App you need to specify it as being 'with events'. This will allow you to receive the events raised in your dll...
Example
Dim With Events oMyclass as MyClass
Will allow you to handle..
oMyclass.ButtonClick
Hope this helps..
You may find this article interesting. It details how to use the .Net language to run scripts. An interesting read even if you don't use it...
http://www.divil.co.uk/net/articles/plugins/scripting.asp |
Eric Coleman |
Posted - Jun 18 2005 : 11:41:15 AM don't you raise a click event? I'm don't know .NET very well, but there should be some sort of "with events" equivalent. |
Vankwysha |
Posted - Jun 16 2005 : 06:22:03 AM "Custom Script";
1) Each button that a developer (usually me) will use in the implementation of my DLL will require different code, much like windows command buttons in the VB environment. One button will create a new game, one will exit etc.
2) I don't want to have to open up the DLL, create a new sub program and add the code that my button will execute for EVERY SINGLE BUTTON THAT I USE.
3) I need to point the engine to a point in space that doesn't actually exist and say "here's the code, go get it."
4) HOW!!?!
Hope that explains it. |
Eric Coleman |
Posted - Jun 16 2005 : 12:44:56 AM What is a "custom script?" |
Vankwysha |
Posted - Jun 15 2005 : 4:56:25 PM I'm not using the native windows button. My class stores the coordinates and size of the button. During the render loop, the method Button.Clicked() is called, which raises the event Button.Click() if the cursor is within the confines of the button and the left mouse button is held down. The constructor of the button takes the coordinates and the size and the DLL handles the rest. The only thing that I can't get to work is the custom script for the button, which must be outside the DLL. |
Eric Coleman |
Posted - Jun 15 2005 : 12:44:33 PM Is a button class necessary? How are people supposed to use this class? Are you using native windows button or are you raising your own click events when a mouse button is pressed while the cursor is within a predetermined area? |
Vankwysha |
Posted - Jun 14 2005 : 4:50:08 PM My button code works perfectly when I use it within the form, I'm already using DirectInput to determine the position of the mouse in relation to the button. My problem is that when I use the code in my DLL, I don't want to have to open up my DLL and add code every time I need it for every single button, I want to be able to point the DLL to code in the form, and then write that code. I'm not talking about the actual workings of the button, that will be handled by the engine, I mean the code for what the button has to do, such as starting a new game or exiting the program. Thanks for your help anyway, ryusten |
ryusten |
Posted - Jun 14 2005 : 12:18:58 PM I'm a DirectX noob myself, but my first thought is to use DirectInput in your DLL. I'll assume that you're making 1 DLL for each part of the code (sound,music,networking,graphics/etc). You can have your KeyboardDLL bind the keyboard input and then just have your DLL expose a Public ProcessEvents() function that is called from the main game loop. And just have the DLL call Friend functions in your other DLL's to update the information it should based on the key events. This ProcessEvents function doesnt need to bind to actual command buttons, just setup a nice long set of IF statements to check the borders of each button. I have no idea how the clipping rectangles work in DirectX so the exact how it beyond me there. |
|
|