Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Создание нового эл-та и шрифты  (Прочитано 20150 раз)
0 Пользователей и 1 Гость смотрят эту тему.
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« : 04-12-2012 06:04 » 

Здравствуйте, опять к вам за помощью.
Запуталась в простом, как всегда.
Пишу в Visual c++ 6.

Вот кусочек программы, создаётся RadioButton
  
Код:
for(i=0;i<nCount+1;i++)
   {
  if(!::IsWindow(cR[i].GetSafeHwnd()))
{
 if(i==0)
 {
 iWS=BS_AUTORADIOBUTTON |WS_CHILD| WS_VISIBLE|  BS_PUSHLIKE| BS_FLAT;
  x0=2;
 }
 else
 {
                                    x0=10;
    if(i==1)
  iWS=BS_AUTORADIOBUTTON |WS_GROUP|WS_CHILD| WS_VISIBLE;
 else
             iWS=BS_AUTORADIOBUTTON |WS_CHILD| WS_VISIBLE;
 }
 CRect rc2(CPoint(rc.left+x0,rc.top+i*20),CSize(n*15,20));

cR[i].CreateEx(WS_EX_WINDOWEDGE, _T("Button"),_T(soob[i]),iWS,
rc2,this,IDC_radioAMMTT+i);
}
   }
Вопрос  какой шрифт будет у подписей радио?
Я думала. что такой же ,как у диалога, в котором создаются эти Radio, а на деле получилось так, как на прикреплённом рисунке.

Те шрифт отличается от шрифта на других эл-тах диалога.
Что я неправильно понимаю?
И как всё это подправить, чтобы подписи были в стиле диалога?


Добавлено через 39 минут и 25 секунд:
Сделала, но хочу всё-таки умных людей послушать.

* ss1.jpg (31.77 Кб - загружено 2089 раз.)
« Последнее редактирование: 04-12-2012 06:44 от ann_nef » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #1 : 04-12-2012 09:36 » 

При динамическом создании контрола (те когда его данные не находятся в файле ресурсов .rc  и, соответственно, не компилируются) его шрифт по умолчанию системный (System). В этом случае необходимо следить за тем, чтобы при изменении системных настроек (размер шрифта, разрешение) диалог не пошёл вразнос. Ибо "стандартные" контролы, также как и размер диалога, будут автоматически изменены, чего явно не произойдёт с динамически созданными, если у них размер шрифта задан жёстко.

Насчёт остального ничего сказать не могу. С возрастом телепатические способности сильно ослабевают и становится всё труднее за кратким "сделала" разобрать код. Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #2 : 04-12-2012 10:47 » 

Пока формулировала свой вопрос, появилась идея, которую я попробовала и получила результат.

До начала создания динамических RadioButton:
CFont* pf = this->GetDlgItem(IDC_статического контрола любого)->GetFont();

А в цикле создания динамических контролов устанавливаю этот шрифт:
this->GetDlgItem(IDC_radioAMMTT+i)->SetFont(pf,TRUE);

Джон, так?

Спасибо, поняла почему нет наследования и используется шрифт по умолчанию.

Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #3 : 04-12-2012 11:16 » 

Нууу, а вдруг ты потом уберёшь элемент "IDC_статического контрола любого"? Каждый раз надо будет следить. Есть более простой способ:
Код: (C++)
CFont *pFont = CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT));
...
GetDlgItem(IDC_radioAMMTT+i)->SetFont(pFont);
« Последнее редактирование: 04-12-2012 15:06 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #4 : 04-12-2012 12:49 » 

Джон,конечно, грамотней сделать,как ты предлагаешь.
Но, результат немного не такой,какой мне бы хотелось... Пока получился шрифт отличный от шрифта статических контролов.
Буду разбираться с твоим  способом.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #5 : 04-12-2012 14:00 » 

Хм... может это зависит от "русскоязычности"? В смысле на русской системе фонты могут отличаться. У меня они одинаковые.
Вот свойства диалога в редакторе ресурсов:



А это значение переменной lf, которую я добавил, чтобы посмотреть параметры шрифта:

Код: (C++)
LOGFONT lf;
pFont->GetLogFont(&lf);



