Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.07.2011, 15:20   #1
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию Как расположить MessageBox посередине окна-владельца?

Здравствуйте!

Подскажите, пожалуйста, возможно ли расположить MessageBox посередине окна-владельца? Если да, то - как?
8Observer8 вне форума Ответить с цитированием
Старый 25.07.2011, 16:08   #2
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию

Я для экспериментов взял отсюда пример. И вставил код:
Код:
    MessageBox(hWnd,
            _T("Hello!"),
            _T("Message"),
            NULL);
Для меня удовлетворительным будет ответ знающего человека, что "невозможно".

Код:
// GT_HelloWorldWin32.cpp
// compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>

// Global variables

// The main window class name.
static TCHAR szWindowClass[] = _T("win32app");

// The string that appears in the application's title bar.
static TCHAR szTitle[] = _T("Win32 Guided Tour Application");

HINSTANCE hInst;

// Forward declarations of functions included in this code module:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

    if (!RegisterClassEx(&wcex))
    {
        MessageBox(NULL,
            _T("Call to RegisterClassEx failed!"),
            _T("Win32 Guided Tour"),
            NULL);

        return 1;
    }

    hInst = hInstance; // Store instance handle in our global variable

    // The parameters to CreateWindow explained:
    // szWindowClass: the name of the application
    // szTitle: the text that appears in the title bar
    // WS_OVERLAPPEDWINDOW: the type of window to create
    // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
    // 500, 100: initial size (width, length)
    // NULL: the parent of this window
    // NULL: this application dows not have a menu bar
    // hInstance: the first parameter from WinMain
    // NULL: not used in this application
    HWND hWnd = CreateWindow(
        szWindowClass,
        szTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        500, 500,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hWnd)
    {
        MessageBox(NULL,
            _T("Call to CreateWindow failed!"),
            _T("Win32 Guided Tour"),
            NULL);

        return 1;
    }

    // The parameters to ShowWindow explained:
    // hWnd: the value returned from CreateWindow
    // nCmdShow: the fourth parameter from WinMain
    ShowWindow(hWnd,
        nCmdShow);

    MessageBox(hWnd,
            _T("Hello!"),
            _T("Message"),
            NULL);

    UpdateWindow(hWnd);

    // Main message loop:
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int) msg.wParam;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_PAINT    - Paint the main window
//  WM_DESTROY  - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;
    TCHAR greeting[] = _T("Hello, World!");

    switch (message)
    {
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);

        // Here your application is laid out.
        // For this introduction, we just print out "Hello, World!"
        // in the top left corner.
        TextOut(hdc,
            5, 5,
            greeting, _tcslen(greeting));
        // End application-specific layout section.

        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
        break;
    }

    return 0;
}
8Observer8 вне форума Ответить с цитированием
Старый 26.07.2011, 11:45   #3
execom
Редкий тунеядец
Форумчанин
 
Аватар для execom
 
Регистрация: 29.10.2006
Сообщений: 595
По умолчанию

На сколько я помню MessageBox всегда по центру экрана. Можно конечно сильно повозиться и попробовать его после передвинуть сразу после появления, но это возможно если не указывать первым параметром хендл вызывающего окна, т.к. в этом случае выполнение вызвавшей программы прерывается до тех пор пока не будет получено сообщение от MessageBox. Но проще, раз уж вы пишете на WinAPI создать новое перекрывающее окошко с помощь CreateWindowEx и ShowWindow, а после получения от пользователя ответа уничтожить его.
execom вне форума Ответить с цитированием
Старый 26.07.2011, 13:49   #4
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

Почему невозможно, повесить себе хук и ловить момент активации окна

Код:
function HookProc(code, wParam, lParam: dword): dword; stdcall;
var
  this, that: TRect;
begin
  if code = HCBT_ACTIVATE then
    begin
      GetWindowRect(wParam, this);
      GetWindowRect(form1.handle, that);
      x := (that.Left + (that.Right  - that.Left) div 2) - ((this.Right  - this.Left) div 2);
      y := (that.Top  + (that.Bottom - that.Top)  div 2) - ((this.Bottom - this.Top)  div 2);
      SetWindowPos(wParam, 0, x, y, 0, 0, SWP_NOSIZE+SWP_NOZORDER+SWP_NOACTIVATE);
    end;
  Result := CallNextHookEx(hook, code, wParam, lParam);
end;

