|
Christian Grauss wrote:
t's probably a MACRO, so put your mouse over it and see if intellisense tells you what it really means.
and if it doesn't, search for _RSA_FZM_CLASS into your hole project, and in the included files...
TOXCCT >>> GEII power [toxcct][VisualCalc]
|
|
|
|
|
Hi,
Does anyone know how to convert a pointer to a managed class to a void * so I can pass it to a unmanaged function which will call into a managed function with the void pointer which then needs to convert the void pointer back to a managed pointer. All the code is in the same exe I am not calling into a dll.
Here is a chunk of code as an example:
__gc class mcFoo {
.
.
.
public: int x;
};
tmain()
{
mcFoo *Foo = new mcFoo();
Foo->x = 1;
xxx(Foo);
//Foo->x == 2
}
#pragma unmanaged
xxx(void *ump)
{
yyy(ump);
}
#pragma managed
yyy(mcFoo *mp)
{
// mp-> x == 1
mp->x = 2;
}
|
|
|
|
|
I believe I have found the solution. By creating a unmanaged class and having it contain a pointer to the managed class (using gcroot) and passing that to the unmanaged function it apears to resolve the compiler issues. If this is the right aproach I have a new question:
If the managed class is complex in that it conatains pointers to other managed classes, such as a container class, do I need to do more such as define the layout mechanism of the class? I am not using this pointer in any of the unmanaged code, just passing it through from on managed function to another through a unmanaged function.
|
|
|
|
|
Hi,
I have a dll that is using mixed mode. I followed these steps to create the
project:
1. Created a managed C++ class library.
2. Added methods and code that uses unmanaged MFC (CString).
3. Compiled.
4. Added this dll as a reference in some C# project.
5. Used the managed classes that were coded in the dll.
Everything was normal until i tried to fix the linker warning:
LINK : warning LNK4243: DLL containing objects compiled with /clr is not linked with /NOENTRY; image may not run correctly
This link says how to fix the linker warning:
http://msdn.microsoft.com/library/d...tomixedmode.asp
Please check the steps given under the section:
"To convert the managed DLL to mixed mode"
After doing whatever was mentioned in that section, when I access a
method in the dll that uses CString, I get an exception in one mfc file.
Details of the exception:
-------------------------------
File : f:\vs70builds\3077\vc\MFCATL\ship\atlmfc\include\cstringt.h
Line : 1088
Expression : AtlIsValidString( psz )
... and blah blah.
Can anyone help me in fixing the linker warning as well as the exception ?
Thanks in advance.
-Raj.
|
|
|
|
|
Hello,
I have created an MFC C++ application. I copy the exe to my colleagues machine.
I want to execute it on my his machine but when I do so on his machine it says hat the MFC71D.DLL
is missing. All I am doing is copying over the exe, I expected it to execute.
Can anyone help? Thank you, Joe
|
|
|
|
|
He has the .NET Framework 1.1 installed... I forgot to mention this.
|
|
|
|
|
joseph1950 wrote:
says hat the MFC71D.DLL
is missing
The D means you gave him a debug build - NEVER do that.
MFC is a dll, as you have discovered. If a release build does not work, then you need to give him the dll. If you've used C runtime functions, you'll need MSVCRT something.dll ( I forget the number ). To avoid this, choose 'use MFC as a static library' when you build your next MFC app, it will be bigger, because it will include the MFC code you use in your app.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
Thank you for your replies. I pulled down project -> properties->general and changed the debug to release and then rebuilt the application. I then also experimented with changing shred dll to static dll as well. My coworker hasn't yet tried the new versions. Am I doing what you said to do?
Joe
|
|
|
|
|
Yes, always give out release versions. Debug versions contain a lot of extra stuff to help debugging, and will be slower, as well as needing debug dlls, and the other issues someone else raised.
I didn't think you could change to static build on an existing project ? Anyhow, I was not saying you should do this, necessarily. I wouldn't, but I mentioned it so you can decide if you want to. Ideally, you should just ship with the dll, then you can ship smaller updates, because you'll know the dll is there. If I was offering software for download, I'd offer the dll seperately.
Don't forget, you may also need MSVCRT, if you've used C runtime functions. I think VC comes with a tool called Depends that tells you what dlls your app needs.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
i don't agree with christian for linking MFC as a static library. sure it does not force you to provide the MFC dll with you program, but it can enlarges enormously your program if you call many MFC functions.
as i already ask[^] on MFC dll version, here is[^] what Alok responded to my great satisfaction...
so to sum up, I advise you get your MFCs as a dynamic linked library (DLL), and always provide that DLL with you programs written with MFC (it is not so big after all...).
Also, as Christian said, be careful not to provide to ones a debug version. visibly here, it was for a collegue, but remember make a release version before distribute your soft... it will increase security (debug information can allow recovering the code) and decreasing considerably the size of your exe...
cheers,
TOXCCT >>> GEII power [toxcct][VisualCalc]
|
|
|
|
|
Thank you for your replies. I pulled down project -> properties->general and changed the debug to release and then rebuilt the application. I then also experimented with changing shred dll to static dll as well. My coworker hasn't yet tried the new versions. Am I doing what you said to do?
Joe
|
|
|
|
|
It worked. I have distributed the app. Thank you. Joe
|
|
|
|
|
toxcct wrote:
don't agree with christian for linking MFC as a static library. sure it does not force you to provide the MFC dll with you program, but it can enlarges enormously your program if you call many MFC functions.
Sorry, I wasn't advocating that as a general approach, I was just trying to give a complete answer. I also said that would bloat the exe size.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
Hi... Sorry if this becomes a long message but, Please look throught this code:
#using <mscorlib.dll>
#using <System.dll>
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;
__gc class SimpleForm : public Form
{
public:
SimpleForm();
private:
Button *btnMe;
void CloseClick(Object *Sender, EventArgs *Args);
};
SimpleForm::SimpleForm()
{
this->BackColor = System::Drawing::Color::Azure;
this->Text = S"Ett litet Test";
btnMe = new Button;
btnMe->Location = Point(115, 225);
btnMe->Text = S"&Close";
btnMe->Click += new EventHandler(this,CloseClick);
this->Controls->Add(btnMe);
}
void SimpleForm::CloseClick(Object *Sender, EventArgs *Args)
{
Close();
}
int __stdcall WinMain()
{
SimpleForm *SF = new SimpleForm();
Application::Run(SF);
return 0;
}
What do I need to add in the class to draw something using GDI+ or whatever way that might be the best. I just want to draw some circles or rectangles or lines onload or onbuttonclick. I have searched all over for some EASY samples of this, but no there are only expert solutions that performs 1000 operations more than I really want to do and which also makes the code VERY hard for an inexperienced programmer to understand.
Any help is appreciated, thanks in advance.
Regards,
Hmmkk
|
|
|
|
|
Oooh... I just figured it out... but without using GDI+...which I eventually want to learn and be able to use properly, so I still want help with this.
The way I solved it was by adding an protected: virtual void OnPaint(PaintEventArgs * pe) to the SimpleForm class... I guess windows has that name on default and understands what to do automaticly? (Am I right?)
Also when this finally worked, I tested some cool OnMouseMove stuffs, it worked too so now I get projectiles of lines drawn from every corner of the work when moving mouse
Awell, so the problem now is mainly, how to send for example X and Y cordinated to another function, ex on some timertick, move the rectangle 1step to the right. I might have a solution myself for this, but any "expert" solution so I learn it the proper way is appreciated.
And of course also, how to implement GDI+ into this? I have tried to include it but I get alot of errors.
Thanks.
Regards,
Hmmkk
|
|
|
|
|
I just happen to be reading this terrific book by Chris Sells, and he has a chapter entitled: Drawing Basics (about 50 pages long).
Anyway, he starts out with this:
"...the System.Drawing namespace is implemented on top of GDI+ (Graphics Device Interface+), the successor to GDI. The original GDI has been a mainstay in Windows,...
GDI+ is a Win32 DLL (gdiplus.dll) that ships with Windows XP,... GDI+ is also an unmanaged C++ class library that wraps gdiplus.dll. System.Drawing classes share many of the same names with the GDI+ C++ classes,..."
"No matter what kind of drawing you're doing, the underlying abstraction that you're dealing with is the Graphics class from the System.Drawing namespace."
In your form class's constuctor C.Sells recommends using code like this:
Graphics g = this::CreateGraphics();<br />
Once you have instantiated a Graphics object, there are numerous drawing calls you can make (these are quite simple).
This is the listing of members to the Graphics class over at the MSDN site:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdrawinggraphicsmemberstopic.asp[^]
You can always override the OnPaint event, but, using the Graphics class properties and methods gives you more flexibility (and can be used anywhere in your Form class code). Calling Invalidate, Update, or Refresh on the Graphics object will fire the OnPaint event (among other things).
|
|
|
|
|
Thanks for the answer.
Yeah, I'm currently using "Graphics g = CreateGraphics();" but so what your saying is that the dlls I use, include a few of the GDI funcions?
I don't use Win XP, but I have downloaded the gdiplus.dll and gdiplus.lib. I tried to include those to my project but I got errors about the enumgdiplus.h (the name was something like that).
If I include stuffs like stdafx and winafx and such... I get other errors, because of that I allready have a Form class and a WinMain... So what ever I seems to do, I get errors=/
Regards,
Hmmkk
|
|
|
|
|
I'm assuming that you are new to .NET. The syntax can be confusing when you first begin, because it is quite different from the familiar Win32.
In re-reading your original post, I noticed that you defined the SimpleForm constructor outside the class definition; you should move that into the class definition. You can view sample Winforms code that accompanies your .NET Framework install (or download the latest from the MSDN site), it's very helpful, and will show you the standard approach.
If you use the old Win32 and MFC header files in your application, you must also have the corresponding LIB files available to the compiler's search path (this is not the default setting for the Visual C++ .NET compiler when an application is compiled with the /clr switch). It's better, though, to use the System.Runtime.InteropServices [DllImport] attribute with the system DLL (user32.dll) as a parameter to import just the functions you need for your project.
Interop can be confusing initially, you might want to read up on the concepts involved:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconconsumingunmanageddllfunctions.asp[^]
Also, there is good sample code on Interop (or PlatformInvoke) included with your .NET Framework SDK.
|
|
|
|
|
Hmm... well about the SimpleForm example, it's just the simplest example I have ever seen on creating a form and then also be able to use all kinds of functions and also create controls in an easy way. I don't like having resource files or stdafx and such, that's why I use this way.
I might not understand you right but your point is that there are many unessesary things I include by importing the dlls? And that I can solve that by only importing the functions I need by using some dllimport runtimeservies called InteropServices?
Btw, yeah I'm kind of new to .NET or at least I don't really know the exclusive things for just .NET... I kind of only know some standard c++, I started going from console -> GUI not too long ago in c++, so that's why I want to get a hold of simple things like drawing and so on, also I need to be good at it for a school project later on. Other than that I have worked abit with Visual Basic before...so all program/memory optimizing and advanced functions is not familiar to me yet. But after all I haven't needed them yet?
Know any good task/program that I can try to create for learning the essentials and everything?
Regards,
Hmmkk
|
|
|
|
|
I've never used MFC that much, so I'm not really familar with it.
However, when you use MFC header files as includes to your managed WinForm project, you're just creating potential problems for yourself. MFC, as useful as it is (especially for the Document/View architecture) is an unmanaged class system. And, as such, it is incompatible with the managed .NET classes (unless you use Interop, or other code techniques to facilitate the integration). The .NET design teams realized that MFC and COM and all the pre-.NET legacy code out there that performs so well, should be able to be used in the CLR Runtime environment (or, hell, no one would want to acquire the coding expertise in the new .NET Framework class system). So, they developed Platform Invoke (or Interop) to make these two worlds accessible to each other.
Interop confuses most programmers unfamilar with it (it confuses me, and I've read a fair amount of documentation on it).
Many of the classes in both MFC and .NET are wrappers for the objects and functions from the underlying Win32 system DLLs. But, that's an oversimplification.
I would suggest that you buy yourself a good book on the subject and look through the example code provided, and also, read the documentation included with your Visual Studio .NET install (and the .NET Framework SDK).
The Framework classes in System.Windows.Forms and System.Runtime.Drawing are the managed .NET equivalent of Windows and Windowing techniques, generally, and MFC has similar classes (with completely different syntax and methods). You can use the two together, but, you should have an understanding of the underlying system calls that the wrappers are making, or you'll be colliding with your own code half the time.
And, so, the simple way is to just use one system or the other until you are familar enough with each to integrate them.
There is a good Microsoft book on this subject:
Programming with Microsoft Visual C++ .NET, Sixth Edition (Core Reference)
by George/Kruglinski Shepherd
|
|
|
|
|
Hello again,
I am recreating an example app - a hexadecimal editor - I am getting three errors when I compile.
These are all C2039's. They are "MeasureFontHeight" is not a member of "CHexViewerView","Top" is not a member of "CRect", and "ReadLine" is not a member of "HexViewerDoc". The code using these follows:
// HexViewerView.cpp : implementation of the CHexViewerView class
//
#include "stdafx.h"
#include "HexViewer.h"
#include "HexViewerDoc.h"
#include "HexViewerView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CHexViewerView
IMPLEMENT_DYNCREATE(CHexViewerView, CScrollView)
BEGIN_MESSAGE_MAP(CHexViewerView, CScrollView)
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, &CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, &CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()
// CHexViewerView construction/destruction
CHexViewerView::CHexViewerView()
{
// TODO: add construction code here
memset(&m_logfont, 0, sizeof(m_logfont));
m_nPointSize = 120;
_tcscpy(m_logfont.lfFaceName, _T("Fixedsys"));
CWindowDC dc(NULL);
m_logfont.lfHeight = ::MulDiv(m_nPointSize,
dc.GetDeviceCaps(LOGPIXELSY),720);
m_logfont.lfPitchAndFamily = FIXED_PITCH;
m_pFont = new CFont;
m_pFont->CreateFontIndirect(&m_logfont);
}
CHexViewerView::~CHexViewerView()
{
if (m_pFont != NULL)
{
delete m_pFont;
}
}
BOOL CHexViewerView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CScrollView::PreCreateWindow(cs);
}
int CHexViewerView::MeasureFontHeight(CFont* pFont, CDC* pDC)
{
//how tall is the identified font in the identified device class(DC)
CFont* pOldFont;
pOldFont = pDC->SelectObject(pFont);
CRect rectDummy;
CString strRender = _T("1234567890ABCDEF- ");
int nHeight = pDC->DrawText(strRender, -1, rectDummy,
DT_TOP | DT_SINGLELINE | DT_CALCRECT);
pDC->SelectObject(pOldFont);
return nHeight;
}
// CHexViewerView drawing
void CHexViewerView::OnDraw(CDC* pDC)
{
CHexViewerDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CString strRender;
CFont* pOldFont;
CSize ScrolledSize;
//int MeasureFontHeight;
int nStartLine;
int nHeight;
CRect ScrollRect;
CPoint ScrolledPos = GetScrollPosition();
CRect rectClient;
GetClientRect(&rectClient);
//Determine how tall each line is
pOldFont = pDC->SelectObject(m_pFont);
nHeight = MeasureFontHeight(m_pFont, pDC);
//Find a starting line based on scrolling
//and current line size
ScrolledSize = CSize(rectClient.Width(),
rectClient.Height());
ScrollRect = CRect(rectClient.left, ScrolledPos.y,
rectClient.right,
ScrolledSize.cy + ScrolledPos.y);
nStartLine = ScrolledPos.y/16;
//Verify we are where we should be
ScrollRect.Top= nStartLine*nHeight;
if (pDoc->m_pFile != NULL)
{
int nLine;
for (nLine = nStartLine;
ScrollRect.top < ScrollRect.bottom;
nLine++)
{
if (!pDoc->ReadLine(strRender, 16, nLine*16))
break;
nHeight = pDC->DrawText(strRender, -1,
&ScrollRect,
DT_TOP | DT_NOPREFIX | DT_SINGLELINE);
ScrollRect.top += nHeight;
}
}
pDC->SelectObject(pOldFont);
// TODO: add draw code for native data here
}
void CHexViewerView::OnInitialUpdate()
{
CHexViewerDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CSize sizeTotal(0,pDoc->m_lFileSize);
SetScrollSizes(MM_TEXT, sizeTotal);
CScrollView::OnInitialUpdate();
}
// CHexViewerView printing
BOOL CHexViewerView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CHexViewerView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CHexViewerView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
// CHexViewerView diagnostics
#ifdef _DEBUG
void CHexViewerView::AssertValid() const
{
CScrollView::AssertValid();
}
void CHexViewerView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}
CHexViewerDoc* CHexViewerView::GetDocument() const // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CHexViewerDoc)));
return (CHexViewerDoc*)m_pDocument;
}
#endif //_DEBUG
// CHexViewerView message handlers
******************************************************
the associated header file code follows:
******************************************************
// HexViewerView.h : interface of the CHexViewerView class
//
#pragma once
class CHexViewerView : public CScrollView
{
protected: // create from serialization only
CHexViewerView();
DECLARE_DYNCREATE(CHexViewerView)
// Attributes
public:
CHexViewerDoc* GetDocument() const;
protected:
CFont* m_pFont;
LOGFONT m_logfont;
int m_nPointSize;
int m_nPageHeight;
int m_nPageWidth;
// Operations
public:
// Overrides
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual void OnInitialUpdate(); // called first time after construct
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
// Implementation
public:
virtual ~CHexViewerView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
DECLARE_MESSAGE_MAP()
};
#ifndef _DEBUG // debug version in HexViewerView.cpp
inline CHexViewerDoc* CHexViewerView::GetDocument() const
{ return reinterpret_cast<CHexViewerDoc*>(m_pDocument); }
#endif
**********************************************************************************
The ReadLine is iterated in the code segment from HexViewerDoc.cpp which follows:
**********************************************************************************
public:
BOOL ReadLine(CString& strLine,
int nLength,
LONG lOffset = -IL);
// TODO: Add your specialized creation code here
return TRUE;
I am unable to see what I am doing wrong. Can anyone help please ?
Thank you in advance. Joe
|
|
|
|
|
as you don't describe the error that occur, and where it does appear, i doubt anyone could help you...
TOXCCT >>> GEII power [toxcct][VisualCalc]
|
|
|
|
|
Thank you for looking at this, I thought I was being specific as to the error and included the segments of code these things came from.
|
|
|
|
|
you provide nowhere it crashes (show the lines instead of the whole code)....
thus, you don't even tell what is the desciption of the error C2039...
TOXCCT >>> GEII power [toxcct][VisualCalc]
|
|
|
|
|
I agree - my question is not well defined. I withdraw it.
I found the example and I was missing an entire code segment.
Thank you for your effort.
Joe
|
|
|
|
|