C
Im Moment löse ich das Problem durch Umgehen. Ich verwende (zähneknirschend) einen eigenen Auswahldialog. Das Programm schreibt dann die absoluten Pfade zeilenweise nach stdout. Der 8MB-Puffer (PATHBUFSIZ) ist zwar hässlich, aber es funktioniert (Btw: vielleicht kann mir jemand sagen, wie man das eleganter macht). Der Stil ist ein wenig mies, aber ich habe das in kurzer Zeit aus dem Forum und MSDN zusammengestückelt...
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <commdlg.h>
#include <malloc.h>
#define PATHBUFSIZ (1024*1024*8)
#define LASTBUFSIZ (1024)
#define KEYNAME "Software\\WasAuchImmer"
#define VALNAME "LastPath"
#define TITLE (argv[0])
// man schimpfe nicht:
OPENFILENAME ofn;
int helpreq = 0;
char *title = NULL;
int show_dialog(char *title, BYTE *lastpath)
{
LPTSTR lpstrFile = (TCHAR*)malloc((unsigned int)PATHBUFSIZ);
*lpstrFile = 0;
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFilter = NULL; //"All files (*.*)|*.*";
ofn.hInstance = NULL;
ofn.hwndOwner = NULL;
ofn.lpstrCustomFilter = NULL;
ofn.nMaxCustFilter = 0;
ofn.lpstrFile = lpstrFile;
ofn.nMaxFile = PATHBUFSIZ;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = (char*)lastpath;
ofn.lpstrTitle = title;
ofn.nFileExtension = 0;
ofn.Flags = OFN_ALLOWMULTISELECT | OFN_ENABLESIZING | OFN_FILEMUSTEXIST |
OFN_HIDEREADONLY | OFN_LONGNAMES | OFN_EXPLORER;
ofn.lpstrDefExt = NULL;
return GetOpenFileName(&ofn);
}
int parse_ofn()
{
char *path = ofn.lpstrFile;
char *file = &ofn.lpstrFile[ofn.nFileOffset-1];
int i;
//wenn nur eine Datei gewaehlt
if (ofn.nFileExtension != 0) {
printf(path);
printf("\n");
return 0;
}
for (i = ofn.nFileOffset-1; i < PATHBUFSIZ; i++) {
if (ofn.lpstrFile[i] == '\0') {
if (ofn.lpstrFile[i+1] == '\0') {
return 0;
}
file = &ofn.lpstrFile[i+1];
printf(path); printf("\\"); printf(file); printf("\n");
}
}
//Pufferueberlauf
return 1;
}
int parse_argv(int argc, char **argv)
{
int i;
for (i = 1; i < argc; i++) {
if (argv[i][0] == '-' || argv[i][0] == '/') {
switch (argv[i][1]) {
case 'h':
case 'H':
case '?':
helpreq = 1;
break;
case 't':
case 'T':
if (i+1 < argc)
title = argv[i+1];
break;
}
}
}
return 0;
}
BYTE *read_reg()
{
HKEY hKey;
DWORD dwData = LASTBUFSIZ;
static BYTE cDaten[LASTBUFSIZ];
RegCreateKeyEx(HKEY_CURRENT_USER,KEYNAME,0,0,REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,NULL,&hKey,0);
RegQueryValueEx(hKey,VALNAME,0,0,cDaten,&dwData);
RegCloseKey(hKey);
return cDaten;
}
void write_reg(char* buf)
{
HKEY hKey;
RegCreateKeyEx(HKEY_CURRENT_USER,KEYNAME,0,0,REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,NULL,&hKey,0);
RegSetValueEx(hKey,VALNAME,0,REG_SZ,(BYTE*)buf,strlen(buf)+1);
RegCloseKey(hKey);
}
int main(int argc, char* argv[])
{
BYTE *lastpath;
parse_argv(argc, argv);
// wenn Hilfe angefordert
if (helpreq) {
printf("Syntax:\n");
printf("%s [-t titel] [-h]\n\n", argv[0]);
printf("ERRORLEVEL 0: Button OK gedrueckt\n");
printf(" 1: Button Cancel gedrueckt\n");
printf(" 2: Pufferueberlauf\n\n");
printf("Nimmt einen 8MB-Puffer fuer die Pfade in Beschlag.\n");
printf("Bei Problemen PATHBUFSIZ aendern und neu uebersetzen.\n");
exit(3);
}
// wenn Titel nicht durch parse_argv() gefunden
if (title == NULL)
title = TITLE;
// versuchen, das letze Verzeichnis aus der Registry zu lesen
lastpath = read_reg();
if (lastpath[0] == '\0')
lastpath = NULL;
// Den Common-Dialog anzeigen
if (show_dialog(title, lastpath) == 0) {
printf("Abgebrochen.\n");
exit(1);
}
// Die OPENFILENAME Struktur verstehen
if (parse_ofn()) {
fprintf(stderr, "%s: Pufferueberlauf.", argv[0]);
exit(2);
}
// wenn nur eine Datei ausgewaehlt
if (ofn.nFileExtension != 0)
// Dateinamen wegschneiden
ofn.lpstrFile[ofn.nFileOffset] = '\0';
// dieses Verzeichnis in die Registry speichern
write_reg(ofn.lpstrFile);
free(ofn.lpstrFile);
return 0;
}