20 de abril de 2006

Arqueología de código

Hace poco me econtré en mi disco duro con un programati que había hecho para divertirme hace algunos años. Lo posteo aquí para recordar la forma "real" de programar directamente el Windows API en C++, sin usar visual tools.

La idea es que ahora acabo de instalar Visual Studio 2005 y estoy comenzando a hacer una aplicación que por medio del los web services de Amazon traiga los nombres de las canciones de un CD (no estoy seguro siquiera que Amazon provea esta info, pero bueno hay q investigar) para renombrar archivos MP3...a ver que tal...

Libro: Masters of Deception
Video: Lost Season 1
Música: Show your bones - The Yeah Yeah Yeahs

---------------------- AQUI VA EL CÓDIGO VIEJO -------------------------
------------------- FALTAN RESOURCES E ICONOS PARA QUE FUNCIONE

// basura.cpp - Programa para actuar como el basurero de Macintosh. Acepta Drag & Drop bajo
// Windows 3.1 unicamente.
// Escrito por Egdares Futch H. 14-Jun-93
// Compilador : Borland C++ 3.1

#include
#include
#include
#include
#include

const UINT CM_ABOUT = 42;
const UINT CM_RECUPERAR = 43;
const UINT CM_BORRAR = 44;

// ****************************************************************************************
// **************************** LISTAS.CPP ************************************************
// ****************************************************************************************

// list.cpp - Manejo de listas encadenadas genericas en C++
// Escrito por Egdares Futch H. para el curso de Programacion III, 1992

// Clase abstracta para descender de ella todos los nodos que se desean
// encadenar

class Node
{
protected:
Node *next;
public:
Node(void) { next = NULL; }
virtual ~Node(void) { }
virtual char *getname(void) const = 0;
Node *getnext(void) { return next; }
void setnext(Node *n) { next = n; }
};

class List
{
protected:
Node *top;
public:
List() { top = NULL; }
List(Node *node) { top = node; }
~List(void) { }
void insert(Node *node) { node->setnext(top); top = node; }
void append(Node *);
};

void List::append(Node *node)
{
Node *tmp = top;

if (top == NULL)
top = node;
else
{
while (tmp->getnext() != NULL)
tmp = tmp->getnext();
tmp->setnext(node);
}
node->setnext(NULL);
}

class IterationList : public List
{
Node *iterationpointer;
public:
IterationList() { }
IterationList(Node *node) : List(node) { }
void InitIteration(void) { iterationpointer = NULL; }
Node *iterate(void);
void iteratedelete(void);
};

// Protocolo : si llamo con itptr == NULL, implica inicializar las cosas

Node *IterationList::iterate(void)
{
if (iterationpointer == NULL)
iterationpointer = top;
else
iterationpointer = iterationpointer->getnext();
return iterationpointer;
}

void IterationList::iteratedelete(void)
{
if (iterationpointer == NULL)
iterationpointer = top;
while (iterationpointer != NULL)
{
Node *next = iterationpointer->getnext();
delete iterationpointer;
iterationpointer = next;
}
top = NULL;
}

// Definicion de clases concretas, basadas en herencia para sacar de ellas la lista de
// archivos para el programa de Basura

class TrashFile : public Node
{
char *name;
public:
// Constructor default, no hace mucho
TrashFile(void) { name = NULL; }
// Constructor con un nombre de archivo
TrashFile(const char *);
virtual ~TrashFile(void);
char *getname(void) const { return name; }
};

// Implementacion del constructor

TrashFile::TrashFile(const char *n)
{
if (n != NULL)
{
name = new char[strlen(n)+1];
strcpy(name,n);
}
else
name = NULL;
}

// Implementacion del destructor

TrashFile::~TrashFile(void)
{
unlink(name);
delete [] name;
}

// *****************************************************************************************
// ********************************** FIN DE LISTAS.CPP ************************************
// *****************************************************************************************

// ********************** Definicion de clase para la aplicacion *************************

class TBasuraApp: public TApplication
{
public:
TBasuraApp(LPSTR AppName,HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) : TApplication(AppName,hInstance,hPrevInstance,lpCmdLine,nCmdShow) { };
virtual void InitMainWindow(void);
virtual void InitInstance(void);
};

// *********************** Definicion de clase para la ventana **************************

_CLASSDEF(TBasuraWindow)
class TBasuraWindow : public TWindow
{
public:
TBasuraWindow(PTWindowsObject Parent,LPSTR Title) : TWindow(Parent,Title) { };
virtual void SetupWindow(void);
virtual void GetWindowClass(WNDCLASS &WndClass);
virtual void Paint(HDC hDC,PAINTSTRUCT _FAR & PaintInfo);
virtual BOOL CanClose(void);
// Funciones virtuales de respuesta de mensajes
virtual void WMSysCommand(RTMessage Msg) = [WM_FIRST + WM_SYSCOMMAND];
virtual void WMDropFiles(RTMessage Msg) = [WM_FIRST + WM_DROPFILES];
// Componentes de datos
HDROP hDrop;
int nFiles;
HICON hVacio,hLleno;
IterationList FileList;
};

