FAQ по C + + Builder

From: Paul Kalyakin <Paul.Kalyakin@p20.f32.n5029.z2.fidonet.org>
Date: Fri, 29 Sep 2000 09:17:30 +0400
                     -==MS Visual C++ / MFC FAQ ==-Версія 1.012 від 29.09.2000ПитанняQ1. Як показати ProgressBar на StatusBar'е?Q2. Як використовувати CTreeCtrl для побудови дерева каталогів диска, як вПровіднику?Q3. Є клас - нащадок CListView. Як змінити стиль у об'єкту CListCtrl,що належить до цього * view (наприклад встановити стиль Report)?Q4. Як CString призвести до char *?Q5. Які бібліотеки (Freeware / Commercial) існують для Visual C + +?Q6. А можна приклад консольної програми?Q7. У створеному майстром (VC 6.0) win32 Console Application спроба вивестиросійський текст дає кракозяблікі.Что робити?Q8. Намагаюся зі своєї програми викликати Word97, для це роблю кількаІмпорт і в результаті маю купу помилок. Як правильно?Q9. А як відредагувати ресурси. Exe файлу?Q10. Як програмно отримати номер білда свого застосування в VC + +?Q11. Який функцією можна перемкнути відеорежим?Q12. Як викликати вікно вибору папки?Відповіді
==============================================================================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);
A2. (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)
    http://msnhomepages.talkcity.com/WindowsWay/stasl/index.html
2- CJLibrary (freeware)
    http://www.codejock.com
Stringray Software (commercial)  www.stingray.comФірма Stringray Software виробляє бібліотеки для Visual C + + (MFC, ATL):1. Stingray Objective Toolkit (PRO) - набір різних компонентів дляMFC і ATL2. Stingray Objective Grid (PRO) - потужна сітка даних з можливостями,близькими до Excel. Дружить з базами даних (через DAO, ADO, ODBC). Можнавикористовувати для введення даних в таблиці БД і для виведення / друку простихзвітів.3. Stingray Objective Chart - засіб для побудови діаграм4. Stingray Objective Views - засіб для створення Visio-подібнихінтерфейсів (за допомогою векторної графіки)5. Stingray Objective Edit - текстовий редактор з підсвічуванням синтаксисукрім цих, є й інші продукти
-------------------------------------------------------------------------------
-
Dundas Software (commercial) http://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Каталоги проставити сам, якщо треба. Просто я волію звалювати всібібліотеки в одну купу. А ще краще зробити # import один раз, а потімпідключати # include "тири-пири.tlh".P.S. З 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 (...);Ось тобі приклад, який встановлює дозвіл 640x480 (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 - http://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>

*

*