Pelles C forum

C language => Windows questions => Topic started by: czerny on September 30, 2014, 05:59:43 PM

Title: Class not registered
Post by: czerny on September 30, 2014, 05:59:43 PM
I have the error:

0x80040154 Class not registered error

after the following sequence:

Code: [Select]
IOpenControlPanel *pocp;

hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
hr = CoCreateInstance(&CLSID_OpenControlPanel, NULL, CLSCTX_INPROC_SERVER, &IID_IOpenControlPanel, (void **)&pocp);

Is it really possible, that IOpenControlPanel class is not registered? Or is there something else wrong?
Title: Re: Class not registered
Post by: aardvajk on September 30, 2014, 06:41:49 PM
All shell interfaces require the apartment threaded model (COINIT_APARTMENTTHREADED), it also only exists on Vista and up.
Title: Re: Class not registered
Post by: czerny on September 30, 2014, 07:48:06 PM
Sorry! What exists only in Vista and uo? The shell interfaces or the apartment threaded model?
Title: Re: Class not registered
Post by: laurro on September 30, 2014, 10:42:59 PM
The IOpenControlPanel interface, and many others shell interfaces but not all,
exist only for Vista and above, see the minimum system requirement.
Tested on my Vista machine:

Code: [Select]
#include <windows.h>
#include <shobjidl.h>
#pragma comment(lib,"ole32.lib")
#pragma comment(lib,"uuid.lib")

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
{
IOpenControlPanel *p;

HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(&CLSID_OpenControlPanel, NULL, CLSCTX_INPROC_SERVER, &IID_IOpenControlPanel, (void **)&p);
if (SUCCEEDED(hr))
{
hr = p->lpVtbl->Open(p, L"Microsoft.Personalization", L"pageColorization", NULL);
p->lpVtbl->Release(p);
}
}
CoInitialize(NULL);
return 0;
}


Laur
Title: Re: Class not registered
Post by: czerny on October 01, 2014, 08:31:24 AM
Sorry! What exists only in Vista and uo? The shell interfaces or the apartment threaded model?
Is there an alternative in w2k/XP?
Title: Re: Class not registered
Post by: laurro on October 01, 2014, 09:12:19 AM
As a COM ? I don't think so. But you can try ShellExecute().

Code: [Select]
#include <windows.h>
#include <shellapi.h>
#pragma comment(lib,"shell32.lib")

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
{
//ShellExecute(NULL, "open", "control", "/name Microsoft.Personalization /page pageColorization", NULL, SW_SHOW);
//ShellExecute(NULL, "open", "control", "/name Microsoft.DateAndTime", NULL, SW_SHOW);
ShellExecute(NULL, "open", "control", "timedate.cpl", NULL, SW_SHOW);
return 0;
}

see
http://msdn.microsoft.com/en-us/library/windows/desktop/cc144191%28v=vs.85%29.aspx#opening_a_control_panel_item_from_the_command_line_with_control.exe (http://msdn.microsoft.com/en-us/library/windows/desktop/cc144191%28v=vs.85%29.aspx#opening_a_control_panel_item_from_the_command_line_with_control.exe)
and
http://msdn.microsoft.com/en-us/library/windows/desktop/ee330741%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ee330741%28v=vs.85%29.aspx)

Laur
Title: Re: Class not registered
Post by: czerny on October 01, 2014, 02:11:48 PM
As a COM ? I don't think so. But you can try ShellExecute().
I know this way! Thanks!
Title: Re: Class not registered
Post by: aardvajk on October 03, 2014, 07:18:54 PM
The interface is Vista plus. Shell interfaces have always required apartment threads.
On XP you can use IShellDispatch::ControlPanelItem (http://msdn.microsoft.com/en-gb/library/windows/desktop/gg537712(v=vs.85).aspx) but it doesn't work on Vista plus. They recommend you use laurro's method above, so I'd just use that.
Title: Re: Class not registered
Post by: laurro on October 03, 2014, 10:49:43 PM
Hi aardvajk
For a method that supposedly does not work, well, I have to close a lot of windows.
Of course it is not your fault, the documentation is wrong and I'm pretty sure is
wrong intentionally. If you have Vista or 7 (x86) run this, I'm not sure on 64 bit
systems, I don't have the possibility to test.

Code: [Select]
#define UNICODE
#include <windows.h>
#include <shobjidl.h>
#include <shldisp.h>
#include <wchar.h>
#pragma comment(lib,"ole32.lib")
#pragma comment(lib,"uuid.lib")
#pragma comment(lib,"oleaut32.lib")

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
{
WIN32_FIND_DATA FileData;
HANDLE hSearch;
wchar_t first[MAX_PATH] = { 0 };
wchar_t *expand = malloc(sizeof(wchar_t));
if (expand)
{
DWORD d = ExpandEnvironmentStrings(L"%SystemRoot%", expand, 1);
expand = realloc(expand, d * sizeof(wchar_t));
if (expand)
{
ExpandEnvironmentStrings(L"%SystemRoot%", expand, d);
wcscpy(first, expand);
wcscat(first, L"\\System32\\*.cpl");
free(expand);
}
else
return 0;
}
else
return 0;
hSearch = FindFirstFile(first, &FileData);
if (hSearch == INVALID_HANDLE_VALUE)
return 0;
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (FAILED(hr))
{
FindClose(hSearch);
return 0;
}
/////////////////////
IShellDispatch *shell;
/////////////////////
hr = CoCreateInstance(&CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, &IID_IShellDispatch, (void **)&shell);
if (FAILED(hr))
{
FindClose(hSearch);
CoInitialize(NULL);
return 0;
}
hr = shell->lpVtbl->ControlPanelItem(shell, FileData.cFileName);
while (1)
{
if (FindNextFile(hSearch, &FileData))
{
hr = shell->lpVtbl->ControlPanelItem(shell, FileData.cFileName);
if (FAILED(hr))
MessageBox(NULL, L"error", FileData.cFileName, MB_OK);
}
else
break;
}
shell->lpVtbl->Release(shell);
FindClose(hSearch);
CoInitialize(NULL);
return 0;
}


Laur