На форме есть кнопка и панель. При нажатии на кнопку запускается Ворд и с помощью функции SetParent() запихивается в панельку. Код следующий (C++ Builder 6): Код (Text): #include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; Variant WordApp; int BorderSize, CaptionHeight; HWND PanelHandle, WordHandle; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { PanelHandle = NULL; WordHandle = NULL; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { //Находим хендл окна панельки. POINT p; p.x = 5; p.y = 5; PanelHandle = WindowFromPoint(Panel1->ClientToScreen(p)); //Запускаем Ворд и определяем хендл его окна. WordApp = ::CreateOleObject("Word.Application"); WideString WordCaption = WordApp.OlePropertyGet("Caption"); WordApp.OlePropertySet("Caption", "123"); WordHandle = FindWindow(NULL, "123"); WordApp.OlePropertySet("Caption", WordCaption); //Запихиваем Ворд в панельку. Сознательно игнорируем то, что //"The new parent window and the child window must belong to the same application", //т.к. другого выхода нет. Игнорируем также то, что для окна Ворда надо было бы поменять //WS_POPUP на WS_CHILD, т.к. в таком случае пропадет меню и кнопочные панели, что не допустимо. ::SetParent(WordHandle, PanelHandle); //Размещаем Ворд так, чтобы не было видно его шапки и границ. WordApp.OlePropertySet("WindowState", 0); BorderSize = (Width - ClientWidth)/2; CaptionHeight = Height - ClientHeight - BorderSize; FormResize(Sender); WordApp.OlePropertySet("Visible", true); Button1->Caption = "Хватит!"; Button1->Enabled = false; } //--------------------------------------------------------------------------- void __fastcall TForm1::FormResize(TObject *Sender) { //При изменении размеров формы изменяем размеры Ворда так, чтобы нигде не было видно шапки //и границ. if (WordHandle) { int NewX = - BorderSize; int NewY = - CaptionHeight; int NewWidth = Panel1->Width + 2*BorderSize; int NewHeight = Panel1->Height + CaptionHeight + BorderSize; SetWindowPos(WordHandle, NULL, NewX, NewY, NewWidth, NewHeight, SWP_ASYNCWINDOWPOS | SWP_NOZORDER); } } //--------------------------------------------------------------------------- При изменении размеров формы Ворд автоматически подстраивается так, чтобы не было видно его границ и шапки. Используется функция SetWindowPos(), в которую передаем флаг SWP_ASYNCWINDOWPOS. Вот его описание в MSDN: Если этот флаг не установить, то при попытке изменить размеры формы у нас происходит один вызов функции FormResize(), соответсветнно один вызов функции SetWindowPos(), размеры изменяются один раз и все – дальше движения мышки игнорируются и форма блокируется с такими размерами, пока не отпустишь и снова не потянешь за край формы. Если этот флаг стоит, то все норм, размеры Ворда синхронно изменяются, в том числе и с открытым документом. Но все это до поры, до времени Проблема возникает, если создать документ и, на пример, изменить масштаб его отображения (там где 25-50-100% и т.п.). После этого, несмотря на установленный флажок SWP_ASYNCWINDOWPOS в вызове функции SetWindowPos() все равно наблюдается описанная выше ситуация – изменения размеров происходит один раз и блокируется. Я пробовал ставить еще флажок SWP_DEFERERASE (Prevents generation of the WM_SYNCPAINT message), но это не исправляет ситуацию. Так же была мысль, что надо посылать всем дочерним окнам в моем окне ворда также сообщения с флажком SWP_ASYNCWINDOWPOS. Попробовал это с помощью функции EnumChildWindows(): Код (Text): EnumChildWindows(WordHandle, (WNDENUMPROC)EnumChildProc, (LPARAM)0); BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam) { SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_ASYNCWINDOWPOS | SWP_DEFERERASE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE); return TRUE; } Но на ситуацию это не повлияло. Как думаете – в чем проблема? Почему пока не измениш, например, масштаб отображения документа (но не только это, та же ситуация при нажатии на некоторые кнопки Ворда, хотя и не все) все работает нормально. А когда измениш – начинает стопорится? Буду благодарен за любые размышления ПС. Прикрепил исходник на C++ Builder (там есть и екзешник – для работы нужен только установленный Ворд) - если у кого возникнет желание посмотреть, о чем это я
Проблема решается заменой функции SetWindowPos на MoveWindow: Код (Text): MoveWindow(WordHandle, NewX, NewY, NewWidth, NewHeight, TRUE);