Well, I don’t know the answer. It’s not well documented. From the discussions went under comp.lang.C++ group, what I understood is that
STL containers in general provide both of these member functions. size() tells you how many elements there are currently in the container, and max_size() gives you an estimate of the maximum possible number of elements that you could put into the container.
As array is of having fixed number of elements, both functions acts similar and returns same value. Thanks Pete Becker
The C++ Standard Template Library (STL) provides a framework for processing algorithms on different kind of containers. However, ordinary arrays don’t provide the interface of STL containers (although, they provide the iterator interface of STL containers). As replacement for ordinary arrays, the STL provides class std::vector. However, std::vector<> provides the semantics of dynamic arrays. It manages data to be able to change the number of elements. This results in some overhead in case only arrays with static size are needed.
New new C++ provides a new class called array which is static in usage but able use a standard C++ container. It also provides access to the underlying data. Thus it’s possible to use as raw array pointers. See the sample snippet below to too see how to use array class. A better documentation can be found at boost::array page.
[sourcecode language='cpp']
// using array class
void FooTR1Array()
{
std::tr1::array arr = {1,2,3,4,5};
using namespace std;
cout << "Contents of array " <
copy( arr.begin(), arr.end(),
ostream_iterator(std::cout,”\t”));
cout << "Size of array - " << arr.size() <
cout << "Front of array - " << arr.front() <
cout << "Front of back - " << arr.back() <
cout << "Array max Size- " << arr.max_size() <
cout << "Array [3] - " << arr[3] <
cout << "First element using pointer - " << *arr.data() <
// array swapping - both arrays should have same properties and size
std::tr1::array arrNew = {111,222,333,444,555};
In this installement, let’s see how to handle the events of the ribbon control. I strongly reconmmend you to read the previous post on the basics of ribbon the way it’s being created. This is a continuation of the previous post.
To handle the events, the IUICommandHandler interface is implemented by the application and defines the Command handler methods for framework events. The following function has to be implemented in the derived class.
Execute
Executes or previews the Commands bound to the Command hand`ler.
UpdateProperty
Sets a property value for a bound Command, for example, setting a Command to enabled or disabled depending on the state of a View.
For each Command in a View(Application.Views in the XML file), the Ribbon framework requires a corresponding Command handler in the host application. A new handler or an existing handler must be bound to the Command through the IUIApplication::OnCreateUICommand notification method. This method is executed when the UI component is created. It’s possible create new command handler by querying IID_PPV_ARGS intefac. Any number of Commands can be bound to a Command handler.
The Command handler serves two purposes. First, it can update the values of properties for any command to which it is bound, such as setting a command to enabled or disabled. Second, it can execute or preview any commands to which it is bound.
In the previous instalment we’ve seen CRibbonImplementer class. So here we will be modifying the class. We’ll be creating the the handler
Step 1 – Include the generated .h file contains control IDs to the implementation .h/.cpp file of CRibbonImplementer
Step 2 & 3 – Derive ribbon implementer class from IUICommandHandler and add the interface to COM Map
Step 4 – Modify OnCreateUICommand function and add UI Handler on creating the control.
Step 5 - Add Execute handler to get notification when the button is clicked. This is like the normal message loop of a Win32 message loop system.
The final Step (6 ) – It’s necessary to implement IUICommandHandler::UpdateProperty as the base class doesn’t provide any implementations. We can leave this interface as unimplemented.
The full Source code is given below. There’s no change in the other part of source code.
[sourcecode language='cpp']
#include “stdafx.h”
#include
#include
#include
#include
// Step 1: Include menu ribbon resource.h
#include “MenuRibbonRes.h”
class CRibbonImplementer:
public CComObjectRootEx,
public IUIApplication,
// Step 2: derive fromm IUICommandHandler
public IUICommandHandler
{
public:
BEGIN_COM_MAP(CRibbonImplementer)
COM_INTERFACE_ENTRY(IUIApplication)
// Step 3: IUICommandHandler add in teh COM Map
COM_INTERFACE_ENTRY(IUICommandHandler)
END_COM_MAP()
STDMETHOD(OnCreateUICommand)(UINT32 nCmdID, __in UI_COMMANDTYPE typeID, __deref_out IUICommandHandler** ppCommandHandler)
{
// Step 4: IUICommandHandler
// if my button is being created, the handler is created and attached
if (nCmdID == cmdMyButton)
{
return QueryInterface(IID_PPV_ARGS(ppCommandHandler));
}
return E_NOTIMPL;
}
/* Step 5: Implement execute function.
This function will be called on clicking
the controls attached to command handler */
STDMETHODIMP Execute(UINT nCmdID,
UI_EXECUTIONVERB verb,
__in_opt const PROPERTYKEY* key,
__in_opt const PROPVARIANT* ppropvarValue,
__in_opt IUISimplePropertySet* pCommandExecutionProperties)
{
HRESULT hr = S_OK;
switch (verb)
{
case UI_EXECUTIONVERB_EXECUTE:
if (nCmdID == cmdMyButton)
{
MessageBox(NULL, _T( “Clicked on My Button!” ),
_T(”My Button Execute”), MB_OK);
}
break;
}
The Office 2007 changed the the conventional menu to a new vibrant, beautiful, and useful(??) ribbons. After that many third party libraries (both commercial and non commercial) vendors provided components to integrate ribbons to our application. Finally Microsoft heed the MFC guys crying a loud to get support on ribbons. Microsoft included Ribbons and other office style controls with MFC Feature Pack for Visual Studio 2008.
The following figure depicts the anatomy of a typical Ribbon.
In the new version of Windows, Windows 7 , it supports ribbons natively and Microsoft allows us to create it using Ribbon Frame Work. Few Accessories application like MS Paint, Wordpad etc. got UI lift with Windows Ribbons.
Developer can create ribbon using Ribbon Markup Language (similar to XML format). For the Windows Ribbon framework (Ribbon) to consume the Ribbon markup file, the markup file must be compiled into a binary format resource file. A dedicated Ribbon markup compiler, the UI Command Compiler (UICC), is included with the Microsoft Windows Software Development Kit (SDK) (7.0 or later) for this purpose. In addition to compiling the binary version of the Ribbon markup, the UICC generates an ID definition header file that exposes all markup elements to the Ribbon host application and a resource file that is used to link the binary markup to the host application at build time.
The workflow for the Ribbon is as follows
OK let’s create a simple ribbon step by step. You should have Windows 7 SDK installed and Visual Studio 2005 or above is required to compile this application. I’m taking a MFC Application do this instead of a Win32 application. I’m just creating a new MFC Dialog Based Application.
We can categorize the ribbon creation in to two categories.
XML Markup, used to define the Ribbon structure and organization of controls
C++ COM interfaces, used to initialize and handle events
Step 1: Create the XML file with your ribbon. Add this XML for the solution. The following XML is a simple ribbon contains the application a Tab,Group and a button inside it.
[sourcecode language='xml']
My Button My Button
[/sourcecode] Step 2: Specify the custom build option for the XML file. The XML file has to be compiled with UICC.exe application. If Visual Studio can’t find the binary, locate it from your Microsoft SDK directory in program files and specify the path in the PATH variable. In the custom build rule, add following string as command line
Active template library (ATL) support is required to implement this functionality. In the project properties, specify ATL support as follows
Step 4 – Implement the IUIApplication interface for your application
It’s necessary to implement the IUIApplication interface for our application to support ribbons. I’ve wrapped inside a class for convenient use. Currently it’s not necessary to provide any implementation for derived interfaces.
class CRibbonImplementer:
public CComObjectRootEx,
public IUIApplication
{
public:
BEGIN_COM_MAP(CRibbonImplementer)
COM_INTERFACE_ENTRY(IUIApplication)
END_COM_MAP()
Step 6: Initialize COM and load the ribbon to the dialog
This operation can be done inside the app class of the application. Inside the InitInstance function, specify the following code. Note that we’re not calling DoModal inside the InitInstance but instead, we’re calling Create function of the dialog class and call RunModalLoop till user closes the dialog.
[sourcecode language='cpp']
BOOL CRibbonMFCApp::InitInstance()
{
CoInitialize( 0 );
// other initialization code can be put here like InitCommonControlEx etc.
CRibbonMFCDlg dlg;
m_pMainWnd = &dlg;
CRibbonHandler ribbon;
dlg.Create(dlg.IDD );
HRESULT hr = ribbon.Init( dlg.GetSafeHwnd());
if (FAILED(hr))
return FALSE;
dlg.RunModalLoop();
return FALSE;
}
[/sourcecode]
Now you’re done
Before compiling ensure that the bitmap specified for the ribbon button is existing in the solution file. Otherwise import it to the solution file.
You can see the application as follows if you successfully compiled your project We’ve not handled any events for the controls that we’ll learn in the next instalment.
The following sample demonstrates, how to convert a vector to list(in other words, how to create a list from vector).
The simplest way is to iterate through all elements of container and add it to the destination container. the following snippet make use of std::copy function to copy contents from source to destination container. The destination and source iterator will be automatically incremented inside on each iteration. Before using this function you will have to ensure the destination container has enough room to hold the source elements. For that it may necessary to resize the container. See the snippet below. Note that you can use this technique with anu containers which supports iterator(actually that’s the purpose of std::copy function).
[sourcecode language='cpp']
#include
#include
#include
#include
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
vector vec;
// prepare the vector
for (int i = 0; i < 10; i++ )
{
vec.push_back( i+1 );
}
// construct list with the size of vector
list lis(vec.size());
// iterate and copy the content to list
copy( vec.begin(), vec.end(), lis.begin());
// output the content to console
copy( lis.begin(), lis.end(), ostream_iterator(cout, “\t” ) );
Reversing a string is one of the first programs we write when we learn about loops. Anyway you don’t have to write the usual loop again to reverse a string. You can use _tcsrev ( _strrev ) function to reverse a character buffer. See the sample below
One of the best editor features I’ve enjoyed in Visual Studio Editor with C# environment is the real time highlighting of syntax and semantic errors etc using Squiggles (wavy underline). As native programmer, I wished a lot of we enjoy similar kind of helpful features with Visual C++ editor.
The new version of Visual C++ (coming with Visual Studio 2010) has implemented squiggles display in the source editor. Hovering over the squiggle displays compiler quality syntax/semantic errors. See the sample image below
Image Courteously – Visual C++ Team Blog
This is really a helpful feature as we don’t need to wait for finding the errors until the build and this can save lot of time. This feature is implemented atop (or make use) of intellisense. In my experience most of the large C++ projects are not directly using Visual Studio for building. If you’re directly using Visual Studio, you can benefit the entire features in a centralised manner. But the new features are certainly helps developers even if they’re using external build systems. The error list window will show the errors identified by the intellisense and this helps you to fix the issues before starting external build.
In the Book, Windows Via C/C++ Jeffrey Richter mentioned about the peculiarity of command line parameter of CreateProcess function.Normally for most of the Windows API, the input parameters are constant. But for CreateProcess, we’ve to pass the a non const string argument as command line parameter because internally the API modifying the input parameter and the the original data passed will be restored back to its original form, when the API call returns.
Let’s a dig a bit more. The CreateProcess API takes the following form
lpCommandLine parameter of the API is actually specified in LPTSTR which is defined as non-const TCHAR pointer. Effectively we’re not getting anything back from the API but still we’ve to pass a writable memory location. Otherwise there’s a chance to face an access violation as the API tries to modify the passing pointer.
The above call makes an access violation as the Microsoft C/C++ compiler placing the constant strings in the read only memory. If you use old version of a Microsoft compiler you may not face this access violation as the constant data is stored at read/write memory location.
The best thing we can do is to copy the string to a temporary buffer and pass to the API. We can hope that Microsoft may fix this issue in their future release.
CreateProcess is actually defined as
[sourcecode language='cpp']
#ifdef _UNICODE
#define CreateProcess CreateProcessW
#else
#define CreateProcess CreateProcessA
#endif
[/sourcecode]
If UNICODE is not defined in your project, the API may call ANSI version (CreateProcessA) function which is actually a wrapper function. Inside ANSI version of the most of the APIs, temporary string buffers are defined and the values are converted from ANSI to UNICODE. These string buffers are passed to the UNICODE version of the API which is actually doing the task(remember that Windows is a UNICODE Operating System). So that access violation may not occur for non-unicode applications.
Basically, somebody back in the 1980’s wanted to avoid allocating memory. (Another way of interpreting this is that somebody tried to be a bit too clever.)
The CreateProcess temporarily modifies the string you pass as the lpCommandLine in its attempt to figure out where the program name ends and the command line arguments begin. Now, it could have made a copy of the string and made its temporary modifications to the copy, but hey, if you modify the input string directly, then you save yourself an expensive memory allocation operation. Back in the old days, people worried about avoiding memory allocations, so this class of micro-optimization is the sort of thing people worried about as a matter of course. Of course, nowadays, it seems rather antiquated.
Now, there may also be good technical reasons (as opposed to merely performance considerations) for avoiding allocating memory on the heap. When a program crashes, the just in time debugger is launched with the CreateProcess function, and you don’t want to allocate memory on the heap if the reason the program crashed is that the heap is corrupted. Otherwise, you can get yourself into a recursive crash loop: While trying to launch the debugger, you crash, which means you try to launch the debugger to debug the new crash, which again crashes, and so on. The original authors of the CreateProcess function were careful to avoid allocating memory off the heap, so that in the case the function is being asked to launch the debugger, it won’t get waylaid by a corrupted heap.
Whether these concerns are still valid today I am not sure, but it was those concerns that influenced the original design and therefore the interface.
In this post, I’m introducing the API which can be used to verify the signature of a Portable Executable (PE) file under windows. The applications like Process Explorer allows to verify the signature of the executables.
We can do the same thing using it using WinVerifyTrust. MSDN has a samplesnippet on the usage of this API. Let me put the same snippet (with some small modifications).
See the snippet list. It’s necessary to use Wide Character string(UNICODE) path to the file to use this function.
[sourcecode language='cpp']
BOOLVerifyEmbeddedSignature(LPCWSTR pwszSourceFile)
{
LONG lStatus;
DWORD dwLastError;
// Initialize the WinVerifyTrust input data structure.
// Default all fields to 0.
memset(&WinTrustData, 0, sizeof(WinTrustData));
WinTrustData.cbStruct = sizeof(WinTrustData);
// This is not applicable if there is no UI because it changes
// the UI to accommodate running applications instead of
// installing applications.
WinTrustData.dwUIContext = 0;
// Set pFile.
WinTrustData.pFile = &FileData;
// WinVerifyTrust verifies signatures as specified by the GUID
// and Wintrust_Data.
lStatus = WinVerifyTrust( NULL, &WVTPolicyGUID, &WinTrustData);
switch (lStatus)
{
case ERROR_SUCCESS:
{
CString strMessage;
strMessage.Format( _T( “The file \”%s\” is signed and the signature was verified.\n”),
pwszSourceFile);
AfxMessageBox( strMessage );
bRet = TRUE;
break;
}
case TRUST_E_NOSIGNATURE:
// The file was not signed or had a signature
// that was not valid.
// Get the reason for no signature.
dwLastError = GetLastError();
if (TRUST_E_NOSIGNATURE == dwLastError ||
TRUST_E_SUBJECT_FORM_UNKNOWN == dwLastError ||
TRUST_E_PROVIDER_UNKNOWN == dwLastError)
{
CString strMessage;
// The file was not signed.
strMessage.Format( _T( “The file \”%s\” is not signed.\n”), pwszSourceFile);
AfxMessageBox( strMessage );
}
else
{
// The signature was not valid or there was an error
// opening the file.
CString strMessage;
strMessage.Format( _T( “An unknown error occurred trying to ”
L”verify the signature of the \”%s\” file.\n”),
pwszSourceFile);
AfxMessageBox(strMessage);
}
break;
case TRUST_E_EXPLICIT_DISTRUST:
// The hash that represents the subject or the publisher
// is not allowed by the admin or user.
AfxMessageBox(L”The signature is present, but specifically disallowed.\n”);
break;
case TRUST_E_SUBJECT_NOT_TRUSTED:
// The user clicked “No” when asked to install and run.
AfxMessageBox( _T( “The signature is present, but not trusted.\n”));
break;
case CRYPT_E_SECURITY_SETTINGS:
/*
The hash that represents the subject or the publisher
was not explicitly trusted by the admin and the
admin policy has disabled user trust. No signature,
publisher or time stamp errors.
*/
MessageBoxW(L”CRYPT_E_SECURITY_SETTINGS – The hash ”
L”representing the subject or the publisher wasn’t ”
L”explicitly trusted by the admin and admin policy ”
L”has disabled user trust. No signature, publisher ”
L”or timestamp errors.\n”);
break;
default:
// The UI was disabled in dwUIChoice or the admin policy
// has disabled user trust. lStatus contains the
// publisher or time stamp chain error.
{
CString strMessage;
strMessage.Format( _T( “Error is: 0x%x.\n”), lStatus );
AfxMessageBox( strMessage );
break;
}
}
return bRet;
}
[/sourcecode]
In one of the previous post I mentioned about How to rename a file using windows API. Many people have asked is there any other option than using MoveFile API for renaming a file. Yes! there’s an alternative you can C-Runtime function rename, _wrenameto rename a file. This code will be portable across platforms as it’s part of standard library function. You can also use _trename , which is a typedef of rename_wrename to make the call compatible with both UNICODE and Non-UNICODE character set
See the sample taken from MSDN itself for renaming a file.
[sourcecode language='cpp']
/* Attempt to rename file: */
int result = _trename( old_filename, new_filename );
if( result != 0 )
_tcprintf( _T(”Could not rename ‘%s’\n”), old_filename );
else
_tcprintf( _T(”File ‘%s’ renamed to ‘%s’\n”), old_filename, new_filename );
return 0;
}
[/sourcecode]
–Updated–
2009/05/25 – Made the sample source compatible with both UNICODE and non-UNICODE character set.
2009/05/25 – Updated few typos