//
// 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.
//
// 
// StringHeapPage.cpp : plik implementacji
//

#include "stdafx.h"
#include "AssemblyDoc.h"
#include "AssemblyView.h"
#include "StringHeapPage.h"


// Okno dialogowe CStringHeapPage

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

CStringHeapPage::~CStringHeapPage()
{
}

void CStringHeapPage::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_STRINGLIST, m_ctrlStringList);
}


BEGIN_MESSAGE_MAP(CStringHeapPage, CPropertyPage)
END_MESSAGE_MAP()


// Procedury obsługi wiadomości CStringHeapPage

void CStringHeapPage::DumpString(
    CListCtrl   *pList,			  // Sterowanie listą, do której są przekazywane dane
    ULONG       cRows,            // Numer ciągu.
    ULONG       oData,            // Indeks danych.
    const char  *psData)          // Dane do wyświetlenia.
{
	ULONG itemIndex;
	TCHAR cBuffer[64];
	LPTSTR lpszBuffer;

	itemIndex = pList->GetItemCount();
	memset(cBuffer, 0, sizeof(cBuffer));

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

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

	lpszBuffer = new TCHAR[strlen(psData) + 1];
	mbstowcs(lpszBuffer, psData, strlen(psData) + 1);
    pList->SetItemText(itemIndex, 2, lpszBuffer);
	delete [] lpszBuffer;

    return;
}

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

	CString strItemLabel = _T("Item");
	CString strIndex = _T("Index");
	CString strString = _T("String");

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

	// Wypełnienie danymi
	CPropertySheet *pPropertySheet = STATIC_DOWNCAST(CPropertySheet, GetParent());
	CAssemblyView* pView = STATIC_DOWNCAST(CAssemblyView, pPropertySheet->GetParent());
	CAssemblyDoc* pDoc = pView->GetDocument();
	IMetaDataImport* pImport  = pDoc->MetaDataImportInterface();

	IMetaDataTables *pTables = NULL;
	HRESULT hr = pImport->QueryInterface(IID_IMetaDataTables, (void**)&pTables);

	const char *pString; // Wskaźnik ciągu.
    ULONG oData;         // Przesunięcie bieżącego ciągu.
	ULONG cRows;
    oData = 0;
	cRows = 0;
    do 
    {
        pTables->GetString(oData, &pString);
        if (*pString != 0)
		{
			DumpString(&m_ctrlStringList, cRows, oData, pString);
		}
        hr = pTables->GetNextString(oData, &oData);
		cRows++;
    }
    while (hr == S_OK);

	pTables->Release();
	pTables = NULL;
	pImport->Release();

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