Лекция 8 апреля 2020 года
Необходимо написать программу, создающую кнопочное меню в графическом режиме. Каждый пункт меню представляет собой заданную объемную фигуру (например, прямоугольник). Перемещение по пунктам меню выполняется с помощью клавиш вверх/вниз с эффектом выделения активного пункта меню. Т.е. Активный пункт меню будет иметь другой фон и цвет шрифта.
Эффект объемности (выпуклости) создается как показано на рисунке:
Верхний контур должен быть светлее чем нижний.
Если наоборот, то будет эффект вогнутости.
#include "windows.h"
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define up 72
#define down 80
#define enter 13
#define esc 27
HDC hDC;
HWND hWnd;
RECT Rect;
HPEN hPen, hOldPen;
HBRUSH hBrush, hOldBrush;
HFONT hFont,hOldFont;
LOGFONT Lf={0};
typedef struct
{
int x[4];
COLORREF col;
char *text;
}Knopka;
typedef struct
{
Knopka *P;
int n, m;
}Menu;
void clearscreen()
{
hPen=CreatePen(PS_SOLID,4,RGB(0,0,255));
hOldPen=(HPEN)SelectObject(hDC,hPen);
hBrush=CreateSolidBrush(RGB(0,0,255));
hOldBrush=(HBRUSH)SelectObject(hDC,hBrush);
Rectangle(hDC,Rect.left,Rect.top,Rect.right,Rect.bottom);
SelectObject(hDC,hOldPen);
DeleteObject(hPen);
SelectObject(hDC,hOldBrush);
DeleteObject(hBrush);
}
void knopka(Knopka *P)
{
hPen=CreatePen(PS_SOLID,4,RGB(255,255,255));
hOldPen=(HPEN)SelectObject(hDC,hPen);
hBrush=CreateSolidBrush(RGB(255,255,255));
hOldBrush=(HBRUSH)SelectObject(hDC,hBrush);
hFont=CreateFontIndirect(&Lf);
hOldFont=(HFONT)SelectObject(hDC,hFont);
Rectangle(hDC,P->x[0]-4,P->x[1]-4,P->x[0]+P->x[2]+4,P->x[1]+P->x[3]+4);
SelectObject(hDC,hOldPen);
DeleteObject(hPen);
SelectObject(hDC,hOldBrush);
DeleteObject(hBrush);
hPen=CreatePen(PS_SOLID,4,RGB(0,0,0));
hOldPen=(HPEN)SelectObject(hDC,hPen);
hBrush=CreateSolidBrush(RGB(0,0,0));
hOldBrush=(HBRUSH)SelectObject(hDC,hBrush);
Rectangle(hDC,P->x[0],P->x[1],P->x[0]+P->x[2]+4,P->x[1]+P->x[3]+4);
SelectObject(hDC,hOldPen);
DeleteObject(hPen);
SelectObject(hDC,hOldBrush);
DeleteObject(hBrush);
hPen=CreatePen(PS_SOLID,4,P->col);
hOldPen=(HPEN)SelectObject(hDC,hPen);
hBrush=CreateSolidBrush(P->col);
hOldBrush=(HBRUSH)SelectObject(hDC,hBrush);
Rectangle(hDC,P->x[0],P->x[1],P->x[0]+P->x[2],P->x[1]+P->x[3]);
SelectObject(hDC,hOldPen);
DeleteObject(hPen);
SelectObject(hDC,hOldBrush);
DeleteObject(hBrush);
SetTextColor(hDC,RGB(0,0,0));
SetBkColor(hDC,P->col);
TextOut(hDC,P->x[0]+2,P->x[1]+2,(LPCSTR)P->text,strlen(P->text));
SelectObject(hDC,hOldFont);
DeleteObject(hFont);
}
Menu menu_init(char* punkt[],int l,int top,int width,int height,int n)
{
int i;
Menu M; M.n=n; M.m=0;
M.P=new Knopka[n];
for(i=0;i<n;i++)
{
M.P[i].x[0]=l;
if(i==0)M.P[i].x[1]=top;
else M.P[i].x[1]=M.P[i-1].x[1]+M.P[i-1].x[3]+10;
M.P[i].x[2]=width;
M.P[i].x[3]=height;
M.P[i].text=new char[strlen(punkt[i])+1];
strcpy(M.P[i].text,punkt[i]);
}
return M;
}
void menu_del(Menu *M)
{
int i;
for(i=0;i<M->n;i++)
delete []M->P[i].text;
delete[]M->P;
}
int menu_vert(Menu *M)
{
int i;
char ch;
do
{
for(i=0;i<M->n;i++)
{
if(M->m==i) M->P[i].col=RGB(0,255,0);
else M->P[i].col=RGB(255,255,0);
knopka(&(M->P[i]));
}
ch=getch();
switch(ch)
{
case up: if(M->m==0) M->m=M->n-1;
else (M->m)--;
break;
case down: if(M->m==M->n-1) M->m=0;
else (M->m)++;
}
}
while (ch!=enter && ch!=esc);
if(ch==esc) M->m=M->n-1;
return M->m;
}
// menu_gr.cpp: Defines the entry point for the console application.
//
#include "stdafx.h"
#include "MENU_win.h"
#include <dos.h>
void vivodtext(int x,int y,char* s)
{
hFont=CreateFontIndirect(&Lf);
hOldFont=(HFONT)SelectObject(hDC,hFont);
SetTextColor(hDC,RGB(0,0,0));
SetBkColor(hDC,RGB(255,255,0));
TextOut(hDC,x,y,(LPCSTR)s,strlen(s));
SelectObject(hDC,hOldFont);
DeleteObject(hFont);
}
int _tmain(int argc, _TCHAR* argv[])
{
hWnd=GetConsoleWindow();
if(!hWnd)
{
printf("Can't get hWnd of console!\n");
getch();
return -1;
}
MoveWindow(hWnd,0,0,800,600,TRUE);
hDC=GetDC(hWnd);
if(!hDC)
{
printf("Can't get device context!\n");
getch();
return -2;
}
GetClientRect(hWnd,&Rect);
clearscreen();
char *S[]={"Input ","Output ","Record ","Exit "};
int m=0;
Menu M=menu_init(S,4,4,60,30,4);
do
{
m=menu_vert(&M);
switch(m)
{
case 0:
vivodtext(100,200,"First punkt");
getch();
break;
case 1:vivodtext(100,240,"Second punkt");
getch();
break;
case 2:vivodtext(100,280,"Three punkt");
getch();
}
}
while(m!=3);
menu_del(&M);
ReleaseDC(hWnd, hDC);
return 0;
}