Graphics Debugging in Visual Studio 2011

 

Metro style games and graphics-intensive apps present a huge opportunity for developers on new devices such as tablets. The primary API for accessing the full power of the underlying graphics hardware on Windows is DirectX 11 (including Direct3D and Direct2D).

One of the most significant innovations we have brought to Visual Studio 11 is a series of tools for assisting you in developing Direct3D games. We made a quick video of some of these features on Channel9 (link). In this post, I will walk through our debugging & diagnostics support for D3D.

The new Graphics Debugger in Visual Studio is a debugging and analysis tool that captures detailed information from a Direct3D application as it executes. You can use it to:

  • Capture rendered frames for later inspection and analysis.
  • View DirectX events and their effects on the application.
  • View 3D meshes before and after vertex shader transformations.
  • Discover which DirectX events contribute to the color of a specific pixel.
  • Jump directly to the location in source code for a particular DirectX call
 

Using Ribbon Editor to design the Ribbon for your application

 

Visual Studio 2010 has integrated the new Ribbon Designer for MFC Applications. Previously I blogged about integrating ribbon with the MFC application and adding even handlers to get the notifications. But the developer must visualize the ribbon while scripting the ribbon code. But using the new Ribbon Designer, we can design ribbons designer, just like the menu designer.


Please check the following links to explore more.
How to integrate a simple ribbon with your MFC Application?
How to handle Ribbon Control Events?
Ribbon designer (MSDN)

 

Windows 7: Task Dialog Part 2 – A more detailed task dialog

 

In the last installment, we’ve seen using the basic version of task dialog. But usually when we see the task dialogs in Windows Vista or 7, it’s more detailed and can have flashy icons etc. Let’s see how to take more control over the task dialogs.

TaskDialogIndirect function can be used to have more options with task dialogs. TASKDIALOGCONFIG structure is used along with TaskDialogIndirect API.

clip_image001

As you’re seeing above the task dialog contains different type of controls, icons and capable of displaying more information to the user. It can have lengthy big buttons, radio buttons, checkbox, footer area, progressbar, custom icon, displaying predefined buttons like OK, Cancel, Yes, No etc. even we can have control over the buttons in the titlebar( minimize, maximize button etc)

The following code describes creating a task dialog with more flexible options. User can specify the callback functions which can be used to control the behavior if the controls and contents in the task bar. Filling the TASKDIALOGCONFIG structure is simple and straight forward as we’re seeing the code. The detailed option can be obtained from MSDN page.


HRESULT CALLBACK CTaskDialogSampleDlg::TaskDialogCallbackProc(
  __in  HWND hwnd,
  __in  UINT uNotification,
  __in  WPARAM wParam,
  __in  LPARAM lParam,
  __in  LONG_PTR dwRefData
)
{
	if( TDN_CREATED == uNotification )
	{
		::SendMessage( hwnd, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, IDOK, TRUE );
		::SendMessage( hwnd, TDM_SET_PROGRESS_BAR_RANGE, 0, 100 );
	}
	else if( TDN_HYPERLINK_CLICKED == uNotification )
	{
		ShellExecute( 0, L"open", (LPCTSTR) lParam, 0, 0, SW_SHOW );
	}
	else if( TDN_TIMER == uNotification )
	{
		static int i = 0;
		::SendMessage( hwnd, TDM_SET_PROGRESS_BAR_POS, i++,0 );
	}

	return 0;
}

void CTaskDialogSampleDlg::OnBnClickedButton1()
{
	int nButtonPressed                  = 0;
	TASKDIALOGCONFIG config             = {0};
	const TASKDIALOG_BUTTON buttons[]   = {
		{ IDOK, L"Elevate Privilege" },
		{ IDCANCEL, L"Run with user privilege" }
	};

	const TASKDIALOG_BUTTON radiobuttons[] = {
		{ IDCANCEL, L"Test Radio" }};
	config.cbSize                       = sizeof(config);
	config.hInstance                    = AfxGetApp()->m_hInstance;
	config.dwCommonButtons              = TDCBF_OK_BUTTON | TDCBF_CANCEL_BUTTON;
	config.pszMainIcon                  = TD_SHIELD_ICON;
	config.pszMainInstruction           = L"Main Instruction";
	config.pszContent                   = L"This is the content.";
	config.pszVerificationText          = L"Conifirm license agreement";
	config.pButtons                     = buttons;
	config.cButtons                     = ARRAYSIZE(buttons);
	config.pRadioButtons				= radiobuttons;
	config.cRadioButtons				= ARRAYSIZE( radiobuttons );
	config.dwFlags						= TDF_SHOW_PROGRESS_BAR |
		TDF_EXPAND_FOOTER_AREA | TDF_ENABLE_HYPERLINKS | TDF_CAN_BE_MINIMIZED
		| TDF_USE_COMMAND_LINKS | TDF_CALLBACK_TIMER;
	config.pszExpandedInformation		= _T( "<a href=\"http://codereflect.com/\" >Codereflect.com</a>" );
	config.pfCallback = TaskDialogCallbackProc;
	BOOL bVerification = FALSE;
	TaskDialogIndirect(&config, &nButtonPressed, NULL, &bVerification);

	switch (nButtonPressed)
	{
	case IDOK:
		break; // the user pressed button 0 (change password).
	case IDCANCEL:
		break; // user canceled the dialog
	default:
		break; // should never happen
	}
}

The callback function is also easy to manage. There are predefined set of events for each type of control and we can simply make use of these controls by sending various messages to update its state and values. One of the best example is updating the progressbar during the lifetime of messagebox. Once the timer is enabled, the callback function will be automatically fired on discrete time interval. The notify messages are specified in detail in MSDN Documentation. Please check it.

To compile this source code, please use latest version of Visual Studio 2010 or any prior version with Windows Vista/7 SDK. You can also use express edition of Visual C++ to try this API.