Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
S

Stephen C Steel

@Stephen C Steel
About
Posts
11
Topics
0
Shares
0
Groups
0
Followers
0
Following
0

Posts

Recent Best Controversial

  • NetMessageBufferSend question
    S Stephen C Steel

    The problem is the unecessary & to take the address of the CString object. If you only need read access to the string data in a CString object, you can use the (LPCTSTR) conversion operator to get a pointer to the buffer. Then you'll have to use a cast, because NetMessageBufferSend() expects an LPBYTE rather than an LPCTSTR. That is, change (LPBYTE)&buffer, to (LPBYTE)(LPCTSTR) buffer, Casting away the constness of the LPCTSTR doesn't matter in this case, since NetMessageBufferSend () is only going to read the buffer. Stephen C. Steel Kerr Vayne Systems Ltd.

    C / C++ / MFC question com json workspace

  • TCP header checksum calculation
    S Stephen C Steel

    It may not be the problem, but you should be suspicous of any cross platform code using bitfields to pick out bits like this. The C standard does not define whether bitfields are allocated starting from the most or least significant bits of the variable. Different compilers may interpret this code differently!

    UCHAR HeaderLength :4; // Header length in 32-bit words

    Some compilers will use the high nibble, others the lower nibble. Its much safer to use masks and shifts:

    Either
    HeaderLength = (uchar_var & 0xF0) >> 4
    or
    HeaderLength = (uchar_var & 0x0F)
    as appropriate. Stephen C. Steel Kerr Vayne Systems Ltd.

    C / C++ / MFC sysadmin algorithms performance help question

  • problems with... MDI and Splitter::CreateView.
    S Stephen C Steel

    If you converting an SDI app where the view was split (two views onto the one document), you'd normally map that to an MDI application where each document frame (CMDIChildWnd) is split into two views. So, you don't want to modify your CMainFrame class (now derived from CMDIFrameWnd), you want to derived a class from CMDIChildWnd, add a splitter and override its virtual OnCreateClientClient() call. Then modify the CMultiDocTemplate created in the applications InitInstance() function to use your derived class rather than CMDIChildWnd. Stephen C. Steel Kerr Vayne Systems Ltd.

    C / C++ / MFC c++

  • Disable MRU file list
    S Stephen C Steel

    To eliminate the menu items, simply remove the ID_FILE_OPEN, ID_FILE_NEW and ID_FILE_MRU_FILE1 menu items from the the menu associated with you document template, but leave them in the default menu IDR_MAINFRAME (which is used when no document is active). You will also need to add a pair of ON_UPDATE_COMMAND_UI() handlers to your CDocument derived class to disable the ID_FILE_OPEN and ID_FILE_NEW commands when a document is active (this will prevent them being invoked via toolbar buttons or accelerator keys). When no document is active, you'll get the default behaviour (they will be enabled, since a handler function is defined). Stephen C. Steel Kerr Vayne Systems Ltd.

    C / C++ / MFC question

  • Scrollbars - How to get a certain style
    S Stephen C Steel

    Have a look at the MSDN documentation for the MFC CWnd member function CWnd::SetScrollInfo () (or the plain SDK function SetScrollInfo () which it invokes). SCROLLINFO scroll_info; scroll_info.cbSize = sizeof (scroll_info); scroll_info.fMask = SIF_PAGE | SIF_POS | SIF_RANGE; scroll_info.nMin = min; scroll_info.nMax = min; scroll_info.nPos = position; scroll_info.nPage = size_of_window; SetScrollInfo (SB_VERT, &scroll_info); Stephen C. Steel Kerr Vayne Systems Ltd.

    C / C++ / MFC tutorial question

  • MultiThreaded Progress bar
    S Stephen C Steel

    Multithreaded apps are simplest if only the main thread deals with drawing the UI, as in your second solution. There is, however, no need to introduce a new message handler in your dialog. Just have the worker thread post a messages directly to the progress control:

    Before starting the worker thread, save the window handle of the progress control in a variable that will be accessible to the worker thread (e.g. m_hProgressCtrl). Then in your worker thread code, post messages to update the progress control directly ::PostMessage (m_hProgressCtrl, PBM_SETRANGE, 0, MAKELPARAM (min, max)); ::PostMessage (m_hProgressCtrl, PBM_SETPOS, position, 0);

    Using ::PostMessage() (instead of the ::SendMessage() inside the CProgressBar member functions) means that the messages to update the progress controls will be queued for the main GUI thread. Stephen C. Steel Kerr Vayne Systems Ltd.

    C / C++ / MFC announcement

  • nebulous TRACE output
    S Stephen C Steel

    No, you aren't being paranoid - there is a bug in Visual Studio version 6.0. The TRACE macro ultimately uses OutputDebugString(), and along the way the application name gets prepended to the output. Visual studio has a filter that attempts to strip the application name before showing the text in the output window, but it is buggy.

    If I add the following code to my application

    TRACE (_T("Text before colon: Text after colon\n"));
    TRACE (_T("Text with parenthesis() before colon: Text after colon\n"));
    TRACE (_T("Text with open parenthesis( before colon: Text after colon\n"));
    TRACE (_T("Text with close parenthesis) before colon: Text after colon\n"));
    TRACE (_T("Text with (text inside parenthesis) before colon: Text after colon\n"));

    then the Visual Studio output window displays

    Text before colon: Text after colon
    Text with parenthesis() before colon
    Text with open parenthesis( before colon
    Text with close parenthesis) before colon: Text after colon
    Text with (text inside parenthesis) before colon

    Interestingly, if I select the text in the output window and paste it to notepad, I get

    Text before colon: Text after colon
    Text with parenthesis() before colonText with open parenthesis( before colonText with close parenthesis) before colon: Text after colon
    Text with (text inside parenthesis) before colon

    Stephen C. Steel Kerr Vayne Systems Ltd.

    C / C++ / MFC debugging question

  • nebulous TRACE output
    S Stephen C Steel

    No, you are probably getting bitten by a Visual Studio bug. Visual Studio filters the output of the OutPutDebugString() function, which the TRACE macro ultimately calls, before showing it in the output window in order to remove the application name (which otherwise gets added). However, the filtering is not too smart (at least with version 6.0), and it messes up the display of TRACE messages that includes both an open parenthesis "(" and a colon ":" in that order.

    When I add the following lines to my code

    TRACE (_T("Text before colon: Text after colon\n"));
    TRACE (_T("Text with parenthesis() before colon: Text after colon\n"));
    TRACE (_T("Text with open parenthesis( before colon: Text after colon\n"));
    TRACE (_T("Text with close parenthesis) before colon: Text after colon\n"));
    TRACE (_T("Text with (text inside parenthesis) before colon: Text after colon\n"));

    the Visual Studio output window displays

    Text before colon: Text after colon
    Text with parenthesis() before colon
    Text with open parenthesis( before colon
    Text with close parenthesis) before colon: Text after colon
    Text with (text inside parenthesis) before colon

    Intrestingly, if I select this text text in the output window and paste it into notepad, I get

    Text before colon: Text after colon
    Text with parenthesis() before colonText with open parenthesis( before colonText with close parenthesis) before colon: Text after colon
    Text with (text inside parenthesis) before colon

    Stephen C. Steel Kerr Vayne Systems Ltd.

    C / C++ / MFC debugging question

  • Multi-threading
    S Stephen C Steel

    A CWnd is really two distinct entities: a C++ object which you access using a CWnd* (typically this), and the Window object created by the system, which you access using a window hande (HWND). In order for MFC to make these two separate entities work like one, it must frequently find the HWND associated with a particular CWnd object, and or find the CWnd object associated with a particular HWND.

    The first operation, mapping from CWnd to the associated HWND is easy (just look up the m_hWnd member variable). This works fine in any thread.

    The second mapping, from HWND to CWnd* uses what is know as a handle map (a table which tracks which HWNDs were created by CWnd objets in that thread). This handle map is thread specific. Furthermore, since you can create HWNDs without even creating a CWnd object (e.g. dialog controls created by the dialog template), MFC sometimes creates generic temporary CWnd objects which you can use for the duration of a message handler to access these HWNDs via a CWnd object.

    The GetParent() member function just calls the Windows API funtion ::GetParent (m_hWnd), which returns the HWND of the parent. MFC then uses the (thread specific) handle maps to get a CWnd object associated with the parent HWND. If the parent window was not created via a CWnd object in the same thread, this will a temporary generic CWnd object. So in your case, when the second thread calls GetParent() it gets a pointer to a temporary generic CWnd and NOT the CMyCWndDerivedClass object that created the parent HWND in the first thread. If you cast the CWnd pointer to a pointer your derived class, you'll acess whatever memory just happens to sit after the temporary CWnd object.

    You can confirm this with

    CWmd *pWnd = GetParent ();
    ASSERT_KINDOF (CMyCWndDerivedClass, pWnd);

    This will work in your main thread, but fail in your derived thread.

    When working with multiple threads, it is much simpler to have only the original main thread responsible for the GUI. Worker threads can update data, and then use ::PostMessage() with an HWND to send a message the main thread (that created the HWND) that it should update its appearance. Since all windows messages are handled by the single GUI thread that creates all HWNDs, the handle maps work just as expected in a single threaded application. It you let multiple threads deal with HWNDs and CWnd objects directly, then you need to understand temporary and permanent handle maps AND when and how they are used by MFC. Believe me, the first approac

    C / C++ / MFC help question announcement

  • Which is The Best Way To Do It ???
    S Stephen C Steel

    Theres nothing wrong with nested classes. If CMySecondClass is only meaningful in the context of a CMyFirstClass object, then nesting the classes makes this clear.

    However, if the second class is an implementation detail that doesn't appear in the public interface, there is another technique that you may be able to apply. In the header file that declares CMyFirstClass you simply give a forward reference to CMySecondClass:

    class CMySecondClass; // forward declaration

    class CMyFirstClass
    {
    public:
    // public interface (CMySecondClass not mentioned)

    protected:
    CMySecondClass *m_p_instance;

    //protected or private member functions
    //which may include arguments of type
    //(CMySecondClass *) or (CMySecondClass&)
    };

    Now, both the declaration and implementation of CMySecondClass can be put in the implementation file for CMyFirstClass. This provides much stronger encapsulation than a nested protected or private class, since the details of CMySecondClass aren't even visible to code that uses CMyFirstClass (other than the fact that CMySecondClass exists). With a nested protected or private class, the details of CMySecondClass are visible, but access is restricted. Stephen C. Steel Kerr Vayne Systems Ltd.

    C / C++ / MFC question

  • How: each doc/view in own thread (advanced)
    S Stephen C Steel

    I don't think that a thread per doc/view is a good approach: there are a lot of complications, and it doesn't change the fact that only one thread can update the GUI at a time (the GDI calls are serialized). A much better approach, which I have used successfully in a couple of commercial applications, is to have one worker thread per doc, with the original GUI thread handling all the views. The worker threads can update each documents contents to reflect the input recieved via TCP/IP independently. You can run into some problems invoking window related functions from a worker thread because of the need to link C++ objects like CWnds with the associated Windows HWND (look up handle maps in the VC++ docs if you want the messy details). As long as the worker threads stick to updating the data in the CDocument derived class, you won't have problems. You may have to use critical sections or some other form of synchronization to stop the GUI thread from reading partially updated document contents though. I get around the handle map problem by defining a user message UM_UPDATE_VIEWS. The worker threads POST (not send) this message to the main window after changing the document contents. The main GUI thread processes this message, by calling CDocument::UpdateAllViews() for the CDocument derived object passed as a pointer in the LPARAM. This way UpdateAllViews() gets invoked by the main GUI thread, so there is no problem with handle maps. Stephen C. Steel Kerr Vayne Systems Ltd.

    C / C++ / MFC debugging help tutorial question
  • Login

  • Don't have an account? Register

  • Login or register to search.
  • First post
    Last post
0
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups