|
|
| (не показано 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
| + | |