|
I want to write a simple windows program that lets me run a dos program with different buttons for different arguments. (I use visual C++, but I'm quite a newbie to windows programming).
1. user makes sure my (front-end) program is in the same directory as the dos program.
2. user specifies the arguments (the bits that come after the the program name ie: program_name.exe -h) (the -h)
3. user specifies a filename for the input/output files (ie: program_name.exe -h input_file.bmp output_file.tgo
Any help would be graciously appreciated.
Thanks.
|
|
|
|
|
Take a look at
CreateProcess, WinExec or good old system
Papa
while (TRUE)
Papa.WillLove ( Bebe ) ;
|
|
|
|
|
Thanks, I did a search for that lot and I found
In CSomeDlg.h<br />
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);<br />
DWORD processPid;<br />
<br />
In CSomeDlg.cpp<br />
void CSomeDlg::startProcess()<br />
{<br />
BOOL bWorked;<br />
STARTUPINFO suInfo;<br />
PROCESS_INFORMATION procInfo;<br />
CString m_Process = "C:\\wherever\\process\\we\\want\\to\\start.exe";<br />
char *vip = "C:\\wherever\\process\\we\\want\\to\\start.exe whatever command line arguments here";<br />
<br />
memset (&suInfo, 0, sizeof(suInfo));<br />
suInfo.cb = sizeof(suInfo);<br />
<br />
bWorked = ::CreateProcess(m_Process,<br />
vip,
NULL,<br />
NULL,<br />
FALSE,<br />
NORMAL_PRIORITY_CLASS,<br />
NULL,<br />
NULL,<br />
&suInfo,<br />
&procInfo);<br />
<br />
<br />
<br />
if (procInfo.dwThreadId = NULL)<br />
{<br />
MessageBox("nope");<br />
}<br />
<br />
playerPid = procInfo.dwProcessId;<br />
}<br />
<br />
<br />
<br />
void CSomeDlg::killProcess()<br />
{<br />
HANDLE ps = OpenProcess( SYNCHRONIZE|PROCESS_TERMINATE, FALSE, processPid);<br />
<br />
EnumWindows(EnumWindowsProc, processPid);<br />
<br />
CloseHandle(ps) ;<br />
}<br />
<br />
BOOL CALLBACK CSomeDlg::EnumWindowsProc(HWND hwnd, LPARAM lParam)<br />
{<br />
DWORD wndPid;<br />
CString Title;<br />
<br />
GetWindowThreadProcessId(hwnd, &wndPid);<br />
<br />
CWnd::FromHandle( hwnd )->GetWindowText(Title);<br />
<br />
if ( wndPid == (DWORD)lParam && Title.GetLength() != 0)<br />
{<br />
::PostMessage(hwnd, WM_CLOSE, 0, 0);<br />
return false;<br />
}<br />
else<br />
{<br />
return true;<br />
}<br />
}<br />
<br />
but I'm quite a newbie can someone help me fill in the blanks (like what other headers I need to include and what to put in the main() or winmain() body).confused:
Anyone?
|
|
|
|
|
Well, I have always been a pipes kinda guy and would normally recommend you look at popen() as it is much easier than CreateProcess, and is alittle more portable. But since you asked to see it as CreateProcess() I would recommend you check out http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q190351&[^] for sample code on spawning console apps and grabbing the handles to do intelligent things to it (control input/output etc).
Of course... if you wanted to know how to do it quick and dirty with popen, consider something like:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char psBuffer[256];
FILE *pFile;
if( (pFile = _popen( "program_name.exe", "-h" )) == NULL )
exit( 1 );
<BR><BR>
while( !feof( pFile ) )
{
if( fgets( psBuffer, 256, pFile ) != NULL )
printf( psBuffer );
}
printf( "Process returned %d\n", _pclose( pFile ) );
}
Or something like that. That code may not work virbatim as I am writing that off the cuff in a browser
Anyways, I hope that link will help you with the CreateProcess() way of doing things. I like popen() when getting down and dirty but I find myself using CreateProcess() more now adays because I can attach a Security Descriptor to the thing. Your milage may vary.
Good luck!
- Dana
|
|
|
|
|
Thank you very much Dana.
Also read up on CreateProcess but I think I'll try some (windows) newbie tutorials first.
Thanks again. _EGGMAN_
|
|
|
|
|
Good morning.
I never was a real C programmer, I went from Pascal to C++ ...
so, a small function design question :
I often see this kind of function where the output value is at the same time returned by the function and assigned to a output variable
char* DoSomething(double val, char *buff)
{
strcpy(buff, something);
return buff;
}
Any explanation ?
Max.
Maximilien Lincourt
For success one must aquire one's self
|
|
|
|
|
This give u the usage in another function call for example
AfxMessageBox ( _T(DoSomething ( dValues , acBuffer ) ) );
while conserving the value returned in acBuffer
Papa
while (TRUE)
Papa.WillLove ( Bebe ) ;
|
|
|
|
|
How can I set the time of a CTime variable? I want to set the time, not the date.
Thanks a lot.
n
|
|
|
|
|
There is a constructor (from docs):
CTime(
int nYear,
int nMonth,
int nDay,
int nHour,
int nMin,
int nSec,
int nDST = –1 );
|
|
|
|
|
From MSDN:
CTime::GetCurrentTime
static CTime PASCAL GetCurrentTime( );
Remarks
Returns a CTime object that represents the current time.
Example
CTime t = CTime::GetCurrentTime();
My opinions may have changed, but not the fact that I am right.
|
|
|
|
|
A CTime object holds both a date and time (which is unfortunate because the name of the class suggests that it just a time value).
So, given a CTime object, how do you go about changing just the time portion? If that's your question, the (also unfortunate) answer is by reassignment. Here's an example:
CTime t = CTime::GetCurrentTime();
t = CTime(t.GetYear(), t.GetMonth(), t.GetDay(), 0, 0, 0);
Regards,
Alvaro
All you need in this life is ignorance and confidence, and then success is sure. -- Mark Twain
|
|
|
|
|
Alvaro,
Your solution is brilliant!
Thanks a lot.
N
|
|
|
|
|
Time is represented by a 32/64 bit number. The date is always part of the "time". If you don't care about the date, always use the current date, and just add the #seconds that represents the time of day.
|
|
|
|
|
Hi !
I was trying to implement a 'Rational Numbers' class when I came across something strange that I never noticed before and that I cannot explain.
Here is my class :
class CRational
{
private:
long m_lNumerator;
long m_lDenominator;
public:
CRational(long lNum=0, long lDenom=1)
{
m_lNumerator=lNum;
m_lDenominator=lDenom;
};
CRational(const CRational& objNombre)
{
m_lNumerator=objNombre.m_lNumerator;
m_lDenominator=objNombre.m_lDenominator;
};
CRational& operator=(const CRational& objNombre)
{
m_lNumerator=objNombre.m_lNumerator;
m_lDenominator=objNombre.m_lDenominator;
return *this;
};
long GetNumerator() { return m_lNumerator; };
long GetDenominator() { return m_lDenominator; };
};
This class is working fine, but I'm wondering why, in the copy constructor, these lines :
m_lNumerator=objNombre.m_lNumerator;
m_lDenominator=objNombre.m_lDenominator;
are allowed by the compiler, because I'm accessing private members of an object.
Well, I tried anyway to change the copy constructor to this :
CRational& operator=(const CRational& objNombre)
{
m_lNumerator=objNombre.GetNumerator();
m_lDenominator=objNombre.GetDenominator();
return *this;
};
...which is refused by the compiler :
error C2662: 'GetNumerator' : cannot convert 'this' pointer from 'const class CRational' to 'class CRational &'
It compiles fine if I remove the 'const' in the declaration of the constructor, which seems strange to me, because I'm not modifying the object 'objNombre', just using its accessors....
Anyone could explain me what's going on ??
Thanks !
Jerome
|
|
|
|
|
Jerome Conus wrote:
This class is working fine, but I'm wondering why, in the copy constructor, these lines :
m_lNumerator=objNombre.m_lNumerator; m_lDenominator=objNombre.m_lDenominator;
are allowed by the compiler, because I'm accessing private members of an object.
This is standard C++... As for the second question, I did not understand what changed from the original code to the example you show. They do look the same... Do you mean copy constructor or assignement operator?
|
|
|
|
|
Thanks for answering my first question.
For my second question, there is a difference :
In the original code, I'm directly accessing the member variables or the class, in the seconde version, I use an accessor, ie instead of doing MyRationalObject.m_lNumerator, I use the accessor : MyRationalObject.GetNumerator() .
The problem is that in the second version, I cannot have the parameter as const anymore.....
Jerome
|
|
|
|
|
Mmmm... Where were my reading glasses? Try to declare the accessors as const , like const long Get... .
|
|
|
|
|
Yep, it's working now ! Thanks !
Jerome
|
|
|
|
|
Jerome,
Alvaro's reply is better than mine: it is the recommended one (const must come after the declaration). If you have problems with this kind of stuff, as I do sometimes, read "Effective C++" from Scott Meyers. It will clarify these questions an many more...
Cheers
|
|
|
|
|
eheh...where were MY reading glasses !! I thought your previous answer (telling me to use the 'const' in the accessors) was the same as the answer of Alvaro, which is the one I tried and that's why I told you it was working fine !!
Anyway, thank you for helping me !
Jerome
|
|
|
|
|
Jerome Conus wrote:
This class is working fine, but I'm wondering why, in the copy constructor, these lines are allowed by the compiler, because I'm accessing private members of an object.
Yes, but the object is of the same class as "this". So the compiler allows it.
Jerome Conus wrote:
Anyone could explain me what's going on ??
objNombre is passed as const reference. "Const" means that it can't be changed, so you can only call member functions that are also declared const. Since GetNumerator and GetDenominator are not const member functions, they could technically be used to change the object's data (member variables). But since you passed objNombre as a const, then it's not legal. I hope this makes sense.
Anyway, you have two options to solve this:
1. Make objNombre not const. This will allow you to call const and non-const members from it. However, this is not the optimal solution.
2. Add const to the declaration of GetNumerator and GetDenominator:
long GetNumerator() const { return m_lNumerator; }; <br />
long GetDenominator() const { return m_lDenominator; };
This is the proper way to do things. Anytime a member function does not change the object's data, it should be made const so that it can be called by const objects, such as your objNombre.
Regards,
Alvaro
All you need in this life is ignorance and confidence, and then success is sure. -- Mark Twain
|
|
|
|
|
Thank you for your answer, everything does make sense now !!
Thanks,
Jerome
|
|
|
|
|
hello all,
i have a little problem with remove scrollbar in htmlview.
when i load a web page, i must wait the document is complete before remove scrollbar.
i do this:
pView->Navigate2(pSite.URLPage,NULL,NULL);
pView->RemoveSlider();
and i want to do pView->RemoveSlider(); only when the page is totaly loaded.
how to wait without blocking the download and the program ???
if you need more information ask me.
Thx you in advance
|
|
|
|
|
OnDocumentComplete gets fired when a document has reached READYSTATE_COMPLETE state. But I think that, as OnNavigateComplete2 (which could also suffice your requirements) does, it's also called for frames inside a frameset.
So you'll need to detect whether it's your document that has finished loading. For that you could store the url you navigated to (in it's canonicalized form) and compare it to that given in one of the above functions. If they're equal, your download is complete.
We are men. We are different. We have only one word for soap. We do not own candles. We have never seen anything of any value in a craft shop. We do not own magazines full of photographs of celebrities with their clothes on. - Steve
|
|
|
|
|
Thx Schlaubi !
yes i know these function but my problem is to wait during the loading.
if i do :
void CBrowserMDIView::OnDocumentComplete(LPCTSTR lpszURL)
{
m_LoadingComplete = TRUE;
}
while (1)
{
if (pView->m_LoadingComplete == TRUE)
{
pView->RemvoveSlider();
.......
break;
}
}
this is a bad solution because my application freeze.During the while(1) the page is not loaded.
my problem is not really to know when a page is loaded but how to wait during the loading without freezing.
thx
|
|
|
|
|