eManual.ru - электронная документация
Секция 3 из 3 - Предыдущая - Следующая
Все секции
- 1
- 2
- 3
mswTabLeft);
void __fastcall Exit();
};
//--------------------------------------------------------------------------
#endif
CPP:
//--------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <comobj.hpp>
#include <clipbrd.hpp>
#include <utilcls.h>
#include <vclutils.hpp>
#include "RxShell.hpp"
#include "MSWord.h"
#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)ExamplesAppsProcview, а можно и по другому.
Под 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 - Предыдущая - Следующая
|