Win32 SDK Gui编程系列之--折线图Chart-程序员宅基地

技术标签: c++  C  c语言  工具  Win32 SDK Gui C/C++  windows  开发语言  

折线图Chart

在这里,虽然不是以通用程序为目标,但稍微变更一下就可以用于其他用途。因此,作为图表的绘制区域,左下方的原点坐标为(0.0,0.0),右上角的坐标为(1.0,1.0)进行正规化。但是,这是X、Y的值是非负值的情况,处理负值时,原点的位置会移动。

Chart01.c

// 折线图
// tcc chart01.c ../lib/winlib.o

#include <windows.h>
#include <time.h>
#include <sys/stat.h>

enum MARGIN { LEFT = 50, TOP = 26, RIGHT = 70, BOTTOM = 24 };

RECT rect;		        // 窗口客户端区域
int width, height;  	// 图形绘制区域的宽度和高度
double* data;
int nData;
struct tm  tmBgn;	    // 开始日期
double vMax = 1000.0;
double vMin = 0.0;

int nx(double x) { return (int)(rect.left + LEFT + x*width + 0.5); }
int ny(double y) { return (int)(rect.top + TOP + (1.0-y)*height + 0.5); }
int yVal(double v){ return ny((v - vMin)/(vMax - vMin)); }

HWND crWindow(HINSTANCE, LPSTR, WNDPROC, int, int, int, int);

