|
for the following code, i am getting bret = false . why is that?
-------------------------------------------
if (OpenClipboard(NULL))
{
bret = EmptyClipboard();
char _Error_MSG_Macro_Buffer[MAX_STRING];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,0,GetLastError(),0,&_Error_MSG_Macro_Buffer[0],MAX_STRING,0);
}
-------------------------------------------
if "OpenClipboard(NULL)" is true, then it should work with no problem, but it fails.
i don't have a window in my application.
"FormatMessage" gives the following:
"Thread does not have a clipboard open.
how can that be?
|
|
|
|
|
This piece of code works...
{<br />
HANDLE hClip;<br />
LPTSTR lptstr;<br />
<br />
if (!::IsClipboardFormatAvailable(CF_TEXT)) <br />
{
return; }<br />
if (!::OpenClipboard(NULL)) <br />
{
return;} <br />
<br />
hClip = ::GetClipboardData(CF_TEXT); <br />
if (hClip != NULL) <br />
{ <br />
lptstr =(LPTSTR) ::GlobalLock(hClip);
if (lptstr != NULL) <br />
{ <br />
<br />
MessageBox(lptstr);
<br />
::GlobalUnlock(hClip); <br />
} <br />
} <br />
::CloseClipboard(); <br />
}
|
|
|
|
|
I can get the string from the clipboard.
The problem is that i can't set a string to it.
that's the reason i need to use EmptyClipboard.
EmptyClipboard failed.
|
|
|
|
|
|
i tried using the code from your first link (i changed OpenClipboard() to OpenClipboard(NULL)), but it doesn't work for me.
i am getting "Thread does not have a clipboard open." with GetLastError for "EmptyClipboard" function call.
the function i am using resides in a DLL. could that be the reason for the problem?
|
|
|
|
|
Hi,
see what MSDN says...
If an application calls OpenClipboard with hwnd set to NULL, EmptyClipboard sets the clipboard owner to NULL; this causes SetClipboardData to fail.
OpenClipboard() and EmptyClipboard()will still work in a .dll
But we need to pass a proper HWND to set clip-board data.
Maybe you can create a window/ or use a window handle temporarily.
|
|
|
|
|
This same code snippet worked fine on my machine. Try calling GetOpenClipboardWindow() and/or GetClipboardOwner() after the clipboard is open. This does not solve the problem, but it might help to uncover something that is not immediately obvious.
A rich person is not the one who has the most, but the one that needs the least.
|
|
|
|
|
I have done Wh_getmessage hook.
In my filter function i have typecast the Wm_char message
like Say if Char 'A' is pressed i send the char 'A' as it is to the application.
NOw if user press 'B' then what i am doing is changing the Char 'B' to BackSpace character.
TO this point the application is working properly in all application for it is a system wide hook , where pressing of B removes 'A' for B is a backspace character
A , B->backspace
out put = NUll
Now what i am doing is using PostMessage api i am sendging 2 characters to that application which is active
Say POSTMESSAGE(C ,D)
I got these problems:
1. The character C when posted to the application , my filter function is called again and( i have defined a rule for C where if the user type
C then change to E) and i expected C to be printed in the application , but instead E is coming.
I have to find a way how to prevent this ie the postmessage which i have send to the application looping through my filter funcion again and again.
___________________________________________________________________________
2. If i declare like this
A , B->backspace character , Postmessage(C,D)
Expected output
CD
Output obtained in notepad and photoshop
AC and D is removed(Wrong)
Output obtaied in all other application
CD(correct)
_________________________________________________________________________
3. So i tried this method
A , B->NULL , Postmessage(backSpace,C,D)
Expected output
CD
Output obtained in notepad and photoshop
CD(correct)
Output obtaied in all other application
AC and D is removed(Wrong)
Could anyone tell me how i can overcome these problems
Thanks in advance
with regards
vimal
|
|
|
|
|
Hi all !
I have a SDI apllication in wich I start another apllication (from the document). I need to make some things when this application has closed so I start a new thread that waits for the termination of this application.
But how can I send a message to the main Thread ?? I read that we cannot pass MFC classes from a thread to another so I cannot pass a pointer to the main window.
Thanks
|
|
|
|
|
Although CWnd object are not thread safe, they are a wrapper for the windows HWND member, which is. Pass this through as a parameter to the tread and send the message to that.
Roger Allen - Sonork 100.10016
Roger Wright: Remember to buckle up, please, and encourage your friends to do the same. It's not just about saving your life, but saving the quality of life for those you may leave behind...
|
|
|
|
|
Hum hum !
Yes that was so easy that I didn't think about that
Thanks a lot for reply
|
|
|
|
|
Ok so That works but the problem is I have to pass also the handle to the process I have to wait for.
So I create a structure with the HWND (window) and the HANDLE (process) and I send this to the Thread. This structure is a local one so datas are no more valid after the functions is left.
What is the best solution ? Dynamically create the structure and delete it from within the thread ?? Or what?
|
|
|
|
|
You get better results by using "PostThreadMessage" and related macros. And never use CWnd* as as already mentioned.
Try this @ home. (B&B)
|
|
|
|
|
I still have to pass two parameters: the HANDLE of the process I have to wait for and the Id of the main Thread. So The problem remains the same...
Or is it a way to retrieve the ThreadId of the application main's Thread ?
|
|
|
|
|
Hi
I want to write information to the registry 'HKEY_LOCAL_MACHINE\Software'.
I don't think it is possible by using the MFC function (WriteProfileString).
How can i fix the problem without having to fear that it won't run perfectly on all windows systems?
What do you guys/girls recommend me?
Greetings
Jens
|
|
|
|
|
No its not possible using the standard MFC functions. We needed to do the same in our app. We took the existing code in the GEtProfileString() and the ancillary functions, pasted them verbatum and changed all the HKEY_CURRENT_USER references to HKEY_LOCAL_MACHINE. After adding a LM to the end of each function name it worked really well.
The only issue you may have is access rights. Depending on how the admin sets up registry access, your application could possible be blocked from writing to HLM.
Roger Allen - Sonork 100.10016
Roger Wright: Remember to buckle up, please, and encourage your friends to do the same. It's not just about saving your life, but saving the quality of life for those you may leave behind...
|
|
|
|
|
Use CRegKey class to read and write to registry.
Regards,
Jijo.
________________________________
Yesterday is history,
Tomorrow is a mystery,
But today is a present.
|
|
|
|
|
I've just read this article:
'http://www.endurasoft.com/techtalk/regdemo2.htm'
Does this API work on all Windows version correctly?
Greetings,
Jens
|
|
|
|
|
Those SDK Functions will surely work on all window platforms.
Regards,
Jijo.
________________________________
Yesterday is history,
Tomorrow is a mystery,
But today is a present.
|
|
|
|
|
Well, i'll try the CRegKey class first out.
If that works good enough, i won't use the SDK functions.
Greetings
Jens
|
|
|
|
|
Okey. CRegKey is easier than SDK methods. If any help, feel free to ask.
Regards,
Jijo.
________________________________
Yesterday is history,
Tomorrow is a mystery,
But today is a present.
|
|
|
|
|
Yes. Totally right.
I just discovered that CRegKey is a wrapper around the SDK methods which allows easier usage / less coding work.
(We all love that .. don't we )
So using the SDK functions directly wouldn't be smart.
I already managed to deleted/create a new key at the 'HKEY_LOCAL_MACHINE' so that's cool.
But i miss 1 big feature (maybe you can still help me with this one).
Let's say i want to copy all contents (all keys and all values of it subkeys) of 'HKEY_CURRENT_USER\Software\CompanyName\ProgName\'
to 'HKEY_LOCAL_MACHINE\Software\CompanyName\ProgName\'
So it's an entire "copy" that has to be made + sub keys should be copied too.
How can i achieve this? I'd like to combine this with the CRegKey class anyways.
Greetings
Jens
|
|
|
|
|
I think there is no readymade function to copy the regkeys recursively.
Using the RegEnumKey () or RegEnumKeyEx () function, we get all the subkeys under a specific key.
Then using this function you can recursively traverse the registry subtree. For that you should know the tree traversal algorithm. Then while reading each key, make an identical copy of it under the destination keytree.
Hope this helps you. The only problem is the tree traversal. It will be a little bit difficult. Dont worry. Im searching some more easier method for copying the registry and will inform you, when i get it.
Regards,
Jijo.
________________________________
Yesterday is history,
Tomorrow is a mystery,
But today is a present.
|
|
|
|
|
ehehe allrightie then
Let me know when you have found something usefull
Thanks
Jens
|
|
|
|
|
hai Jens,
Use the following code. I got it from my friend - John AV, who is a registry expert. Okey. First be thorough with the code, make any changes if you need, then use it.
const static int nMaxValueNameSize = MAX_PATH;
const static int nMaxValueValueSize = 4096;
const static int nMaxClassSize = MAX_PATH;
const static int nMaxKeyNameSize = MAX_PATH;
BOOL CopyRegistryKey(HKEY hkRootFrom, const CString& strFromPath, HKEY hkRootTo, const CString& strToPath)
{
HKEY hkFrom;
LONG res = ::RegOpenKeyEx(hkRootFrom, strFromPath, 0, KEY_READ, &hkFrom);
if (ERROR_SUCCESS != res) {
return FALSE;
}
HKEY hkTo;
res = ::RegCreateKeyEx(hkRootTo, strToPath, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hkTo, 0);
if (ERROR_SUCCESS != res) {
::RegCloseKey(hkFrom);
return FALSE;
}
BOOL bRes = CopyKeys(hkFrom, hkTo) && CopyValues(hkFrom, hkTo);
::RegCloseKey(hkFrom);
::RegCloseKey(hkTo);
return bRes;
}
static BOOL CopyKeys(HKEY hkFrom, HKEY hkTo)
{
TCHAR lpstrName[nMaxKeyNameSize];
TCHAR lpstrClass[nMaxClassSize];
for (int i = 0;;i++) {
DWORD nNameSize = nMaxKeyNameSize;
DWORD nClassSize = nMaxClassSize;
LONG res = ::RegEnumKeyEx(hkFrom, i, lpstrName, &nNameSize, 0, lpstrClass, &nClassSize, 0);
if (ERROR_NO_MORE_ITEMS == res) {
break;
}
HKEY hkNew;
res = ::RegCreateKeyEx(hkTo, lpstrName, 0, lpstrClass, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hkNew, 0); ;
if (ERROR_SUCCESS != res) {
return FALSE;
}
::RegCloseKey(hkNew);
BOOL bRes = CopyRegistryKey(hkFrom, lpstrName, hkTo, lpstrName);
if (! bRes) {
return FALSE;
}
}
return TRUE;
}
static BOOL CopyValues(HKEY hkFrom, HKEY hkTo)
{
TCHAR lpstrName[nMaxValueNameSize];
BYTE pValue[nMaxValueValueSize];
for (int i = 0;;i++) {
DWORD nType;
DWORD nNameSize = nMaxValueNameSize;
DWORD nValueSize = nMaxValueValueSize;
LONG res = ::RegEnumValue(hkFrom, i, lpstrName, &nNameSize, 0, &nType, pValue, &nValueSize);
if (ERROR_NO_MORE_ITEMS == res) {
break;
}
res = ::RegSetValueEx(hkTo, lpstrName, 0, nType, pValue, nValueSize);
if (ERROR_SUCCESS != res) {
return FALSE;
}
}
return TRUE;
}
Hope this helped you.
Regards,
Jijo.
________________________________
Yesterday is history,
Tomorrow is a mystery,
But today is a present.
|
|
|
|
|