// ******************** TBasuraWindow::SetupWindow() *****************************

void TBasuraWindow::SetupWindow(void)
{
nFiles = 0;
hVacio = LoadIcon(GetApplication()->hInstance,"VACIO");
hLleno = LoadIcon(GetApplication()->hInstance,"LLENO");
}

// ******************** TBasuraWindow::GetWindowClass() **************************

void TBasuraWindow::GetWindowClass(WNDCLASS &WndClass)
{
TWindow::GetWindowClass(WndClass);
WndClass.hIcon = LoadIcon(GetApplication()->hInstance,"VACIO");
}

// ********************* TBasuraWindow::Paint() ***********************************

#pragma argsused

void TBasuraWindow::Paint(HDC hDC,PAINTSTRUCT _FAR & PaintInfo)
{
Node *it;
char buffer[50];

int ypos = 0;
FileList.InitIteration();
while ((it = FileList.iterate()) != NULL)
{
TextOut(hDC,0,ypos,it->getname(),strlen(it->getname()));
ypos += 20;
}
TextOut(hDC,0,ypos,buffer,sprintf(buffer,"Número de archivos = %d",nFiles));
}

// *********************** TBasuraWindow::CanClose() *********************************

BOOL TBasuraWindow::CanClose(void)
{
if (nFiles > 0)
{
if (MessageBox(HWindow,"El basurero tiene archivos. Desea terminar?\n (Los archivos no se borrarán)",
"Hay basura!",MB_ICONINFORMATION | MB_YESNO) == IDYES)
{
DestroyIcon(hVacio);
DestroyIcon(hLleno);
DragAcceptFiles(HWindow,FALSE);
return TRUE;
}
else
return FALSE;
}
DestroyIcon(hVacio);
DestroyIcon(hLleno);
DragAcceptFiles(HWindow,FALSE);
return TRUE;
}

// ************************* TBasuraWindow::WMSysCommand() ********************************

void TBasuraWindow::WMSysCommand(RTMessage Msg)
{
switch(Msg.WParam)
{
case CM_ABOUT:
MessageBox(HWindow,"Basura fue escrito por Egdares Futch\n usando Borland C++ 3.1",
"Acerca de Basura",MB_ICONINFORMATION | MB_OK);
break;
case CM_BORRAR:
nFiles = 0;
FileList.InitIteration();
FileList.iteratedelete();
InvalidateRect(HWindow,NULL,TRUE);
SetClassWord(HWindow,GCW_HICON,(WORD)hVacio);
FlashWindow(HWindow,FALSE);
break;
default:
DefWndProc(Msg);
}
}

// ************************* TBasuraWindow::WMDropFiles **********************************

void TBasuraWindow::WMDropFiles(RTMessage Msg)
{
char buffer[80];

hDrop = (HDROP)Msg.WParam;
int NewFiles = DragQueryFile(hDrop,-1,(LPSTR)NULL,0);
if (nFiles == 0)
{
SetClassWord(HWindow,GCW_HICON,(WORD)hLleno);
FlashWindow(HWindow,FALSE);
}
nFiles += NewFiles;
for (int i = 0 ; i < NewFiles ; i++)
{
DragQueryFile(hDrop,i,buffer,80);
FileList.append(new TrashFile(buffer));
}
DragFinish(hDrop);
if (!IsIconic(HWindow))
InvalidateRect(HWindow,NULL,TRUE);
Msg.Result = 0;
}

// **************************** TBasuraApp::InitMainWindow() *******************************

void TBasuraApp::InitMainWindow(void)
{
MainWindow = new TBasuraWindow(NULL,Name);
}

// **************************** TBasuraApp::InitInstance() ********************************

void TBasuraApp::InitInstance(void)
{
TApplication::InitInstance();
HMENU SystemMenu = GetSystemMenu(MainWindow->HWindow,FALSE);
AppendMenu(SystemMenu,MF_SEPARATOR,0,NULL);
AppendMenu(SystemMenu,MF_STRING,CM_BORRAR,"&Eliminar basura");
AppendMenu(SystemMenu,MF_STRING,CM_RECUPERAR,"Recu&perar basura");
AppendMenu(SystemMenu,MF_STRING,CM_ABOUT,"&Acerca de Basura ...");
DragAcceptFiles(MainWindow->HWindow,TRUE);
}

// ************************* WinMain (programa principal) **********************************

#pragma argsused

int PASCAL _export WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
TBasuraApp Basura("Basura", hInstance, hPrevInstance,lpCmdLine, SW_SHOWMINNOACTIVE);

Basura.Run();
return Basura.Status;
}

No hay comentarios.: