Tech Support > Microsoft Windows > Development Resources > File Association?
File Association?
Posted by Allan M on February 21st, 2004


How do I setup a file association for my application from within my
program?

Posted by Frane Roje on February 21st, 2004


I thinik you'll have to write something to the registry( I know this from
VB,so don't ask me
for any kind of code)

--

---------------------------
Time to get it done!

Remove (d*elete*) to reply

"Allan M" <allanm1@ihug.co.nz> wrote in message
news:01c3f891$bdb7edc0$74c0adcb@default...


Posted by Alf P. Steinbach on February 21st, 2004


* "Allan M" <allanm1@ihug.co.nz> schriebt:
That depends on how advanced you want it.

Very simply, look at the registry entries created by the ftype and assoc commands.



Posted by Joakim Braun on February 22nd, 2004


"Allan M" <allanm1@ihug.co.nz> skrev i meddelandet
news:01c3f891$bdb7edc0$74c0adcb@default...
Basically, one part of the Windows registry contains data to associate a
file extension with another part of the registry ("ProgID"), which specifies
what actions are permissible on the file, what applications to use and how
to call them. For instance, if you type ".doc" in HKEY_CLASSES_ROOT in the
registry editor, you see entries like:

(Standard) REG_SZ Word.Document.8

This makes the system look up another entry called "Word.Document.8", which
among other things contains this:
shell
Open
ddeexec
(Standard) REG_SZ [REM _DDE_Direct][FileOpen("%1")]

This would use DDE (Dynamic Data Exchange) to call Word's main window
handler with various messages, but there are other possible mechanisms too.

The mechanism is not exactly intuitive. I would strongly recommend getting
an overview by glancing through the entire file extension stuff at MSDN
before you do any coding. I was quite stumped by this a while ago, and
didn't find too much in the way of helpful code, so I'm posting my own
quick-and-dirty code below... It has suboptimal error checking, and I'm a
Windows newbie. But it gives you a rough idea what to do.

Joakim Braun

Below is quick'n-dirty code to
1. Register the file extension
2. Register a ProgID which uses DDE to open files
3. Handle resulting DDE messages in your frame window

//************************************************** *****************

bool
RegisterFileExtension( char* inFileExtension,
char* inPerceivedTypeData,
char* inContentTypeData,
char* inProgID){

bool result = false;
long fResult = ERROR_SUCCESS;
TCHAR perceivedTypeKeyName[] = TEXT("PerceivedType"),
contentTypeKeyName[] = TEXT("Content Type");
HKEY fileExtensionKey = NULL;
DWORD disposition = 0;

try{

fResult = RegCreateKeyEx( HKEY_CLASSES_ROOT,
inFileExtension,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&fileExtensionKey,
&disposition);

if(fResult != ERROR_SUCCESS)
throw fResult;

// Set value of CurVer key
fResult = RegSetValueEx( fileExtensionKey,
NULL,
0,
REG_SZ, // flag for value type
(BYTE*) inProgID, // address of value data
strlen(inProgID));

if(fResult != ERROR_SUCCESS)
throw fResult;

// Set value of FriendlyTypeName key
fResult = RegSetValueEx( fileExtensionKey,
perceivedTypeKeyName, // address of value to set
0,
REG_SZ, // flag for value type
(BYTE*) inPerceivedTypeData, // address of value data
strlen(inPerceivedTypeData));

if(fResult != ERROR_SUCCESS)
throw fResult;

// Set value of InfoTip key
fResult = RegSetValueEx( fileExtensionKey,
contentTypeKeyName, // address of value to set
0,
REG_SZ, // flag for value type
(BYTE*) inContentTypeData, // address of value data
strlen(inContentTypeData));

if(fResult != ERROR_SUCCESS)
throw fResult;

RegCloseKey(fileExtensionKey);
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_DWORD, NULL, NULL);

result = true;
}
catch(...){

}

return result;
}

//************************************************** *****************

bool
RegisterProgID( char* inProgID,
char* inCurrentVersionData,
char* inFriendlyTypeNameData,
char* inInfoTipData,
int inDefaultIconID,
char* inExecutable){

bool result = false;
long fResult = 0;
TCHAR currentVersionKeyName[] = TEXT("CurVer"),
friendlyTypeNameKeyName[] = TEXT("FriendlyTypeName"),
infoTipKeyName[] = TEXT("InfoTip"),
defaultIconKeyName[] = TEXT("DefaultIcon"),
shellOpenKeyName[] = TEXT("shell\\open"),
shellOpenCommandKeyName[] = TEXT("command"),
shellOpenDdeexecKeyName[] = TEXT("ddeexec"),
shellOpenDdeexecKeyValue[] = TEXT("[open(\"%1\")]"),
shellOpenDdeexecApplicationKeyName[] = TEXT("application");
HKEY applicationProgIDKey = NULL,
currentVersionKey = NULL,
shellOpenKey = NULL,
shellOpenCommandKey = NULL,
shellOpenDdeexecKey = NULL,
defaultIconKey = NULL;
string str;
cString iconIDstr((long)inDefaultIconID);
DWORD disposition = 0;

try{

//************************************************** ******
// Open/create top level application PROGID key
fResult = RegCreateKeyEx( HKEY_CLASSES_ROOT,
inProgID,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&applicationProgIDKey,
&disposition);

if(fResult != ERROR_SUCCESS)
throw fResult;

// Set value of unnamed key
fResult = RegSetValueEx( applicationProgIDKey,
NULL/*LPCTSTR lpValueName*/, // address of value to set
0,
REG_SZ, // flag for value type
(BYTE*) inProgID, // address of value data
strlen(inProgID));

//************************************************** ******
// Create CurVer key
fResult = RegCreateKeyEx( applicationProgIDKey,
currentVersionKeyName,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&currentVersionKey,
&disposition);

if(fResult != ERROR_SUCCESS)
throw fResult;

// Set value of CurVer key
fResult = RegSetValueEx( currentVersionKey,
NULL/*LPCTSTR lpValueName*/, // address of value to set
0,
REG_SZ, // flag for value type
(BYTE*) inCurrentVersionData, // address of value data
strlen(inCurrentVersionData));

if(fResult != ERROR_SUCCESS)
throw fResult;

RegCloseKey(currentVersionKey);

//************************************************** ******
// Set value of FriendlyTypeName key
fResult = RegSetValueEx( applicationProgIDKey,
friendlyTypeNameKeyName, // address of value to set
0,
REG_SZ, // flag for value type
(BYTE*) inFriendlyTypeNameData, // address of value data
strlen(inFriendlyTypeNameData));

if(fResult != ERROR_SUCCESS)
throw fResult;

//************************************************** ******
// Set value of InfoTip key
fResult = RegSetValueEx( applicationProgIDKey,
infoTipKeyName, // address of value to set
0,
REG_EXPAND_SZ, // flag for value type
(BYTE*) inInfoTipData, // address of value data
strlen(inInfoTipData));

if(fResult != ERROR_SUCCESS)
throw fResult;

//************************************************** ******
// Create shell/open key
fResult = RegCreateKeyEx( applicationProgIDKey,
shellOpenKeyName,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&shellOpenKey,
&disposition);

if(fResult != ERROR_SUCCESS)
throw fResult;

// Create shell/open/command key
fResult = RegCreateKeyEx( shellOpenKey,
shellOpenCommandKeyName,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&shellOpenCommandKey,
&disposition);

if(fResult != ERROR_SUCCESS)
throw fResult;

str = "\"";
str += inExecutable;
str += "\" \"%1\"";

// Set value of shell/open/command key
fResult = RegSetValueEx( shellOpenCommandKey,
NULL/*LPCTSTR lpValueName*/, // address of value to set
0,
REG_SZ, // flag for value type
(BYTE*) str.c_str(), // address of value data
str.length());

RegCloseKey(shellOpenCommandKey);

// Create shell/open/ddeexec key
fResult = RegCreateKeyEx( shellOpenKey,
shellOpenDdeexecKeyName,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&shellOpenDdeexecKey,
&disposition);

if(fResult != ERROR_SUCCESS)
throw fResult;

// Set value of shell/open/ddeexec/ key
fResult = RegSetValueEx( shellOpenDdeexecKey,
NULL/*LPCTSTR lpValueName*/, // address of value to set
0,
REG_SZ, // flag for value type
(BYTE*) shellOpenDdeexecKeyValue, // address of value data
lstrlen(shellOpenDdeexecKeyValue));

if(fResult != ERROR_SUCCESS)
throw fResult;

// Set value of shell/open/ddeexec/application key
fResult = RegSetValueEx( shellOpenDdeexecKey,
shellOpenDdeexecApplicationKeyName, // address of value to set
0,
REG_SZ, // flag for value type
(BYTE*) inProgID, // address of value data
strlen(inProgID));

if(fResult != ERROR_SUCCESS)
throw fResult;

RegCloseKey(shellOpenDdeexecKey);

//************************************************** ******
// Create DefaultIcon key

str = "\"";
str += inExecutable;
str += "\",";
str += (char*)iconIDstr;

fResult = RegCreateKeyEx( applicationProgIDKey,
defaultIconKeyName,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&defaultIconKey,
&disposition);

if(fResult != ERROR_SUCCESS)
throw fResult;

// Set value of default icon key
fResult = RegSetValueEx( defaultIconKey,
NULL/*LPCTSTR lpValueName*/, // address of value to set
0,
REG_SZ, // flag for value type
(BYTE*) str.c_str(), // address of value data
str.length());

if(fResult != ERROR_SUCCESS)
throw fResult;

RegCloseKey(defaultIconKey);

//************************************************** ******
// Cleanup
RegCloseKey(applicationProgIDKey);

SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_DWORD, NULL, NULL);

result = true;
}
catch(...){

}

return result;
}

//************************************************** *****************
// From my frame window handler

case WM_DDE_INITIATE:
{
/*
WM_DDE_INITIATE
wParam = (WPARAM) hwnd; // handle of posting appl.
lParam = MAKELPARAM(aApp, aTopic); // appl. and topic atoms
aApp Value of the low-order word of lParam.
Contains an atom that identifies the application with which
a conversation is requested. The application name cannot contain slashes
(/)
or backslashes (\). These characters are reserved for network
implementations.
If aApp is NULL, a conversation with all applications is requested.

aTopic Value of the high-order word of lParam.
Contains an atom that identifies the topic for which a conversation
is requested. If the topic is NULL, conversations for all available
topics are requested.


To complete the initiation of a conversation,
the server application must respond with one or more WM_DDE_ACK messages,
where each message is for a separate topic.
When sending WM_DDE_ACK message, the server should create new aApp and
aTopic atoms;
it should not reuse the atoms sent with WM_DDE_INITIATE.
*/

ATOM aApp = LOWORD(lParam),
aTopic = HIWORD(lParam),
appNameAtom = 0,
systemTopicAtom = 0;
TCHAR appStr[255],
topicStr[255],
systemTopicStr[] = TEXT("System");

GlobalGetAtomName(aApp, appStr, sizeof(appStr) / sizeof(TCHAR) /
sizeof(char));
GlobalGetAtomName(aTopic, topicStr, sizeof(topicStr) / sizeof(TCHAR) /
sizeof(char));

if(lstrcmp(topicStr, systemTopicStr) == 0){

// we have a system conversation going
// Make new atoms for app name and topic
appNameAtom = AddAtom(appStr);
systemTopicAtom = AddAtom(systemTopicStr);

SendMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)hwnd,
MAKELPARAM(appNameAtom, systemTopicAtom));
}
return 0;
}
break;

case WM_DDE_EXECUTE:
{
HGLOBAL hGlobal = (HGLOBAL)lParam;
TCHAR* cmdString = (TCHAR*) GlobalLock(hGlobal);

if(cmdString){

// parse the string
// cString is my own string class - but you see the point
cString theString(cmdString);
string plainString = (string&) theString;
short fileNamePtrStart = 0;
char openString[] = "[open(\"";
char* fileNamePtr = 0;

fileNamePtrStart = plainString.find(openString);

if(fileNamePtrStart != string::npos){

fileNamePtr = &plainString[strlen(openString)];

// we now have the start of a file name in startOffset
fileNamePtr[strlen(fileNamePtr) - 3] = 0x00;

theString = fileNamePtr;

// theString now contains the path to the file.
// open the file as appropriate, then...

GlobalUnlock(hGlobal);

DDEACK ack;
PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)hwnd,
PackDDElParam(WM_DDE_ACK, (UINT) &ack, (UINT)lParam));
}
}
else
GlobalUnlock(hGlobal);
return 0;
}
break;

case WM_DDE_TERMINATE:
{
PostMessage((HWND)wParam, WM_DDE_TERMINATE, (WPARAM)hwnd, 0);
return 0;
}
break;




Similar Posts