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

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

Вернуться   Форум программистов > Клуб программистов > Свободное общение
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 20.09.2010, 12:47   #1
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию Borderless Window / WinAPI

Приветствую.
Встала задача, вообще какая технология - WPF, у меня есть рабочие варианты на MFC, но сейчас пытаюсь в WPF сделать. Суть проблемы в чем, мне надо создать окно, которое можно было бы ресайзить но + к этому, без Windows бордюра (рамки), т.е. все окно есть никак иное клиентская ареа. Яркий пример подобного рода окон - iTunes для Windows

Разумеется надо ловить WM_NCCALCSIZE сообщения, и в нем устанавливать. Но вот ведь странно выходит, Если в MFC
Код:
void CMainWindow:OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS *lpncsp)
{
	if(lpncsp->lppos)
	{
		int cxfr = GetSystemMetrics(SM_CXSIZEFRAME);
		int cyfr = GetSystemMetrics(SM_CYSIZEFRAME);
		InflateRect(lpncsp->rgrc, cxfr - 1, cyfr - 1);
	}
	CFrameWnd::OnNcCalcSize(bCalcValidRects, lpncsp);
}
Все супер выходит, бордюр исчезает и остается только клиентская часть, то в WPF
Код:
protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            var source = PresentationSource.FromVisual(this) as HwndSource;
            source.AddHook(WindowProc);
        }

        private IntPtr WindowProc(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            switch (Msg)
            {
                case 0x0086: // WM_NCACTIVATE
                    handled = true;
                    return (IntPtr)1;

                case Win32.WM_NCCALCSIZE:
                    {
                        handled = true;
                        return Win32.Window.WMNCCalcSize(hWnd, wParam, lParam);
                    }
Код:
public static IntPtr WMNCCalcSize(IntPtr Handle, IntPtr wParam, IntPtr lParam)
            {
                if (wParam.ToInt32() == 1)
                {
                    var ncsp = (NCCALCSIZE_PARAMS)Marshal.PtrToStructure(lParam, typeof(NCCALCSIZE_PARAMS));

                    var cxfr = GetSystemMetrics(SystemMetric.SM_CXSIZEFRAME);
                    var cyfr = GetSystemMetrics(SystemMetric.SM_CYSIZEFRAME);

                    //ncsp.rgrc0.left += 0; // вроде нормально становится
                    //ncsp.rgrc0.top += 0;
                    //ncsp.rgrc0.right -= 4; // а вот справа и снизу 4 наверное, пикселя не понятно чего
                   // ncsp.rgrc0.bottom -= 4;

                    Marshal.StructureToPtr(ncsp, lParam, true);

                    //return (IntPtr)(NCCALCSIZE.WVR_ALIGHTBOTTOM | NCCALCSIZE.WVR_ALIGHTLEFT | NCCALCSIZE.WVR_ALIGHTOP | NCCALCSIZE.WVR_ALIGHTRIGHT);
                }
                return IntPtr.Zero;
            }
Тоже импортировал InflateRect в WPF, нифига не работает. Знаю что можно AllowTransparency включить и бордюр исчезнет, но мне нельзя ее включать + окно содержит много контента, не хотелось бы Layered окна подключать.

на скриншоте красная полоска - это рамка окна но как видно, справа и снизу черные места, вот их бы убрать как то.

Упс. все решилось, root element'у ставим Margin, где право и лево будет значения < 0, и grid (в моем случае) покрывает все окно
Изображения
Тип файла: jpg Безимени-1.jpg (32.3 Кб, 168 просмотров)

Последний раз редактировалось BOBAH13; 20.09.2010 в 13:45.
BOBAH13 вне форума Ответить с цитированием
Старый 20.09.2010, 18:36   #2
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Приветствую снова. Продолжаю оформлять и бороться с Windows API. Дело в том, что по приходу WM_NCACTIVATE, что собственно информирует, что окно активировалось или наоборот, деактивировалось. Но как прикол (а iTunes в Apple, видимо побороли), после активации/деактивации рисуются бордюры, а рисуются видимо DefWindowProc сразу после WM_NCACTIVATE, т.к. после этой мессаги ко мне приходят только WM_ACTIVATE, WM_ACTIVATEAPP и не более. Вот и вопрос, как же отрубить эту "фичу".

Edit:
Я прошу извинения, может это покажется флудом, но уже какой раз замечаю, могу сидеть долго и не найти ответа, а как только отпишусь на форуме, и через несколько минут радость. Ну все же, вдруг кому понадобиться, сбор такой ифны в одном месте я не встречал, уж поверьте.

А все решилось просто
Код:
case Win32.WM_NCACTIVATE:
                    var result = Win32.DefWindowProc(hWnd, Win32.WM_NCACTIVATE, wParam, new IntPtr(-1));
                    handled = true;
                    return result;

Последний раз редактировалось BOBAH13; 20.09.2010 в 18:50.
BOBAH13 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
window.document.write и window.alert() Syltan JavaScript, Ajax 0 26.08.2010 21:32
WINDOW::CONSOLE nikleb Общие вопросы C/C++ 7 31.10.2008 17:44
Immediate Window ZORRO2005 Microsoft Office Excel 1 24.05.2008 16:23
window() ( Pascal ) Artificial Помощь студентам 1 16.01.2008 21:50
Функция window( ). Adamant Общие вопросы C/C++ 1 27.10.2007 09:10