Что значит "результат немного не такой,какой мне бы хотелось"?

Добавлено через 22 минуты и 16 секунд:
UPDATE

Покопался ща в MSDN для GetStockObject. Без объяснения причин, советуют лучше так не делать:

Цитата: MSDN
DEFAULT_GUI_FONT
Default font for user interface objects such as menus and dialog boxes. It is not recommended that you use DEFAULT_GUI_FONT or SYSTEM_FONT to obtain the font used by dialogs and windows; for more information, see the remarks section. The default font is Tahoma.
...
Remarks
It is not recommended that you employ this method to obtain the current font used by dialogs and windows. Instead, use the SystemParametersInfo function with the SPI_GETNONCLIENTMETRICS parameter to retrieve the current font. SystemParametersInfo will take into account the current theme and provides font information for captions, menus, and message dialogs.
Попробовал, ещё "более правильным способом":

Код: (C++)
        NONCLIENTMETRICS ncm;
        ncm.cbSize = sizeof(NONCLIENTMETRICS);
        UINT uiParam = sizeof(NONCLIENTMETRICS);
        ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, uiParam, &ncm, 0);

Действительно получается Tahoma:



Может это тебе поможет получить "немного такой" результат.

Добавлено через 12 минут и 27 секунд:
Тоже прикол:

CFont *pFont = this->GetFont();

возвращет какой-то "MS Shell Dlg 2".


* ss1.gif (3.45 Кб - загружено 1828 раз.)
* ss2.gif (4 Кб - загружено 1863 раз.)
* ss3.gif (7.99 Кб - загружено 1903 раз.)
« Последнее редактирование: 04-12-2012 15:12 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 04-12-2012 15:49 » 

И ещё за событиями смены темы и dpi экрана следить придётся... (Если уж совсем-совсем по-хорошему.)
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #7 : 04-12-2012 16:27 » 

Ну это то, о чём я сказал в #2. Я просто не видел, как она создаёт фонт-объект. При получении же системного фонта (как выше), это не имеет значения, тк он будет автоматически иметь "нужный" размер.
А вот за размерами контрола - да. Надо следить, но только в том случае, если используются жёстко кодированные размеры. При привязке размеров контрола к размеру диалога (функциональной зависимости), про это тоже можно забыть.

Кстати, можно поменять dpi без перезапуска системы?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #8 : 05-12-2012 05:32 » 

Джон,
1 .немного не такой результат: у диалога и статических контролов шрифт MS Sans Serif, а после
CFont *pFont = CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT));
...
GetDlgItem(IDC_radioAMMTT+i)->SetFont(pFont);         ----->                    шрифт MS Shell Dlg

2. Более "правильный" способ ещё не поняла. Не понял

3. Предположим, что ориентироваться на статические контролы, кот. описаны в файле rc, не очень хорошо(вдруг удалю в дальнейшем).
Но, ведь сам диалог опиcан статически, его я точно удалять не буду.
Как добраться до его шрифтов для дальнейшего использования? Здесь была моя ладья...
« Последнее редактирование: 05-12-2012 05:34 от ann_nef » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #9 : 05-12-2012 08:48 » 

Джон,
1 .немного не такой результат: у диалога и статических контролов шрифт MS Sans Serif, а после
CFont *pFont = CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT));
...
GetDlgItem(IDC_radioAMMTT+i)->SetFont(pFont);         ----->                    шрифт MS Shell Dlg

Вот теперь ты говоришь понятно. Ага

Значит смотри. Способ, которым я пользовался многие годы это через ф. GetStockObject(DEFAULT_GUI_FONT). Теперь оказывается, что его не рекомендуют использовать.

2. Более "правильный" способ ещё не поняла. Не понял

Оказываетя лучше пользоваться ф. SystemParametersInfo. Эта ф-я позволяет получить структуру LOGFONT дефолтного шрифта, который используется в диалогах и меню, на основе которой можно создать объект типа CFont. Для этого у него есть ф-я CreateFontIndirect.

Код я уже был привёл. Ещё раз:

