CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Jan 2009
    Location
    England
    Posts
    68

    [RESOLVED] using composition with scope issue

    Following on from my console project I decided to change a line in my method for SetColor() in my color class that calls a public method in my ConsoleApp class. I now get an error 35 C:\vmAPI\color.cpp `GetWriteHnd' was not declared in this scope? I can resolve this by replacing GetWriteHnd() with GetStdHandle(STD_OUTPUT_HANDLE), but what if I really needed access to GetWriteHnd()?

    As far as I know, the rule of thumb is a console has a color and a console has a cursor, thus I would place color and cursor class within the consoleApp class. I hope I am implementing this the correct way.

    Here is the cut down version of the code that shows the issue (Which I have indicated):
    Code:
    //-----------------------------------------------------------------------------
    // Project:      vmAPI Framework
    // Name:         ConsoleApp.h
    // Description:  Console application class definition file
    // Author:       Gerald Bates
    //-----------------------------------------------------------------------------
    #ifndef __CONSOLE_APP_H__
    #define __CONSOLE_APP_H__
    
    #include <windows.h>
    #include "color.h"
    
    namespace vm {
    
    class vmConsoleApp
    {  
    public:
       vmConsoleApp(int width = 79, int height = 49, char *consoleTitle = "NONAME");
       ~vmConsoleApp();
       
       // Some WIN32 API functions need to use these handles
       HANDLE GetWriteHnd() const;
       HANDLE GetReadHnd() const;
       HANDLE GetErrorHnd() const;
       
       void SetColor(int fg, int bg = BLACK) { cColor.SetColor(fg, bg); }
       
    private:
       HANDLE m_hOut;    // Handle to Write to the console
       HANDLE m_hIn;     // Handle to Read from the console
       HANDLE m_hError;  // Handle to std Error - directs to std out ?
       
       int  m_nLeft, m_nTop, m_nRight, m_nBottom;  // Console size
       char *m_pchConsoleAppTitle;                 // Console title
    
       int SetWriteHnd();
       int SetReadHnd();
       int SetErrorHnd();
       int CreateConsoleApp();
       int SetConsoleAppTitle();
       
       vmColor cColor;
    };
    
    } // namespace vm
    
    #endif // __CONSOLE_APP_H__
    Code:
    //-----------------------------------------------------------------------------
    // Project:      vmAPI Framework
    // Name:         ConsoleApp.cpp
    // Description:  Console application class impementation file
    // Author:       Gerald Bates
    //-----------------------------------------------------------------------------
    #include <iostream>
    #include "consoleApp.h"
    
    using namespace vm;
    
    //-----------------------------------------------------------------------------
    // Function/Method: vmConsoleApp(int, int, char *)
    // Description:     Console application class constructor
    // Return:          N/A
    //-----------------------------------------------------------------------------
    vmConsoleApp::vmConsoleApp(int width, int height, char *consoleTitle) 
       : m_nLeft(0), m_nTop(0), m_nRight(width), m_nBottom(height), 
         m_pchConsoleAppTitle(consoleTitle)
    {
       SetWriteHnd();  // Obtain and set the standard output handle
       SetReadHnd();   // Obtain and set the standard input handle
       SetErrorHnd();  // Obtain and set the standard error handle
       
       // If we don't have a valid output/input HANDLE, don't create a console app
       if((GetWriteHnd() != INVALID_HANDLE_VALUE && GetWriteHnd() != NULL) &&
          (GetReadHnd() != INVALID_HANDLE_VALUE && GetReadHnd() != NULL) ) 
          CreateConsoleApp();
    }
    
    //-----------------------------------------------------------------------------
    // Function/Method: ~vmConsoleApp()
    // Description:     Console application class destructor
    // Return:          N/A
    //-----------------------------------------------------------------------------
    vmConsoleApp::~vmConsoleApp() { }
    
    //-----------------------------------------------------------------------------
    // Function/Method: SetWriteHnd()
    // Description:     Set the standard output handle - Write
    // Return:          If SetWriteHnd() is successful then EXIT_SUCCESS is
    //                  returned, otherwise EXIT_FAILURE is returned
    //-----------------------------------------------------------------------------
    // Note:            If the function GetStdHandle() fails, the return value is
    //                  INVALID_HANDLE_VALUE.  To get extended error information,
    //                  call GetLastError().  If an application does not have
    //                  associated standard handles, such as a service running on
    //                  an interactive desktop, and has not redirected them, the
    //                  return value is NULL.
    //
    // MSDN - http://msdn.microsoft.com/en-us/library/ms683231(VS.85).aspx
    //-----------------------------------------------------------------------------
    int vmConsoleApp::SetWriteHnd()
    {
       m_hOut = GetStdHandle(STD_OUTPUT_HANDLE);
       
       if(m_hOut == INVALID_HANDLE_VALUE || m_hOut == NULL) {
          std::cout << "Error occurred obtaining the standard output handle."
                    << std::endl;
          return EXIT_FAILURE;
       }
       return EXIT_SUCCESS;
    }
    
    //-----------------------------------------------------------------------------
    // Function/Method: SetReadHnd()
    // Description:     Set the standard input handle - Read
    // Return:          If SetReadHnd() is successful then EXIT_SUCCESS is
    //                  returned, otherwise EXIT_FAILURE is returned
    //-----------------------------------------------------------------------------
    // Note:            See SetWriteHnd() above for more details
    //-----------------------------------------------------------------------------
    int vmConsoleApp::SetReadHnd()
    {
       m_hIn = GetStdHandle(STD_INPUT_HANDLE);
       
       if(m_hIn == INVALID_HANDLE_VALUE || m_hIn == NULL) {
          std::cout << "Error occurred obtaining the standard input handle."
                    << std::endl;
          return EXIT_FAILURE;
       }
       return EXIT_SUCCESS;
    }
    
    //-----------------------------------------------------------------------------
    // Function/Method: SetErrorHnd()
    // Description:     Set the standard error handle - Error
    // Return:          If SetErrorHnd() is successful then EXIT_SUCCESS is
    //                  returned, otherwise EXIT_FAILURE is returned
    //-----------------------------------------------------------------------------
    // Note:            See SetWriteHnd() above for more details
    //-----------------------------------------------------------------------------
    int vmConsoleApp::SetErrorHnd()
    {
       m_hError = GetStdHandle(STD_ERROR_HANDLE);
       
       if(m_hError == INVALID_HANDLE_VALUE || m_hError == NULL) {
          std::cout << "Error occurred obtaining the standard error handle."
                    << std::endl;
          return EXIT_FAILURE;
       }
       return EXIT_SUCCESS;
    }  
    
    //-----------------------------------------------------------------------------
    // Function/Method: GetWriteHnd()
    // Description:     Get the standard output handle - Write
    // Return:          HANDLE to standard output
    //-----------------------------------------------------------------------------
    HANDLE vmConsoleApp::GetWriteHnd() const { return m_hOut; }
    
    //-----------------------------------------------------------------------------
    // Function/Method: GetReadHnd()
    // Description:     Get the standard input handle - Read
    // Return:          HANDLE to standard input
    //-----------------------------------------------------------------------------
    HANDLE vmConsoleApp::GetReadHnd() const { return m_hIn; }
    
    //-----------------------------------------------------------------------------
    // Function/Method: GetErrorHnd()
    // Description:     Get the standard error handle - Error
    // Return:          HANDLE to standard error
    //-----------------------------------------------------------------------------
    HANDLE vmConsoleApp::GetErrorHnd() const { return m_hError; }
    
    //-----------------------------------------------------------------------------
    // Function/Method: CreateConsoleApp()
    // Description:     Creates a console application
    // Return:          If CreateConsoleApp() is successful then EXIT_SUCCESS is
    //                  returned, otherwise EXIT_FAILURE is returned
    //-----------------------------------------------------------------------------
    int vmConsoleApp::CreateConsoleApp()
    {
       SMALL_RECT sWindowSize = { m_nLeft, m_nTop, m_nRight, m_nBottom };
       COORD sBufferSize = { sWindowSize.Right, sWindowSize.Bottom };
       
       // The screen buffer is zero based so it's necessary to subtract 1
       sWindowSize.Right = sBufferSize.X - 1;
       sWindowSize.Bottom = sBufferSize.Y - 1;
       
       if(SetConsoleWindowInfo(m_hOut, TRUE, &sWindowSize) == 0) {
          DWORD err = GetLastError();
          CONSOLE_SCREEN_BUFFER_INFO SBInfo;
          GetConsoleScreenBufferInfo(m_hOut, &SBInfo);
          
          std::cout << "SetConsoleWindowInfo() Error: " << err << std::endl;
          std::cout << "The largest console window size on this system is "
                    << SBInfo.dwMaximumWindowSize.X << " X "
                    << SBInfo.dwMaximumWindowSize.Y << std::endl;
                    
          return EXIT_FAILURE;
       }
       else {
          SetConsoleAppTitle();
          SetConsoleScreenBufferSize(m_hOut, sBufferSize);
       }
       return EXIT_SUCCESS;
    }
    
    //-----------------------------------------------------------------------------
    // Function/Method: SetConsoleAppTitle()
    // Description:     Set console title
    // Return:          If SetConsoleAppTitle() is successful then EXIT_SUCCESS is
    //                  returned, otherwise EXIT_FAILURE is returned
    //-----------------------------------------------------------------------------
    int vmConsoleApp::SetConsoleAppTitle()
    {
       if( !SetConsoleTitle(m_pchConsoleAppTitle) ) {
          DWORD err = GetLastError();
          std::cout << "SetConsoleAppTitle() Error: " << err << std::endl;
          
          return EXIT_FAILURE;
       }  
       return EXIT_SUCCESS;
    Code:
    //-----------------------------------------------------------------------------
    // Project:      vmAPI Framework
    // Name:         Color.h
    // Description:  Color class definition file
    // Author:       Gerald Bates
    //-----------------------------------------------------------------------------
    #ifndef __COLOR_H__
    #define __COLOR_H__
    
    #include <windows.h>
    
    namespace vm {
    
    #define BLACK    0
    #define WHITE    FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
    #define RED      FOREGROUND_RED
    #define GREEN    FOREGROUND_GREEN
    #define BLUE     FOREGROUND_BLUE
    #define YELLOW   FOREGROUND_RED | FOREGROUND_GREEN
    #define ORANGE   FOREGROUND_RED | FOREGROUND_YELLOW
    #define CYAN     FOREGROUND_GREEN | FOREGROUND_BLUE
    #define MAGENTA  FOREGROUND_BLUE | FOREGROUND_RED
    
    #define BLINK    128
    
    class vmColor
    {  
    public:
       vmColor(int fg = WHITE, int bg = BLACK);
       ~vmColor();
       
       void SetColor(int fg, int bg);
       int  GetForegroundColor() const;
       int  GetBackgroundColor() const;
       
    private:
       int m_nForegroundColor;
       int m_nBackgroundColor;
    };
    
    } // namespace vm
    
    #endif // __COLOR_H__
    Code:
    //-----------------------------------------------------------------------------
    // Project:      vmAPI Framework
    // Name:         Color.cpp
    // Description:  Color class implementation file
    // Author:       Gerald Bates
    //-----------------------------------------------------------------------------
    #include "color.h"
    
    using namespace vm;
    
    //-----------------------------------------------------------------------------
    // Function/Method: vmColor(int fg, int bg)
    // Description:     Color class constructor
    // Return:          N/A
    //-----------------------------------------------------------------------------
    vmColor::vmColor(int fg, int bg) { SetColor(fg, bg); }
    
    //-----------------------------------------------------------------------------
    // Function/Method: ~vmColor()
    // Description:     Color class destructor
    // Return:          N/A
    //-----------------------------------------------------------------------------
    vmColor::~vmColor() {}
    
    //-----------------------------------------------------------------------------
    // Function/Method: SetColor(int fg, int bg)
    // Description:     Set the text color and background
    // Return:          void
    //-----------------------------------------------------------------------------
    void vmColor::SetColor(int fg, int bg)
    {
       WORD wColor = ((bg & 0x0F) << 4) + (fg & 0x0F);
       SetConsoleTextAttribute(GetWriteHnd(), wColor | FOREGROUND_INTENSITY); << ERROR HERE ??
       
       m_nForegroundColor = fg;
       m_nBackgroundColor = bg;
    }
    
    //-----------------------------------------------------------------------------
    // Function/Method: GetForegroundColor()
    // Description:     Get the current foreground color
    // Return:          int - Representing the current foreground color 
    //-----------------------------------------------------------------------------
    int vmColor::GetForegroundColor() const { return m_nForegroundColor; }
    
    //-----------------------------------------------------------------------------
    // Function/Method: GetBackgroundColor()
    // Description:     Get the current background color
    // Return:          int - Representing the current background color 
    //-----------------------------------------------------------------------------
    int vmColor::GetBackgroundColor() const { return m_nBackgroundColor; }
    What the mind can conceive it can achieve.

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: using composition with scope issue

    Since the compiler error is a simple line, all you needed to post is the actual implementation of the function that is giving the problem. The implementation of those other functions are not important and adds clutter to the real problem.

    As a matter of fact, You didn't even need to post the example you did post:
    Code:
    class vmColor
    {
        void CallSomeFunction();
    };
    
    class vmConsoleApp
    {
        public:
           void SomeFunction();
           vmColor c;
    };
    
    void vmColor::CallSomeFunction()
    {
        SomeFunction();
    }
    Is this what the code you posted boils down to?

    Regards,

    Paul McKenzie

  3. #3
    Join Date
    Jan 2009
    Location
    England
    Posts
    68

    Re: using composition with scope issue

    Paul, I am no expert so I thought it was better just to post what I did. In future I will try to replicate issues in a more compact way. I noticed you made vmColor c; public in vmConsoleApp so I tried it and I still got the same error? I am lacking in some basic understanding here! I tried making the classes friends of each other and that does not help either?
    What the mind can conceive it can achieve.

  4. #4
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: using composition with scope issue

    The vmColor object may be within the vmConsoleApp class, but that doesn't mean it can get unqualified access to vmConsoleApp methods. You have a few options:

    1) Make the methods in vmConsoleApp that it needs to access static.
    2) Make vmConsoleApp a singleton.
    3) Pass a pointer to the vmConsoleApp (typically "this") into the vmColor object to be used in the relevant call. Be careful if you do this in the vmConsoleApp constructor---you shouldn't try to access the pointer before the constructor exits!

  5. #5
    Join Date
    Feb 2005
    Location
    Denver
    Posts
    353

    Re: using composition with scope issue

    Taking Lindley's option #3 one step further...

    Since vmColor is a class that can stand completely on it's own, there's really no reason for it to have any knowledge of the vmConsoleApp object. Therefore, you might want to derive from the vmColor class with something like vmConsoleColor, then add a member reference to the vmConsoleApp class within this new derived class. Oh, and don't forget to change the member within your vmConsoleApp object from vmColor to vmConsoleColor.

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: using composition with scope issue

    Quote Originally Posted by Gerald Bates View Post
    Paul, I am no expert so I thought it was better just to post what I did. In future I will try to replicate issues in a more compact way.
    Every C++ compiler error can be duplicated with a few lines of code and empty or close to empty dummy classes.

    Anytime there is an issue with compilation, it is always wise to create a skeleton program like I did, see what the problem is, and given that small code, figure out a solution. It's better to do that than to have be inundated with member functions, comments, constants, and who knows what else that has nothing to do with the real problem. You will appreciate solving issues this way especially when you get to templated code, where the smaller example, the better.

    I know what I posted wasn't supposed to compile -- I posted so that I can get a better understanding of what the error is, and hopefully it illustrates succinctly what the problem is to others helping you.

    Regards,

    Paul McKenzie

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured