Главная > Программирование > Языки C/C++/Builder > |
FAQ по C++Builder |
Секция 3 из 3 - Предыдущая - Следующая
Все секции
- 1
- 2
- 3
#include "MSWordLoc.h" #include "VMessage.h" #pragma package(smart_init) #define START "Start" #define WORD_EXE "WinWord.exe" //************************************************************************** // Копирование текста в буфер //-------------------------------------------------------------------------- void __fastcall CopyRTFToClipboard(AnsiString buf) { // регистрируем формат RichText Word cfRTF = (Word)RegisterClipboardFormat(TEXT("Rich Text Format")); Clipboard()->Open(); int nTextLen = (buf.Length() + 1) * sizeof(TCHAR); HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE,nTextLen); if(hGlobal != NULL) { void *lpText = GlobalLock(hGlobal); memcpy(lpText,buf.c_str(),nTextLen); Clipboard()->Clear(); GlobalUnlock(hGlobal); Clipboard()->SetAsHandle(cfRTF,(int)hGlobal); } Clipboard()->Close(); } // Класс TMSWord //************************************************************************** // Деструктор //-------------------------------------------------------------------------- __fastcall TMSWord::~TMSWord() { msWord.Clear(); } // Создание объекта и открытие файла //-------------------------------------------------------------------------- bool __fastcall TMSWord::Create(AnsiString fileName) { // если объект уже создан if(!msWord.IsEmpty()) { try { // пытаемся активизировать Word if((short)msWord.Exec(PropertyGet("AppIsRunning") << msWordTitle) == -1) msWord.Exec(Procedure("AppRestore") << msWordTitle); } catch (EOleSysError& e) { // если окно с документом (не Word) было закрыто пользователем, то ErrorCode = 0 // выходим из catch сразу на загрузку документа (без запуска Word-a) if(e.ErrorCode) { // перехватываем событие, когда Word уже был запущен программой // а потом закрыт пользователем if(e.ErrorCode != 0x800706BA) { MessageBox(e.Message + LoadStr(MSWORD_ERROR1),msError); return false; } if(!Run()) // запускаем Word повторно return false; } } } // объект еще не создан else if(!Run()) // пытаемся запустить return false; // объект успешно создан, открываем файл try { msWord.Exec(Procedure("AppShow")); msWord.Exec(Procedure("FileNew") << fileName); // получаем заголовок созданного окна msWordTitle = AnsiString("Microsoft Word - ") + msWord.Exec(PropertyGet("WindowName")); return true; } catch (Exception& e) { MessageBox(e.Message + LoadStr(MSWORD_ERROR2),msError); } return false; } // Закрытие Word //-------------------------------------------------------------------------- void __fastcall TMSWord::Exit() { try { if(!msWord.IsEmpty() && MessageBox(LoadStr(MSWORD_CONFIRM),msConfirm_YesNo) == IDYES) msWord.Exec(Procedure("AppClose")); } catch (...) { } } // Переход на закладку //-------------------------------------------------------------------------- bool __fastcall TMSWord::GotoBookmark(AnsiString mark) { try { msWord.Exec(Procedure("EditGoto") << NamedParm("Destination",mark.c_str())); return true; } catch (Exception& e) { MessageBox(e.Message + "\nBookmark: " + mark,msError); } return false; } // Вставка текста в текущую позицию курсора //-------------------------------------------------------------------------- void __fastcall TMSWord::InsertText(AnsiString str) { msWord.Exec(Procedure("Insert") << str); } // Вставка текста в текущую позицию курсора с переходом на новую строку //-------------------------------------------------------------------------- void __fastcall TMSWord::InsertTextEOL(AnsiString str) { msWord.Exec(Procedure("Insert") << (str + '\n')); } // Вставка текста в текущую позицию курсора //-------------------------------------------------------------------------- void __fastcall TMSWord::Paste() { msWord.Exec(Procedure("EditPaste")); } // Восстановление (активация) Word //-------------------------------------------------------------------------- void __fastcall TMSWord::Restore() { try { msWord.Exec(Procedure("AppRestore") << msWordTitle); msWord.Exec(Procedure("AppMaximize") << msWordTitle << 1); // максимизируем } catch (EOleSysError&) { MessageBox(LoadStr(MSWORD_INFO),msInfo); } } // Собственно запуск Word-a как OLE-сервера //-------------------------------------------------------------------------- bool __fastcall TMSWord::Run() { bool isWordRunning = true; // сначала пытаемся переключиться на активный Word try { msWord = Variant::GetActiveObject("Word.Basic"); } catch (EOleSysError& e) { isWordRunning = false; } if(!isWordRunning) { // нет запущенного Word try { msWord = Variant::CreateObject("Word.Basic"); msWord.Exec(Procedure("AppMaximize") << 1); // максимизируем } catch (EOleSysError& e) { MessageBox(e.Message + LoadStr(MSWORD_ERROR1),msError); return false; } } return true; } // Запуск Word-a как приложения //-------------------------------------------------------------------------- bool __fastcall TMSWord::RunApplication(AnsiString dir) { if(FileExecute(START,WORD_EXE,dir,esNormal) <= 32) { MessageBox(LoadStr(MSWORD_ERROR1),msError); return false; } Delay(20000); return true; } // Задание характеристик шрифта //-------------------------------------------------------------------------- void __fastcall TMSWord::SetFontFormat(TFont *f,WinwordColor color) { msWord.Exec(Procedure("FormatFont") << NamedParm("Points",f->Size) << NamedParm("Font",f->Name.c_str()) << NamedParm("Color",color)); if(f->Style.Contains(fsBold)) msWord.Exec(Procedure("Bold") << 1); if(f->Style.Contains(fsItalic)) msWord.Exec(Procedure("Italic") << 1); if(f->Style.Contains(fsUnderline)) msWord.Exec(Procedure("Underline") << 1); if(f->Style.Contains(fsStrikeOut)) msWord.Exec(Procedure("Strikethrough") << 1); } // Задание характеристик шрифта //-------------------------------------------------------------------------- void __fastcall TMSWord::SetFontFormat(char *fontName,int fontSize,TFontStyles style,WinwordColor fontColor) { TFont *f = new TFont(); f->Name = fontName; f->Size = fontSize; f->Style = style; SetFontFormat(f,fontColor); delete f; } // Задание имени закладки //-------------------------------------------------------------------------- void __fastcall TMSWord::SetBookmark(AnsiString mark) { msWord.Exec(Procedure("EditBookmark") << NamedParm("Name",mark) << NamedParm("Add",1)); } // Задание характеристик абзаца //-------------------------------------------------------------------------- void __fastcall TMSWord::SetParagraphFormat(int leftIndent,int rightIndent, int before,int after, WinwordSpacing lineSpacing, WinwordAlign align) { msWord.Exec(Procedure("FormatParagraph") << NamedParm("LeftIndent",AnsiString(leftIndent).c_str()) << NamedParm("RightIndent",AnsiString(rightIndent).c_str()) << NamedParm("Before",before) << NamedParm("After",after) << NamedParm("LineSpacing",lineSpacing) << NamedParm("Alignment",align)); } // Установка позиций табуляции //-------------------------------------------------------------------------- void __fastcall TMSWord::SetTabs(int *tabs,int num,WinwordTabType type) { for(int i = 0;i < num;i++) msWord.Exec(Procedure("FormatTabs") << NamedParm("Position",AnsiString(tabs[i]).c_str()) << NamedParm("Align",type) << NamedParm("Set",1)); } -+---------- >Q40: Как сделать таймер с интервалом < 1 мс? A(VK): Использовать Performance Counter. Функцией QueryPerformanceFrequency получаем частоту счётчика, которая, как правило, выше 1Мгц, создаём отдельный поток и в цикле функцией QueryPerformanceCounter считываем его значение. Практически, на P200 достаточно точно определяются интервалы в 20 мкс. -+---------- >Q41: Как определить количество памяти, доступной Windows и её свободный объём? A(VK): Использовать функцию API GlobalMemoryStatus(...). -+---------- >Q42: Как получить список запущенных задач? A(VK): Надо составить список главных окон приложений (top-level windows). Окно считается главным если: 0. Имеет заголовок 1. Видимо 2. Не имеет родителя Приходим к следующему коду: bool __stdcall EnumProc(HWND hWnd,long) { char buffer[100]; if(hWnd==NULL) return false; GetWindowText(hWnd,buffer,sizeof(buffer)); if (buffer[0] && IsWindowVisible(hWnd) && GetWindowLong(hWnd,GWL_HWNDPARENT)==0) { // Ваш код }; return true; } В нужном месте вызываем его EnumWindows((WNDENUMPROC)EnumProc,0); -+---------- >Q43: Как получить список исполняемых процессов? A(VK): Можно посмотреть в $(BCB)\Examples\Apps\Procview, а можно и по другому. Под W95/98: #include <tlhelp32.h> PROCESSENTRY32 PC32; hnd=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if ((int)hnd==-1) return; PC32.dwSize=sizeof(PC32); i=Process32First(hnd,&PC32); while (i) { // Ваш код // PID процесса берётся из PC32.th32ProcessID; // Имя файла через ExtractFileName(PC32.szExeFile); i=Process32Next(hnd,&PC32); }; CloseHandle(hnd); Под NT: DWORD PIDStack[512]; DWORD modNeeded; EnumProcesses(PIDStack,sizeof(PIDStack),&modNeeded); -+---------- >Q44: Как узнать загрузку процессора? A(VK): Под W95/98 : HKEY CPULoadKey; int CPULoad; ULONG Type = REG_DWORD; DWORD CPULoadSize = sizeof (CPULoad); Один раз в начале программы: RegOpenKey(HKEY_DYN_DATA,"PerfStats\\StartStat",&CPULoadKey); RegQueryValueEx(CPULoadKey,"KERNEL\\CPUUsage",NULL, &Type, (LPBYTE)&CPULoad, &CPULoadSize); RegCloseKey(CPULoadKey); RegOpenKey(HKEY_DYN_DATA,"PerfStats\\StatData",&CPULoadKey); По мере необходимости RegQueryValueEx(CPULoadKey,"KERNEL\\CPUUsage",NULL, &Type, (LPBYTE)&CPULoad, &CPULoadSize); CPULoad содержит результат в процентах. Один раз в конце RegCloseKey(CPULoadKey); RegOpenKey(HKEY_DYN_DATA,"PerfStats\\StopStat",&CPULoadKey); RegQueryValueEx(CPULoadKey,"KERNEL\\CPUUsage",NULL, &Type, (LPBYTE)&CPULoad, &CPULoadSize); RegCloseKey(CPULoadKey); Под NT либо использем PDH.dll, но она мало у кого есть, либо начинаем шаманские пляски вокруг performance keys в реестре. Пример есть на www.codepile.com, файл ntcounters.cpp. -+---------- >Q45: Нашёл в хэлпе полезную функцию ROUND, а программа не компилируется. Пишет "Call to undefined function" :( Как же округлять? A(VK): Функция ROUND (как, впрочем, и TRUNC) принадлежит OCX-контролу F1Book. Пишем свою: #include <math.h> double Round(double Argument, int Precision) { double div = 1.0; if(Precision >= 0) while(Precision--) div *= 10.0; else while(Precision++) div /= 10.0; return floor(Argument * div + 0.5) / div; } Hint: точность может быть отрицательной. Round(1234,-2)==1200. -+---------- >Q46: Как сменить цвет надписи у TButton? Никак. Используйте, например, TBitBtn. -+---------- >Q47. Можно как нибудь засунуть заданные файлы в dll (dll создаем), а потом пpогpаммно извлечь их на фоpму ? A(VF): 1. Помещаем свои рисунки в RES файл: - Создаем файл Image.rc и пишем в нем: MYIMAGE BITMAP Image.bmp - Обрабатываем Image.rc утилой Brcc32.exe: Brcc32.exe Image.rc, полyчаем файл Image.res. 2. Подключаем полученный Image.res файл к Dll'ке: - Image.res помещаем в каталог с Dll-проектом. - Пишем: USERES("Image.res"); - Компилим Dll. 3. Подгружаем Dll'ку и берем картинку из нее: Объявить HINSTANCE hDllHandle; ... hDllHandle = LoadLibrary("MyDll.dll"); if(hDllHandle != NULL) { Image1->Picture->Bitmap->Handle = LoadBitmap(hDllHandle, "MYIMAGE"); FreeLibrary(hDllHandle); } else { //Сообщаем о невозможности подгрузить Dll и обрабатываем ошибку! } -+---------- >Q48. Как засунуть в pесуpсы файлы jpeg? A(AP): 1) Засовываем Jpeg в res-файл. В файле MyJpeg.rc пишем: MyJPEG RCDATA "MyCoolJPEG.jpg" И натравливаем на это дело brcc32 -- brcc32 MyJpeg.rc Для полного счастья осталось написать в нашем модуле что-то в духе #pragma resource "MyJPEG.res" 2) Загружаем Jpeg из ресурсов Например, в *.h файле определяем у нашей формы в секции private (к примеру) переменную TJPEGImage *MyJPEG; Естественно, где-то вверху есть #include <JPEG.hpp> Далее, в конструкторе формы пишем: (Собственно, тут два варианта; гурманы могут извращатсья с FindResource, LoadResource и в качестве заключительного аккорда -- LockResource; а мы пойдем... нет-нет, всего лишь другим путем.) MyJPEG = new TJPEGImage(); TResourceStream *JPEGRes = new TResourceStream((int)HInstance,AnsiString("MyJPEG"),RT_RCDATA); MyJPEG->LoadFromStream(JPEGRes); JPEGRes->Free(); 3) Осталось дело за малым -- использовать этот самый Jpeg: В каком-нибудь OnPaint у PaintBox'а написать: ((TPaintBox*)Sender)->Canvas->Draw(0, 0, MyJPEG); -+---------- >Q49. Как программно скролировать TMemo? A: EM_LINESCROLL. Например, SendMessage(Memo->Handle, EM_LINESCROLL, 0, Memo->Lines->Count); -+---------- [end of FAQ]
Секция 3 из 3 - Предыдущая - Следующая
Вернуться в раздел "Языки C/C++/Builder" - Обсудить эту статью на Форуме |
Главная - Поиск по сайту - О проекте - Форум - Обратная связь |