이 팁은 천리안 프로그래머포럼에 유수님이 98년 6월 3일에 올려놓으셨던 팁을 '허락없이' 전제한 것입니다.
문제가 있을 경우 즉시 삭제하겠습니다.
-----------------------------------------------------------------------------
안녕하세요. 유수(피찌에냐이)입니다.
다음은 하우투 씨벌더에 실린 클래스를 좀더 낳게 개조한 겁니다.
이 클래스를 이용하면, 프로그램내에 히스토리기능을 넣을 수 있습니다.
이전문서 ┏━ A문서
┣━ B문서
┗━ C문서
의 형태로 서브메뉴를 만들수 있습니다.
필요한 부분에 약간의 주석을 첨가하였습니다. 사용예는 끝에 있습니다.
궁금하신 점이 있으면, 멜이나 질문란에 올려 주시면 됩니다.
[FileHis.h]의 내용
//---------------------------------------------------------------------------
#ifndef FileHistoryH
#define FileHistoryH
//---------------------------------------------------------------------------
class TFileHistory
{
private:
// String list to hold the history file names
TStringList *HistoryList;
// Menu seperators that will mark the beginning and end of the history
TMenuItem *TopSeperator, *BottomSeperator;
//The file menu
TMenuItem *FileMenu;
//Holds maximum number of history items allowed
int MaxHistoryItems;
//Holds name of the file that contains history file names
String HistoryFileName;
//Callback function that opens a particular file
void (__closure *OpenFileFunc) (String FileName);
//Function that rebuilds the history list
void RebuildHistory(void);
//Function to handle click event on file history items
void __fastcall HistoryItemClick(TObject *Sender);
public:
// construct the file history object
TFileHistory(int theMaxHistoryItems,
String theHistoryFileName,
TMenuItem *theFileMenu,
void (__closure *theOpenFileFunc) (String FileName));
//destructor
~TFileHistory(void);
//Function for menu item click event handlers to call
void MaintainHistory(String OldFile);
void Clear(void);
};
#endif
[FileHis.cpp]의 내용 : 충분히 주석을 달지 않아서 죄송합니다.
//---------------------------------------------------------------------------
#include
#pragma hdrstop
#include "FileHis.h"
//---------------------------------------------------------------------------
//Constructor
TFileHistory::TFileHistory(int theMaxHistoryItems, //생성자
String theHistoryFileName,
TMenuItem *theFileMenu,
void (__closure *theOpenFileFunc) (String FileName))
{
//assign defaults from values passed
MaxHistoryItems = theMaxHistoryItems;
HistoryFileName = theHistoryFileName;
FileMenu = theFileMenu;
OpenFileFunc = theOpenFileFunc;
//Initialize the file history list
HistoryList = new TStringList;
//Attempt to open the file and load history items
//If the attempt fails, ignore the error
try
{
if (FileExists(HistoryFileName))HistoryList->LoadFromFile(HistoryFileName);
//if the history file was found set up the menu
RebuildHistory();
}
catch (...)
{
}
}
//Destructor
TFileHistory::~TFileHistory(void) // 소멸자
{
try
{
//Save the history list
HistoryList->SaveToFile(HistoryFileName);
}
catch (...)
{
//Display an error message
MessageBox(NULL, "Could not save history file", "Error",
MB_ICONERROR : MB_OK);
}
//Destroy the history list
HistoryList->Free();
}
//Function actually changes the file menu to show the history items
void TFileHistory::Clear(void) // 히스토리를 지움
{
int Pos, HNum;
HNum = FileMenu->Count;
if (HNum != 0)
for (Pos = 0; Pos < HNum; Pos++)
{
FileMenu->Delete(0);
HistoryList->Delete(0);
}
HistoryList->SaveToFile(HistoryFileName);
}
void TFileHistory::RebuildHistory(void) // 히스토리 목록과 메뉴를 만듬
{
TMenuItem *MenuItem;
int Pos, HNum;
HNum = FileMenu->Count;
if (HNum != 0)
for (Pos = 0; Pos < HNum; Pos++)
FileMenu->Delete(0);
//Trim list, if required, to maximum items allowed
if (HistoryList->Count > MaxHistoryItems) // 최대설정갯수보다 많으면 ...
for (Pos = MaxHistoryItems; Pos < HistoryList->Count; Pos++)
HistoryList->Delete(MaxHistoryItems);
//If there are history items then build menu items
if (HistoryList->Count > 0) {
//for each file in the history list
for (Pos = 0; Pos < HistoryList->Count; Pos++) {
//Create a new menu item
MenuItem = new TMenuItem(FileMenu);
//use position numer as accelerator in front of file name
if (ExtractFileName(HistoryList->Strings[Pos]) == "")
// 이부분은 디렉토리 히스토리(자주가기)의 경우와 파일히스토리(최근
// 문서) 구분해서 메뉴의 캡션을 만듭니다.
MenuItem->Caption = "&" + IntToStr(Pos + 1) + " " + HistoryList->St
rings[Pos];
else
MenuItem->Caption = "&" + IntToStr(Pos + 1) + " " + ExtractFileName
(HistoryList->Strings[Pos]);
//assign event handler
MenuItem->OnClick = HistoryItemClick;
//Insert into file menu
FileMenu->Insert(Pos, MenuItem);
}
//Create and insert a seperator following the last item
}
}
//클릭을 했을 때, 지정해준 함수를 실행합니다.
void __fastcall TFileHistory::HistoryItemClick(TObject *Sender)
{
int Pos;
String NewName;
//Calculate position in history list
//from releative position of selected file name
Pos = FileMenu->IndexOf((TMenuItem *)Sender); // 클릭된 항목의 위치를 얻구..
//Get file name from history list
NewName = HistoryList->Strings[Pos]; // 실제 히스토리 문자열을 얻습니다.
//Call back to owner form function to open the file
OpenFileFunc(NewName); // 함수 실행
}
//Called by the main application to maintain the
//history list
void TFileHistory::MaintainHistory(String NewFile)
{
int Pos;
Pos = HistoryList->IndexOf(NewFile);
if (Pos !=-1) // 존재하면
HistoryList->Delete(Pos);
HistoryList->Insert(0, NewFile);
RebuildHistory();
}
###### 사용예 ##########
먼저 filehis.h를 include 시킵니다.
사용하고 하는 클래스내에 다음과 같이 선언하고,
TFileHistory *FileHistory;
[폼이 생성되는 부분에서]
FileHistory = new TFileHistory
(8, ExtractFilePath(Application->ExeName) + "History", Reopen1, &OpenFile);
//최대 갯수 8개를 설정하며, 현재 디렉토리에 history라는 파일명으로 목록을 저
//장하며, 붙게 될(?) 메뉴아이템이름은 Reopen1이며, 실행함수는 OpenFile로
//설정합니다.
[폼이 파괴디는 부분에서]
delete FileHistory;
간단한 OpenFile함수는
void TMainForm::OpenFile(String FFileName)
{
FileHistory->MaintainHistory(FFileName); // 히스토리 갱신...
//클래스를 보시면 아시겠지만, 중복되면 삭제를 자동으로 갱신하게 만들어 놓았어요.
RichEdit1->Lines->LoadFromFile(FFileName);
}
필요에 맞게 코딩하면 되겠죠..^^;
히스토리 갱신 역시 개인의 필요에 맞는 부분에서 코딩하시면 됩니다.
화일을 실제로 대화상자에서 열 때, 대화상자가 닫힌다음 OpenFile(OpenDialog1->File
Name)형태로 효율적으로 사용하면 됩니다.
그리고, 자주가는 폴더 역시 화일열기를 응용하면 됩니다. 그럼...
흐르는 물... 유수~~~