Код: (C++)
        NONCLIENTMETRICS ncm;
        ncm.cbSize = sizeof(NONCLIENTMETRICS);
        UINT uiParam = sizeof(NONCLIENTMETRICS);
        ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, uiParam, &ncm, 0);

После вызова SystemParametersInfo в поле ncm.lfMenuFont находятся параметры дефолтного шрифта. Сначала посмотри в дебагере, какой там получается фонт - поле lfFaceName (см. скриншот). Если это не MS Sans Serif, то тогда попробуй вызывать ф-ю диалога GetFont(), и посмотри какой шрифт она вернёт. К я уже сказал, у меня все три способа возвращают разные результаты:
1. GetStockObject(DEFAULT_GUI_FONT) -> Ms Shell Dlg
2. SystemParametersInfo -> Tahoma
Но, ведь сам диалог опиcан статически, его я точно удалять не буду.
Как добраться до его шрифтов для дальнейшего использования? Здесь была моя ладья...
(про это я тоже уже был написал)
3. this->GetFont() -> Ms Shell Dlg 2

С той лишь разницей, что в свойствах диалога прописан Ms Shell Dlg (см. скриншоты).

Если у тебя с ф-ей SystemParametersInfo получится что надо, то тогда тебе надо будет добавить в диалог объект типа CFont (с локальной переменной не получится, тк она будет разрушена в конце ф-ции), например:

Код: (C++)
CFont m_DlgFont;

затем, где-нить в ф-ции инициаллизации, после вызова SystemParametersInfo (см. код выше) сделать след.:

Код: (C++)
m_DlgFont.CreateFontIndirect(&ncm.lfMenuFont);

ну и... использовать его:

Код: (C++)
GetDlgItem(IDC_radioAMMTT+i)->SetFont(&m_DlgFont);

Если же ни один из этих способов тебе MS Sans Serif не вернёт, то... будем думать. Студия 6 это ты уже написала. А винда какая? А то у меня есть такое смутное подозрение, что MS Sans Serif был в старых версиях, поэтому и в студию его загнали в качестве стандарта.



Добавлено через 20 минут и 20 секунд:
Ща попробовал на 6ой студии ХРюша СП3. Третий способ вернул MS Sans Serif.
« Последнее редактирование: 05-12-2012 09:08 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #10 : 05-12-2012 11:07 » 

Да, "чукча думать,однако, будет".
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #11 : 05-12-2012 15:32 » 

Дык, а чего тут думать? Вот это пробовала? Вместо:

Код: (C++)
CFont *pFont = CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT));

вот это:

Код: (C++)
CFont *pFont = this->GetFont();


Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #12 : 06-12-2012 06:57 » 

Хм, всё гениальное просто. Краснею
Спасибо, Джон, конечно всё получилось.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #13 : 06-12-2012 08:41 » 

Просто-то оно просто. Только нафига так запутанно? Вопрос ессно риторический.

Ну и не забывай про что мы тебе с Димкой сказали насчёт изменения системных настроек.
Раньше это казалось чем-то далёким. А сейчас это суровые будни. Наши клиенты обзавелись гигантскими мониторами (нафига?), ну и кажется им всё мелким, вот и ставят dpi на 125-150%. Вот тут-то такие огрехи и проявляются.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #14 : 06-12-2012 09:34 » 

Спасибо,учту.
Записан
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #15 : 07-12-2012 20:26 » 

Ну, вот одна проблема ушла, другая объявилась. И опять надеюсь на вашу помощь.
Вопрос такой:
как описать-создать событие, типа потери фокуса, если я создала контрол, типа CEdit?

Для того, чтобы проверить введенные данные с помощью этого контрола.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #16 : 08-12-2012 20:56 » 

а как ты его создала ? Если визардом - то просто добавь событие. Визард вставит определение функции-обработчика, макрос для карты событий и заготовку реализации обработчика.

Код:
		afx_msg void OnEnKillfocus();
DECLARE_MESSAGE_MAP()
....
.....
BEGIN_MESSAGE_MAP(CMyEdit, CEdit)
ON_CONTROL_REFLECT(EN_KILLFOCUS, &CMyEdit::OnEnKillfocus)
END_MESSAGE_MAP()

