OpenDialog에서 특정경로만 나오게 하려면...
Q&A 게시판에 질문을 보고 만들어 봤습니다.
http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_qna&no=52648
원리1. 먼저 OpenDialog의 왼쪽에 바로가기의 내용은 register에서 수정하면 변경이 가능합니다.
Register 위치는?
classroot = HKEY_CURRENT_USER
key = SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\ComDlg32\\PlacesBar
이곳에 place0 부터 입력하면 되구요
datatype이 dword로 입력하면 과련된 폴더가 나오고
string으로 입력하면 입력한 폴더가 나옵니다.
즉 OpenDialog->Execute()를 호출하기전에
위 register에 내용을 변경해 버리면
OpenDialog의 왼쪽에 바로가기의 내용을 원하는대로 보여줄수 있습니다.
원리2. OpenDialog의 윗쪽에 Combobox와 앞뒤로가기 버튼등은 어떻게 조절하는지는 잘모릅니다.
그래서 그냥 findwindow로 찾아서 hide시켜 보았습니다.
==================<< 코드 >> ========================
void __fastcall TForm1::Button1Click(TObject *Sender)
{
SaveClearDlgRegister("C:\\Zzang\\"); //현재 resister에 내용을 따로저장한후 clear한다.
Timer1->Interval=100;
Timer1->Enabled=true; // timer를 enable시킨다. .. dialog가 뜬후에 resister복구및
// dialog폼의 특성 윈도우를 hide시킴
OpenDialog1->InitialDir="c:\\Zzang\\";
OpenDialog1->FileName = ""; // 다른 folder에서 한번 오픈한경우 filename을 clear해줘야 InitialDir가적용됨
if(OpenDialog1->Execute())
{
Edit1->Text=OpenDialog1->FileName;
}
}
typedef struct __DlgKey
{
String sName;
int type;
String sValue;
int val;
void *Data;
}DlgKey;
//register의 내용을 save한후에 clear시킴
void __fastcall TForm1::SaveClearDlgRegister(String sPath)
{
reg->RootKey =HKEY_CURRENT_USER ;//HKEY_LOCAL_MACHINE;
reg->OpenKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\ComDlg32\\PlacesBar", true);
ValLst->Clear();
reg->GetValueNames(ValLst);
RegLst->Clear();
int iDataType;
DlgKey *dKey;
for(int i=0;iCount;i++)
{
dKey=new DlgKey;
dKey->sName=ValLst->Strings[i];
dKey->type=reg->GetDataType(ValLst->Strings[i]);
if(dKey->type==rdInteger)
dKey->val=reg->ReadInteger(dKey->sName);
else if(dKey->type==rdString)
dKey->sValue=reg->ReadString(dKey->sName);
else if(dKey->type==rdExpandString)
dKey->sValue=reg->ReadString(dKey->sName);
else if(dKey->type==rdBinary)
{
int size=reg->GetDataSize(dKey->sName);
dKey->Data=malloc(size);
reg->ReadBinaryData(dKey->sName,dKey->Data,size);
}
else if(dKey->type==rdUnknown )
{
int size=reg->GetDataSize(dKey->sName);
dKey->Data=malloc(size);
reg->ReadBinaryData(dKey->sName,dKey->Data,size);
}
RegLst->AddObject(dKey->sName,(TObject *)dKey);
reg->DeleteValue(dKey->sName);
}
reg->WriteString("place0",sPath);
reg->CloseKey();
}
const int LB_FILETYPES_ID = 1089; // "File types:" label
const int LB_FILENAME_ID = 1090; // "File name:" label
const int LB_DRIVES_ID = 1091; // "Look in:" label
// 타이머 핸들러에서 OpenDialog의 특정 윈도우를 hide시키고
// clear한 register내용을 복구시킴
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
HWND hWnd=GetParent(OpenDialog1->Handle);
if(hWnd)
{
HWND hToolBar=FindWindowExA(hWnd,NULL,"ToolBarWindow32","");
HWND hCombo=FindWindowExA(hWnd,NULL,"ComboBox","");
ShowWindow(hToolBar,SW_HIDE);
ShowWindow(hCombo,SW_HIDE);
String str="잘되나?";
SendMessage(hWnd, CDM_SETCONTROLTEXT, LB_DRIVES_ID, (LPARAM)str.c_str());
RestoreDlgRegister();
Timer1->Enabled=false;
}
}
//register의 내용을 복구한다.
void __fastcall TForm1::RestoreDlgRegister()
{
reg->RootKey =HKEY_CURRENT_USER ;//HKEY_LOCAL_MACHINE;
reg->OpenKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\ComDlg32\\PlacesBar", true);
int iDataType;
DlgKey *dKey;
reg->DeleteValue("place0");
for(int i=0;iCount;i++)
{
dKey=(DlgKey *)RegLst->Objects[i];
if(dKey->type==rdInteger)
{
reg->WriteInteger(dKey->sName,dKey->val);
}
else if(dKey->type==rdString)
reg->WriteString(dKey->sName,dKey->sValue);
else if(dKey->type==rdExpandString)
reg->WriteString(dKey->sName,dKey->sValue);
else if(dKey->type==rdBinary)
{
reg->WriteBinaryData(dKey->sName,dKey->Data,sizeof(dKey->Data));
}
else if(dKey->type==rdUnknown )
{
reg->WriteBinaryData(dKey->sName,dKey->Data,sizeof(dKey->Data));
}
delete dKey;
}
RegLst->Clear();
reg->CloseKey();
}
헤헤 꼼수지만 이와같이 하면 원하는 폴더만 OpenDialog에 보이게 할수 있을것 같습니다.
몇가지 문제가 있을듯..
- 직접 입력창에 타이핑해서 folder를 옮길수는 있네요..
- 지정한 폴더에서 하위 폴더로 내려간경우 원래 위로 한칸씩 올라올수 없구..
- viewstyle을 변경하지도 못하네요..
그럼...