void setData(HWND hWnd) {
    char path[256], buf[256];
    time_t t, timeNow = time(NULL);	
    int n;

    memset(&tmBgn, 0, sizeof(tmBgn));	// 零清除
    tmBgn.tm_year = 2011 - 1900;	    // 2011年
    tmBgn.tm_mon  =    9 - 1;	    	// 9月
    tmBgn.tm_mday =    4;		        // 4日(周日)
    t = mktime(&tmBgn);
    nData = (timeNow - t)/(24*60*60);
    data = (double*)calloc(nData, sizeof(double));
    for (n = 0; n < nData; n++) {
	struct stat buf;
	struct tm *tm = localtime(&t);
	wsprintf(path, "c:/Temp/www-access-log/access%d%02d%02d.txt", 
			tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
	stat(path, &buf);
	data[n] = (double)buf.st_size/1000.0;
	t += 24 * 60 * 60;
    }
}

void paint(HWND hwnd){
    int n;
    double x, y, xLast, yLast;
    char buf[32];
    RECT rc;
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hwnd, &ps);
    time_t t;

    GetClientRect(hwnd, &rect);
    width  = (rect.right - rect.left) - LEFT - RIGHT;
    height = (rect.bottom - rect.top) - TOP - BOTTOM;
    SetRect(&rc, nx(0.0), 0, nx(1.0), ny(1.0));  
    DrawText(hdc, "访问日志文件大小(KB)", -1, &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
    for (n = 0; n <= 5; n++) {		// Y轴
	y = (double)n / 5;
	MoveToEx(hdc, nx(0.0), ny(y), NULL);
	LineTo(hdc, nx(1.0)+6, ny(y));
	sprintf(buf, "%d", n*1000/5);
	SetRect(&rc, nx(1.0), ny(y)-10, nx(1.0)+60, ny(y)+10);  
        DrawText(hdc, buf, -1, &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
    }
    t = mktime(&tmBgn);
    for (n = 0; n < nData; n+=7) {	// X轴
	struct tm *tm = localtime(&t);
	x = (n + 0.5) / nData;
	MoveToEx(hdc, nx(x), ny(0.0), NULL);
	LineTo(hdc, nx(x), ny(1.0));
	SetRect(&rc, nx(x)-50, ny(0), nx(x)+50, ny(0)+24);  
	wsprintf(buf, "%d-%02d-%02d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
        DrawText(hdc, buf, -1, &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
	t += 7 * 24 * 60 * 60;
    }
    xLast = 0.5 / nData;
    yLast = yVal(data[0]);
    MoveToEx(hdc, nx(xLast), yLast, NULL);
    for (n = 1; n < nData; n++) {	 // 折线图
	x = (n + 0.5) / nData;
	y = yVal(data[n]);
	LineTo(hdc, nx(x), y);
	xLast = x;
	yLast = y;
    }
    EndPaint(hwnd, &ps);
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
    case WM_PAINT:   paint(hwnd);  break;
    case WM_DESTROY: PostQuitMessage(0); break;
    default: return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    HWND hWnd = crWindow(hInstance, TEXT("Chart"), WindowProc, 10, 10, 800, 300);
    if (!hWnd) return FALSE;
    SetWindowText(hWnd, TEXT("Chart01"));
    setData(hWnd);
    return msgLoop();
}

这个项目的实施结果如下图所示。

在访问量的推移图中追加移动平均。

在前节的图表中,追加7天移动平均的程序如下所示。

Chart02.c
 

// 折线图。 在chart01.c添加移动平均值。
// tcc chart02.c ../lib/winlib.o

#include <windows.h>
#include <time.h>
#include <sys/stat.h>

enum MARGIN { LEFT = 50, TOP = 26, RIGHT = 70, BOTTOM = 24 };

RECT rect;		// 窗口客户端区域
int width, height;  	// 图形绘制区域的宽度和高度
double* data;
double* mvavg;		 // 移动平均(7天)数据
int nData;
struct tm  tmBgn;	// 开始日期
double vMax = 1000.0;
double vMin = 0.0;

int nx(double x) { return (int)(rect.left + LEFT + x*width + 0.5); }
int ny(double y) { return (int)(rect.top + TOP + (1.0-y)*height + 0.5); }
int yVal(double v){ return ny((v - vMin)/(vMax - vMin)); }

HWND crWindow(HINSTANCE, LPSTR, WNDPROC, int, int, int, int);

void setData(HWND hWnd) {
    double sum;		// 移动平均
    char path[256], buf[256];
    time_t t, timeNow = time(NULL);
    int n;

    memset(&tmBgn, 0, sizeof(tmBgn));	 // 零清除
    tmBgn.tm_year = 2011 - 1900;	 // 2011年
    tmBgn.tm_mon  =    9 - 1;		// 9月
    tmBgn.tm_mday =    4;		 // 4日(周日)
    t = mktime(&tmBgn);
    nData = (timeNow - t)/(24*60*60);
    data  = (double*)calloc(nData, sizeof(double));
    mvavg = (double*)calloc(nData, sizeof(double));
    sum = 0.0;
    for (n = 0; n < nData; n++) {
	struct stat buf;
	struct tm *tm = localtime(&t);
	wsprintf(path, "c:/Temp/www-access-log/access%d%02d%02d.txt", 
			tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
	stat(path, &buf);
	data[n] = (double)buf.st_size/1000.0;
	t += 24 * 60 * 60;
	sum += data[n];
	if (n >= 7) sum -= data[n-7];
	mvavg[n] = sum / 7;
    }
}

void paint(HWND hwnd){
    int n;
    double x, y, xLast, yLast;
    char buf[32];
    RECT rc;
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hwnd, &ps);
    HPEN hPen, hOldPen;
    time_t t;

    GetClientRect(hwnd, &rect);
    width  = (rect.right - rect.left) - LEFT - RIGHT;
    height = (rect.bottom - rect.top) - TOP - BOTTOM;
    SetRect(&rc, nx(0.0), 0, nx(1.0), ny(1.0));  
    DrawText(hdc, "访问日志文件大小(KB)", -1, &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
    for (n = 0; n <= 5; n++) {		 // Y轴
	y = (double)n / 5;
	MoveToEx(hdc, nx(0.0), ny(y), NULL);
	LineTo(hdc, nx(1.0)+6, ny(y));
	sprintf(buf, "%d", n*1000/5);
	SetRect(&rc, nx(1.0), ny(y)-10, nx(1.0)+60, ny(y)+10);  
        DrawText(hdc, buf, -1, &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
    }
    t = mktime(&tmBgn);
    for (n = 0; n < nData; n+=7) {	// X轴
	struct tm *tm = localtime(&t);
	x = (n + 0.5) / nData;
	MoveToEx(hdc, nx(x), ny(0.0), NULL);
	LineTo(hdc, nx(x), ny(1.0));
	SetRect(&rc, nx(x)-50, ny(0), nx(x)+50, ny(0)+24);  
	wsprintf(buf, "%d-%02d-%02d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
        DrawText(hdc, buf, -1, &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
	t += 7 * 24 * 60 * 60;
    }

    xLast = 0.5 / nData;
    yLast = yVal(data[0]);
    MoveToEx(hdc, nx(xLast), yLast, NULL);
    for (n = 1; n < nData; n++) {	// 折线图
	x = (n + 0.5) / nData;
	y = yVal(data[n]);
	LineTo(hdc, nx(x), y);
	xLast = x;
	yLast = y;
    }

    // 绘制移动平均图
    hPen = CreatePen(PS_SOLID, 2, 0xFF);	// RED
    hOldPen = SelectObject(hdc, hPen);
    xLast = 6.5 / nData;
    yLast = yVal(mvavg[6]);
    MoveToEx(hdc, nx(xLast), yLast, NULL);
    for (n = 7; n < nData; n++) {	// 折线图
	x = (n + 0.5) / nData;
	y = yVal(mvavg[n]);
	LineTo(hdc, nx(x), y);
	xLast = x;
	yLast = y;
    }
    SelectObject(hdc, hOldPen);
    DeleteObject(hPen);

    EndPaint(hwnd, &ps);
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
    case WM_PAINT:   paint(hwnd);  break;
    case WM_DESTROY: PostQuitMessage(0); break;
    default: return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    HWND hWnd = crWindow(hInstance, TEXT("Chart"), WindowProc, 10, 10, 800, 300);
    if (!hWnd) return FALSE;
    SetWindowText(hWnd, TEXT("Chart02"));
    setData(hWnd);
    return msgLoop();
}

这个项目的实施结果如下图所示。

求7天的移动平均(红色)的话,根据星期的变动会被吸收,变成非常光滑的折线图。

单对数图

当Y轴的数值波动很大时,只把Y轴做成对数的单对数图(下图)是有效的。

节目如下所示。drawLogGraph函数是单对数图的绘图函数,是drawLinearGraph函数之前显示的线性(比例)刻度图的绘图函数。

Graph01.c

// 折线图。
// mcc -shared graph01.c

#include <windows.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>

#define EXPORT __declspec(dllexport)

#define LEFT  	60
#define TOP   	26
#define RIGHT 	70
#define BOTTOM 	30

RECT rect;		// 窗口客户端区域
int width, height;  	// 图形绘制区域的宽度和高度
double* data;
double* mvavg;		// 移动平均(7天)数据
int nData;
struct tm  tmBgn;	// 开始日期
double vMax;
double vMin;
void *null = 0;

int nx(double x) { return (int)(rect.left + LEFT + x*width + 0.5); }
int ny(double y) { return (int)(rect.top + TOP + (1.0-y)*height + 0.5); }
double yVal(double v){ 
    return (double)ny((log10(v) - log10(vMin))/(log10(vMax) - log10(vMin)));
}

EXPORT void setData() {
    double sum;		// 移动平均
    char path[256], buf[256];
    time_t t, timeNow = time(NULL);
    int n;
    int factor;

    memset(&tmBgn, 0, sizeof(tmBgn));	// 零清除
    tmBgn.tm_year = 2011 - 1900;	// 2011年
    tmBgn.tm_mon  =    9 - 1;		// 9月
    tmBgn.tm_mday =    1;		 // 1天
    t = mktime(&tmBgn);
    nData = (timeNow - t)/(24*60*60);
    data  = calloc(nData, sizeof(double));
    mvavg = calloc(nData, sizeof(double));
    sum = 0.0;
    for (n = 0; n < nData; n++) {
	struct _stat buf;
	struct tm *tm = localtime(&t);
	wsprintf(path, "c:/Temp/www-access-log/access%d%02d%02d.txt", 
			tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
	_stat(path, &buf);
	data[n] = (double)buf.st_size/1000.0;
	if (data[n] == 0) break;
	if (n == 0) {
	    vMax = data[n];
	    vMin = data[n];
	} else {
	    if (data[n] > vMax) vMax = data[n];
	    if (data[n] < vMin) vMin = data[n];
	}
	t += 24 * 60 * 60;
	sum += data[n];
	if (n >= 7) sum -= data[n-7];
	mvavg[n] = sum / 7;	// 7天的移动平均
    }
    nData = n;
    vMin = pow(10.0, floor(log10(vMin < 1.0 ? 1.0 : vMin)));
    vMax = pow(10.0, ceil(log10(vMax)));
}

// 纵轴(日志大小)为对数大小(片对数图)
EXPORT void drawLogGraph(HWND hwnd) {
    int n, k, nY;
    double x, y, xLast, yLast, yBase;
    char buf[256];
    RECT rc;
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hwnd, &ps);
    HPEN hPen, hOldPen;
    time_t t;
    int DAYS = 30;
    int NY = (int)(log10(vMax) - log10(vMin));

    GetClientRect(hwnd, &rect);
    width  = (rect.right - rect.left) - LEFT - RIGHT;
    height = (rect.bottom - rect.top) - TOP - BOTTOM;
    SetRect(&rc, nx(0.0), 0, nx(1.0), ny(1.0));  
    DrawText(hdc, "访问日志文件大小(KB)",
		-1, &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
    for (n = 0; n <= NY; n++) {		// Y轴
	y = (double)n / NY;
	MoveToEx(hdc, nx(0.0), ny(y), NULL);
	LineTo(hdc, nx(1.0)+6, ny(y));
	sprintf(buf, "%.0f", vMin*pow(10.0, (double)n));
	SetRect(&rc, nx(1.0), ny(y)-10, nx(1.0)+70, ny(y)+10);  
        DrawText(hdc, buf, -1, &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
    }

    // Y轴方向辅助划线
    hPen = CreatePen(PS_DOT, 1, 0x808080);
    hOldPen = SelectObject(hdc, hPen);
    nY = (int)vMin;
    for (n = 0; n < NY; n++) {		// Y轴
	yBase = vMin * pow(10.0, (double)n);
	for (k = 2; k < 10; k++) {
	    y = yBase * k;
	    MoveToEx(hdc, nx(0.0), (int)yVal(y), NULL);
	    LineTo(hdc, nx(1.0)+6, (int)yVal(y));
	}
    }
    SelectObject(hdc, hOldPen);
    DeleteObject(hPen);

    t = mktime(&tmBgn);
    for (n = 0; n < nData; n++) {	// X轴
	struct tm *tm = localtime(&t);
	if (tm->tm_mday == 1) {
	    x = (double)n / nData;
	    MoveToEx(hdc, nx(x), ny(0.0), NULL);
	    LineTo(hdc, nx(x), ny(1.0));
	    SetRect(&rc, nx(x)-60, ny(0.0), nx(x)+60, ny(0.0)+24);  
	    wsprintf(buf, "%d-%02d-%02d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
            DrawText(hdc, buf, -1, &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
	}
	t += 24 * 60 * 60;
    }

    xLast = 0.0;
    yLast = yVal(data[0]);
    MoveToEx(hdc, nx(xLast), (int)yLast, null);
    for (n = 1; n < nData; n++) {	// 折线图
	x = (double)n / nData;
	y = yVal(data[n]);
	LineTo(hdc, nx(x), (int)y);
	xLast = x;
	yLast = y;
    }

    // 绘制移动平均图
    hPen = CreatePen(PS_SOLID, 2, 0xFF);	// RED
    hOldPen = SelectObject(hdc, hPen);
    xLast = 6.0 / nData;
    yLast = yVal(mvavg[6]);
    MoveToEx(hdc, nx(xLast), (int)yLast, null);
    for (n = 7; n < nData; n++) {	 // 折线图
	x = (double)n / nData;
	y = yVal(mvavg[n]);
	LineTo(hdc, nx(x), (int)y);
	xLast = x;
	yLast = y;
    }
    SelectObject(hdc, hOldPen);
    DeleteObject(hPen);

    EndPaint(hwnd, &ps);
}

EXPORT void drawLinearGraph(HWND hwnd) {
    int n;
    double x, y, xLast, yLast;
    char buf[32];
    RECT rc;
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hwnd, &ps);
    HPEN hPen, hOldPen;
    time_t t;
    int DAYS = 30;

    GetClientRect(hwnd, &rect);
    width  = (rect.right - rect.left) - LEFT - RIGHT;
    height = (rect.bottom - rect.top) - TOP - BOTTOM;
    SetRect(&rc, nx(0.0), 0, nx(1.0), ny(1.0));  
    DrawText(hdc, "访问日志文件大小(KB)", 
		-1, &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
    for (n = 0; n <= 5; n++) {		// Y轴
	y = (double)n / 5;
	MoveToEx(hdc, nx(0.0), ny(y), NULL);
	LineTo(hdc, nx(1.0)+6, ny(y));
	sprintf(buf, "%.0f", n*vMax/5);
	SetRect(&rc, nx(1.0), ny(y)-10, nx(1.0)+60, ny(y)+10);  
        DrawText(hdc, buf, -1, &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
    }
    t = mktime(&tmBgn);
    for (n = 0; n < nData; n+=DAYS) {	// X轴
	struct tm *tm = localtime(&t);
	x = (n + 0.5) / nData;
	MoveToEx(hdc, nx(x), ny(0.0), NULL);
	LineTo(hdc, nx(x), ny(1.0));
	SetRect(&rc, nx(x)-60, ny(0.0), nx(x)+60, ny(0.0)+24);  
	wsprintf(buf, "%d-%02d-%02d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
        DrawText(hdc, buf, -1, &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
	t += DAYS * 24 * 60 * 60;
    }

    xLast = 0.5 / nData;
    yLast = yVal(data[0]);
    MoveToEx(hdc, nx(xLast), (int)yLast, null);
    for (n = 1; n < nData; n++) {	// 折线图
	x = (n + 0.5) / nData;
	y = yVal(data[n]);
	LineTo(hdc, nx(x), (int)y);
	xLast = x;
	yLast = y;
    }

    // 绘制移动平均图
    hPen = CreatePen(PS_SOLID, 2, 0xFF);	// RED
    hOldPen = SelectObject(hdc, hPen);
    xLast = 6.5 / nData;
    yLast = yVal(mvavg[6]);
    MoveToEx(hdc, nx(xLast), (int)yLast, null);
    for (n = 7; n < nData; n++) {	// 折线图
	x = (n + 0.5) / nData;
	y = yVal(mvavg[n]);
	LineTo(hdc, nx(x), (int)y);
	xLast = x;
	yLast = y;
    }
    SelectObject(hdc, hOldPen);
    DeleteObject(hPen);

    EndPaint(hwnd, &ps);
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_55465758/article/details/136018892

智能推荐

适合入门的8个趣味机器学习项目-程序员宅基地

文章浏览阅读86次。首发地址:https://yq.aliyun.com/articles/221708谈到机器学习,相信很多除学者都是通过斯坦福大学吴恩达老师的公开课《Machine Learning》开始具体的接触机器学习这个领域,但是学完之后又不知道自己的掌握情况,缺少一些实际的项目操作。对于机器学习的相关竞赛挑战,有些项目的门槛有些高,参加后难以具体的实现,因此造..._scrath五子棋下载

oracle 12c avg,Oracle 12c新特性系列专题-安徽Oracle授权认证中心-程序员宅基地

文章浏览阅读83次。原标题:Oracle 12c新特性系列专题-安徽Oracle授权认证中心 随着Oracle database 12c的普及,数据库管理员 (DBA) 的角色也随之发生了转变。 Oracle 12c数据库对 DBA 而言是下一代数据管理。它让 DBA 可以摆脱单调的日常管理任务,能够专注于如何从数据中获取更多价值。未来我们会推出基于Oracle12c的技术文章,帮助DBA尽快掌握新一代数据库的新特性..._ilm add policy row store compress advanced row after

第七周项目三(负数把正数赶出队列)-程序员宅基地

文章浏览阅读150次。问题及代码:*Copyright(c)2016,烟台大学计算机与控制工程学院 *All right reserved. *文件名称:负数把正数赶出队列.cpp *作者:张冰 *完成日期;2016年10月09日 *版本号;v1.0 * *问题描述: 设从键盘输入一整数序列a1,a2,…an,试编程实现: 当ai>0时,ai进队,当ai<0时,将队首元素出队,当ai

Linux命名空间学习教程(二) IPC-程序员宅基地

文章浏览阅读150次。本文讲的是Linux命名空间学习教程(二) IPC,【编者的话】Docker核心解决的问题是利用LXC来实现类似VM的功能,从而利用更加节省的硬件资源提供给用户更多的计算资源。而 LXC所实现的隔离性主要是来自内核的命名空间, 其中pid、net、ipc、mnt、uts 等命名空间将容器的进程、网络、消息、文件系统和hostname 隔离开。本文是Li..._主机的 ipc 命名空间

adb强制安装apk_adb绕过安装程序强制安装app-程序员宅基地

文章浏览阅读2w次,点赞5次,收藏7次。在设备上强制安装apk。在app已有的情况下使用-r参数在app版本低于现有版本使用-d参数命令adb install -r -d xxx.apk_adb绕过安装程序强制安装app

随便推点

STM32F407 越界问题定位_stm32flash地址越界怎么解决-程序员宅基地

文章浏览阅读290次。如果是越界进入硬件错误中断,MSP 或者 PSP 保存错误地址,跳转前会保存上一次执行的地址,lr 寄存器会保存子函数的地址,所以如果在 HardFault_CallBack 中直接调用 C 语言函数接口会间接修改了 lr,为了解决这个问题,直接绕过 lr 的 C 语言代码,用汇编语言提取 lr 寄存器再决定后面的操作。由于 STM32 加入了 FreeRTOS 操作系统,可能导致无法准确定位,仅供参考(日常编程需要考虑程序的健壮性,特别是对数组的访问,非常容易出现越界的情况)。_stm32flash地址越界怎么解决

利用SQL注入上传木马拿webshell-程序员宅基地

文章浏览阅读1.8k次。学到了一种操作,说实话,我从来没想过还能这样正常情况下,为了管理方便,许多管理员都会开放MySQL数据库的secure_file_priv,这时就可以导入或者导出数据当我如图输入时,就会在D盘创建一个名为123456.php,内容为<?php phpinfo();?>的文件我们可以利用这一点运用到SQL注入中,从拿下数据库到拿下目标的服务器比如我们在使用联合查询注入,正常是这样的语句http://xxx?id=-1 union select 1,'你想知道的字段的内容或查询语句',

Html CSS的三种链接方式_html链接css代码-程序员宅基地

文章浏览阅读2.9w次,点赞12次,收藏63次。感谢原文:https://blog.csdn.net/abc5382334/article/details/24260817感谢原文:https://blog.csdn.net/jiaqingge/article/details/52564348Html CSS的三种链接方式css文本的链接方式有三种:分别是内联定义、链入内部css、和链入外部css1.代码为:<html>..._html链接css代码

玩游戏哪款蓝牙耳机好?2021十大高音质游戏蓝牙耳机排名_适合游戏与运动的高音质蓝牙耳机-程序员宅基地

文章浏览阅读625次。近几年,蓝牙耳机市场发展迅速,越来越多的消费者希望抛弃线缆,更自由地听音乐,对于运动人士来说,蓝牙耳机的便携性显得尤为重要。但目前市面上的大多数蓝牙耳机实际上都是“有线”的,运动过程中产生的听诊器效应会严重影响听歌的感受。而在“真无线”耳机领域,除了苹果的AirPods外,可供选择的产品并不多,而AirPods又不是为运动场景打造的,防水能力非常差。那么对于喜欢运动又想要“自由”的朋友来说,有没有一款产品能够满足他们的需求呢?下面这十款小编专门为大家搜罗的蓝牙耳机或许就能找到适合的!网红击音F1_适合游戏与运动的高音质蓝牙耳机

iOS 17 测试版中 SwiftUI 视图首次显示时状态的改变导致动画“副作用”的解决方法-程序员宅基地

文章浏览阅读1k次,点赞6次,收藏7次。在本篇博文中,我们在 iOS 17 beta 4(SwiftUI 5.0)测试版中发现了 SwiftUI 视图首次显示时状态的改变会导致动画“副作用”的问题,并提出多种解决方案。

Flutter 自定义 轮播图的实现_flutter pageview轮播图 site:csdn.net-程序员宅基地

文章浏览阅读1.9k次。  在 上篇文章–Flutter 实现支持上拉加载和下拉刷新的 ListView 中,我们最终实现的效果是在 listView 上面留下了一段空白,本意是用来加载轮播图的,于是今天就开发了一下,希望能给各位灵感。一 、效果如下说一下大体思路   其实图片展示是用的 PageView ,然后,下面的指示器 是用的 TabPageSelector ,当然整体是用 Stack 包裹起来的。1、..._flutter pageview轮播图 site:csdn.net

推荐文章

热门文章

相关标签