.....
......
void CMyEdit::OnEnKillfocus()
{
CEdit::CMyEdit();//поведение родителя
}

если вручную, то нужно поймать сообщение WM_COMMAND +WM_REFLECT_BASE. Либо в самом диалоге - WM_CMMAND (читай МСДН по его параметрам)

всё это можно подглядеть в определении макроса, используемого визардом
Код:
// for control notification reflection
#define ON_CONTROL_REFLECT(wNotifyCode, memberFxn) \
{ WM_COMMAND+WM_REFLECT_BASE, (WORD)wNotifyCode, 0, 0, AfxSigCmd_v, \
(static_cast<AFX_PMSG> (memberFxn)) },

либо при помощи Spy++  Улыбаюсь

события CEdit (передаются в параметре wParam) -
Код:
/*
 * Edit Control Notification Codes
 */
#define EN_SETFOCUS         0x0100
#define EN_KILLFOCUS        0x0200
#define EN_CHANGE           0x0300
#define EN_UPDATE           0x0400
#define EN_ERRSPACE         0x0500
#define EN_MAXTEXT          0x0501
#define EN_HSCROLL          0x0601
#define EN_VSCROLL          0x0602
« Последнее редактирование: 08-12-2012 21:00 от Алексей++ » Записан

ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #17 : 09-12-2012 06:51 » 

Алексей, Editы были созданы CreateEx.     
Пишу на Visual c++ 6.

Пыталась использовать PreTranslateMessage для захвата KillFocus,но что-то неправильно делала.
Полдня с этим вчера промучилась, сделала вариант с табуляцией.
Получилось поймать табуляцию, те событие WM_KEYDOWN и значение VK_TAB.
Результат есть, но немного корявенький.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #18 : 09-12-2012 20:11 » 

произведи свой класс от CEdit и в нём переопредели виртуальную фунцию обработки сообщений:
http://msdn.microsoft.com/en-us/library/8k57wfbs(v=vs.71).aspx

Код:
class CMyEdit: public CEdit
{
virtual LRESULT WindowProc(
   UINT message,
   WPARAM wParam,
   LPARAM lParam
);
};

RESULT CMyEdit::WindowProc(
   UINT message,
   WPARAM wParam,
   LPARAM lParam
)
{
 switch(message)
 {
    case WM_COMMAND +WM_REFLECT_BASE:
    {
         if(wParam==EN_KILLFOCUS)
         {
             ...
         }
    }
    break;
 }

 
   CEdit::WindowProc(message,wParam,lParam );
}

или можно использовать макросы визарда вручную:
Код:
	class CMyEdit:public CEdit
{

public:

CMyEdit()
{
}
protected:
afx_msg void OnEnChange();
afx_msg void OnEnKillfocus();
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnPaint();

//макрос для объявления функций карты сообщений
DECLARE_MESSAGE_MAP()
};


внимание!
макрос содержит следующее

Код:
#define DECLARE_MESSAGE_MAP() \
protected: \
static const AFX_MSGMAP* PASCAL GetThisMessageMap(); \
virtual const AFX_MSGMAP* GetMessageMap() const; \

то есть уровень доступа protected. Поэтому я этот макрос всегда в конец объявления класса передвигаю - на всякий случай ))

в реализации:


Код:
	BEGIN_MESSAGE_MAP(CMyEdit, CEdit)
ON_CONTROL_REFLECT(EN_CHANGE, &CMyEdit::OnEnChange)
ON_CONTROL_REFLECT(EN_KILLFOCUS, &CMyEdit::OnEnKillfocus)
ON_WM_KEYUP()
ON_WM_PAINT()
END_MESSAGE_MAP()

void CMyEdit::OnEnChange()
{

}

void CMyEdit::OnEnKillfocus()
{

}


void CMyEdit::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
switch(nChar)
{
case VK_RETURN:
{

}
break;
}

CMyEdit::OnKeyUp(nChar, nRepCnt, nFlags);
}


void CMyEdit::OnPaint()
{
CMyEdit::OnPaint();
//а тут можно и самим порисовать
}
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines