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
R

Roger Stoltz

@Roger Stoltz
About
Posts
1.4k
Topics
14
Shares
0
Groups
0
Followers
0
Following
0

Posts

Recent Best Controversial

  • sort a map by Value
    R Roger Stoltz

    NajaR12 wrote:

    Can anybody tell me how to sort a map based on the values.

    Why do you want to do that? Your desire suggests that you have misunderstood the purpose of a map. The key is supposed to be unique and the value is identified by its corresponding key so you may write code such as in order to retrieve the "box" associated with the key:

    Box& box = Map[key];

    However, if your "boxes" are unique you may use them as keys, e.g.:

    Map[box1] = key2;
    Map[box2] = key4;
    Map[box3] = key1;
    Map[box4] = key3;

    Consider using a std::list that is entry-sorted.

    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
    "High speed never compensates for wrong direction!" - unknown

    C / C++ / MFC tutorial

  • MFC UI Thread vs. Background Thread
    R Roger Stoltz

    «_Superman_» wrote:

    In MFC, you should not directly access UI elements from background threads.

    True.

    «_Superman_» wrote:

    Instead, you must send messages to the UI thread to get and set elements for the UI.
    Use can use SendMessage or PostMessage.

    Not entirely true. The reason for not accessing UI elements from another thread than the main thread is that you can quite easily create a deadlock situation. MFC classes for UI elements uses ::SendMessage() which will block until the message has been handled. If the main thread is not processing messages, possibly waiting for the thread that manipulates the UI element, the application will deadlock. This of course means that you cannot use ::SendMessage(), even if you call it directly, as it would create the same potential deadlock situation. ::PostMessage() must be used since it doesn't wait for the message to be handled. It is possible to use ::SendMessageTimeout() to avoid a deadlock situation, but if the call fails the receiving thread never gets the message.

    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
    "High speed never compensates for wrong direction!" - unknown

    C / C++ / MFC question csharp c++ visual-studio design

  • WaitForSingleObject
    R Roger Stoltz

    You probably have code looking like this in your thread:

    while( !m_bStopPushThread )
    {
    // Do whatever the thread is supposed to do
    }

    Chances are that the m_bStopPushThread has been optimized into a register in your thread controlling loop which means that the thread won't see the value change. This happens if the variable is not written to inside the loop. Building a debug version disguises this behaviour since optimizations usually are turned off. The remedy is to declare the variable m_bStopPushThread as volatile, which will tell the compiler to read its value from the variables memory address every time and not to hold its value in a register.

    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
    "High speed never compensates for wrong direction!" - unknown

    C / C++ / MFC debugging

  • Office converter DLLs and thread safety
    R Roger Stoltz

    Mattias G wrote:

    No, I wasn't hoping that calling LoadLibrary from within the thread (that later will call ForeignToRtf32) would in some magical way make the DLLs thread safe.

    Ok, I just couldn't find any other explanation to what you meant by "loading a DLL within the context of a thread". I interpreted your text as, whatever you meant by it, you thought it would prevent the problems you got when trying to use multiple threads when accessing the converter DLLs. But never mind. The only thing important is that you only need to call ::LoadLibrary() once for any DLL, subsequent calls will do nothing in practice. I have never used the DLLs you are trying to use, nor have I found anything useful trying to google it. So I have no idea what kind of functionality the DLLs expose, how to use them or what their function prototypes may look like. But that may not be necessary....

    Mattias G wrote:

    Still getting a lot of exceptions of types 0x800401FD CO_E_OBJNOTCONNECTED and 0x8001010E RPC_E_WRONG_THREAD (though I'm not using any COM interfaces explicitly in my application).

    Ok, so that means the DLLs uses COM in order to perform its ForeignToRtf32(). When you use COM from different threads you have to initialize COM for every thread that makes use of the COM library by calling e.g. ::CoInitialize() or one of its equivalents. Failure to do so may seem to work, but will cause unpredictable errors being very hard to realize that they originate from not initializing COM. In addition you have to have a message pump for every thread that creates a COM server. Initializing COM for a thread is called setting up an "apartment" and COM interfaces are not allowed to cross apartment boundaries without being properly marshalled by using e.g. ::CoMarshalInterThreadInterfaceInStream() or the GlobalInterfaceTable(GIT). Using a COM interface from an apartment without proper marshalling will result in the error RPC_E_WRONG_THREAD. Since you do not use any COM interfaces in your application I assume that the converter DLLs create the necessary COM servers "under the hood". This probably means that you cannot possibly marshal any COM interface to any other thread than the one you have used to do whatever initialization needed for the converter DLLs, which should be ex

    C / C++ / MFC tools question announcement workspace

  • Office converter DLLs and thread safety
    R Roger Stoltz

    Mattias G wrote:

    I'm running into difficulties when calling the exported conversion functions like ForeignToRtf32 in the multi-threaded version of my program, even if the libraries are loaded within the context of the calling thread. Does anyone know about the thread safety of these converters?

    If I understand your question/problem correctly, this has nothing to do with the converter DLLs. What do you mean by "loaded within the context of the calling thread"? I suspect you mean that you call ::LoadLibrary() for each thread that uses the library and you assume that it somehow will make calls to the DLL thread safe. Calling ::LoadLibrary() will load the desired DLL and map into the address space of the process the first time it is called. Subsequent calls to ::LoadLibrary() will only increment the reference count for the DLL in the process, which means that the code and variables will be shared among the calling threads. Calling ::FreeLibrary() will decrement the reference count. Read more here[^].

    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
    "High speed never compensates for wrong direction!" - unknown

    C / C++ / MFC tools question announcement workspace

  • Using MS Excel in VC++
    R Roger Stoltz

    QSMZ wrote:

    I want to use MS Excell in VC++ program for recording and plotting data.

    I'm not really clear on what you mean. Perhaps you would benefit from writing a DLL that you use from Excel for "data recording" depending on the where you get the "data" from. If you only want Excel for presentation reasons you may record and plot the data in your own application, but save it to an Excel file and draw charts in it using automation as Cédric said. I've done this about five years ago, but unfortunately that means I don't have any source code to give away and I've forgotten the details. However, it's not really that hard, just search for Excel and automation and you'll get a lot of useful results. One tip I remember though, use multidimensional safearrays for writing the data into the Excel sheet if you have a lot of data. I had about 10MB and writing it cell by cell took about 40 minutes. Using a multidimensional safearray it only took a couple of seconds.

    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
    "High speed never compensates for wrong direction!" - unknown

    C / C++ / MFC c++ tutorial question

  • Multithreading using AfxBeginThread
    R Roger Stoltz

    Eugen Podsypalnikov wrote:

    Wow, I did not know it ! Thank you very much, Roger !

    :) You're most welcome.

    Eugen Podsypalnikov wrote:

    As possible "workaround" could be also the usage of a limitation function:

    bool CYourDialog::IsWorking() {
    return m_bWorking;
    }

    Naah, I wouldn't count on that. This also depends on your optimization settings... ;) There's a compiler switch that tells the compiler to expand "any suitable" function as inline, which would generate the same code as if you would have referenced the variable directly even though you haven't declared the function explicitly as inline. Then you would be back to square one, with the possibility that the variable could be optimized into a register.

    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
    "High speed never compensates for wrong direction!" - unknown

    C / C++ / MFC csharp visual-studio help

  • Multithreading using AfxBeginThread
    R Roger Stoltz

    Perhaps it's just a typo, but if not you should be aware of the following: There's a big risk the thread will never exit as you've failed to declare the m_bWorking variable as volatile. It depends on your optimization settings. The compiler may choose to hold the variable in a register in the while-loop, not reading it from its actual memory location since it's not being modified in the while-loop. Declaring it as volatile will tell the compiler that the variable must be read from its memory location and cannot be optimized into a register.

    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
    "High speed never compensates for wrong direction!" - unknown

    C / C++ / MFC csharp visual-studio help

  • ATL compiler error
    R Roger Stoltz

    DavidCrow wrote:

    Previously, my CMyEventHandler class was derived from, among others, IWMPEvents, and I thought I had the appropriate IWMPEvents entry in the BEGIN_COM_MAP() macro. So I don't understand what the Media Player server could have been asking for that I was not providing/exposing.

    Yep, but as I understand it you got a compiler error at that time and not the runtime error that says the server cannot find the IWMPEvents interface in your client.

    DavidCrow wrote:

    They were added by the ATL Object Wizard.

    Okay. You probably used the wizard that is used for creating COM servers. But that's a minor problem, it just made me unsure of what you were trying to do. Never mind.

    DavidCrow wrote:

    How does moving the IWMPEvents interface to CMyEventSink differ from having it in CMyEventHandler?

    In your case it doesn't really make a difference in practice. However, I consider the nested class a more versatile solution or design pattern. One major benefit is to avoid circular references. Consider COM server A that creates another COM server B. A is created by the client C. B exposes a source interface, e.g. a connection point, for which A implements an event sink and register itself for receiving COM events from B. When B requests the interface for the event sink it will increment the reference of A according to COM rules. The problem is that when C wants to destroy A by releasing its last reference, the A reference counter will not reach zero as B still holds a reference to it. This will force a kind of catch 22 situation where neither A nor B will get their last reference released. The root cause is that both C and B uses the same object for reference counting in A. One solution is to create another object, like a nested class inside A, that serves as event sink. My point is that if you master this way of creating an event sink, you'll probably never have to do it in another way. I also consider it more clean from a design point of view.

    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
    "High speed never compensates for wrong direction!" - unknown

    C / C++ / MFC c++ help question

  • ATL compiler error
    R Roger Stoltz

    DavidCrow wrote:

    Roger Stoltz wrote:

    The error returned to the server is most likely E_NOINTERFACE.

    Which is 0x8004002. The error that I am getting is 0x80040202.

    Well, you're not the server which means that what I'm talking about is the error message your client is sending the Media Player when the Media Player server asks for your implementation of the IWMPEvents source interface. David, now I'm just guessing, but I get the impression that you've misinterpreted some part of what I've been trying to explain and I cannot really figure out what part... Most likely I haven't been very clear on the subject so let me try again. It looks like you've opted for my suggestion based on a nested class to use as an event sink, otherwise I don't understand your pEventHandler variable as it should be this in the call to Advise(). Whatever pEventHandler points to doesn't seem to expose the IWMPEvents interface judging from the error you got. If you are using the nested class version you should remove the IWMPEvents entry from the COM_MAP in the outer class and put it into the presumably non-existing COM_MAP of the inner/nested class. You can think of the COM_MAP as being traversed when QueryInterface() is called on your object. I don't understand why you're exposing the IMyEventHandler and IDispatch interfaces from your class. Perhaps you did it intentionally or it could be a misunderstanding. Who is going to use those interfaces? If you're not trying to develop a COM server yourself that exposes e.g. IMyEventHandler, then I guess it shouldn't be there in the first place. However, now that you've provided an important part of your class declaration I can try and patch together a declaration based on the nested class scenario for you. I hope things will clear up afterwards. It should look something like this:

    class ATL_NO_VTABLE CMyEventHandler :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CMyEventHandler, &CLSID_MyEventHandler>,
    public IDispatchImpl,
    {
    public:
    CMyEventHandler() {}

    DECLARE_REGISTRY_RESOURCEID(IDR_MYEVENTHANDLER)

    DECLARE_PROTECT_FINAL_CONSTRUCT()

    BEGIN_COM_MAP(CMyEventHandler)
    COM_INTERFACE_ENTRY(IMyEventHandler)
    COM_INTERFACE_ENTRY(IDispatch)
    END_

    C / C++ / MFC c++ help question

  • ATL compiler error
    R Roger Stoltz

    DavidCrow wrote:

    MSDN article Q183216 talks about my sink object (CMyEventHandler) may be missing something that QueryInterface() is looking for. As far as I can tell, my sink object has implemented all of the IWMPEvents methods.

    The article Q183216 is talking about when the server is querying for the source interface, IWMPEvents in your case, and the client who is supposed to implement the interface responds with an error that says the interface is not supported/implemented. The error returned to the server is most likely E_NOINTERFACE. For this to be applicable in your situation you must have forgotten to put the entry in the COM_MAP, but as I understand from your previous posts you've already got that in place. This made me wonder if the server might be requesting another interface such as IDispatch, e.g. if the IWMPEvents inherits from IDispatch, but as far as I can tell with the OLEView tool this is not the case. Can you successfully "find" the connection point with IConnectionPointContainer::FindConnectionPoint()? Are you possibly making the call from a worker thread? If you are, does it work if you try to do this from your main thread?

    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
    "High speed never compensates for wrong direction!" - unknown

    C / C++ / MFC c++ help question

  • ATL compiler error
    R Roger Stoltz

    DavidCrow wrote:

    It appears that I have steps 1-5 in place. Do you agree?

    Nope, I don't agree. Not unless you've altered the code you presented earlier where you tried to create an instance of CMyEventHandler by calling CreateInstance() into what I suggested, e.g. using new.

    DavidCrow wrote:

    Does the duck sample talk about how to avoid the GUID error that I'm battling?

    Nope. The question is irrelevant as a CLSID for CMyEventHandler won't be needed when you create a CMyEventHandler on the heap or the stack. Note that what the compiler complains about is a missing "Class ID", CLSID, since it refers to the 'object' CMyEventHandler. The CLSID is the identity of the server one is trying to create with a call to CreateInstance(). This is not the same as the identity of the interface you're trying to use called "Interface ID" or IID, which also has a Globally Unique IDentifier assigned to it. Your CMyEventHandler declaration should look something like this:

    class ATL_NO_VTABLE CMyEventHandler :
    public CComObjectRootEx<CComSingleThreadModel>,
    public IWMPEvents
    {
    public:
    BEGIN_COM_MAP( CMyEventHandler )
    COM_INTERFACE_ENTRY(IWMPEvents)
    END_COM_MAP()

    public:
    	/\* Here goes declarations of the functions in the IWMPEvents interface \*/
    

    };

    The code where you create the Media Player server should look something like this, as partially described in the article:

    CComPtr<IWMPPlayer> spWMPPlayer;
    CComPtr<IConnectionPoint> spConnectionPoint;
    DWORD dwAdviseCookie;
    HRESULT hr;

    /* I don't know the CLSID or ProgID of the Media Player server as I'm currently sitting on an
    ** Ubuntu machine at home, but let's just assume you've successfully created the Media Player
    ** server and you have a valid interface pointer for it: spWMPPlayer.
    ** Anyway you seem to have taken care of that already. ;-)
    */

    /* Create the CMyEventHandler object */
    CMyEventHandler* pMyEventHandler = new CComObject<CMyEventHandler>;

    /* Get the connection point */
    CComQIPtr<IConnectionPointContainer, &__uuidof(IConnectionPointContainer)> spConnectionContainer( spWMPPlayer );
    if( spConnectionContainer )
    {
    hr = spConnectionContainer->FindConnectionPoint( __uuidof(IWMPEvents), &spConnectionPoint )
    if( pMyEventHandler && SU

    C / C++ / MFC c++ help question

  • ATL compiler error
    R Roger Stoltz

    DavidCrow wrote:

    It's just getting notified of events that's troubling me.

    Okay... Basically this is what you have to do:

    1. Implement a class that derives from the event interface you're interested in and put the interface in the COM_MAP. As I understand it you've already done this part.
    2. When you've successfully created the Media Player server and got an interface pointer (IWMPPlayer), you create an instance of the class mentioned above; not by using CreateInstance(), use new or similar (you know what I mean).
    3. Ask IWMPPlayer for the IConnectionPointContainer interface as described in the article.
    4. Find the connection point you want, IWMPEvents, by calling IConnectionPointContainer::FindConnectionPoint() and you should get an IConnectionPoint interface in return as described in the article.
    5. Register your class as an event listener by calling IConnectionPoint::Advise() and provide a pointer to your instance of your CMyEventHandler. Store the cookie and the IConnectionPoint interface pointer as you'll need it when you unregister from the server.
    6. You should be all set to catch events from Media Player!
    7. Remember to call IConnectionPoint::Unadvise() when you're done.

    The ATLDuck sample[^] explains how to set up connection point further. It gives you a complete working example and not just some code snippets.

    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
    "High speed never compensates for wrong direction!" - unknown

    C / C++ / MFC c++ help question

  • ATL compiler error
    R Roger Stoltz

    DavidCrow wrote:

    My overall intent is to open a .mp3 file using the Windows Media Player COM object, and then read some information from one of the headers.

    Perhaps this is not what you'd like to hear/read, but wouldn't it suffice to read the mp3 file from your application if you're only interested in the header? I guess you've thought about this alternative already and discarded it. If not, you may find this[^] or this[^] useful. I don't know what header information you're looking for. More about the Media Player solution... Have you had a look at this article[^] about handling Media Player events in C++? Provided that you successfully can create the Media Player server, you should be able to find something in the article above that you can use. You should also have a look at the ATL sample that demonstrates connection points: ATLDuck.

    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
    "High speed never compensates for wrong direction!" - unknown

    C / C++ / MFC c++ help question

  • ATL compiler error
    R Roger Stoltz

    DavidCrow wrote:

    a .idl file was created and it has a GUID in it for the IMyEventHandler interface.

    David, I don't get exactly what you're trying to do. It seems like you're trying to create COM server and register something else that you have developed (CMyEventHandler?) for receiving COM events. Right? What I'm trying to figure out is why you're trying to create an instance of your CMyEventhandler... Is it really a COM server? If so, from where is it created and does the header files created have a CLSID for it? Usually you would create a COM server with e.g. ::CoCreateInstance(), or one of its equivalents. You provide the CLSID for the server, the IID for the desired interface and a pointer to store the interface pointer in if the call was successful. If the server produces COM events that the client is interested in, the client uses a mechanism in the server to register itself as an event listener (Advise()?). From your explanation I don't see the above happening, a part from calling CreateInstance but for what looks to me as the "wrong" object. Can you elaborate on this a bit further David?

    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
    "High speed never compensates for wrong direction!" - unknown

    C / C++ / MFC c++ help question

  • AT commands gives +CMS Error: 303 for Sony Ericssion Phones.
    R Roger Stoltz

    Le@rner wrote:

    PLease tell me general method or command set which is applicable for all mobiles.

    I guess that would be the Hayes command set[^].

    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
    "High speed never compensates for wrong direction!" - unknown

    C / C++ / MFC help question

  • AT commands gives +CMS Error: 303 for Sony Ericssion Phones.
    R Roger Stoltz

    Le@rner wrote:

    is there defferent AT commands for diffrent type of Mobile Phones?

    Yes, even different phones from the same vendor differ in what AT command set they support. To my knowledge, the specifications for supported AT commands are company confidential.

    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
    "High speed never compensates for wrong direction!" - unknown

    C / C++ / MFC help question

  • Message Queues
    R Roger Stoltz

    Yeah, I'm good too. :-) Looks like I've just been assigned to something that looks very promising and may last for at least this year. So I'm happy. :-D

    Rajesh R Subramanian wrote:

    I'm not sure I got your queries right; let me know if I've been unclear somewhere.

    Ohhh, now you're asking for it my friend... ;)

    Rajesh R Subramanian wrote:

    I said a Window (the program) can have more than one Message Queue running

    I think this adds to the confusion. It looks like you're saying that a window is a program and of course it's not. To my understanding the question was never about whether an application can have more than one thread that has a message queue, or if an application may have multiple message queues. I interpret the OP's question in short terms as "does the message queue belong to a thread or a window" and the correct answer for that in equally short terms can only be "the thread".

    Rajesh R Subramanian wrote:

    I think that the term "UI thread" is horribly misleading, as a UI thread need not have a UI associated with it at all!

    Agreed at least a 100%! The concept of "UI-thread" only makes sense as it is necessary to process messages when GUI objects are created in the thread.

    Rajesh R Subramanian wrote:

    I can of course re-route the messages internally if I have additional UI threads running within.

    Yep, that's possible. But that's more related to ::PostThreadMessage() than window objects. Never mind, it's beside the point. I think the essential part of my point is that a window will only receive messages in the message queue that belongs to the thread that created the window. We can look at it this way: You send messages to windows by calling either ::SendMessage() or ::PostMessage(). They both need a window handle as argument. The window retrieves the messages sent to it by calling e.g. ::GetMessage(), which also needs a window handle. The point I'm trying to make can be found in the documentation for ::GetMessage() that says "the window must belong to the calling thread". This means that a UI-thread can only have one message queue and since a window can only belong to one thread, it can only have one message queue where messages sent to the window will be pu

    C / C++ / MFC data-structures

  • Message Queues
    R Roger Stoltz

    Hi Rajesh, Hope you're good and having fun! ;-) I got a little confused when I read your post....

    Rajesh R Subramanian wrote:

    As a result, a window can have more than one message queue, if it has multiple UI threads running within.

    Ummm...:confused: Not really sure what you mean here, but to my knowledge a window is only served by one message queue and pump in the sense that messages sent to the window will be queued in the message queue that belongs to the thread that created the window in the first place. On the other hand, you may of course spawn new UI-threads from your "window" and create new windows in the newly created thread. Or, do you really mean that messages sent to a window may end up in different threads/queues?

    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
    "High speed never compensates for wrong direction!" - unknown

    C / C++ / MFC data-structures

  • Message Queues
    R Roger Stoltz

    sharda.bhagwatkar wrote:

    Are there separate message queues for each window or each thread has its own message queue.

    A window does not have a message queue of its own. Multiple windows may be served by the message queue and message pump in the User Interface thread that the windows are created from. In e.g. a simple dialog-based application there is initially only one thread and even if you create new windows, they will be served by the message queue in that thread. Keep in mind that all those small buttons and other controls are windows as well. Every thread spawned is initially without a message queue. There are two kind of threads: worker threads and User Interface threads. Worker threads won't have a message queue, but UI-threads will get a message queue created when a message is sent, or posted, to the thread. Read more about it in this small section[^].

    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
    "High speed never compensates for wrong direction!" - unknown

    C / C++ / MFC data-structures
  • Login

  • Don't have an account? Register

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