- fill the Form with your menubar, your toolbar, and a Panel (if the Form is resizable, make the Panel anchored or docked).
- make the Panel scroll (ScrollBars property).
- add all actual content to the Panel, not the Form.
you derive your own DoubleBufferedPanel from the normal Panel, then in its constructor you can set the double-buffered property (as it is protected). Once you build a project with such DoubleBufferedPanel class present (but still unused), Visual Designer should have it available and now you can replace the Panel by a DoubleBufferedPanel.
you can change the properties of a regular Panel at run-time, something akin to:
Indeed, SetStyle isn't public either, my mistake. So you have to create your own Panel.
Here[^] is an article where I did exactly that; there is a download near the end. It is in C#, I trust it would be basically the same in C++//CLI. Getting Visual Designer to find the new controls depends on a number of factors, I don't think I know them all; one is your code has to compile; another may well be the new Control has to be the first (or only?) class in its source file.
I have a question that's been plaguing me for a day or so. I'll try to explain as best as possible. No code this time, just some general questions.
I have a hierarchy of Windows forms, MainForm->AdminForm->JobDetailsForm. JobDetailsForm requires objects from MainForm, and AdminForm is just a middle man. Is there a slick way to get information from an object in MainForm to JobDetails form without passing the object through AdminForm? The object is an ArrayList of Objects called Users. I set information in the MainForm, and then I get that information inside of JobDetailsForm. Currently I'm doing something similar to
//no operations on users
//some operations on users
AdminForm has no use for users, it simply displays some information unrelated to users. If possible, I'd also like the operations preformed in JobDetailsForm to be reflected in the users object used in MainForm. I'm thinking a global or static variable could solve this, but from what I understand, there are no global or static variables in managed C++/CLI. Any ideas or suggestions?
however, after start->parse(temp) the value of start is always "1/1/1 0 " I'm only interested in the date "5/26/2011". MSDN has several differnt "Parse" methods, and I've tried a few others, but the result is always "1/1/1 0 "
Sorry for the smileys, I think CP website is taking my returned string I'm typing into the question and converting it into some kind of smiley code.
In an application class I try to use this wrapper to receive the values event returned.
In particular in the constructor I initialize the wrapper object: Form1(void)
this->lib=gcnew Library(); //istanzio il wrapper
//event_registered= gcnew Library::eventRegistered(this,&Form1::processEvent);
and in the function I call a wrapper event register funciotn:
error_status err_reg_event=this->lib->registerEvent(); //utilizzo il wrapper
The problem: I think a mistake to use the wrapper by my application or also in wrapper building.
Infact I' ve got error on the callback function when I try to receive event message.
I apologize for my bad English, hoping to be able to explain problem
Someone can indicates me an example or tutorial to learn how can I work with managed C++/CLI and unmanaged C type?
thanks to help me.
I followed your advice and I've read How to: "Marshal Callbacks and Delegates Using C++ Interop"
I've tried to work on my application.
I' ve done this:
1) I decided to create a simple example without wrapper.h. So I' working only in a Form1.h.
2) Since my form1.exe work with the library of an electronic device and I constantly receive
the events returned by this device, I thinked to put the define of delegate, IntPtr and the callback unmanaged function as form1 private attributes and I declared them in the Form1 constructor:
3) After, in constructor, I call the function registerEvent(). In this function I put the calling at the library function "TED_PixRad_RegisterEventCallback":
4) the callback implementation in my Form1 is this:
void cdeclEventCallback(const event_id eventID, const Event *eventData, void* customData )
gcroot<Form1^> & native_handle = *((gcroot<Form1^>*)customData);
Oss1: I think I must using _native_handle and not passing this (Form1 refer).
Oss3: processEvent is an internal function of Form1 that receive the code eventID and write the code mean in a form1 label.
Oss2: The compilation is without errors or warnings.
Assuming that I can not debug because the device connected to a machine other than the development,I have seen that the device gives me error event handling return
In particular, writing message on Form1 labels I' ve seen that I cannot enter in cdeclEventCallback function and I cannot call processEvent().
I can not understand what could be in error and this is a logic error in using Marshal:: GetFunctionPointerForDelegate in my example.
I find that probably the error lies in the way the gcroot, because if I pass NULL in place of _native_handle and put processEvent () outside of Form1, I do not come back errors on callback events in the logs of the device;
OSS2: I used gcroot to pass ref of FORM1 between the managed and unmanaged code;
OSS3: I remember that the prototype of "TED_PixRad_RegisterEventCallback" library function is:
and customData for me is my Form1 (in general my object class).
I must implements processEvent like object function (then as Form1 funciotn) and so I must to pass FORM1 refer in TED_PixRad_RegisteredEventCallback that is the function of unmanaged library.
I've never done this with C++/CLI but I've done it quire frequently between C# (managed) and C (native), and the one thing to remember is in the native world you must declare the callback function as StdCall.
thantks for advice.
Reading your article, I had an idea:
- I haven't used gcroot but directly GCHandle.
- I must casting because parameter library function is void*.
This is what I've done:
1) I 've used GCHandle to build an handle to object (for my example FORM1) and I've used GCHandle.Alloc() to reserve memory when i send object refer from managed code to unmanaged library. I' ve done this in the constructor. So it is:
3) Since library function receives void* customData parameter and it returns this in callback function, I must cast my pointer Form1 refer from IntPtr to void*. After, in the callback function I must casting from void* to IntPtr and in second time I must casting from intPtr to Form1^.
The implementation of the callback funciton now is:
Now I must call processEvent like an object function and not like Form1 external function.
I compiled without problems and doing some tests I've seen that behavior is correct, that the occurrence of an event correctly calls the callback function and that this uses the correctly reference at Form1.
Less than denials I think the problem is solved, thank you all for your help.
I'm a long time lurker on CodeProject, and finally have a problem that I'm getting nowhere on.
We have a C++ application we're building in VS2008 that uses "it just works" interop to create reports using Crystal Reports. So there is a C# ReportHandler (which contains a reference to the Report itself), and a C++/CLI ReportWrapper. If the ReportWrapper is built as a static lib, it works under both WinXP x32 and Win7 x64. However, when the ReportWrapper is built as a DLL, it works under WinXP x32 but crashes under Win7 x64 (it's built as a x86 application either way).
It crashes not when the app starts, but when you try to bring up the File:Open dialog using CFileDialog::DoModal(). The call stack is not obvious:
If I force the "bVistaStyle" flag in CFileDialog to false, the dialog does work without crashing the app; however, it then causes strange out of memory errors later on when we try to actually load a file (using dynazip). That tells me that something nefarious is going on, other than just with the CFileDialog (I suspect some strange DLL corruption).
- we have a similar Report/ReportHandler/ReportWrapper in a different application, and there are no problems with that app.
- if the app is built in release configuration under WinXP x86, it runs fine when installed on Win7 x64.
- if the app is built in release configuration under Win7 x64 (as an x86 project), it runs fine.
So it only crashes when running the debug build (whether debugging or not).
Here's what I've tried so far:
- I compared project settings between the app that works and the one that doesn't. As far as I can tell they're the same.
- I compared project settings between the Release and Debug configurations.
- I created a dummy test MFC app and started pulling in libraries/assemblies/dlls from the app that doesn't work; in the test app, however, the same Report/ReportHandler/ReportWrapper works properly. However, I have not pulled in all of the libraries that are linked into the app.
- I've reread about implementing IJW interop (someone else implemented it) to confirm we've set it up properly.
- I've tried depends (x86), but depends crashes when I try to profile the app.
- I've enabled loader snaps to try and see if anything odd is going on, but have limited experience looking at DLL loading.
- various and sundry other things that I can't think of right now, all to no avail (I've been struggling with this for a while).
Any suggestions on how to approach this problem would be most welcome. Given what's going on, I think there's actually a deeper problem underlying this that's only exposed in this particular configuration (when built as a DLL) -- I don't think it's just a matter of the DLL configuration being the problem.
Gosh, on the surface I can only hazard a guess. You seem to have covered things pretty thoroughly though.
Some wild-assed guesses:
1. When you statically link and run the app, the .NET framework is automatically loaded. When you dynamically link and run, perhaps a different version of the framework is started outside of your control. For example, if there's a shell extension pulled in by the Open dialog, perhaps it's loading .NET 2 and you need 3.5 or 4? This could throw an exception when your DLL finally gets loaded.
2. Does the DLL form reference a C# assembly and fail b/c you need to handle the AppDomain.AssemblyResolve event? Just having the assembly in the same dir as the C++/CLI DLL does NOT mean that C# assembly will be found automatically as I've learned the hard way.
3. Any clues in the Fusion Log views after the failed load? (use fuslogvw.exe) or in the System Event viewer logs?
I'll ponder more but it's hard to help w/o playing around w/ things as I'm sure you're aware...
Thanks, John, I appreciate the effort. I don't mind guesses at this point, wild-assed or not.
1. I'll look further into that to make sure we're binding to the correct version. We've typically deployed our app binding to .NET 2, to keep the installer footprint small. Unfortunately I can't use depends to find out exactly what's being loaded.
2. I have "resolve #using References" set to the output folder where the assembly DLL is built, and I've made the assembly a dependency of the wrapper library in the VS solution. I've set references for it in no other way.
3. No clues. I ran fuslogvw and enabled all logging; when I run the app to point of failure, nothing appears in the log so I presume that means no binding is triggered. In my test app that does work, nothing shows up in the Fusion log until I actually launch the report. The app that's failing never even gets that far (I just run it and do File:Open).
Last Visit: 31-Dec-99 18:00 Last Update: 26-Sep-23 12:43