Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Запуск MFC-приложения с параметрами  (Прочитано 19132 раз)
0 Пользователей и 9 Гостей смотрят эту тему.
olgat
Гость
« : 23-01-2007 15:12 » 

Подскажите, пожалуйста, как можно запустить MFC-приложение с параметрами?
Есть ли аналог для int main( int argc, char* argv[] ) ?
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #1 : 23-01-2007 15:20 » 

Выдержка из книги Д. Рихтера "Виндовс для проффесионалов"
Цитата
Командная строка процесса
При создании новому процессу передается командная строка, которая почти никог да не бывает пустой — как минимум, она содержит имя исполняемого файла, исполь зованного при создании этого процесса. Однако, как Вы увидите ниже (при обсужде нии функции CreateProcess), возможны случаи, когда процесс получает командную строку, состоящую из единственного символа — нуля, завершающего строку. В момент запуска приложения стартовый код из библиотеки С/С++ считывает командную строку процесса, пропускает имя исполняемого файла и заносит в параметр pszCmdLine функции (w)WinMain указатель на оставшуюся часть командной строки.
Параметр pszCmdLine всегда указывает на ANSI-строку. Но, заменив WinMain на wWinMain, Вы получите доступ к Unicode-версии командной строки для своего про цесса
Программа может анализировать и интерпретировать командную строку как угод но. Поскольку pszCrndLine относится к типу PSTR, а не PCSTR, не стесняйтесь и запи сывайте строку прямо в буфер, на который указывает этот параметр, но ни при каких условиях не переступайте границу буфера. Лично я всегда рассматриваю этот буфер как "только для чтений". Если в командную строку нужно внести изменения, я снача ла копирую буфер, содержащий командную строку, в локальный буфер (в своей про грамме), который затем и модифицирую.
Указатель на полную командную строку процесса можно.получить и вызовом функции GetCommandLine.
PTSTR GetCommandLine();
Она возвращает указатель на буфер, содержащий полную командную строку, вклю чая полное имя (вместе с путем) исполняемого файла.
Во многих приложениях безусловно удобнее использовать командную строку, предварительно разбитую на отдельные компоненты, доступ к которым приложение может получить через глобальные переменные _argc и _argv (или _wargu). Функ ция CommandLineToArgvW расщепляет Unicode-строку на отдельные компоненты:
PWSTR CommandLineToArgvW( PWSTR pszCmdLine, int pNumArgs);
Буква W в конце имени этой функции намекает на "широкие" (wide) символы и подсказывает, что функция существует только в Unicode-версии. Параметр pszCmdLine указывает на командную строку Его обычно получают предварительным вызовом GetCommandLineW Параметр pNumArgs — это адрес целочисленной переменной, в которой задается количество аргументов в командной строке. Функция Command LineToArgvW возвращает адрес массива указателей на Unicode-строки
CommandLineToArgvW выделает нужную память автоматически. Большинство при ложений не освобождает эту память, полагаясь на операционную систему, которая проводит очистку ресурсов по завершении процесса И такой подход вполне прием лем. Нo если Вы хотите сами освободить эту память, сделайте так:
int pNumArgs;
PWSTR *ppArgv = CommandLineToArgvW(GetCommandLineW(), &pNumArgs);
// используйте эти аргументы if (*ppArgv[1] == L x ) {
// освободите блок памяти HeapFree(GetProcessHeap() 0 ppArgv);
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
olgat
Гость
« Ответ #2 : 23-01-2007 16:13 » 

СПАСИБО!!!
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #3 : 23-01-2007 16:35 » 

olgat,  Какой именно объект ты используешь? CWinApp?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #4 : 24-01-2007 15:40 » new

olegat,

если ты пойдешь в проект-> установки-> вкладка "дебаг"-> там есть поле "программные аргументы"

А обрабатывать - в C...App::InitInstance():

   // Parse command line for standard shell commands, DDE, file open
   CCommandLineInfo cmdInfo;
   ParseCommandLine(cmdInfo);
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #5 : 11-08-2008 09:09 » 

Ой как интересно выходит - мне сейчас понадобилось считать из командной строки не только имя запущенного приложения, но и пользовательские установки. И тут я узнала оочень много нового о себе и своем представлении о жизни...
Короче, я уже ничего не понимаю, мож кто-то наставит на путь истинный?

Есть проектик, иду в установки проекта->дебаг-> программные аргументы
и пишу теста ради:

Код:
 -a test -b mjau
Далее начинаются, с моей точки зрения, чудеса:

Если считать командную строку так:

Код:
LPTSTR sCmdLine = GetCommandLine();

то все ок, т.е. там и имя , и мои параметры.

ЕСли же идти по стандарту:

Код:
	CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);

то в cmdInfo.m_strFileName стоит "test"! Вместо имени ехе-шника!
И как это понимать?

Т.е. в жизни можно забить на надежду на облегчение труда и парсить строку с помощью CommandLineToArgvW.  Отлично
НО мне, если честно, принцип бы понять... Почему происходит эта странная замена?  Не понял
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #6 : 11-08-2008 10:14 » 

Если действительно хочешь понять, посмотри исходники класса CCommandLineInfo и ф-ции ParseCommandLine. Там уже забиты многие вещи типа /p или -p - не помню точно - для печати и тд.
Ты можешь переписать класс и исползовать свой объект, ну или получать всю строку и парсить самой.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #7 : 11-08-2008 11:20 » 

Джон,

я посмотрела список занятых параметров - мои туда не входят.
А переписывать класс как-то нет смысла, я и так спокойно парсить могу. Просто хотелось же без изобретения велосипеда обойтись Ага да видно не судьба...
Я думала, может кто-то уже с этим сталкивался и знает ответ.
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #8 : 11-08-2008 12:45 » 

Бррр ничего не понял. Что ты хочешь? Смотри у тебя есть объект CCommandLineInfo, в который встроена определённая логика работы с определёнными параметрами

Параметры перебираются здесь - всё довольно просто
Код:
void CWinApp::ParseCommandLine(CCommandLineInfo& rCmdInfo)
{
for (int i = 1; i < __argc; i++)
{
LPCTSTR pszParam = __targv[i];
BOOL bFlag = FALSE;
BOOL bLast = ((i + 1) == __argc);
if (pszParam[0] == '-' || pszParam[0] == '/')
{
// remove flag specifier
bFlag = TRUE;
++pszParam;
}
rCmdInfo.ParseParam(pszParam, bFlag, bLast);
}
}

Обработка каждого параметра, который является флажком (признак -) происходит здесь

Код:
void CCommandLineInfo::ParseParamFlag(const char* pszParam)
{
// OLE command switches are case insensitive, while
// shell command switches are case sensitive

if (lstrcmpA(pszParam, "pt") == 0)
m_nShellCommand = FilePrintTo;
else if (lstrcmpA(pszParam, "p") == 0)
m_nShellCommand = FilePrint;
else if (lstrcmpiA(pszParam, "Register") == 0 ||
lstrcmpiA(pszParam, "Regserver") == 0)
m_nShellCommand = AppRegister;
else if (lstrcmpiA(pszParam, "Unregister") == 0 ||
lstrcmpiA(pszParam, "Unregserver") == 0)
m_nShellCommand = AppUnregister;
else if (lstrcmpA(pszParam, "dde") == 0)
{
AfxOleSetUserCtrl(FALSE);
m_nShellCommand = FileDDE;
}
else if (lstrcmpiA(pszParam, "Embedding") == 0)
{
AfxOleSetUserCtrl(FALSE);
m_bRunEmbedded = TRUE;
m_bShowSplash = FALSE;
}
else if (lstrcmpiA(pszParam, "Automation") == 0)
{
AfxOleSetUserCtrl(FALSE);
m_bRunAutomated = TRUE;
m_bShowSplash = FALSE;
}
}

Если твои параметры не попадают в этот список, то они просто игнорируются объектом CCommandLineInfo. Ну в самом деле, откуда ему знать, что ты (или я, или ещё кто другой) захотят передать. Он отвечает только за уже встроеные в МFC механизмы.

Например - означает флажок, -а - нет такого флажка - игнорируем.

След. параметр без -. Значит обрабатываем

