Hottest Forum Q&A on CodeGuru - week of March 1st, 2004


Introduction:

Lots of hot topics are covered in the Discussion Forums on CodeGuru. If you missed the forums this week, you missed some interesting ways to solve a problem. Some of the hot topics this week include:


Why does my automation control does not work properly? (top)

Thread:

Johndc has some problems with his automation control. It worked before adding a simple resource to the project. But now, it does not! Do you know what the problem can be?

I have a problem with my automation program.

I created a new MFC DLL by using the VS6 MFC AppWizard (DLL) and
started building my automation control. I tested my program by
loading my automation and everything was working fine. Then, I
added a resource to my project and my automation control has not
been working since.

I did some research and found that the link file myprogram.res had
changed size to less than before. I opened the old one and
compared it with the new file that was created when I compiled and
found that a type "TYPELIB" was missing.

Can anyone tell me what that "TYPELIB" type is and why my automation
control does not work anymore?

BTW, the DLL gets registered fine. It's just when I try to use it it
will the error with "Could not load the selected Type Library"...
appear.

This is a very interesting question. How can this happen that a simple resource causes such a problem? Sam Hobbs suggests the following:

"I think you need to add a class. I don't know what you need to do to make the class support Automation, but you need to do that somehow. However you do it, you should use ClassWizard to create the class. Then, use the Automation tab of the ClassWizard to add properties and/or methods. I am nearly certain that the type library will be created automatically when you do that."


Why do I get the error: Can't open afxhelp.hm? (top)

Thread:

d0153030 is working on project that works perfectly. But, he still gets one error.

I am getting the following error while compiling the project. Still,
the program is executing fine. No problem. (Why) and how can I
remove this error:
--------------Configuration: Project - Win32 Debug---------------
Making help file...
hlp\Project.hpj(1) : error:
Microsoft (R) Help Compiler
HCRTF 4.03.0002
Copyright (c) Microsoft Corp 1990 - 1995. All rights reserved.
project.hpj
HC5011: Error: Project.hpj :
Cannot open the file "afxhelp.hm."

Project.exe - 2 error(s), 0 warning(s)

Well, that requires the afxhelp.hm file to be included. It is generated by app wizard hpj (help project file) that contains an include statement that should be a fully qualified path, not just a filename.

If this is generated without a full path, you probably have a problem with a Registry entry.

You have two choices:

  • One is to correct the problem manually by editing the #include line.
    Help Workshop does not use the INCLUDE environment variable to search for files. You have to specify the full path. It should look like this:

    #include <C:\Microsoft Visual Studio\VC98\MFC\include\afxhelp.hm>
    unless you have changed install defaults.

  • A second choice would be checking the Registry:
    HKEY_CURRENT_USER\Software\Microsoft\DevStudio\6.0\General
    This contains a MFCPath32Bit key with the value set to a MFC folder path, something like this:

    C:\Program Files\Microsoft Visual Studio\VC98\MFC
Note: If you have changed the install defaults, you would have to adjust path the appropriately; otherwise, it will not work!


Why do my Overloading -> and * operator not work properly? (top)

Thread:

iangoldby does have some problems with overloading of the -> and * pointer. Take a look at his interesting problem.

I have a strange problem with overloading the -> and * operators.
I'm trying to do this to make dereferencing a pointer to the class
intrinsically safe. I think the problem is the same in both cases,
so I'll describe the * operator:

In myreal.h:
const CMyReal& operator * (void);
and in myreal.cpp
const CMyReal& CMyReal::operator * (void)
{
    if (this)
        return *this;
    else
        return CMyReal::Bad;
}
where CMyReal::Bad is a static object representing Not-A-Number.
Now, when I write:
CMyReal *myreal = NULL;
float x = (myreal->operator *()).value();
it calls my overloaded operator function and I get Not-A-Number, as
expected. But if I write the following code:
float x = (*myreal).value();
It doesn't call the overloaded operator function but tries to
dereference the NULL pointer directly and I get an access violation
error.

