Windows Programming (5) use the scroll bar

Source: Internet
Author: User
Tags textout

The program in this article comes from Windows Programming (fifth edition)

The original intention of designing the scroll bar is that there are too many items to be displayed in the customer zone. In this header file, we include a lot of system information:

// Total number of rows # define numlines (INT) (sizeof sysmetrics/sizeof sysmetrics [0]) struct {int index; tchar * szlabel; tchar * szdesc ;} // struct array sysmetrics [] = {sm_cxscreen, text ("sm_cxscreen"), text ("screen width in pixels"), sm_cyscreen, text ("sm_cyscreen "), text ("screen height in pixels"), sm_cxvscroll, text ("sm_cxvscroll"), text ("vertical scroll width"), sm_cyhscroll, text ("sm_cyhscroll "), text ("horizontal scroll height"), sm_cycaption, text ("sm_cycaption"), text ("caption Bar Height"), sm_cxborder, text ("sm_cxborder "), text ("window Border width"), sm_cyborder, text ("sm_cyborder"), text ("window border height"), sm_cxfixedframe, text ("sm_cxfixedframe "), text ("dialog window frame width"), sm_cyfixedframe, text ("sm_cyfixedframe"), text ("dialog window frame height"), sm_cyvthumb, text ("sm_cyvthumb "), text ("vertical scroll thumb height"), sm_cxhthumb, text ("sm_cxhthumb"), text ("horizontal scroll thumb width"), sm_cxicon, text ("sm_cxicon "), text ("icon width"), sm_cyicon, text ("sm_cyicon"), text ("icon height"), sm_cxcursor, text ("sm_cxcursor "), text ("cursor width"), sm_cycursor, text ("sm_cycursor"), text ("cursor height"), sm_cymenu, text ("sm_cymenu "), text ("menu bar height"), sm_cxfullscreen, text ("sm_cxfullscreen"), text ("full screen client area width"), sm_cyfullscreen, text ("sm_cyfullscreen "), text ("full screen client area height"), sm_cykanjiwindow, text ("sm_cykanjiwindow"), text ("Kanji window height"), sm_mousepresent, text ("sm_mousepresent "), text ("Mouse present flag"), sm_cyvscroll, text ("sm_cyvscroll"), text ("vertical scroll arrow height"), sm_cxhscroll, text ("sm_cxhscroll "), text ("horizontal scroll arrow width"), sm_debug, text ("sm_debug"), text ("debug version flag"), sm_swapbutton, text ("sm_swapbutton "), text ("mouse buttons swapped flag"), sm_cxmin, text ("sm_cxmin"), text ("minimum window width"), sm_cymin, text ("sm_cymin "), text ("minimum window height"), sm_cxsize, text ("sm_cxsize"), text ("min/max/Close button width"), sm_cysize, text ("sm_cysize "), text ("min/max/Close button height"), sm_cxsizeframe, text ("sm_cxsizeframe"), text ("window sizing frame width"), sm_cysizeframe, text ("sm_cysizeframe"), text ("window sizing frame height"), sm_cxmintrack, text ("sm_cxmintrack"), text ("minimum window tracking width"), sm_cymintrack, text ("sm_cymintrack"), text ("minimum window tracking height"), sm_cxdoubleclk, text ("sm_cxdoubleclk"), text ("Double Click x tolerance"), sm_cydoubleclk, text ("sm_cydoubleclk"), text ("Double Click y tolerance"), sm_cxiconspacing, text ("sm_cxiconspacing"), text ("Horizontal icon spacing"), sm_cyiconspacing, text ("sm_cyiconspacing"), text ("vertical icon spacing"), sm_menudropalignment, text ("sm_menudropalignment"), text ("Left or Right menu drop"), sm_penwindows, text ("sm_penwindows"), text ("pen extensions installed"), sm_dbcsenabled, text ("sm_dbcsenabled"), text ("double-byte char set enabled"), sm_cmousebuttons, text ("sm_cmousebuttons"), text ("Number of mouse buttons"), sm_secure, text ("sm_secure"), text ("security present flag"), sm_cxedge, text ("sm_cxedge"), text ("3-D Border width"), sm_cyedge, text ("sm_cyedge"), text ("3-D border height"), sm_cxminspacing, text ("sm_cxminspacing"), text ("minimized window spacing width"), sm_cyminspacing, text ("sm_cyminspacing"), text ("minimized window spacing height"), sm_cxsmicon, text ("sm_cxsmicon"), text ("small icon width"), sm_cysmicon, text ("sm_cysmicon"), text ("small icon height"), sm_cysmcaption, text ("sm_cysmcaption"), text ("Small caption height"), sm_cxsmsize, text ("sm_cxsmsize"), text ("Small caption button width"), sm_cysmsize, text ("sm_cysmsize"), text ("Small caption button height"), sm_cxmenusize, text ("sm_cxmenusize"), text ("menu bar button width"), sm_cymenusize, text ("sm_cymenusize"), text ("menu bar button height"), sm_arrange, text ("sm_arrange"), text ("How minimized windows arranged"), sm_cxminimized, text ("sm_cxminimized"), text ("minimized window width"), sm_cyminimized, text ("sm_cyminimized"), text ("minimized window height"), sm_cxmaxtrack, text ("sm_cxmaxtrack"), text ("Maximum draggable width"), sm_cymaxtrack, text ("sm_cymaxtrack"), text ("Maximum draggable height"), sm_cxmaximized, text ("sm_cxmaximized"), text ("width of maximized window"), sm_cymaximized, text ("sm_cymaximized"), text ("height of maximized window"), sm_network, text ("sm_network"), text ("network present flag"), sm_cleanboot, text ("sm_cleanboot"), text ("How system was booted"), sm_cxdrag, text ("sm_cxdrag"), text ("Avoid drag x tolerance"), sm_cydrag, text ("sm_cydrag"), text ("Avoid drag y tolerance"), sm_showsounds, text ("sm_showsounds"), text ("present sounds visually"), sm_cxmenucheck, text ("sm_cxmenucheck"), text ("menu check-mark width"), sm_cymenucheck, text ("sm_cymenucheck"), text ("menu check-mark height"), sm_slowmachine, text ("sm_slowmachine"), text ("slow processor flag"), sm_mideastenabled, text ("sm_mideastenabled"), text ("Hebrew and Arabic enabled flag"), sm_mousewheelpresent, text ("sm_mousewheelpresent"), text ("mouse wheel present flag"), sm_virtualxscreen, text ("sm_xvirtualscreen"), text ("virtual screen x origin"), sm_yvirtualscreen, text ("sm_yvirtualscreen"), text ("virtual screen y origin"), sm_cxvirtualscreen, text ("sm_cxvirtualscreen"), text ("virtual screen width"), sm_cyvirtualscreen, text ("sm_cyvirtualscreen"), text ("virtual screen height"), sm_cmonitors, text ("sm_cmonitors"), text ("number of monitors"), sm_samedisplayformat, text ("sm_samedisplayformat"), text ("Same color format flag ")};

