Большой архив статей, книг, документации по программированию, вебдизайну, компьютерной графике, сетям, операционным системам и многому другому
 
<Добавить в Избранное>    <Сделать стартовой>    <Реклама на сайте>    <Контакты>
  Главная Документация Новости ИТ Программы Книги Games   Обои   Экспорт RSS E-Books
 
Поиск по сайту

TOP-10 программ
Symantec Norton Ghost 9.0
Partition Magic 8.0.2 Pro
Xilisoft 3GP Video Converter v3.1.7.0616b
Norton AntiVirus 2005
Xilisoft 3GP Video Converter v2.1.52.831b
Антивирус Касперского Personal 5.0.303 beta 2
RAR Password Cracker 4.12
ABBYY PDF Transformer v1.00.820
Windows Movie Maker 2.6
MP3 To Ringtone Gold v3.02
 
Наши сервисы
Рассылка новостей. Подпишитесь на рассылку сейчас и вы всегда будете в курсе последних событий в мире информационных технологий.
Новостные информеры. Поставьте наши информеры к себе и у вас на сайте появится дополнительный постоянно обновляемый раздел.
Добавление статей. Если вы являетесь автором статьи или обзора на тему ИТ присылайте материал нам, мы с удовольствием опубликуем его у себя на сайте.
 
 

   Программирование -> C/C++ -> Уроки программирования на C/C++ под Windows 95


Улучшенная прокрутка


Вы наверное заметили, что вертикальная прокрутка, организованная в предыдущей программе, не очень эффективна. На данном уроке мы улучшим вертикальную прокрутку и добавим горизонтальную.
Вот пример программы:


//файл sm.h остался прежним, поэтому он здесь не приводится



//файл main.cpp

#include <windows.h>

#include "sm.h"



//описание оконной процедуры

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);



//Это главная функция программы.

int WINAPI WinMain(HINSTANCE hInst,

                   HINSTANCE hPrevInst,

                   PSTR szCmdLine,

                   int iCmdShow)

{

  HWND hwnd;

  MSG  msg;

  WNDCLASSEX w;

  static CHAR *szAppName={"TextOutExample"};

  w.cbSize=sizeof(w);

  w.style=CS_HREDRAW|CS_VREDRAW;

  w.lpfnWndProc=WndProc;

  w.cbClsExtra=0;

  w.cbWndExtra=0;

  w.hInstance=hInst;

  w.hIcon=LoadIcon(NULL,IDI_APPLICATION);

  w.hCursor=LoadCursor(NULL,IDC_ARROW);

  w.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);

  w.lpszMenuName=NULL;

  w.lpszClassName=szAppName;

  w.hIconSm=w.hIcon;

  RegisterClassEx(&w);



  hwnd=CreateWindow(

       szAppName,

       "System metrics",

       WS_OVERLAPPEDWINDOW|WS_VSCROLL,

       CW_USEDEFAULT, CW_USEDEFAULT,

       CW_USEDEFAULT, CW_USEDEFAULT,

       NULL,

       NULL,

       hInst,

       NULL);

  ShowWindow(hwnd,iCmdShow);

  UpdateWindow(hwnd);



  while(GetMessage(&msg,NULL,0,0))

  {

    TranslateMessage(&msg);

    DispatchMessage(&msg);

  }

  return msg.wParam;

}



//Оконная процедура

LRESULT CALLBACK WndProc(HWND hwnd, UINT imsg,

                         WPARAM wParam, LPARAM lParam)