Код:
void CCommandLineInfo::ParseParamNotFlag(const TCHAR* pszParam)
{
if (m_strFileName.IsEmpty())
m_strFileName = pszParam;
else if (m_nShellCommand == FilePrintTo && m_strPrinterName.IsEmpty())
m_strPrinterName = pszParam;
else if (m_nShellCommand == FilePrintTo && m_strDriverName.IsEmpty())
m_strDriverName = pszParam;
else if (m_nShellCommand == FilePrintTo && m_strPortName.IsEmpty())
m_strPortName = pszParam;
}

Отсюда m_strFileName = test

Дальше опять флажок -b - нет такого, игнорируем. Ну и последний параметр тоже не попадает ни в один из обработчиков. Значит тоже игнорируем.

Всё.

Так чего же ты хочешь/ждёшь? Что ты ожидаешь увидеть в m_strFileName? Один раз зайди дебуггером в ф-ю ParseCommandLine затрать одну минуту и всё станет ясно. Ага

А я тебе сразу посоветовал, сделать свой класс CMyCommandLineInfo : public CCommandLineInfo и перепиши в нём две ф-ции - для флажковых параметров и для обычных. И всего делов

Код:
void CMyCommandLineInfo::ParseParamNotFlag(const TCHAR* pszParam)
{
CString stParam(pszParam);

if(stParam.CompareNoCase(_T("test"))==0)
{

}
else if(stParam.CompareNoCase(_T("mjau"))==0)
{

}

}

void CMyCommandLineInfo::ParseParamFlag(const char* pszParam)
{
CString stParam(pszParam);

if(stParam.CompareNoCase(_T("a"))==0)
{

}
else if(stParam.CompareNoCase(_T("b"))==0)
{

}
}

Делов на 1,5 минуты. Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #9 : 11-08-2008 13:32 » 

Джон,

все, приплыли... Похоже, пивом для поправки морального здоровья я сегодня не обойдусь... Я зол!
Я ковырялась там в поисках возможностей выдать все, что не попадает под стандартный шаблон, в виде отдельной строки...
В моей дурной башке почему-то сидело твердое убеждение, что где-то есть в этом классе такая возможность...  А черт его знает... Короче, я поискала-не нашла. Спросила.
А дальше меня утащили на совещание на полдня, только сейчас пришла, посмотрела твое сообщение и поняла, что понедельник таки день тяжелый.  Отлично
Меня просто заклинило и я начала искать в направлении того самого клина.

Все, вопрос снят. Спасибочки за лечение дурной головы. Извиняюсь.

А задачку я сделала через CommandLineToArgvW:

Код:

BOOL CTestApp::InitInstance()
{
//...
checkCmdLine();
}

void CTestApp::checkCmdLine()
{
// get as wstr
LPWSTR sCmdLineW = GetCommandLineW();

int nArgNumber = 0;
char** pArgs = NULL;

// parse as wstr
LPWSTR* sArgs = CommandLineToArgvW (sCmdLineW, &nArgNumber);
if( NULL == sArgs )
{
                          // какое-то сообщение об ошибке
return ;
}
else
{
pArgs = new char* [nArgNumber];
for( int i = 0; i < nArgNumber; i++)
{
pArgs[i] = new char [100];
sprintf(pArgs[i], "%ws", sArgs[i]);
}
}

// analize args
m_nMasterId = -1; m_nSourceId = -1; m_nSeqId = -1; m_nState = -1;
for ( int i = 0; i < nArgNumber; i++ )
{
if ( (strcmp (pArgs[i], "a") == 0) && (i < (nArgNumber - 1)) )
{
sPar1 =  pArgs[i + 1] ;
}

if ( (strcmp (pArgs[i], "b") == 0) && (i < (nArgNumber - 1)) )
{
sPar2= pArgs[i + 1] ;
}
}

// Free memory allocated for CommandLineToArgvW arguments.
LocalFree(sArgs);
for ( i = 0; i < nArgNumber; i++ )
{
delete pArgs[i];
pArgs[i] = NULL;
}
delete pArgs;
             pArgs = NULL;
}

Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #10 : 11-08-2008 14:56 » 

Ир, ты просто забыла золотое правило - халявы не бывает. Очень редко, когда объект сделанный чужаком подходит под твои нужды. А для простого разбора параметров используй тело ф-ции ParseCommandLine. А вызывать rCmdInfo.ParseParam не обязательно (ну или обязательно в том случае, если ты хочешь сохранить OLE и DDE механизмы MFC). А то у тебя чёт много букафф ИМХО. Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines