MS Visual C + + / MFC FAQ, C / C + +, Програмування, статті

Paul Kalyakin <Paul.Kalyakin@p20.f32.n5029.z2.fidonet.org>
www.rusdev.newmail.ru

Питання

Відповіді

Q1. Як показати ProgressBar на StatusBar'е?

A1.

Припустимо, що ви хочете показати CProgressCtrl на весь StatusBar.
Для цього необхідно виконати наступне:
– Виберіть пункт меню View – Resource Symbols. Натисніть кнопку New і
додайте нове ім'я, в нашому прикладі це буде ID_PROGRBAR.
– У файлі MainFrm.cpp знайдіть оголошення масиву indicators (він
знаходитися відразу після END_MESSAGE_MAP) і відредагуйте його до
следующе увазі

  static UINT indicators[] =
             {
                 ID_PROGRBAR
              };

– У файлі _MainFrm.h створіть protected змінну m_bCreated типу
BOOL і public змінну m_progress типу CProgressCtl.
– У файлі MainFrm.cpp відредагуйте кінець функції
int CMainFrame:: OnCreate (LPCREATESTRUCT lpCreateStruct) таким чином:

до ділянки коду:

                    if (!m_wndStatusBar.Create(this ) ||
! M_wndStatusBar.SetIndicators (indicators,
                       sizeof(indicators)/sizeof (UINT)))
                   {
TRACE0 ("Failed to create status bar \ n");
                       return -1; // fail to create
                   }

додайте такий рядок:

          else {
m_wndStatusBar.SetPaneInfo (0, ID_PROGRBAR, SBPS_STRETCH, 10);
               }

Крім того, додайте ініціалізацію нашої змінної m_bCreated

                    .........
                     m_bCreated=FALSE;
                    ..........

– Тепер ми можемо використовувати ProgressBar в рядку статусу, природно не
забувши створити цей об'єкт. Припустимо, у нас є функція
CMainFrame:: OnWork (). Вона буде виглядати приблизно так:

   void CMainFrame::OnWork()
            {
              RECT rc;
                m_wndStatusBar.GetItemRect(0,&rc);
               if (m_bCreated==FALSE)
               {
/ / Створюємо m_progress
m_progress.Create (WS_VISIBLE | WS_CHILD, rc, & m_wndStatusBar, 1);
/ / Встановлюємо розмір від 0 до 100
                 m_progress.SetRange(0,100);
                 m_progress.SetStep(1);
                 m_bCreated=TRUE;
                }
                for (int I = 0; I < 100; I++)
                {
                  Sleep(20);
                  m_progress.StepIt();
                }
            }

-Якщо відкомпілювати проект на цій фазі, то все буде працювати, але при
зміні розміру вікна лінійка ProgressBar'а розміри міняти не буде, тому
необхідно перекрити подія OnSize:

            void CMainFrame::OnSize(UINT nType, int cx, int cy)
            {
                CFrameWnd::OnSize(nType, cx, cy);
                 if (m_bCreated)
                  {
                      RECT rc;
                      m_wndStatusBar.GetItemRect(0,&rc);
m_progress.SetWindowPos (& wndTop, rc.left, rc.top,
rc.right - rc.left, rc.bottom - rc.top, 0);
                    }
              }

– Ось тепер все /-))))) Відкомпілюйте проект і переконайтеся, що всі
працює.

Q2. Як використовувати CTreeCtrl для побудови дерева каталогів диска, як в
Провіднику? Невже необхідно рекурсивно проглянути диск, а потім прописати
ручками все ітем даного контрола??

A2. (A. Лисиці Дмітрій. dimik@infopro.spb.su)

Це гальмівної і глючной. На великих дисках це займе кілька хвилин. Якщо
каталоги додаються або удалются іншими додатками під час роботи твого
контрола, то будеш весь в проблемах. Все набагато простіше. Ніяких рекурсій.
Переглядаємо кореневої каталог на предмет наявності підкаталогів і створюємо ітеми
першого рівня, в яких створюємо по одному фіктивному ітему (щоб хрестик
був і ітем можна було розкрити).
+ Каталог 1
+ Каталоги 2
+ Каталог 3

Як тільки юзер намагається розкрити ітем, відповідний нікому каталогу, ми
видаляємо з нього фіктивний ітем, переглядаємо цей підкаталог і додаємо
відповідні ітеми зі своїми фіктивними усередині.
-Каталог 1
+ Каталог 4
+ Каталог 5
+ Каталог 6
+ Каталоги 2
+ Каталог 3

Як тільки юзер закриває ітем, ми видаляємо з нього всі дочірні ітеми і
назад додаємо фіктивний. Якщо структура каталогів змінилася, для
поновлення юзеру досить просто закрити і відкрити відповідну гілку.
Саме так і працює "Провідник".

Q3. Є клас – нащадок CListView. Як змінити стиль у об'єкту CListCtrl,
належить до цього * view (наприклад встановити стиль Report)?

A3.

Для цього пишіть в OnInitialUpdate вашого виду

void CMyListView::OnInitialUpdate()
{
 ......
        CListView::OnInitialUpdate();

    CListCtrl& theCtrl = GetListCtrl();
    DWORD dwStyle=GetWindowLong(theCtrl.m_hWnd,GWL_STYLE);
    SetWindowLong(theCtrl.m_hWnd,GWL_STYLE,dwStyle|LVS_REPORT);
 ....

A3. (by Pavel Nazin 2:5020/1053.21)

Набагато простіше перекрити PreCreateWindow (краще всього скористатися
ClassWizard-ом) і длубати переданий за посиланням CREATESTRUCT типу такого:

BOOL CMyListView::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style | = LVS_REPORT; / / так ми додаємо стиль
cs.style & = LVS_REPORT; / / а ось так знімаємо

    return CMyListView::PreCreateWindow(cs);
}

Q4. Як CString привести до char *? _

A4. (by Yuri Khodin 2:5020/1200.20)

#include <atlbase.h>
USES_CONVERSION;
 CString strData(_T("Some Data"));
 char* lpszString = T2A((LPTSTR)(LPCTSTR)strData);

A4. (by Paul Kalyakin 2:5029/3.29 hjobyf@mail.ru)

CString tmp_str;
char* st;

st=tmp_str.GetBuffer(tmp_str.GetLength())

важливо те, що якщо з tmp_str що-небудь зробити, то необхідно знову отримати
покажчик на внутрішній буфер CString.

Q5. Які бібліотеки Freeware / Commercial існують для Visual C + +? _

A5.

1- BCG Control Library (freeware)
    msnhomepages.talkcity.com/WindowsWay/stasl/index.html

2- CJLibrary (freeware)
    www.codejock.com

Stringray Software (commercial) www.stingray.com
Фірма Stringray Software виробляє бібліотеки для Visual C + + (MFC, ATL):
1. Stingray Objective Toolkit (PRO) – набір різних компонентів для
MFC і ATL
2. Stingray Objective Grid (PRO) – потужна сітка даних з можливостями,
близькими до Excel. Дружить з базами даних (через DAO, ADO, ODBC). Можна
використовувати для введення даних у таблиці БД і для виведення / друку простих
звітів.
3. Stingray Objective Chart – засіб для побудови діаграм
4. Stingray Objective Views – засіб для створення Visio-подібних
інтерфейсів (за допомогою векторної графіки)
5. Stingray Objective Edit – текстовий редактор з підсвічуванням синтаксису

крім цих, є й інші продукти

Dundas Software (commercial) www.dundas.com
Фірма Dundas Software виробляє бібліотеки для Visual C + + (MFC):
1. Dundas Ultimate Toolbox – набір компонентів для MFC, за складом
дещо відрізняється від Stingray Objective Toolkit.
2. Dundas Ultimate Grid – сітка даних, конкурент Stingray Objective Grid.
3. Dundas TCP / IP – реалізація протоколів POP3, NEWS та т.п.
4. Dundas Chart – діаграми
та інші продукти

Q6.А можна приклад консольної програми? _

A6. by Alexander Fedorov (2:5030/437.74)

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


void main()
 {
 HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
 SMALL_RECT srct;
 CHAR_INFO chiBuffer[160];
 COORD coord1, coord2;
 char ddd[666];
CharToOem ("2:5095 / 38 - злісний ламерюга", ddd);
 DWORD cWritten;
 coord1.Y = 0; coord1.X = 0;
 hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsoleOutputCharacter (hStdout, ddd, lstrlen (ddd), coord1, cWritten);
 for (int i = 0; i {
 WORD wColors = 1 + i * 3;
 coord1.X = i;
 WriteConsoleOutputAttribute(hStdout, , 1, coord1, cWritten);
 }
 srct.Top = 0; srct.Left = 0; srct.Bottom = 1; srct.Right = 79;
 coord1.Y = 0; coord1.X = 0;
 coord2.Y = 1; coord2.X = 80;
 ReadConsoleOutput(hStdout, chiBuffer, coord2, coord1, );
 for (i = 0; i {
srct.Left = (SHORT) ((double) (79 - lstrlen (ddd)) * rand () / RAND_MAX);
 srct.Top = (SHORT)((double)25 * rand() / RAND_MAX);
 srct.Bottom = srct.Top + 1;
 WriteConsoleOutput(hStdout, chiBuffer, coord2, coord1, );
 }
 Sleep(10000);

Q7. У створеному майстром (VC 6.0) win32 Console Application спроба вивести
російський текст дає кракозяблікі.Что робити? _

A7. by Dmitriy Reznitskiy (2:5020/1452.112)

CharToOem, OemToChar – воно?

Q8. Намагаюся зі своєї програми викликати Word97, для це роблю кілька імпортом
і
в результаті маю купу помилок. Як правильно? _

A8. by Igor Tkachoff (2:5037/9.37)


// Office.h

#define Uses_MSO2000_

 #ifdef Uses_MSO2000
 // for Office 2000
 #import <mso9.dll>
 #import <vbe6ext.olb>
# Import <msword9.olb> rename ("ExitWindows", "_ExitWindows")
# Import <excel9.olb> rename ("DialogBox", "_DialogBox") \
 rename("RGB","_RGB") \
 exclude("IFont","IPicture")
# Import <dao360.dll> rename ("EOF", "EndOfFile") rename ("BOF", "BegOfFile")
 #import <msacc9.olb>

#else
 // for Office 97
 #import <mso97.dll>
 #import <vbeext1.olb>
# Import <msword8.olb> rename ("ExitWindows", "_ExitWindows")
# Import <excel8.olb> rename ("DialogBox", "_DialogBox") \
 rename("RGB","_RGB") \
 exclude("IFont","IPicture")
 #import <DAO350.DLL> \
rename ("EOF", "EndOfFile") rename ("BOF", "BegOfFile")
 #import <msacc8.olb>

#endif

<>pКаталогі проставити сам, якщо треба. Просто я вважаю за краще звалювати все
бібліотеки в одну купу. А ще краще зробити # import один раз, а потім
підключати # include "Тири-пири.tlh".
PS З 2000'ним акуратніше. Деякі методи (типу Run, Open, Add) мають нову
версію. І якщо хочеш сумісність з 97 то слід викликати старі версії,
які називаються типу RunOld і т.п.

Q9. А як відредагувати ресурси. Exe файлу? _

A9.

Це можливо лише під NT.

Q10. Як програмно отримати номер білду свого застосування в VC + +? _

A10. by Pavel Zolotuhin (2:5025/60.15)

Штатної можливості немає, оскільки не всі однаково трактують поняття "номер
білду "і не всі однаково його використовують. Однак більшість людей використовують
для зберігання номера білда конкретного файлу ресурси типу VERSIONINFO, звідки
цю інформацію можна потім отримати (для відображення в діалозі "Про програму"
🙂 За допомогою функцій з version.dll.

Спрощено кажучи, інформація про версію файлу зберігається в VERSIONINFO у вигляді
чотирьох чисел, значимість яких убуває зліва направо. Наприклад, для
mfc42.dll з поставки Win2k версія файлу виглядає як 6.0.8665.0. Тут перша
цифра, як я розумію, збігається з версією продукту (MSVC 6), друга означає
підверсію (MSVC 6.0), третя – номер білду, а четверта – я не знаю. У своїх
dll-ках і exe-шниках Microsoft постійно використовує цю схему, я – теж.
Зазвичай для автоматичного збільшення номера версії використовуються макроси
Visual Studio (== скрипти на VBScript), колупають файл ресурсів проекту. Ці
макроси або зв'язуються з кнопкою на панелі інструментів MSDev, або викликаються з
обробника події Application_BeforeBuildStart у файлі макросів. Приклади
подібних макросів горою лежать на девелоперських сайтах, на зразок
www.codeguru.com. Для себе я зробив власний, який реалізує номер білду
у зазначеному вище сенсі. Ось його ісходник (повинен працювати на MSVC6SP3).

 Sub IncVersion()
 'DESCRIPTION: Increments file version
      Dim oDoc
      Dim iVer

Set oDoc = Documents.Open (Application.ActiveProject & ". Rc", "Text")
      if oDoc Is Nothing Then
          Exit Sub
      End If

oDoc.Selection.FindText "FILEVERSION", dsMatchCase
      if Len(oDoc.Selection) = 0 Then
          oDoc.Close dsSaveChangesNo
          Set oDoc = Nothing
          Exit Sub
      End If
      oDoc.Selection.EndOfLine
      oDoc.Selection.FindText ",", dsMatchBackward
      oDoc.Selection.CharLeft
      oDoc.Selection.WordLeft dsExtend
      iVer = oDoc.Selection
      iVer = iVer + 1
      oDoc.Selection = iVer

oDoc.Selection.FindText "" "FileVersion" "", dsMatchCase
      if Len(oDoc.Selection) = 0 Then
          oDoc.Close dsSaveChangesNo
          Set oDoc = Nothing
          Exit Sub
      End If
      oDoc.Selection.EndOfLine
      oDoc.Selection.FindText ",", dsMatchBackward
      oDoc.Selection.CharLeft
      oDoc.Selection.WordLeft dsExtend
      iVer = oDoc.Selection
      iVer = iVer + 1
      oDoc.Selection = iVer

      oDoc.Close dsSaveChangesYes
      Set oDoc = Nothing

End Sub

Q11. Який функцією можна перемкнути відеорежим?

A11. by Alexander Shargin (2:5030/852.22)

Цим займається ChangeDisplaySettings (…);

Ось тобі приклад, який встановлює дозвіл 640×480 (24 bit):

=== Cut ===
   DEVMODE md;
   ZeroMemory(&md, sizeof(md));
   md.dmSize = sizeof(md);
   md.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
   md.dmBitsPerPel = 24;
   md.dmPelsWidth = 640;
   md.dmPelsHeight = 480;
   ChangeDisplaySettings(&md, 0);
=== Cut ===

Тільки не повторюй помилку, яку допустив я, коли писав цей приклад:
віднови вихідне дозвіл, коли твоя програма буде закінчувати
виконання.

Q12. Як викликати вікно вибору теки?

A12.

Скористайтеся наступною функцією:

BOOL FGetDirectory(LPTSTR szDir)
{ BOOL fRet;
   TCHAR szPath[MAX_PATH];
   LPITEMIDLIST pidl;
   LPITEMIDLIST pidlRoot;
   LPMALLOC lpMalloc;
   BROWSEINFO bi =
       {
       NULL,
       NULL,
       szPath,
"Виберіть папку",
       BIF_RETURNONLYFSDIRS,
       NULL,
       0L,
       0
      };
if (0! = SHGetSpecialFolderLocation (HWND_DESKTOP, CSIDL_DRIVES, & pidlRoot))
     return FALSE;
   if (NULL == pidlRoot)
     return FALSE;
   bi.pidlRoot = pidlRoot;
   pidl = SHBrowseForFolder(&bi);
   if (NULL != pidl)
     fRet = SHGetPathFromIDList(pidl, szDir);
   else
     fRet = FALSE; // Get the shell's allocator to free PIDLs
if (! SHGetMalloc (& lpMalloc) & & (NULL! = lpMalloc))
   {
     if (NULL != pidlRoot)
     {
       lpMalloc->Free(pidlRoot);
     }
     if (NULL != pidl)
     {
       lpMalloc->Free(pidl);
     }
lpMalloc->Release();
}
return fRet;
}

LPTSTR PszAlloc(int cch)
{
return (LPTSTR) LocalAlloc (LMEM_FIXED, sizeof (TCHAR) * (cch +1));
}

bool PszDeAlloc(HLOCAL mem_ptr)
{
return (LocalFree(mem_ptr)==NULL) ? true : false;
}

Потім, при необхідності запропонувати користувачеві вибрати папку
використовуйте приблизно такий код:

....
LPTSTR fname;
fname=PszAlloc(250);
FGetDirectory(fname);
......
PszDeAlloc((HLOCAL)fname);

HomePage для цього FAQ – www.rusdev.newmail.ru

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*