|
Hi, I just started playing around with SDL.Net some hours ago and everything works perfectly when I use the SDL.Net window functions instead of a WinForm.
The problem is that I want to use the input functions of SDL.Net with my application, but my application will use D3D/OGL(not implented yet) for rendering, so I'll need a WinForm.
So is it possible to use SDL.Net on a WinForm?
|
|
|
|
|
Yes it should. Windows Forms are classes that encapsulate the native Window APIs. The TextBox , for example, encapsulates the Edit common control; the ListView the List-view common control; etc.
Every class that extends Control is, in fact, tied to an HWND . That's what the Control.Handle property is - an IntPtr (processor-specific bit length integer). The Control.WndProc method is the callback function to handle window messages. Many Window API functions are encapsulated by Windows Forms (even setting the Control.Text property in the Windows Forms BCL ends up sending the WM_SETTEXT windows message most often), but some times you need to P/Invoke other functions like FindWindow or something.
Since your question is rather open-ended, I recommend you read about[^] the Control class members and about P/Invoke[^].
Please search this forum using "Search comments" above to search for function names to find examples, or visit http://pinvoke.net[^] for many, many function signatures.
If you have further questions, please be specific in your request.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Customer Product-lifecycle Experience
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
I'm not sure you understood my question correctly, but thanks for answering anyway.
SDL.Net is a cross-platform API which provides functionality as window creation, 2D rendering and input handling. The problem is that to become cross-platform it needs to hide the WinForm away from the user of SDL.Net, otherwise it wouldn't run on Mono and such projects(if there are other).
So without taking a WinForm (or control) SDL creates it's own window, if you do this AND also call the standard "InitializeComponents" two windows will be created. You could tell SDL not to create a window, but then it wouldn't be possible to keep track of mouse position and check if mouse/keyboard keys was pressed.
So what I want to do is to create ONE window and have a "System.Windows.Forms.Form" variable after that, with this window I want to check if any keys have been pressed and if the mouse have moved.
Hope I made it clear this time.
|
|
|
|
|
I'm well aware of what SDL is, but you didn't describe what you were trying to do. If you were trying to interop SDL windows and had to use their handles to, say, play video or create a drawing surface you would need to access the window handle of a window. Without specific use cases with such open-ended questions, it's difficult to provide an answer.
Windows Forms does work in some alternative implementations like Mono and Portable.NET (and yes, there are others), if you have the right libraries. Mono can, for example, use the Wine libraries to provide compatible Windows Forms using the existing System.Windows.Forms.dll assembly. Other implementations and bindings - even for Mono - may use GTK or Qt to provide Windows Forms support. Do keep in mind, however, that Windows Forms is not defined by the CLI as standard so a CLI implementation like .NET, Mono, or Portable.NET doesn't have to implement it.
InitializeComponent is not a standard at all, but merely a method that Visual Studio places all the design-time calls into. If you wrote your own from scratch - or even started with the design-time output that Visual Studio outputs - you can call it anything you like or refactor the code into different methods, including the constructor itself.
What I am wondering is why you're creating two different Windows Forms here. SDL can handle input as well, so it could be used in lieu of Windows Forms. Why is it that you require Windows Forms in this case?
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Customer Product-lifecycle Experience
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
I'm sorry, you are right, I didn't said was I was going to do. I'm also sorry about the wrong things I said about Mono.
What I'm doing is developing an input library, currently I have support for DirectInput, but I also want to add support for SDL.Net. The problem is that it seems that I can't use the input functionality of SDL.Net without allowing SDL.Net to create a WinForm, I can't just use a previously created WinForm.
So I need to use the input functionality of SDL.Net, but at the same time be able to render with APIs like D3D. To render with for example D3D I need to provide a WinForm and I can't get the WinForm when SDL.Net have created it.
|
|
|
|
|
As far as specifics go I'm afraid I can't be of much help. I worked with SDL a little back when it was first made available in a barely stable form.
What I can offer is suggestions, however. At some point, SDL must bind to a window handle. In Windows, it's impossible not to since every control and window is handled by the Windows window manager. The key is getting access to that window handle so that you can site (position) or even parent controls (like an input box) to a parent window.
For example, see my article Embedding .NET Controls in Java[^] where I pioneered a way using JNI to get the window handle for Java controls (that don't expose them in Java directly) and then parent .NET controls in a frame through COM interop.
Another approach you might take now that you know (or maybe knew) Windows Forms are just encapsulated HWND s - so anything native you can do to them you can do in .NET, often requiring P/Invoke - is to find an SDL forum and don't even mention .NET. The reason is that they may shove you off to a forum like this (a game of hot potato). It's not a .NET implementation problem, however.
SDL uses abstraction and factories to be platform "independent" by using appropriately providers for the underlying platform, just like Java requires a JVM for a specific platform (Windows, Linux, Mac, etc.). SDK is the same way, as is .NET (or CLI implementations, rather). At some point you may have to do the same, using a provider to, say, parent an SDL "control" to a window in Windows, and whatever the equivalent is for GTK or Qt.
This is also what Windows Forms does in other CLI implementations. Mono, for example, has Wine (for native Windows Forms through Windows emulation), GTK, Qt, and perhaps some others for providing Windows Forms (so long as you don't expect the Handle property to return anything and stick with the publicly exposed methods and properties).
Finally, consider if you even need to be platform independent. If not, don't make it hard on yourself because it can get very hard. Much of what you see in the .NET Framework class libraries isn't standard and may not be supported on other platforms. Chances are that you've used something to already ruin portability already. The only sure way is to use scanning tools and fully understand the CLI implementation at http://www.ecma-international.org/publications/standards/ecma-335.htm[^]. Just something to think about.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Customer Product-lifecycle Experience
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Thanks, I guess I just need to keep searching for a way to get that WinForm.
BTW Thanks for all the (long) answers.
|
|
|
|
|
I've got two methods:
public void Decrypt()<br />
{<br />
ASCIIEncoding text = new ASCIIEncoding(); <br />
RijndaelManaged szyfr = new RijndaelManaged();<br />
szyfr.Key=key;<br />
szyfr.IV=iv;<br />
byte[] tmp = text.GetBytes(password);<br />
MemoryStream in = new MemoryStream(tmp);<br />
CryptoStream deszyfr = new CryptoStream(in, szyfr.CreateDecryptor(), CryptoStreamMode.Read);<br />
byte[] dPassword = new byte[tmp.Length];<br />
deszyfr.Read(dPassword, 0, dPassword.Length);<br />
password = text.GetString(dPassword);<br />
<br />
<br />
<br />
<br />
}<br />
<br />
public void Encrypt()<br />
{<br />
ASCIIEncoding text = new ASCIIEncoding(); <br />
RijndaelManaged szyfr = new RijndaelManaged();<br />
szyfr.GenerateKey();<br />
szyfr.GenerateIV();<br />
key=szyfr.Key;<br />
iv=szyfr.IV;<br />
byte[] in = tekst.GetBytes(password);<br />
MemoryStream out = new MemoryStream();<br />
<br />
CryptoStream zaszyfr = new CryptoStream(out, szyfr.CreateEncryptor(), CryptoStreamMode.Write);<br />
zaszyfr.Write(in, 0, in.Length);<br />
zaszyfr.FlushFinalBlock();<br />
password = text.GetString(out.ToArray());<br />
}
Don't worry about some of these variable names - they're "culturally-influenced"
password, key and iv are members of the class which owns these methods.
This code is virually re-written from msdn and even though it doesn't work. password is encrypted, but the an exception is thrown at
deszyfr.Read(dPassword, 0, dPassword.Length);<br /> , in the Decrypt() method. It says PCKS7 padding is incorrect and cannot be removed (from the decrypted message I guess). When I change paddingMode of szyfr to Zeros , the decrypted password doesn't match the original. It seems that used key or iv don't match, but they actually do, as you cans see from the code. Any idea how I can get the things going?
|
|
|
|
|
Hi,
can anyone tell me what the following line of code means, its pretty simple i think but i dont understand what the '/b' bit does.....
if (e.KeyChar != '\b')
also what if you replaced the '\b' with '\a' what would be the outcome ???
please help
Cheers
|
|
|
|
|
Don't even try to tell me that this is not homework...
"\a" is escape sequence for alert (beep)... go figure!
David
Never forget: "Stay kul and happy" (I.A.)
David's thoughts / dnhsoftware.org / MyHTMLTidy
|
|
|
|
|
Please read section 2.4.4.4: Character Literals[^] in the C# Language Specification about character literals and what literals are supported in C#.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Customer Product-lifecycle Experience
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
in a unmanaged c++ code,there is a function:void GetString(CStringAray & strarray);
in c#, how to use this GetString function? Give me some examples codes. Thanks a lot!
[Dllimport("mydll.dll")]
public extern static GetString(XXX)???
|
|
|
|
|
That's not so easy to answer. CStringArray is obviously a class and this forum has no idea what that class does. I do wonder, however, why you need to call this. Is there a string array in a native process you need to get?
It all comes down to marshaling[^] the data represented by that instance of CStringArray to managed code (a class or struct). Not all types simply marshal. The CLR marshals the primitives and a few others (function pointers, interface pointers, etc.) correctly - sometimes with a little help[^] required - but you must first declare the managed representation of CStringArray before you can even think about marshaling it. To do that - if you need help - we need to know what CStringArray looks like.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Customer Product-lifecycle Experience
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Assuredly, there is a string array in a native process i need to get.More than one,the length of string and string array are inconstant.I post my problem on the internet, but nobody can help me which bother me so much. Can you help me? If CStringArray can not suit me, how to do?
|
|
|
|
|
It's important that I know the data structure for the CStringArray . When marshaling data from native to manage code or back, the data must be marshaled in a way that can be represented in both native and managed code. For example, a simple string[] array in manage could would marshal a contiguous array of references (marshaled as pointers) to null-terminated character arrays, something like in this ASCII art:
_____
| a |----->"Points to 'a'"
| b |---+
| c |-+ |
----- | +->"Points to 'b'"
|
|
+--->"Points to 'c'" That's a very generalized representation, but it helps know how to marshal a string[] array. Without knowing how the CStringArray class stores data, it's impossible to tell you how to marshal it for sure.
If you're not sure of the structure of CStringArray , 1) look in the headers for the definition of the class, or 2) tell us where this class is defined. Is it an MFC class, or an ATL class? Is it defined by another library.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Customer Product-lifecycle Experience
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
CStringArray is a standard class of Vc++6.0/MFC,not ATL or not my defined class. In my native codes,
there is implemention as follows:
void GetStrings(CStringArray &stringArray)
{
CString a = "a";
CString b= "aaaa";
stringArray.Add(a);
stringArray.Add(b);
}
The length of stringArray is inconstant.
The initial purpose is as follows:
In C# program, I need get some strings which the number of string is
inconstant from a native c++ dll. Because MFC's CStringArary is good,i use
it as export variable.
If CStringArray can not suit me ,how to do in c++ dll?
|
|
|
|
|
If you look at the documentation for the CStringArray class, you'd see that it's declared in atlcoll.h, which you can find in the Vc7\atlmfc\include directory under your VS.NET installation path. Looking at it's definition, you can find that it has fields defined like so:
CString* m_pData;
INT_PTR m_nSize;
INT_PTR m_nMaxSize;
INT_PTR m_nGrowBy; The CString class is defined in cstringt.h, and extends the CSimpleStringT , which contains on member, PXSTR and is defined in atlsimpstr.h. PXSTR is a typedef of a templated class. CString is a platform-specific character set, being ANSI on Windows 9x/Me and Unicode on Windows NT-based platforms like XP.
This means you should be able to define a class like so:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
class CStringArray
{
public string[] m_pData;
IntPtr m_nSize;
IntPtr m_nMaxSize;
IntPtr m_nGrowBy;
} You should declare your P/Invoke method like so:
[DllImport("mydll.dll", CharSet=CharSet.Auto)]
static extern void GetString(out CStringArray strarr); Try this and it should work for you.
You should not expose your P/Invoke method publicly, but instead encapsulate it in a method that is exposed publicly and removes the burden of having to work with natively-defined data, which isn't always so nice to work with in managed code.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Customer Product-lifecycle Experience
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Sorry , it does not work. I will send my examples to you.Please check it and correct it.
|
|
|
|
|
Sorry.I can not upload my example codes online,so just paste it here.
Regular Dll using shared MFC dll:
extern "C" void PASCAL EXPORT GetValues(CStringArray & stringArray)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CString a = "a";
CString b = "b";
stringArray.Add(a);
stringArray.Add(b);
}
c# managed codes:
using System;
using System.Runtime.InteropServices;
namespace CSharpProject
{
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
class CStringArray{
public string[] m_pData;
IntPtr m_nSize;
IntPtr m_nMaxSize;
IntPtr m_nGrowBy;
}
class Class1
{
[DllImport("MFCDLL.dll", CharSet=CharSet.Auto)]
static extern void GetValues(out CStringArray strarr);
[STAThread]
static void Main(string[] args)
{
CStringArray stringArray = new CStringArray();
GetValues(out stringArray);
}
}
}
Above codes do not work correctly.
|
|
|
|
|
What about it doesn't work? Is an exception thrown? On what line is the exception thrown (debug your application in VS.NET or use cordbg.exe on the command line)? What's the exception type and message?
Stating that it "doesn't work" doesn't help me diagnose the problem, so I can't provide any advice to you without knowing exactly doesn't work.
Also make sure that "MFCDll.dll" is in a directory referenced in your PATH environment variable. The DLL is loaded using LoadLibrary , which checks the working directory for the application that's loading it, then in directories in the PATH environment variable.
For information about how native DLLs are found, read the documentation[^] for LoadLibrary . If you're interested to know how managed assemblies are located, read How the Runtime Locates Assemblies[^].
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Customer Product-lifecycle Experience
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
1, I build a Regular Dll using shared MFC dll as follows:
extern "C" void PASCAL EXPORT GetValues(CStringArray & stringArray)<br />
{<br />
AFX_MANAGE_STATE(AfxGetStaticModuleState());<br />
CString a = "a"; <br />
CString b = "b";<br />
<br />
stringArray.Add(a);<br />
stringArray.Add(b);<br />
}
2,build a c# console project named text.exe as follows:
using System;<br />
using System.Runtime.InteropServices;<br />
<br />
namespace CSharpProject<br />
{<br />
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]<br />
class CStringArray{<br />
public string[] m_pData;<br />
IntPtr m_nSize; <br />
IntPtr m_nMaxSize; <br />
IntPtr m_nGrowBy;<br />
}<br />
<br />
class Class1<br />
{ <br />
[DllImport("MFCDLL.dll", CharSet=CharSet.Auto)]<br />
public static extern void GetValues(out CStringArray strarr);<br />
<br />
[STAThread]<br />
static void Main(string[] args)<br />
{<br />
CStringArray stringArray = new CStringArray();<br />
GetValues(out stringArray); <br />
}<br />
}<br />
}
3, Copy MFCDLL.dll to the directory of text.exe.
4,double press text.exe ,but program throws exception:System.ExecutionEngineException. When debugging the text.exe,variable:stringArray is undefined value.I think maybe there is some problem with the structure of class CStringArray.
P.S.
1. If debugging the program yourself ,you should diagnose the problem.
2. In ..\MFC\include\AFXCOLL.h, In CStringArray,there is:
protected:<br />
CString* m_pData;
int m_nSize;
int m_nMaxSize;
int m_nGrowBy;
so ,i modify your CStringArray:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]<br />
class CStringArray{ <br />
public string[] m_pData;<br />
int m_nSize; <br />
int m_nMaxSize;<br />
int m_nGrowBy;<br />
} But it does not work,too.
Thank you very much.
|
|
|
|
|
One problem could be that the marhsaler must know the size of the array, but one must use MarshalAsAttribute.SizeConst and MarshalAsAttribute.SizeParamIndex only works for marshaling method parameters, not struct fields.
The Marshal class in System.Runtime.InteropServices can be useful for custom marshaling, which you can read about here: http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemRuntimeInteropServicesICustomMarshalerClassTopic.asp[^].
Also, the native code is different from your original code you posted. Since you are not instantiating the CStringArray then you must use ref instead of out in your P/Invoke signature and must instantiate the managed CStringArray . You can read about the differences between ref and out here: http://msdn.microsoft.com/library/en-us/csref/html/vclrfPassingMethodParameters.asp[^]. Since CStringArray is a class, it will be a reference type. Try just leaving off the ref or out and declaring the parameter simply as (CStringArray stringArray) . Typically out and ref are used with struct params, since structs are value types and are passed by-value; or with double pointers for reference types.
Finally, I am not debugging your code. This development community is here to help you learn, but not to do your work. That will never teach anyone anything. Debugging your code and helping to diagnose the problem is what you should be doing and is part of the development lifecycle.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Customer Product-lifecycle Experience
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
This is the just problem i meeted. And hidn't solve it until now.
I use a similar class in c# to warp it, but it does't work well too.
And finally i get a wrong result:
I find
the size of CStringArray doesn't equal to marshal_size of the similar class in c#.
And i do it with the attribute of explicit, but ummy, it doesn't work well too.
So, anybody can help me ?
|
|
|
|
|
i have found the code here (http://www.codeproject.com/dotnet/CSharpWhiteboard.asp) ,but it only can be used by two users . unfortunately, i need one which can support many users (i know that it need a server ,and need to use SOCKET) .
how to finish it ??? need to help !
thanks !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
can u send me some useful things about it ?
my email------------- saxon_100@hotmail.com
need helps . i know there are many master-hand
|
|
|
|
|
This appears to be the THIRD time you have asked this question. This first time you received no replies. The second time you received a messsage to say that "your method for asking for help probably isn't the most effective."
I should point out that if you have a question regarding an article (http://www.codeproject.com/dotnet/CSharpWhiteboard.asp[^]) you should ask in the forum of the article. You have not done this.
Secondly, your question ("how to finish it???") requires and answer that will be very time consuming to answer fully. However, a brief look at the article would suggest that it IS finished as the original author only intended to write a 2 person whiteboard.
My: Blog | Photos | Next SQL Presentation
WDevs.com - Open Source Code Hosting, Blogs, FTP, Mail and More
|
|
|
|
|