{

  PAINTSTRUCT ps;

  HDC         hdc;

  TEXTMETRIC  tm;

  static int  cxChar,cyChar,iVscrollPos=0,iVscrollMax,cyClient,cxClient,

              iMaxWidth,iHscrollMax,iHscrollPos;

  int         iPaintBeg,iPaintEnd,iVscrollInc,iHscrollInc,i,x,y;

  CHAR        szBuffer[10];



  switch(imsg)

  {

    case WM_CREATE:

         hdc=GetDC(hwnd);

         GetTextMetrics(hdc,&tm);

         cxChar=tm.tmAveCharWidth;

         cyChar=tm.tmHeight+tm.tmExternalLeading;

         iMaxWidth=120*cxChar;

         ReleaseDC(hwnd,hdc);

         return 0;



    case WM_SIZE:

         cxClient=LOWORD(lParam);

         cyClient=HIWORD(lParam);



         iVscrollMax=max(0, N_LINES+2-cyClient/cyChar);

         iVscrollPos=min(iVscrollPos, iVscrollMax);

         SetScrollRange(hwnd,SB_VERT,0,iVscrollMax,FALSE);

         SetScrollPos(hwnd,SB_VERT,iVscrollPos,TRUE);



         iHscrollMax=max(0, 2+(iMaxWidth-cxClient)/cxChar);

         iHscrollPos=min(iHscrollPos,iHscrollMax);

         SetScrollRange(hwnd,SB_HORZ,0,iHscrollMax,FALSE);

         SetScrollPos(hwnd,SB_HORZ,iHscrollPos,TRUE);

         return 0;



    case WM_PAINT:

         hdc=BeginPaint(hwnd, &ps);

         iPaintBeg=max(0,iVscrollPos+ps.rcPaint.top/cyChar-1);

         iPaintEnd=min(N_LINES,iVscrollPos+ps.rcPaint.bottom/cyChar);



         for(i=iPaintBeg; i<iPaintEnd; i++)

         {

           x=cxChar*(1-iHscrollPos);

           y=cyChar*(1-iVscrollPos+i);

           TextOut(hdc,x,y,sm[i].szLabel,

                   lstrlen(sm[i].szLabel));

           wsprintf(szBuffer,"%5d",

                    GetSystemMetrics(sm[i].i));

           TextOut(hdc,x+22*cxChar,y,szBuffer,

                   lstrlen(szBuffer));

           TextOut(hdc,x+24*cxChar+8*cxChar,y,

                   sm[i].szDesc,lstrlen(sm[i].szDesc));

         }

         EndPaint(hwnd, &ps);

         return 0;



    case WM_VSCROLL:

         switch(LOWORD(wParam))

         {

           case SB_TOP:

                iVscrollInc = -iVscrollPos; break;

           case SB_BOTTOM:

                iVscrollInc = iVscrollMax-iVscrollPos; break;

           case SB_LINEUP:

                iVscrollInc = -1;

                break;

           case SB_LINEDOWN:

                iVscrollInc = 1;

                break;

           case SB_PAGEUP:

                iVscrollInc = min(-1,-cyClient/cyChar);

                break;

           case SB_PAGEDOWN:

                iVscrollInc = max(1,cyClient/cyChar);

                break;

           case SB_THUMBTRACK:

                iVscrollInc=HIWORD(wParam)-iVscrollPos;

                break;

           default: iVscrollInc=0;

         }



         iVscrollInc=max(-iVscrollPos,

                         min(iVscrollInc,iVscrollMax-iVscrollPos));

         if(iVscrollInc!=0)

         {

           iVscrollPos += iVscrollInc;

           ScrollWindow(hwnd,0,-cyChar*iVscrollInc,NULL,NULL);

           SetScrollPos(hwnd,SB_VERT,iVscrollPos,TRUE);

           UpdateWindow(hwnd);

         }

         return 0;



    case WM_HSCROLL:

         switch(LOWORD(wParam))

         {

           case SB_LINEUP:

                iHscrollInc=-1; break;

           case SB_LINEDOWN:

                iHscrollInc=1; break;

           case SB_PAGEUP:

                iHscrollInc=-8; break;

           case SB_PAGEDOWN:

                iHscrollInc=8; break;

           case SB_THUMBPOSITION:

                iHscrollInc=HIWORD(wParam)-iHscrollPos;

                break;

           default: iHscrollInc=0;

         }

         iHscrollInc=max(-iHscrollPos,

                         min(iHscrollInc,iHscrollMax-iHscrollPos));

         if(iHscrollInc!=0)

         {

           iHscrollPos+=iHscrollInc;

           ScrollWindow(hwnd,-cxChar*iHscrollInc,0,NULL,NULL);

           SetScrollPos(hwnd,SB_HORZ,iHscrollPos,TRUE);

         }

         return 0;



    case WM_DESTROY:

         PostQuitMessage(0);

         return 0;

  }



  return DefWindowProc(hwnd,imsg,wParam,lParam);

}

В этой программе есть небольшие улучшения:

  • Вы не сможете прокрутить окно так, чтобы последняя строка оказалась в самом верху. Прокрутка продолжается только до тех пор, пока появится последняя строка. Для того, чтобы сделать это, программа расчитывает диапазон полосы прокрутки и положение бегунка при обработке сообщения WM_SIZE. (Сообщение WM_SIZE посылается окну тогда, когда изменяется его размеры). Диапазон прокрутки вычисляется на основании числа строк текста (N_LINES) и размера рабочей области (cyClient).
    Если рабочая область будет достаточно велика, чтобы в ней поместились все строки, тогда минимальное и максимальное положение диапазона прокрутки будет равно нулю. Это приведет к тому, что Windows удалит полосу прокрутки, т.к. она уже больше не нужна.
    Аналогично, если ширина рабочей области будет достаточна для отображения 120 символов (см. WM_CREATE: ... iMaxWidth=120*cxChar;), то исчезнет и горизонтальная полоса прокрутки.
  • Перед тем, как прокрутить окно, расчитывается приращение текущей позиции прокрутки - iVscrollInc (для вертикальной прокрутки), iHscrollInc (для горизонтальной прокрутки). Затем выполняется прокрутка окна с помощью функции

ScrollWindow(hwnd, xInc, yInc, pRect, pClipRect);


Параметры xInc и yInc задают величину прокрутки. Параметры pRect и pClipRect устанавливаются в NULL для того, чтобы прокрутить всю рабочую область.
В результате вызова функции ScrollWindow рабочая область, открываемая после прокрутки, делается недействительной, что заставляет Windows послать окну сообщение WM_PAINT. При обработке этого сообщения перерисовываются те строки, которых не было видно до прокрутки окна (а не все строки, как в предыдущей версии программы).

  • Поскольку сообщение WM_PAINT обрабатывается быстрее, чем в предыдущей версии программы (т.к. перерисовываются не все строки, а только вновь открытые), теперь программа обрабатывает сообщение SB_THUMBTRACK вместо SB_THUMBPOSITION, т.е. теперь вертикальная прокрутка выполняется при движении ползунка, а не при отпускании левой клавиши мыши, как в предыдущей версии.

[   ОГЛАВЛЕНИЕ   ]


 
Популярные книги

Ремонт и обслуживание компьютера дома

Подробнее

Дизайн помещений и интерьеров в 3ds max 7 (+CD)

Подробнее

Проектирование реляционных баз данных. Просто и доступно

Подробнее


 
Новости ИТ
10.01.2009  Skype появился на Android и готовится к покорению iPhone
10.01.2009  Студенты-хакеры улучшат безопасность бостонского метро
09.01.2009  Exeda -- корпоративный цифровой ассистент с Android Linux
09.01.2009  Правительство Вьетнама массово переходит на Open Source
09.01.2009  Windows 7 build 7000
09.01.2009  Silicon Power представила скоростную SDHC
09.01.2009  CES 2009: RealView 360 3D Desktop Scanner - настольный 3D-сканер, один из первых в мире
09.01.2009  W90 - очень быстрый мультимедийный ноутбук ASUS «Ultimate-уровня»
09.01.2009  CES 2009: SanDisk представила семейство G3 - самых быстрых SSD-накопителей на флэш-памяти MLC
09.01.2009  ZOTAC GeForce GTX 285 и GTX 285 AMP! Edition - 3D-ускорители для геймеров на новом GPU NVIDIA
09.01.2009  Net Applications: в декабре доли Firefox и Chrome росли за счет IE
09.01.2009  Imation говорит о «новом классе» SSD и первом в отрасли полном наборе для модернизации на основе SSD
09.01.2009  Маршрутизатор D-Link Xtreme N DIR-685 может играть роль NAS, сервера печати... и цифровой фоторамки
09.01.2009  Очень тонкая фотокамера Pentax Optio P70 имеет разрешение 12 Мп
09.01.2009  pureSilicon 1TB Nitro - первый в мире 2,5-дюймовый SSD объемом 1 ТБ
09.01.2009  Дебютировали мобильные GPU ATI Mobility Radeon HD 4000
09.01.2009  NVIDIA GeForce GTX 285 и GTX 295 представлены официально
09.01.2009  Scythe выпустила процессорный кулер Mugen 2
09.01.2009  Optio E70 - новая компактная камера Pentax начального уровня
09.01.2009  Новый iPhone получит четырехъядерный процессор?
 
Полезно

 
Copyright © CompDoc.Ru
При цитировании и перепечатке ссылка на www.compdoc.ru обязательна. Карта сайта.
 
Rambler's Top100