SetWindowsHookEx(WH_CBT, @HookProc, hInstance, GetCurrentThreadID);
...
UnhookWindowsHookEx(hook);
Ну на С уже сами переведёте
Вложения
Тип файла: zip window pos hook.zip (212.2 Кб, 46 просмотров)
пыщь

Последний раз редактировалось JTG; 26.07.2011 в 13:53.
JTG вне форума Ответить с цитированием
Старый 26.07.2011, 14:02   #5
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию

Цитата:
Можно конечно сильно повозиться и попробовать его после передвинуть сразу после появления
Подскажите, пожалуйста, как передвинуть. Можно не указывать первым параметром хендл вызывающего окна.
8Observer8 вне форума Ответить с цитированием
Старый 26.07.2011, 14:09   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

А может стоит разработать свою альтернативную форму этого диалога?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 26.07.2011, 15:47   #7
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию

Цитата:
А может стоит разработать свою альтернативную форму этого диалога?
Я думаю будет непросто реализовать все готовые возможности MassageBox'a. Я где-то читал о сабклассинге окна. Может его можно использовать? Или я не в ту степь подался. Читал здесь. Надо будет ещё почитать. Может с MessageBox'ом это не прокатит?

Цитата:
Почему невозможно, повесить себе хук и ловить момент активации окна
Ну вот... придётся разбираться с хуками)) Я раньше намеренно пропускал эту тему, так как с первого раза не понял. Вот здесь, должно быть, неплохо написано. Буду читать.

Дайте, пожалуйста, кто-нибудь ссылку, где хорошо написано о хуках.
8Observer8 вне форума Ответить с цитированием
Старый 26.07.2011, 19:19   #8
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

MessageBoxIndirect и своя оконная функция для отрисовки

Зачем хуки, когда проще и надежнее свой диалог нарисовать?
p51x вне форума Ответить с цитированием
Старый 27.07.2011, 10:30   #9
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию

Цитата:
MessageBoxIndirect и своя оконная функция для отрисовки
Спасибо за новую информацию! Есть над чем подумать.

Цитата:
Зачем хуки, когда проще и надежнее свой диалог нарисовать?
Что будет для меня проще я оценить не могу, пока сам не попробую. Мне главное сохранить всю функциональность MessageBox'a и задавать его положение по центру окна владельца. Правда может возникнуть ситуация, когда окно-владелец появится в самом верху экрана, а размер его окажется меньше МessageBox'а (из-за большого количества текста в МessageBox'е), то получится не очень красиво, так как верхняя часть МessageBox'а будет скрыта. Но об этом подумаю потом.

Это всё делается для удобства пользователя.
8Observer8 вне форума Ответить с цитированием
Старый 23.01.2015, 18:53   #10
Джозеф
Новичок
Джуниор
 
Регистрация: 16.01.2015
Сообщений: 1
По умолчанию

Цитата:
Сообщение от JTG Посмотреть сообщение
Почему невозможно, повесить себе хук и ловить момент активации окна

Код:
function HookProc(code, wParam, lParam: dword): dword; stdcall;
var
  this, that: TRect;
begin
  if code = HCBT_ACTIVATE then
    begin
      GetWindowRect(wParam, this);
      GetWindowRect(form1.handle, that);
      x := (that.Left + (that.Right  - that.Left) div 2) - ((this.Right  - this.Left) div 2);
      y := (that.Top  + (that.Bottom - that.Top)  div 2) - ((this.Bottom - this.Top)  div 2);
      SetWindowPos(wParam, 0, x, y, 0, 0, SWP_NOSIZE+SWP_NOZORDER+SWP_NOACTIVATE);
    end;
  Result := CallNextHookEx(hook, code, wParam, lParam);
end;

SetWindowsHookEx(WH_CBT, @HookProc, hInstance, GetCurrentThreadID);
...
UnhookWindowsHookEx(hook);
А как расширить функционал этого хука – чтобы ни один из краёв MessageBox’а не появлялся частично за пределами Рабочего стола, если родительское окно находится где-нибудь в углу экрана, а отодвигался бы оттуда, чтобы пользователь видел его целиком. У меня лично не получилось.
Джозеф вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
MessageBox в приложении без окна Олвин Общие вопросы Delphi 5 16.02.2010 11:14
Как расположить title в гриде вертикально codekick БД в Delphi 0 24.01.2010 12:47
Как расположить вершины многоугольника против часовой стрелки ? Вадим Буренков Помощь студентам 7 21.08.2009 10:42
Как расположить слово по диагонали Wi1D Помощь студентам 27 06.02.2009 20:14