Similarly, (myreal->operator ->())->value() is okay, but
myreal->value() fails with an access violation.

Any idea what I am doing wrong?

Unfortunately, your override of operator * in your CMyReal class only affects the use of a * when you have an object of the CMyReal type. You are trying to use it on a pointer to a CMyReal, which is not the same type.

As soon as you introduce a raw pointer, you aren't going to be able to override the operator * and get a dereference of the raw pointer to call your overridden routine.

I don't know whether this is at all useful to you, but you could wrap the pointer inside of a class—something like this:

class CMyRealPtr
{
   private:
      static CMyReal Bad;
      CMyReal* m_ptr;

   public:
      CMyRealPtr( CMyReal* ptr = NULL ) : m_ptr( ptr ) {}

      const CMyReal& operator*()
      {
         if ( m_ptr )
            return *m_ptr;

         return Bad;
      }
};


CMyReal CMyRealPtr::Bad( -1 );

int main()
{
   CMyRealPtr myreal = NULL;
   float x = (myreal.operator *()).value();
   float y = (*myreal).value();

   return 0;
}

Now, the pointer is not a raw pointer anymore, but instead is an object. The explicit call to operator * and the dereference of the myreal object both call the operator* member of CMyRealPtr.

Thanks to jwbarton for his beautiful explanation.


How can I textout the value of a pointer of an array? (top)

Thread:

lwong is curious about the usage of a pointer of an array with the TextOut function.

How do I textout the value of a pointer of an array?

You need a pointer to a char array and x and y values that represent the upper left corner of where the text will be displayed.

CClientDC dc(this);
char *Text=new char[128];
strcpy(Text,"Test string");
dc.TextOut(10,10,Text,strlen(Text));
delete []Text;

The above would display the 'Test string' string 10 pixels from the top and 10 pixels from the left of the client area defined by the DC.

CClientDC dc(this);

CRect WndRect;
GetClientRect(&WndRect);

char* Text=new char[128];
strcpy(Text,"Test string");

CFont NewFont;
NewFont.CreatePointFont(100,"Courier New",&DC);
CFont * OldFont=dc.SelectObject(&NewFont);

CSize TextSize=dc.GetTextExtent(Text,strlen(Text));

CPoint TextPoint;
TextPoint.cx=(WndRect.CenterPoint().x-(TextSize.cx/2));
TextPoint.cy=(WndRect.CenterPoint().y-(TextSize.cy/2));

dc.TextOut(TextPoint.cx,TextPoint.cy,Text,strlen(Text));

dc.SelectObject(OldFont);
delete []Text;

The above would display the string 'Test string' in the center of the client area in a Courier New font with a point size of 10.

Unfortunately, the pointer of an array is not of the char type; instead, it is a float. How do you convert between them? And, what about CClientDC dc(this)? Does that lead to flickering?

Take a look at the full thread to get the answer.




About the Author

Sonu Kapoor

Sonu Kapoor is an ASP.NET MVP and MCAD. He is the owner of the popular .net website http://dotnetslackers.com. DotNetSlackers publishs the latest .net news and articles - it contains forums and blogs as well. His blog can be seen at: http://dotnetslackers.com/community/blogs/sonukapoor/

Comments

  • Can we create editable list control in MFC?

    Posted by ketu0001 on 10/22/2007 04:18am

    Can we create editable list control in MFC?
    example -
    I want to store employee ID and employeename in list control.
    I want to modify the functionality in such a way that on double clicking on an item in the list, it should be editable. Can anybody please help me in this?

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • Hundreds of millions of users have adopted public cloud storage solutions to satisfy their Private Online File Sharing and Collaboration (OFS) needs. With new headlines on cloud privacy issues appearing almost daily, the need to explore private alternatives has never been stronger. Join ESG Senior Analyst Terri McClure and Connected Data in this on-demand webinar to take a look at the business drivers behind OFS adoption, how organizations can benefit from on-premise deployments, and emerging private OFS …

Most Popular Programming Stories

More for Developers

RSS Feeds