Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
VC_Lect.doc
Скачиваний:
6
Добавлен:
01.07.2025
Размер:
15 Мб
Скачать
☆

24.3.3.Ansi-версия программы для ис mvs-2005.

Как это ни удивительно, но эта версия программы полностью совпадает с версией для MVS 6.0. Единственное, что требуется, так это установка в свойствах проекта для параметра Character Set значения “Not Set” (рис.1).

Рис.1. Окно свойств проекта, ветвь «General»

В приложениях с графическим интерфейсом целесообразно поместить чтение данных из реестра в обработчик события OnCreate() класса вида, а запись данных в реестр – в обработчик события OnDestroy().

24.3.4.Ansi-версия программы для ис mvs-2008

/*ReadIniFile() - чтение значений ключей Legs и Name из файла инициализации*/

void ReadIniFile(int &Legs, char *Name)

{

Legs=theApp.GetProfileInt("ELEPHANT","LegsNumber",4);

CString work=theApp.GetProfileString("ELEPHANT","State","Малышка");

strcpy_s(Name,work.GetLength()+1,work.GetBuffer());

}

/*WriteIniFile() - запись значений ключей Legs и Name в файл

инициализации*/

bool WriteIniFile(const int Legs,const char *Name)

{

if(!theApp.WriteProfileInt("ELEPHANT","LegsNumber",Legs)) return false;

if(!theApp.WriteProfileString("ELEPHANT","State",Name)) return false;

return true;

}

24.4.Установка размеров и положения главного окна-рамки приложения

Для установки размеров и положения главного окна-рамки приложения, а также его заголовка, найдите функцию InitInstance() в главном файле вашего приложения и модифицируйте ее следующим образом:

// …

// The one and only window has been initialized, so show and update it

int ScrWidth =GetDeviceCaps(GetDC(0),HORZRES), // ширина экрана в пикселах

ScrHeight=GetDeviceCaps(GetDC(0),VERTRES); // высота экрана в пикселах

/*Задаем ширину и высоту своего окна. В данном случае первоначальный размер

окна будет вдвое меньше высоты и ширины экрана*/

int Width=ScrWidth/2, Height=ScrHeight/2;

/*Задаем координаты окна на экране. В данном случае окно будет

размещено посередине экрана */

int nLeftRect=(ScrWidth-Width)/2,

nTopRect=(ScrHeight-Height)/2;

m_pMainWnd->SetWindowPos(0,nLeftRect,nTopRect,Width,Height,0);

/*Задаем заголовок главного окна приложения */

m_pMainWnd->SetWindowText(_T("Супер-пупер редактор"));

m_pMainWnd->ShowWindow(SW_SHOW);

m_pMainWnd->UpdateWindow();

// …

24.5.Создание дополнительного потока в консольном приложении

См. проект (папку) ThreadsInConsoleMFC. Из приведенного ниже листинга файла ThreadsInConsoleMFC.cpp удалены несущественные части кода: директивы препроцессора, часть сгенерированного мастером MVS кода.

/* Иллюстрация создания и использования второго потока в консольном приложении.*/

//…

CWinApp theApp;

using namespace std;

bool Stop=FALSE;

char res[1024];

char * Rus(char *src)

{

CharToOem(src,res); return res;

}

UINT ComputeInThread(LPVOID pParam)

{

printf(Rus("Второй поток запущен...\n"));

float Sum=0;

for(int i=0;i<30000000;i++)

{

Beep(rand()/20,50);

if(Stop) break;

}

printf(Rus("\nВторой поток завершен\n"));

return 0;

}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])

{

// …

CWinThread* MyThread;

MyThread=AfxBeginThread(ComputeInThread,0,THREAD_PRIORITY_NORMAL);

// Просто иллюстрация загрузки строки из ресурса.

// В ресурсном файле (.rc) пришлось установить, вручную,

// кодовую страницу 1251 вместо 1252

char szError[MAX_LOADSTRING];

LoadString(0, IDS_Error, szError, MAX_LOADSTRING);

if (!MyThread) printf(Rus(szError));

//

Sleep(5000); /* задерживаем основной поток для того, чтобы второй поток вывел свое сообщение */

//////////////////// поток можно приостанавливать и возобновлять printf(Rus("Приостанавливаем выполнение вт. потока на 2 сек. ...\n"));

MyThread->SuspendThread();

Sleep(2000);

MyThread->ResumeThread();

//

char ch;

do

{

printf(Rus("Завершить второй поток [y/n]?"));

ch=getche();

}while(ch!='y');

Stop=TRUE;

getch();

// …

}

Несколько комментариев к программе.

Как видно из листинга, даже в консольном приложении можно создавать дополнительные (помимо главного потока – primary thread) потоки. Проще всего это сделать с использованием библиотеки MFC, для чего опять-таки проще всего создать заготовку консольного приложения, которое поддерживает MFC. Для создания дополнительного потока необходимо сделать следующее.

Во-первых, надо написать функцию, которая будет исполняться в этом потоке. Эта функция должна иметь такой прототип:

UINT MyThreadProc(LPVOID pParam);

Естественно, что имя функции произвольно (в приведенном выше примере эта функция имеет имя ComputeInThread). Посредством параметра pParam в функцию можно передать любые данные, например, указатель на некоторый объект, как это иллюстрируется в справочной системе MSDN:

UINT MyThreadProc( LPVOID pParam )

{

CMyObject* pObject = (CMyObject*)pParam;

if (pObject == NULL ||

!pObject->IsKindOf(RUNTIME_CLASS(CMyObject)))

return 1; // если pObject недействителен

// обрабатываем 'pObject'

return 0; // поток завершен успешно

}

// в теле какой-либо другой функции программы

pNewObject = new CMyObject;

AfxBeginThread(MyThreadProc, pNewObject); // запуск дополнительного потока

Потоку можно как передать любые данные посредством параметра pParam, так и получить результат его работы. К примеру, pParam может быть указателем на структуру.

Во-вторых, надо описать указатель на поток:

CWinThread* MyThread;

В-третьих, надо запустить поток на выполнение с помощью функции AfxBeginThread. Эта функция создает поток – объект класса CWinThread, и, в зависимости от значения параметра dwCreateFlags, поток либо будет сразу запущен на выполнение, либо его надо будет запустить с помощью функции CWinThread::ResumeThread().

Поток будет выполняться до тех пор, пока выполняется функция MyThreadProc(). Выполнение потока можно приостанавливать и возобновлять с помощью функций CWinThread::SuspendThread() и CWinThread::ResumeThread() соответственно.

Проверить фактическое число потоков в своем приложении можно с помощью Диспетчера задач Windows: перейти к вкладке Процессы и добавить с помощью команды Вид|Выбор столбцов столбец Счетчик потоков.

Использование в программе дополнительных потоков вовсе не ограничивается технологией, использованной в приведенной выше программе. Более подробные сведения по программированию многопоточных приложений можно найти в работе [1] и в MSDN.

В частности, предоставляется возможность создания как рабочих потоков (worker threads), так и потоков пользовательского интерфейса (user-interface threads). Потоки пользовательского интерфейса, в отличие от рабочих потоков, имеют окна и, значит, могут обрабатывать сообщения Windows.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]