The first line defines the number of elements in the array. Then we define the struct array. If the number of elements is large and one row cannot be displayed, how can I add a scroll bar?

Let's look at the program first:

# Include <windows. h> # include "sysmets. H "lresult callback wndproc (hwnd, uint, wparam, lparam); int winapi winmain (hinstance, // the current instance handle hinstance hprevinstance, // The previous instance handle lpstr lpcmdline, // command line int icmdshow) // display status {static tchar szappname [] = text ("Show System content"); // window handle hwnd; // message MSG; // window wndclass; // window style: when the window is moved or changed, the wndclass window is repainted. style = cs_hredraw | cs_vredraw; // specifies the callback function wndclass. lpfnwndproc = Wndproc; // The extra bit is used to determine the position of the next window class. wndclass is not used for the moment. cbclsextra = 0; // The extra bit is used to confirm the location of the next window instance. wndclass is not used for the moment. cbwndextra = 0; // instance handle wndclass. hinstance = hinstance; // The Mount icon wndclass. hicon = loadicon (null, idi_application); // load the cursor wndclass. hcursor = loadcursor (null, idc_arrow); // The background is white wndclass. hbrbackground = (hbrush) getstockobject (white_brush); // menu: No wndclass. lpszmenuname = NULL; // window class name wndclass. lpszclassname = szappnam E; // The registration window if (! Registerclass (& wndclass) {return-1 ;}// create a window hwnd = createwindow (szappname, // name of the window class, must be a registered text ("system content"), // window title ws_overlappedwindow | ws_vscroll, // window style, add the vertical scroll bar cw_usedefault, // X coordinate cw_usedefault, // y coordinate cw_usedefault, // width cw_usedefault, // height null, // parent window handle null, // menu window handle hinstance, // WINDOS of the advanced version ignores NULL ); // display window // showwindow (hwnd, sw_showna); showwindow (hwnd, icmdshow); // update window updatewindow (hwnd); // message loop while (getmessage (& msg, Null,) {translatemessage (& MSG); // send the message to the window dispatchmessage (& MSG);} return MSG. wparam;} lresult callback wndproc (hwnd, uint message, wparam, lparam) {// character width, uppercase letter width, character height static int cxchar, cxcaps, cychar; // window size static int cxclient, cyclient; // The Position of the scroll bar static int ivscrollpos; HDC; // This variable is used to index sysmets. each element of the struct array sysmetrics [] defined in H int I; // vertical position of the output text int y; // Drawing Structure paintstruct pS; // string tchar szbuf Fer [10]; // font information structure textmetric TM; Switch (Message) {Case wm_create: HDC = getdc (hwnd); // obtain the text size of the system font, stored in TM gettextmetrics (HDC, & TM); // average character width cxchar = TM. tmavecharwidth; // the average width of uppercase letters. cxcaps = (TM. tmpitchandfamily & 1? 3: 2) * cxchar/2; // total character height: height + row spacing cychar = TM. tmheight + TM. tmexternalleading; releasedc (hwnd, HDC); // set the scroll bar range: Window handle, scroll bar type, minimum position, maximum position, whether to re-paint setscrollrange (hwnd, sb_vert, 0, numlines-1, false); // The Position of the square of the scroll bar. The parameter is window handle, scroll bar type, and the new position is setscrollpos (hwnd, sb_vert, ivscrollpos, true ); return 0; Case wm_size: cxclient = loword (lparam); cyclient = hiword (lparam); Return 0; Case wm_paint: HDC = beginpaint (hwn D, & PS); for (I = 0; I <numlines; I ++) {// The row width * The number of changed rows y = cychar * (I-ivscrollpos ); // output string to the specified area (use the current font, background color, color) // The parameter is: device content handle, X coordinate, Y coordinate, string with output (irrelevant to whether or not it ends with 0), number of characters // lstrlen calculates the string length textout (HDC, 0, Y, sysmetrics [I]. szlabel, lstrlen (sysmetrics [I]. szlabel); // output from 22 uppercase letters, because the first column has only 20 uppercase letters textout (HDC, 22 * cxcaps, Y, sysmetrics [I]. szdesc, lstrlen (sysmetrics [I]. szdesc); // The last column is the right-aligned settextalign (HDC, ta_right | ta_top );/ /40 * cxchar is the column width of the second and third columns // wsprintf is used to format and store the string (ending with 0) in the specified buffer ), the return value is the number of strings // getsystemmetrics is used to obtain system parameters. The return value is the system parameters textout (HDC, 22 * cxcaps + 40 * cxchar, Y, szbuffer, wsprintf (szbuffer, text ("% 5d"), getsystemmetrics (sysmetrics [I]. index); // change the Alignment Method Back. Otherwise, the right alignment is also set to settextalign (HDC, ta_left | ta_top) in the next loop;} endpaint (hwnd, & PS ); return 0; // scroll bar message case wm_vscroll: // wparam of the scroll bar message indicates the scroll bar operation switch (loword (wparam) {// click the up arrow to flip a row down Sb_lineup: ivscrollpos-= 1; break; // click the bottom arrow of the vertex to flip a line up. Case sb_linedown: ivscrollpos + = 1; break; // click on the square to flip a page up, each page is: (customer zone/line height) so many rows case sb_pageup: ivscrollpos-= cyclient/cychar; break; // click below the box: Flip down one page case sb_pagedown: ivscrollpos + = cyclient/cychar; break; // drag the scroll bar. The height of wparam indicates the position of the scroll bar. Case sb_thumbposition: ivscrollpos = hiword (wparam); break; default: break ;} // This sentence is for ivscrollpos = max (0, min (ivscrollpos, numl Ines-1); // if the position of the scroll bar changes if (ivscrollpos! = Getscrollpos (hwnd, sb_vert) {// setscrollpos (hwnd, sb_vert, ivscrollpos, true) for the position of the small square of the scroll bar; // set it to an invalid area, invalidaterect (hwnd, null, true);} return 0; Case wm_destroy: postquitmessage (0); Return 0;} return defwindowproc (hwnd, message, wparam, lparam );}

The idea of the program is as follows: when creating a window, you must tell the system that you want to add a scroll bar (vertical). In the wm_create message, you must perform some basic settings on the scroll bar. Wm_vscroll corresponds to the scroll bar, which can be divided into three parts: the first part receives the message of the scroll bar; the second part is to let the small square of the scroll bar scroll to a specific position, the third part is the scrolling effect of the text on the page.

First look at the first part: What is the function of the scroll bar: When you click the up or down button, a row of text will be rolled; when you click the scroll above or below the small square, it will scroll one page of text, and drag the scroll bar to scroll to the specified place. Which of the following operations is passed through the low-byte wparam of the wm_vscroll message. In the program, use the global variable ivscrollpos to record the rolling position. Each time the position of the scroll bar is changed.

Ivscrollpos = max (0, min (ivscrollpos, numlines-1); to prevent the position of the scroll bar from exceeding a certain range, you can block it, roll up or down the scroll bar to understand the result.
By using setscrollpos (hwnd, sb_vert, ivscrollpos, true), the square of the scroll bar is placed to a location that can be located. In the third part, the function of wm_paint is to scroll the page. In fact, when you see that the second row is displayed at the original first row, the system does not actually output the first row, however, the first line of output is located in the customer zone, so you cannot see it! The second line follows the first line and is placed at the beginning.

This scroll bar has an obvious drawback, that is, it is not what we want to see: the length of the scroll bar reflects the percentage of the content displayed on the current page, specifically:

Page size/scroll length = page size/entire range = number of displayed files/total number of files

Although this is only a small change, his implementation method is very different from the above. In general, he needs to use the scrollinfo structure to record the information of the scroll bar, and then use getscrollinfo to obtain information and set the information through setscrollinfo. In the response message to the scroll bar, content is rolled through scrollwindow (unlike the previous program, which is implemented in the wm_paint message ).

Let's look at the program:

# Include <windows. h> # include "sysmets. H "lresult callback wndproc (hwnd, uint, wparam, lparam); int winapi winmain (hinstance, // the current instance handle hinstance hprevinstance, // The previous instance handle lpstr lpcmdline, // command line int icmdshow) // display status {static tchar szappname [] = text ("Show System content"); // window handle hwnd; // message MSG; // window wndclass; // window style: when the window is moved or changed, the wndclass window is repainted. style = cs_hredraw | cs_vredraw; // specifies the callback function wndclass. lpfnwndproc = Wndproc; // The extra bit is used to determine the position of the next window class. wndclass is not used for the moment. cbclsextra = 0; // The extra bit is used to confirm the location of the next window instance. wndclass is not used for the moment. cbwndextra = 0; // instance handle wndclass. hinstance = hinstance; // The Mount icon wndclass. hicon = loadicon (null, idi_application); // load the cursor wndclass. hcursor = loadcursor (null, idc_arrow); // The background is white wndclass. hbrbackground = (hbrush) getstockobject (white_brush); // menu: No wndclass. lpszmenuname = NULL; // window class name wndclass. lpszclassname = szappnam E; // The registration window if (! Registerclass (& wndclass) {return-1 ;}// create a window hwnd = createwindow (szappname, // name of the window class, must be a registered text ("system content"), // window title ws_overlappedwindow | ws_vscroll | ws_hscroll, // window style, add the scroll bar cw_usedefault, // X coordinate cw_usedefault, // y coordinate cw_usedefault, // width cw_usedefault, // height null, // parent window handle null, // menu window handle hinstance, // WINDOS of the advanced version ignores NULL ); // display window // showwindow (hwnd, sw_showna); showwindow (hwnd, icmdshow); // update window updatewindow (hwnd); // message loop while (getm Essage (& MSG, null, 0, 0) {translatemessage (& MSG); // send the message to the window dispatchmessage (& MSG);} return MSG. wparam;} lresult callback wndproc (hwnd, uint message, wparam, lparam) {// character width, uppercase letter width, character height static int cxchar, cxcaps, cychar; // window size static int cxclient, cyclient; // maximum width static int imaxwidth; // The Position static int ivertpos, ihorzpos, ipaintbeg, ipaintend, and HDC; // This variable is used to index sysmets. every element of the struct array sysmetrics [] defined in H Int I; // position of the output text int X, Y; // Drawing Structure paintstruct pS; // This structure contains the information of the scroll bar // set information through the setscrollinfo function, use the getscrollinfo function to obtain information about scrollinfo Si; // string tchar szbuffer [10]; // font information structure textmetric TM; Switch (Message) {Case wm_create: HDC = getdc (hwnd ); // obtain the text size of the system font, which is stored in the TM gettextmetrics (HDC, & TM); // average character width cxchar = TM. tmavecharwidth; // average width of uppercase letters cxcaps = (TM. tmpitchandfamily & 1? 3: 2) * cxchar/2; // total character height: height + row spacing cychar = TM. tmheight + TM. tmexternalleading; releasedc (hwnd, HDC); // maximum span = 40 characters + 22 uppercase letters imaxwidth = 40 * cxchar + 22 * cxcaps; return 0; Case wm_size: cxclient = loword (lparam); cyclient = hiword (lparam); // set the size of the vertical scroll bar information // Si of the struct. cbsize = sizeof (SI); // specify the parameters to be set and obtained: This is the range of the maximum and minimum values and the size of the page Si. fmask = sif_range | sif_page; // the smallest Si at the scroll bar position. nmin = 0; // The maximum Si position of the scroll bar. nmax = numlines-1; // Page size Si. npage = cyclient/cychar; // set the parameter setscrollinfo (hwnd, sb_vert, & Si, true) of the scroll bar; // set the level scroll bar information SI. cbsize = sizeof (SI); SI. fmask = sif_range | sif_page; SI. nmin = 0; SI. nmax = 2 + imaxwidth/cxchar; SI. npage = cxclient/cxchar; setscrollinfo (hwnd, sb_horz, & Si, true); Return 0; Case wm_paint: HDC = beginpaint (hwnd, & PS); SI. cbsize = sizeof (SI); SI. fmask = sif_pos; getscrollinfo (hwnd, sb_vert, & Si); ivert Pos = SI. NPOs; getscrollinfo (hwnd, sb_horz, & Si); ihorzpos = SI. NPOs; // max (0, Current Position + highest point of the rectangle area to be drawn/character height) // ipaintbeg = max (0, ivertpos + PS. rcpaint. top/cychar); ipaintbeg = max (0, ivertpos); // The place where the drawing ends = Current Position + the height of the image to be drawn ipaintend = min (numlines-1, ivertpos + PS. rcpaint. bottom/cychar); for (I = ipaintbeg; I <= ipaintend; I ++) {// the starting position of X for drawing: 1 is set by yourself, the larger the value, the wider the left side. x = cxchar * (1-ihorzpos); // the start position of Y for the drawing. Y = cychar * (I-ivertpos); textout (HDC, X, Y, sysmetrics [I]. szlabel, lstrlen (sysmetrics [I]. szlabel); // output from a location after 22 uppercase letters, because the first column has a maximum of 20 uppercase letters textout (HDC, x + 22 * cxcaps, y, sysmetrics [I]. szdesc, lstrlen (sysmetrics [I]. szdesc); settextalign (HDC, ta_right | ta_top); textout (HDC, x + 22 * cxcaps + 40 * cxchar, Y, szbuffer, wsprintf (szbuffer, text ("% 5d"), getsystemmetrics (sysmetrics [I]. index); settextalign (HDC, ta_left | ta_top );} Endpaint (hwnd, & PS); Return 0; // vertical scroll bar message case wm_vscroll: // obtain the vertical scroll bar information SI. cbsize = sizeof (SI); // All parameters Si. fmask = sif_all; getscrollinfo (hwnd, sb_vert, & Si); // vertical position ivertpos = SI. NPOs; // wparam of the scroll bar message indicates the operation switch (loword (wparam) of the scroll bar {Case sb_top: Si. NPOs = SI. nmin; break; Case sb_bottom: Si. NPOs = SI. nmax; break; Case sb_lineup: Si. NPOs-= 1; break; Case sb_linedown: Si. NPOs + = 1; Case sb_pageup: Si. npage-= SI. npage; B Reak; Case sb_pagedown: Si. NPOs + = SI. npage; break; Case sb_thumbtrack: Si. NPOs = SI. ntrackpos; break; default: break;} Si. fmask = sif_pos; setscrollinfo (hwnd, sb_vert, & Si, true); getscrollinfo (hwnd, sb_vert, & Si); If (SI. NPOs! = Ivertpos) {// scroll the content of the specified window scrollwindow (hwnd, 0, cychar * (iVertPos-si.nPos), null, null); updatewindow (hwnd);} return 0; // horizontal scroll bar message case wm_hscroll: Si. cbsize = sizeof (SI); SI. fmask = sif_all; getscrollinfo (hwnd, sb_horz, & Si); ihorzpos = SI. NPOs; Switch (loword (wparam) {Case sb_lineleft: Si. NPOs-= 1; break; Case sb_lineright: Si. NPOs + = 1; break; Case sb_pageleft: Si. NPOs-= SI. npage; break; Case sb_pageright: Si. NPOs + = SI. NPAG E; break; Case sb_thumbposition: Si. NPOs = SI. ntrackpos; break; default: break;} Si. fmask = sif_pos; setscrollinfo (hwnd, sb_horz, & Si, true); getscrollinfo (hwnd, sb_horz, & Si); If (SI. NPOs! = Ihorzpos) {scrollwindow (hwnd, cxchar * (iHorzPos-si.nPos), 0, null, null); // updatewindow (hwnd);} return 0; Case wm_destroy: postquitmessage (0 ); return 0;} return defwindowproc (hwnd, message, wparam, lparam );}

 

Note the following points in the program:

1. The vertical and horizontal scroll bars are set in the program. In the wm_size message, as the window changes, the size of the small block of the scroll bar also changes.

2. Before using getscrollinfo or setscrollinfo, Si. cbsize = sizeof (SI) is required. This is because of compatibility. In addition, you must specify the content in scrollinfo, which is controlled by fmask.

3. Several lines of code in the program are confusing:

Ipaintbeg = max (0, ivertpos + PS. rcpaint. top/cychar); in fact, due to PS. rcpaint. top = 0, this line of code can also be written as: ipaintbeg = max (0, ivertpos );

Ipaintend = min (numlines-1, ivertpos + PS. rcpaint. bottom/cychar); drawing end position = current position of the scroll bar + number of lines drawn, and number of lines = width of the customer area/width of each line;

X = cxchar * (1-ihorzpos); X coordinate of the drawing. That 1 is not too "Top lattice". You can also set it to a larger value, and the result is very obvious.

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.