|
|
(не показано 57 промежуточных версий 4 участников) |
Строка 1: |
Строка 1: |
− | ===Имеется приложение на основе CRichEditView. Как узнать, что пользователь меняет текст?===
| + | #REDIRECT [[FAQ:WinAPI_VCPP]] |
− | Добавить обработчик сообщения EN_CHANGE. Сообщение генерируется CRichEditView каждый раз, когда пользователь изменяет текст в окне CRichEditView
| + | |
− | ===Чем метод CArray::GetSize отличается от метода CArray::GetCount?===
| + | |
− | Абсолютно ничем. (Скорее всего, были предыдущие библиотеки, в которых функции, одинаковые по смыслу, имели разные имена. Поэтому в целях совместимости оставили оба)
| + | |
− | ===Как загрузить строку из ресурса?===
| + | |
− | <pre>
| + | |
− | CString m_Temp;
| + | |
− | m_Temp.LoadString(ID_MYSTRING);
| + | |
− | </pre>
| + | |
− | ===Как поменять иконку у элемента (item) в CListCtrl ?===
| + | |
− | <pre>
| + | |
− | //заполняем структуру LVITEM
| + | |
− | LVITEM lvItem;
| + | |
− | memset(&lvItem,0,sizeof(lvItem));
| + | |
− |
| + | |
− | lvItem.mask = LVIF_IMAGE;//меняться будет картинка
| + | |
− | lvItem.iItem = ...;// индекс элемента списка (Zero-based)
| + | |
− | lvItem.iSubItem = 0;
| + | |
− | lvItem.iImage = ...; //индекс иконки (из списка контрола)
| + | |
− |
| + | |
− | pList->SetItem(& lvItem);
| + | |
− | </pre>
| + | |
− | ===Имеется класс Class1, содержащий мембер типа указатель на Class2. В Class2 также имеется указатель на Class1. Компилятор выдаёт ошибку. Что надо делать?===
| + | |
− | Предварительно объявляем класс Class2. Тогда компилятору будет известно, что описание класса Class2 будет встречено дальше, и станет возможным объявление указателей на класс до описания самого класса.
| + | |
− | <pre>
| + | |
− | Class2;//предопределение
| + | |
− |
| + | |
− | Class1
| + | |
− | {
| + | |
− | Class2* p;
| + | |
− | };
| + | |
− |
| + | |
− | Class2
| + | |
− | {
| + | |
− | Class1* p;
| + | |
− | };
| + | |
− | </pre>
| + | |
− | ===Как переключить раскладку в другом (то есть в активном) процессе?===
| + | |
− | Использовать функции:
| + | |
− | GetKeyboardLayout - определить текущую раскладку
| + | |
− | LoadKeyboardLayout - загрузить новую раскладку
| + | |
− | | + | |
− | см.также
| + | |
− | VerLanguageName - получить строку с описанием языка
| + | |
− | | + | |
− | (подробности - в MSDN)
| + | |
− | ===Как получить хендл контрола Edit зная его ID ?===
| + | |
− | Пусть контрол лежит на окне CMyWnd
| + | |
− | Тогда:
| + | |
− | <pre>
| + | |
− | void CMyWnd::некая_процедура()
| + | |
− | {
| + | |
− | //для MFC
| + | |
− | CEdit* ed=(CEdit* ) GetDlgItem(ID_EDIT1);
| + | |
− | HWND hwnd=ed->GetSafeHwnd();
| + | |
− | ...
| + | |
− |
| + | |
− | //для Win32 API
| + | |
− | HWND hwnd=GetDlgItem(m_hWnd,ID_EDIT1);
| + | |
− | ...
| + | |
− | }
| + | |
− | </pre>
| + | |
− | ===Как из дочернего окна закрыть приложение?===
| + | |
− | Нужно послать родительскому окну (*pParent) сообщение WM_CLOSE:
| + | |
− | pParent->PostMessage(WM_CLOSE);//MFC
| + | |
− | или
| + | |
− | ::PostMessage(pParent->m_hWnd,WM_CLOSE,(WPARAM)0,(LPARAM)0);//API
| + | |
− | ===Как корректно перевести BSTR в CString и наоборот?===
| + | |
− | 1) Нужно просто присвоить переменной типа CString переменную типа BSTR.
| + | |
− | Оператор = класса CString сам всё переведёт.
| + | |
− | | + | |
− | 2)
| + | |
− | <pre>
| + | |
− | //указатель на будущий буфер с BSTR.
| + | |
− | // (По сути, BSTR определён как
| + | |
− | // typedef WCHAR* BSTR;
| + | |
− | // то есть указатель на 16-битный символ юникод)
| + | |
− |
| + | |
− | BSTR bstrHE=0;
| + | |
− |
| + | |
− | CString Str="мой текст";
| + | |
− |
| + | |
− | //Выделить память и загрузить адрес блока в bstrHE
| + | |
− | bstrHE=Str.AllocSysString();
| + | |
− |
| + | |
− | //...
| + | |
− | //тут работаем с bstrHE[]
| + | |
− | //...
| + | |
− |
| + | |
− | //освобождаем память
| + | |
− | SysFreeString(bstrHE);
| + | |
− | </pre>
| + | |
− | ===Как получить доступ к графическим ресурсам элементов текущей темы оформления Windows?===
| + | |
− | Использовать функции
| + | |
− | | + | |
− | OpenThemeData()
| + | |
− | DrawThemeBackground()
| + | |
− | DrawFrameControl()
| + | |
− | CloseThemeData().
| + | |
− | | + | |
− | (подробности - в MSDN)
| + | |
− | ===Имеется класс , производный от CDialog. Когда диалог в фокусе, нажатие на Enter или Esc приводит к закрытию диалога. Как это запретить?===
| + | |
− | При нажатии Enter происходит выполнение команды IDOK,
| + | |
− | при нажатии Esc - IDCANCEL.
| + | |
− | Нужно переопределить в классе виртуальные функции OnOk() и OnCancel(),
| + | |
− | которые соответственно вызываются для этих команд. При помощи
| + | |
− | визарда эти функции добавить можно так: Положить на диалог две кнопки
| + | |
− | с идентификаторами IDOK и IDCANCEL (при создании нового диалога они там
| + | |
− | есть сразу), затем двойной клик по кнопке добавляет соответствующий
| + | |
− | обработчик. В обработчиках надо удалить вызовы СDialog::OnOK() и
| + | |
− | CDialog::OnCancel(), тогда диалог закрываться не будет.
| + | |
− | Однако тогда диалог станет невозможно закрыть кнопкой с крестиком :)
| + | |
− | | + | |
− | Лечить так: добавить обработчик сообщения WM_CLOSE - OnClose(), и в нём
| + | |
− | сделать вызов OnOk() или OnCancel() :
| + | |
− | <pre>
| + | |
− | void CPlayersPropsDialog::OnClose()
| + | |
− | {
| + | |
− | CDialog::OnClose();
| + | |
− | CDialog::OnCancel();//добавлено
| + | |
− | }
| + | |
− | </pre>
| + | |
− | ===VC++6. Я написал простейший макрос, а компилятор на него ругается. ума не приложу, что за глюк?===
| + | |
− | <pre>
| + | |
− | #define my_macr(x,y,z) \
| + | |
− | z=\
| + | |
− | (x+y)*\
| + | |
− | (x-y)
| + | |
− | </pre>
| + | |
− | Скорее всего после одного из символов соединения строк "\" имеется
| + | |
− | пробел или табуляция. Их надо удалить. Можно найти их "наощупь", а
| + | |
− | можно включить показ непечатных символов в студии. Найти эту команду
| + | |
− | можно так:
| + | |
− | Tools->Customize...->вкладка Commands. , В окошке Category выбрать
| + | |
− | "Edit", и среди кнопок справа найти кнопку , на которой написано "a.b"
| + | |
− | Эту кнопку надо перетащить на одну из панелей инструментов студии.
| + | |
− | ===Как получить список всех процесов, включая idle ?===
| + | |
− | Использовать функции
| + | |
− | Process32First()
| + | |
− | Precess32Next()
| + | |
− | ===Как программно установить переменные окружения?===
| + | |
− | Чтобы добавить или изменить их программно, необходимо воспользоваться
| + | |
− | ключом реестра HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\
| + | |
− | Session Manager\Environment, а затем отправить широковещательное
| + | |
− | сообщение WM_SETTINGCHANGE. Это позволит приложениям узнать об
| + | |
− | изменениях:
| + | |
− | | + | |
− | ::SendMessage(HWND_BROADCAST,WM_SETTINGCHANGE,0,0);
| + | |
− | ===Как сделать,чтобы у окна был черный фон?===
| + | |
− | переопределить обработчик сообщения WM_CTLCOLOR - OnCtlColor() :
| + | |
− | <pre>
| + | |
− | | + | |
− | CBrush br(RGB(0,0,0));
| + | |
− |
| + | |
− | HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
| + | |
− | {
| + | |
− | HBRUSH hbr = CMyDlg::OnCtlColor(pDC, pWnd, nCtlColor);
| + | |
− |
| + | |
− | //фон диалога (или вьюшки)
| + | |
− | if(nCtlColor==CTLCOLOR_DLG)
| + | |
− | {
| + | |
− | return (HBRUSH)br;
| + | |
− | }
| + | |
− |
| + | |
− | //фон статиков (если нужно)
| + | |
− | if(nCtlColor==CTLCOLOR_STATIC)
| + | |
− | {
| + | |
− | //делаем фон текста статика прозрачным
| + | |
− | pDC->SetBkMode(TRANSPARENT);
| + | |
− | return (HBRUSH)br;
| + | |
− | }
| + | |
− |
| + | |
− | return hbr;
| + | |
− | }
| + | |
− | </pre>
| + | |
− | ===Почему на моем компьютере экзешник, созданный в MFC запускается, а на других компьютерах - нет? Требует какую-то dll-ку.===
| + | |
− | Нужно выбирать режим Release :
| + | |
− | | + | |
− | Menu->Build->Configurations...->Release,
| + | |
− | | + | |
− | и экзешник, соответственно, брать из папки Release проекта
| + | |
− | ===Как в диалог добавить меню?===
| + | |
− | Надо сделать в ресурсах меню, затем вставить в диалог:
| + | |
− | | + | |
− | открыть в редакторе диалог, в свойствах (во вкладке General, окошко Menu) указать идентивикатор ресурса меню.
| + | |
− | При помощи визарда добавить для меню обработчики OnCommand() и OnUpdateСommand().
| + | |
− | ===Я добавил визардом меню в диалог. Добавил обработчики для пунктов меню. Но пункты работают, но OnUpdate для пунктов не вызывается - то есть не получается ни затенить, ни чек поставить. Что делать?===
| + | |
− | В диалоге у меню апдейта не происходит сам, в отличие от мейнфрейма.
| + | |
− | Для этого нужно сделать самим апдейт в обработчике сообщения WM_KICKIDLE.
| + | |
− | Визардом обработчик не добавляется, поэтому можно переопределить
| + | |
− | виртуальную DefWindowProc() и там обработать:
| + | |
− | #include <afxpriv.h> //этот файл надо включить, там определёна WM_KICKIDLE
| + | |