|
I have a dialog app with a function similar to this:
void CMyDlg::OnButton1()
{
//This bit works
WinExec("cmd.exe /c xcopy /s "+myfolder+" "+target_folder+" >>mylog.txt&exit",SW_HIDE);
// This is what i want to do:
// if (all files have been copied and cmd.exe exits then display the msgbox, if not, wait until filecopy is done and then display the msgbox)
// {
AfxMessageBox("Done! All files copied to target folder.",MB_OK|MB_ICONINFORMATION);
// }
}
The way the function works right now, the msgbox displays too early, and not after all the files are copied.
I guess i need some kind of return value, and then if its true/false then display msgbox.
How to solve this problem, any suggestions? Is this "doable" in any easy way?
Createprocess? If so, how would the Createprocess code look like?
thx!
|
|
|
|
|
Google for "CProcessWait". It used to be in an article here on CP, but PJ Naughter or Arendt (sorry do not know anymore) put it in a utility library.
|
|
|
|
|
rolfhorror wrote: Createprocess? If so, how would the Createprocess code look like?
Call CreateProcessEx() followed by WaitForSingleObject() .
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
In my program, I deliberately did not specify a background color in my WNDCLASSEX struct. As a result, I must paint it manually. My WNDPROC simply passes off all its arguments to an identical (static) function in a Controller class I created. The Controller class looks up the relevant HWND in a list and routes to the appropriate message handler for each object via a pointer GuiObject pointer.
My problem is the WM_ERASEBKGND message. The device context is contained in the WPARAM parameter, but when I try to pass WPARAM to my object's message handler, I get a linker error:
"LNK2001: unresolved external symbol "protected: virtual int __thiscall GuiObject::OnEraseBackground(void)" (?OnEraseBackground@GuiObject@@MAEHXZ)"
As far as I can tell, this only happens with Windows data types. I can pass ints and other things in with no problem.
Here is the code:
LRESULT Controller::MessageDispatcher(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)<br />
{<br />
for(current=head; !current->hWnd; current=current->next)<br />
if(current->next=NULL) break;<br />
<br />
switch(msg)<br />
{<br />
case WM_ERASEBKGND:<br />
current->OnEraseBackground((HDC) wParam);<br />
break;<br />
...<br />
}<br />
Can anyone tell me what I'm doing wrong?
Thanks in advance
-- modified at 11:32 Monday 6th August, 2007
|
|
|
|
|
If "current->OnEraseBackground((HDC)wParam);" compiles, then you are missing the actual implementation
of the OnEraseBackground method.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Ummm, this is weird . . .
I checked the implementation and everything looks correct. The function is stubbed in both my GuiObject.h and GuiObject.cpp files.
Just for grins, I tried removing the virtual keyword from the function in the header. It compiled just fine. Then I made it virtual again and now it compiles fine either way.
Is this a VS.NET bug??
Thanks for pointing me in the right direction, though.
|
|
|
|
|
We used to build our software with VC 6.0 and use rebase.exe to split the debug information off into a separate file (after adding debug information to the Release builds). Once we moved to VS 2005 and Vista, the same procedures stopped working. The Release build still have the options turned on to add debug information to executables; however, rebase.exe fails to find it.
We need the .dbg files so that we can create crash reports, if the software ever fails on a remote system.
cheers,
-B
|
|
|
|
|
Hi...
I've a VC5 Win32 dll which I've converted to VC8 with same code and project settings.
The dll contains lot of STL code.
I'm getting crash from the main application when I'm using release version of the DLL. The Debug version works fine.
Could anybody help me out...?
|
|
|
|
|
I use VC2005.
When I compile the project with /GX-,such error:
LINK error1181:Cann't open input file "Gx.obj"
Somebody would like to help me how to resolve such problems?
Thanks
|
|
|
|
|
well, obviously, you set the parameter on the linker, not the compiler...
|
|
|
|
|
perhaps that is true.
And would you like to tell me how and where should set such parameter?
Thanks
|
|
|
|
|
kcynic wrote: /GX-
This is taken as an input object file for the linker, hence the gx.obj. Are you sure you gave it to the compiler and not the linker ?
|
|
|
|
|
Hi all,
Any pointers on methods of image comparision(two bmp image sof high resolution)
Regards
|
|
|
|
|
Have you seen this?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Hello,
I have a control window of type CEdit over which I want a ListBox to appear.
But when the list box appears on the edit box some part of the edit box is still seen even within the listbox.
How should I hide the edit box completely ?
Thanks
Prithaa
|
|
|
|
|
completely?
With a this->ShowWindow(SW_HIDE);
I hope this works in your case
|
|
|
|
|
CEdit::ShowWindow(SW_HIDE);
Greetings from Germany
|
|
|
|
|
I have written a piece of code to enumerate a subkey name in the registry.Here is the function:
<code>
HKEY RegOpen( HKEY hKey, LPCTSTR pszSubKey, DWORD dwRights)
{
HKEY hSubKey;
if ( RegOpenKeyEx(
hKey,
pszSubKey,
0,
dwRights,
&hSubKey
) == ERROR_SUCCESS
)
{
return hSubKey;
}
return NULL;
};
bool RegEnumSubKeys(
CString szName,
HKEY hStartKey,
CString strStartKey
)
{
DWORD dwSubKeyCnt, dwMaxSubKey;
if ( RegQueryInfoKey(
hStartKey,
NULL,
NULL,
0,
&dwSubKeyCnt,
&dwMaxSubKey,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
) == ERROR_SUCCESS
)
{
if(dwSubKeyCnt)
{
dwMaxSubKey +=1;
LPTSTR pszKeyName = (LPTSTR)::malloc( dwMaxSubKey*sizeof(TCHAR) );
if(pszKeyName)
{
FILETIME ftWriteTime;
LONG retCode;
DWORD i=0;
for(i=0;i< dwSubKeyCnt; i++)
{
if (ERROR_SUCCESS == (retCode = RegEnumKeyEx(
hStartKey,
i,
pszKeyName,
&dwMaxSubKey,
NULL,
NULL,
NULL,
&ftWriteTime
))
)
{
CString csFound;
csFound.Format(_T("%s\\%s"), strStartKey, pszKeyName);
TRACE(_T("%s\n"), csFound);
HKEY hSubKey = RegOpen(hStartKey, pszKeyName, KEY_ALL_ACCESS);
if(hSubKey)
{
if(RegEnumSubKeys(szName, hSubKey, csFound))
{
RegClose(hSubKey);
}
else
{
RegClose(hSubKey);
::free( (LPVOID) pszKeyName );
return false;
}
}
else
{
::free( (LPVOID) pszKeyName );
return false;
}
}
else
{
::free( (LPVOID) (LPCTSTR) pszKeyName );
return false;
}
}
::free( (LPVOID) pszKeyName );
}
else
return false;
}
return true;
}
return false;
};
unfortunately, the function only can trace one branch of the registry. I checked the code, the RegEnumKeyEx returned ERROR_MORE_DATA when it execute twice or more。However, if I use the RegEnumKey instead of RegEnumKeyEx, the function works well. Who can tell me why? Highly appreciated!
-- modified at 20:47 Monday 6th August, 2007
|
|
|
|
|
Please modify your post by surrounding the code snippet with <pre> tags.
How is RegEnumSubKeys() initially called?
What is RegOpen() ?
I assume you know of the missing comma in the function's parameter list.
Have you considered simplifying your code to something like:
LONG RegEnumSubKeys( HKEY hStartKey, LPCTSTR lpszStartKey )
{
LONG retCode;
HKEY hSubKey;
TCHAR szKeyName[MAX_PATH];
int i = 0;
retCode = RegOpenKeyEx(hStartKey, lpszStartKey, 0, KEY_READ, &hSubKey);
if (ERROR_SUCCESS == retCode)
{
while (ERROR_SUCCESS == retCode)
{
DWORD dwMaxSubKey = MAX_PATH;
retCode = RegEnumKeyEx(hSubKey,
i++,
szKeyName,
&dwMaxSubKey,
NULL,
NULL,
NULL,
NULL);
if (ERROR_NO_MORE_ITEMS == retCode)
break;
else if (ERROR_SUCCESS == retCode)
retCode = RegEnumSubKeys(hSubKey, szKeyName);
}
retCode = RegCloseKey(hSubKey);
}
return retCode;
}
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Thanks for you response! I have appended the RegOpen function to the original code snippets.
I have tried your code, unfortunately it can only enumerate one branch of the registry just like my original code. If replace the RegEnumKeyEx with RegEnumKey, it works. However, the RegEnumKey is obsolete in MSDN.
In the CodeProject site, I checked http://www.codeproject.com/system/cregistrykey.asp[^] that uses RegEnumKeyEx to finish the job. It is pretty complicated and I did not find remarkable logical differences between his codes and mine.
|
|
|
|
|
retinex wrote: I have tried your code, unfortunately it can only enumerate one branch of the registry...
I'm not sure what you did to make it stop working, but I used that code to drill down several levels deep and it worked fine.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
<code>for(i=0;i< dwSubKeyCnt; i++)
{
DWORD ghostMaxSubKey = dwMaxSubKey;
if (ERROR_SUCCESS == (retCode = RegEnumKeyEx(
hStartKey,
i,
pszKeyName,
&ghostMaxSubKey,
NULL,
NULL,
NULL,
&ftWriteTime
))
)
{
Thanks for your help.
I checked my code and added one line prior to the RegEnumKeyEx,e.g. the Underlined code. It works fine. However, I don't know why?
|
|
|
|
|
I get the error when compiling my old project with VS 2005, no problems with VS 2003.
:-
3>c:\AC_emu\filetreectrl.cpp(460) : error C3861: 'TRACE': identifier not found
How can I get rid of this error please;
e.g. TRACE(_T("Cannot select a empty path\n"));
|
|
|
|
|
It's an MFC construct. Is your project using MFC?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Yes its an MFC Dialog application.
|
|
|
|
|