//
// Copyright (c) 2002
// Ronald Kevin Burton
//
// Z poniższym kodem nie jest związana żadna gwarancja poprawności działania.
// Program został dołączony do książki ".NET CLR. Księga eksperta" w celu
// ilustracji koncepcji i zasad przedstawionych w tej książce. Program może być 
// używany na własne ryzyko.
//
// Przyznaje się prawo do użycia lub kopiowania tego oprogramowania do dowolnego celu
// bez konieczności ponoszenia żadnych opłat pod warunkiem, że powyższe uwagi zostaną 
// zachowane we wszystkich kopiach. Przyznaje się także prawo do modyfikacji kodu
// i dystrybucji zmodyfikowanego kodu pod warunkiem zachowania powyższych uwag
// oraz dołączenia informacji mówiącej o modyfikacji kodu.
//
// 
// GUIDHeapPage.cpp : plik implementacji
//

#include "stdafx.h"

#define INIT_GUID
#include <initguid.h>

#include "AssemblyDoc.h"
#include "AssemblyView.h"
#include "GUIDHeapPage.h"


// Okno dialogowe CGUIDHeapPage

IMPLEMENT_DYNAMIC(CGUIDHeapPage, CPropertyPage)
CGUIDHeapPage::CGUIDHeapPage()
	: CPropertyPage(CGUIDHeapPage::IDD)
{
}

CGUIDHeapPage::~CGUIDHeapPage()
{
}

void CGUIDHeapPage::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_GUIDLIST, m_ctrlGuidList);
}

BEGIN_MESSAGE_MAP(CGUIDHeapPage, CPropertyPage)
END_MESSAGE_MAP()


// Procedury obsługi wiadomości CGUIDHeapPage
LPWSTR CGUIDHeapPage::GUIDAsString(GUID inGuid, LPWSTR guidString, ULONG bufLen)
{
    StringFromGUID2(inGuid, guidString, bufLen);
    return guidString;
}
void CGUIDHeapPage::DumpGuid(
    CListCtrl   *pList,			  // Sterowanie listą, do której przesyłane są dane
    ULONG       cRows,            // Numer obiektu typu blob.
    ULONG       oData,            // Indeks danych.
    const GUID  *pGuid)           // Dane do wyświetlenia.
{
	ULONG itemIndex;
	TCHAR lBuffer[256];
	TCHAR cBuffer[64];
	
	itemIndex = pList->GetItemCount();
	memset(lBuffer, 0, sizeof(lBuffer));

    wsprintf(cBuffer, _T("%d"), cRows);
	itemIndex = pList->InsertItem(itemIndex, cBuffer);

    wsprintf(cBuffer, _T("%d(0x%02x)"), oData, oData);
	pList->SetItemText(itemIndex, 1, cBuffer);

	pList->SetItemText(itemIndex, 2, GUIDAsString(*pGuid, lBuffer, sizeof(lBuffer)));
}

BOOL CGUIDHeapPage::OnInitDialog()
{
	CPropertyPage::OnInitDialog();

	CString strItemLabel = _T("Item");
	CString strIndex = _T("Index");
	CString strGUID = _T("GUID");

	CRect rect;
	// Wstawienie trzech kolumn (tryb raportu) i modyfikacja nowych elementów nagłówka
	m_ctrlGuidList.GetWindowRect(&rect);
	m_ctrlGuidList.InsertColumn(0, strItemLabel, LVCFMT_LEFT,
		                        rect.Width() * 1/6, 0);
	m_ctrlGuidList.InsertColumn(1, strIndex, LVCFMT_LEFT,
		                        rect.Width() * 1/6, 1);
	m_ctrlGuidList.InsertColumn(2, strGUID, LVCFMT_LEFT,
		                        rect.Width() * 2/3, 2);

	// Wypełnienie danymi
	CPropertySheet *pPropertySheet = STATIC_DOWNCAST(CPropertySheet, GetParent());
	CAssemblyView* pView = STATIC_DOWNCAST(CAssemblyView, pPropertySheet->GetParent());

	// Wskaźnik GUID.
	const GUID *pGuid = (const GUID *)pView->GUIDTable();
	DWORD guidTableSize = pView->GUIDTableSize()/sizeof(GUID);
	// Przesunięcie bieżącego GUID.
    ULONG oData = 1;
	ULONG cRows = 1;
    do 
    {
        DumpGuid(&m_ctrlGuidList, cRows, oData, pGuid + (cRows-1));
		cRows++;
		oData++;
    }
    while (oData < guidTableSize);

	return TRUE;  // zwrócenie TRUE, chyba że ognisko ustawiono na element sterujący
}
