CWnd::ShowWindow as most think is perhaps the most used member function in CWnd the basic MFC window class. Sticking heavily to MFC has its disadvantages. Before coming to that, let me say this. SW_SHOW and SW_HIDE aren’t the only values that can be passed to the function.
- SW_HIDE: Hides this window and passes activation to another window.
- SW_MINIMIZE: Minimizes the window and activates the top-level window in the system’s list.
- SW_RESTORE: Activates and displays the window. If the window is minimized or maximized, Windows restores it to its original size and position.
- SW_SHOW: Activates the window and displays it in its current size and position.
- SW_SHOWMAXIMIZED: Activates the window and displays it as a maximized window.
- SW_SHOWMINIMIZED: Activates the window and displays it as an icon.
- SW_SHOWMINNOACTIVE: Displays the window as an icon. The window that is currently active remains active.
- SW_SHOWNA: Displays the window in its current state. The window that is currently active remains active.
- SW_SHOWNOACTIVATE: Displays the window in its most recent size and position. The window that is currently active remains active.
- SW_SHOWNORMAL: Activates and displays the window. If the window is minimized or maximized, Windows restores it to its original size and position.
Here, window activation, whether you need it or not is an important thought. Now here is the point. You can’t do any of these to a window created in a different thread. CWnd doesn’t have a function for this purpose. Its object oriented policies doesn’t allow it to have one I guess. A win32 API is here to save the day; ShowWindowAsync. This API can set the visibility state of a window created in another thread. So, if you are in a multi-threaded application be sure to use this API to hide or show your window in case of creation of the same from different threads.
First of all, CString doesn’t have a direct member function for this. But at times we will need this functionality and it is not that particular not to add it as a member if they can add functions like SpanIncluding, Replace etc. So lets discuss some ways which I found that can get the job done.
NO!!! This is not even a way to do it. One can think that what if we use SpanExcluding using the character we want as a delimiter and subtract the length of resultant string from the length of original string. Similar is the case for SpanIncluding. Now, listen to this! These functions will not return all the characters other than the delimiters. Its somewhat continuous. For example, calling SpanExluding for string “abc:cd” with delimiter “:” will return string “abc” only. Same is the case with SpanIncluding.
This is the most easiest way in terms of lines of code. Both function returns the count of the character that is replaced or removed. Take care to make a copy of the string before doing this. It involves editing of the string; especially the Remove function requires shifting of characters after the removed character. So this method is not suitable for large strings as it can cause performance hit.
I searched a lot for a function that works like magic in a single line of code. The conclusion as I could find was, There is no highway option! The best thing you can do is to use Find function in a while loop to find each character. Is that complex? here’s the code:
int CharacterCount( CString& csString_i, LPCTSTR sChar_i )
if( csString_i.IsEmpty() || L"" == sChar_i )
int nFind = -1;
int nCount = 0;
while( -1 != ( nFind = csString_i.Find( sChar_i, nFind + 1 )))
Got a better way? Please give your thoughts as comments.