|
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
|
|
|
|
|
Hello,
I have added a variable to a class using add variable wizard. I wish to undo
or delete this addition - how do I do that? Thank you in advance.
Joe
|
|
|
|
|
you can do this manually by removing the member from the class.
there's nothing more to do.
if you wished to remove a function member added with class wizard, it would be a bit more difficult, especially when it is a message handler ; but as i understand, it is not your case, is it ?
TOXCCT >>> GEII power [toxcct][VisualCalc]
|
|
|
|
|
Thank you, I have removed it manually.
|
|
|
|
|
Now I get the error;
Just-In-Time Debugging
System.NullReferenceException
This is how I want it:
lblQ->Text = myQuestions[CurrentQuestion]->getQuestion()
myQuestions is a pointer class (declared: Question myQuestions __nogc[CurrentQuestion]; ) and getQuestion returns the string theQuestion. lblQ is btw just an Label (Label *lblQ)
and also I just tried two ways:
1:
lblQ->Text = new System::String(myQuestions[CurrentQuestion]->getQuestion();.c_str());
2:
myQuestions[CurrentQuestion]->setQuestion("hi");
string temp = myQuestions[CurrentQuestion]->getQuestion();
lblQ->Text = new System::String(temp.c_str());
Both gave the Just-In-Time debugger error.
Best Regards,
Hmmkk
|
|
|
|
|
myQuestions[CurrentQuestion] obviously == NULL ??? Is it a pointer and it needs to be allocated with new ?
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
Yes, I guess your quite right there.
I bet there is some major error in the code that could be much better done=s But after all this is just a test program that I'm making.
To give you some insider/background info about the program:
I'm trying to create a Quiz program. I create by a class MainForm that inherits Form (the system one). The MainForm consists pretty much only by a previous and next button for CurrentQuestion++ or -- then call UpdateScreen, where it's suppose to update the Label lblQs text to the "theQuestion" string in a Question class, which shall store questions and answers.
Is there anyway you could watch through my short code or do you have any idea of a sollution?
Best Regards,
Hmmkk
|
|
|
|
|
Hmmkk wrote:
But after all this is just a test program that I'm making.
Then it's a good chance to learn how to do things well There's never a reason to write sloppy code.
Having said that, this code doesn't look that sloppy to me, it's just a simple mistake, you're trying to access something and you need to check that it exists first, and create it if it doesn't and it needs to.
Hmmkk wrote:
Is there anyway you could watch through my short code or do you have any idea of a sollution?
At this stage, I don't even know what your list contains. HOwever, the solution is that you need to create an object to sit at the position you're trying to access, before you try to access it, as I said initially.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|