IBMinfo78请进

闲言碎语不用讲,就请你用SDK编程来PK一下VCL库的运行效率~
测试程序源码和资源在此:https://download.csdn.net/download/DelphiGuy/15450045

程序足够简单,用C++Builder就是几分钟的事,SDK编程也应该可以在一两个小时之内完成。就是循环解码、绘制10个JPEG图片到窗口上。
要点:
1. JPEG要循环解码,每次绘制之前先解码成bitmap再绘制到窗口,不是一次性解码成bitmap,然后只绘制bitmap,那样帧率会高得多
2. 窗口最大化,图像拉伸填满整个客户区
...全文
1864 52 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
52 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2021-03-03
  • 打赏
  • 举报
回复
赵4老师 2021-03-03
  • 打赏
  • 举报
回复
关键是能显示超过32767行的数据,Excel2003好像就不行。 数据越多,越能彰显其优势。 这段代码是V1.0数据多到一屏显示不下时,还无法分屏; 我现在用的是V3.0,数据多到几十屏才能显示时,会自动分屏。鼠标在曲线上移动还能用浮窗显示对应数据,……一大堆新功能。
  • 打赏
  • 举报
回复
复制了几百行数据,变成这样了:


还行,相当于一个初步的chart组件了,只是不能缩放,不能拖动
赵4老师 2021-03-03
  • 打赏
  • 举报
回复
数据行数太少。 另外第52行 if (h==0) h=1; 改为 if (h<10) h=10; if (h>200) h=200;
  • 打赏
  • 举报
回复
老赵的代码UI如下:


咋回事,数据不对吗
「已注销」 2021-03-02
  • 打赏
  • 举报
回复
加班回来,好坏这样了,就此别过。 祝各位安好!
「已注销」 2021-03-02
  • 打赏
  • 举报
回复
接前面...C++ Style,C去掉::

//剩余代码....
//Process WM_COMMAND 事件过程 for Window/Dialog/Ctrl:Form
int Window_OnCommand(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{ //TODO: Message WM_COMMAND Processing Code.
	static DWORD wmCtrlID = LOWORD(wParam);
	static DWORD wmEvent = HIWORD(wParam);
	switch (wmCtrlID)
	{
	case IDC_BUTTON1:
	case IDC_BUTTON2:
	case IDC_BUTTON3:
	case IDC_BUTTON4:
	{
		switch (wmEvent)
		{
		case BN_CLICKED:
		{
			::SendMessage(hWndListBox1, LB_RESETCONTENT, 0, 0L);
			DWORD T1 = ::GetTickCount();
			char lpszItem[MAX_PATH];
			for (int i = 0; i < 10000; i++)
			{
				sprintf(lpszItem, "String %d", i);
				::SendMessage(hWndListBox1, LB_ADDSTRING, 0, (LPARAM)lpszItem);
			}
			DWORD T2 = ::GetTickCount();
			char lpWinText[MAX_PATH];
			double t = (T2 - T1) / 1000;
			sprintf(lpWinText, "Time Lost: %.3f s.", t);
			::SetWindowText(ghWnd, lpWinText);
			break;
		}
		}

		break;
	}
	default:
		return ::DefWindowProc(hWnd, nMsg, wParam, lParam);
	}
	return 0;
}

//Process WM_MOUSEMOVE 事件过程 for Window/Dialog/Ctrl:Form
void Window_OnMouseMove(HWND hWnd, int x, int y, UINT nKeyFlags)
{ //TODO: Message WM_MOUSEMOVE Processing Code.
	return;
}

//Process WM_KEYDOWN 事件过程 for Window/Dialog/Ctrl:Form
void Window_OnKeyDown(HWND hWnd, UINT vk, BOOL fDown, int cRepeat, UINT nFlags)
{ //TODO: Message WM_KEYDOWN Processing Code.
	::SetWindowText(hWnd, "WndMain处理WM_KEYDOWN消息.");
	return;
}

void /*CWnd::*/ AddToolTip(HWND hWndCtrl, LPSTR lpTooltipText)
{
	static HWND hWndTooltip;
	static HINSTANCE hInstance;
	TOOLINFO ti = {0};
	hInstance = ::GetModuleHandle(NULL);
	hWndTooltip = ::CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, TOOLTIPS_CLASS, "",
								   WS_POPUP | WS_BORDER | WS_CLIPSIBLINGS | TTS_ALWAYSTIP /* | TTS_BALLOON/*气球状*\/*/,
								   0, 0, 0, 0, NULL, (HMENU)(UINT_PTR)NULL, hInstance, NULL);
	if (!hWndTooltip)
	{
		::MessageBox(NULL, "Tooltips Window Creation Failed.", "Error", MB_ICONEXCLAMATION | MB_OK);
	}
	else
	{
		ti.cbSize = sizeof(ti);
		ti.uFlags = TTF_SUBCLASS | TTF_IDISHWND;
		ti.hwnd = ::GetParent(hWndCtrl);
		ti.uId = (UINT)hWndCtrl;
		ti.lpszText = lpTooltipText;
		::SendMessage(hWndTooltip, (UINT)TTM_ADDTOOL, (WPARAM)0, (LPARAM)&ti);
	}
	return;
}

static LRESULT CALLBACK ButtonSubClass_Proc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	ButtonOldProc = (WNDPROC)::GetProp(hWnd, "OLDWNDPROC");
	HWND hWndParent = ::GetParent(hWnd);
	static LONG lButtonState; //ButtonUp = 0 , ButtonDown = 1
	static LONG lMouseOver;	  //MouseOut = 0 ,  lMouseOver = 1
	RECT Rect = {0};
	HDC hDC = {0};
	PAINTSTRUCT PS = {0};
	HBRUSH hBrush = {0};
	POINT Point = {0};
	COLORREF BackColor = {0};
	COLORREF ForeColor = {0};
	char szText[128] = {0};
	switch (Message)
	{
		//添加Win控件的WM_MSG消息。
	case WM_PAINT:
	{
		//将此部分WM_MSG放入CWnd::SubClass_Proc;当主窗体WndProc回调函数中WM_CREATE消息或主程序中CreateWindowEx时创建控件,利用SetProp挂载ControlSubClass_Proc(),
		//例如: SetProp(hWndChild, "OLDWNDPROC", (HANDLE)SetWindowLong(hWndChild, GWL_WNDPROC, (LONG)ControlSubClass_Proc)) ;
		::GetClientRect(hWnd, &Rect);
		::GetWindowText(hWnd, szText, sizeof(szText));
		if (lMouseOver == 1)
		{
			BackColor = RGB(32, 64, 128); //Button-On Colors.
			ForeColor = RGB(255, 255, 255);
		}
		else
		{
			BackColor = RGB(255, 255, 255); //Button-Off Colors.
			ForeColor = RGB(32, 64, 128);
		}
		hBrush = ::CreateSolidBrush(BackColor);
		::SelectObject(hDC, hBrush);
		hDC = ::BeginPaint(hWnd, &PS);
		::FillRect(hDC, &Rect, hBrush);
		if ((lButtonState == 1) && (lMouseOver == 1))
		{ //Button-Down && lMouseOver.
			::DrawEdge(hDC, &Rect, EDGE_ETCHED, BF_RECT);
		}
		else
		{
			::DrawEdge(hDC, &Rect, EDGE_ETCHED, BF_FLAT);
		}
		::SetBkColor(hDC, BackColor);
		::SetBkMode(hDC, TRANSPARENT);
		::SetTextColor(hDC, ForeColor);
		::DrawText(hDC, szText, -1, &Rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
		::DeleteObject(hBrush);
		::EndPaint(hWnd, &PS);
		break;
	}
	case WM_MOUSEMOVE:
	{
		if (lMouseOver == 0)
		{
			::SetCapture(hWnd);
			lMouseOver = 1;
			::InvalidateRect(hWnd, NULL, TRUE);
		}
		else
		{
			::GetWindowRect(hWnd, &Rect);
			::GetCursorPos(&Point);
			if (::PtInRect(&Rect, Point) == FALSE)
			{
				::ReleaseCapture();
				lMouseOver = 0;
				lButtonState = 0;
				::InvalidateRect(hWnd, NULL, TRUE);
			}
		}

		break;
	}
	case WM_LBUTTONUP:
	{
		::ReleaseCapture();
		lMouseOver = 0;
		::InvalidateRect(hWnd, NULL, TRUE);
		if (lButtonState == 1)
		{
			::SendMessage(hWndParent, (UINT)WM_COMMAND, (WPARAM)MAKELONG(::GetWindowLongPtr(hWnd, GWL_ID), BN_CLICKED), (LPARAM)hWnd);
		}
		lButtonState = 0;

		break;
	}
	case WM_LBUTTONDOWN:
	{
		lButtonState = 1;
		::InvalidateRect(hWnd, NULL, TRUE);

		break;
	}

	case WM_DESTROY:
	{
		//ToDo:Add Code Here, for WM_DESTROY.
		::SetWindowLong(hWnd, GWL_WNDPROC, (LONG)ButtonOldProc);
		::RemoveProp(hWnd, "OLDWNDPROC");
		break;
	}
	default:
		return ::CallWindowProc((WNDPROC)ButtonOldProc, hWnd, Message, wParam, lParam);
	}
	return 0;
}
「已注销」 2021-03-02
  • 打赏
  • 举报
回复
Example"Just a joke" 现成块直入,编辑15分钟左右。ListBox 10000行1.000秒

//#pragma region Application_Prepair
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <commdlg.h>
#include <stdio.h>
enum
{
	IDD_FORM1 = 1,
	IDC_BUTTON1,
	IDC_BUTTON2,
	IDC_BUTTON3,
	IDC_BUTTON4,
	IDC_LISTBOX1
};
static HINSTANCE ghInstance;
static HWND ghWnd, hWndChild;
static HWND hWndButton1, hWndButton2, hWndButton3, hWndButton4, hWndListBox1;
//#pragma endregion Application_Prepair

//@重要信息:预先声明、定义 WM_CREATE 事件过程 for Window/Dialog/Ctrl:Form
void Window_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct);
//@重要信息:预先声明、定义 WM_COMMAND 事件过程 for Window/Dialog/Ctrl:Form
int Window_OnCommand(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam);
//@重要信息:预先声明、定义 WM_MOUSEMOVE 事件过程 for Window/Dialog/Ctrl:Form
void Window_OnMouseMove(HWND hWnd, int x, int y, UINT nKeyFlags);
//@重要信息:预先声明、定义 WM_KEYDOWN 事件过程 for Window/Dialog/Ctrl:Form
void Window_OnKeyDown(HWND hWnd, UINT vk, BOOL fDown, int cRepeat, UINT nFlags);
//Add Application WinMain(),主窗体挂载WM消息回调函数WndProc().
static LRESULT CALLBACK WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);

//控件子类化消息处理函数,CButton::SubClass_Proc();如嫌“外挂”不过瘾,则使用SuperClass方式。
//(@重要信息:)Insert the BELOW CODE to the Parent Form WndProc().
static WNDPROC ButtonOldProc;
static LRESULT CALLBACK ButtonSubClass_Proc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
void /*CWnd::*/ AddToolTip(HWND hWndCtrl, LPSTR lpTooltipText); //Func

//窗体、容器类通用消息处理函数,Window WndProc();
//static LRESULT CALLBACK WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	static DWORD wmCtrlID = LOWORD(wParam);
	static DWORD wmEvent = HIWORD(wParam);
	switch (Message)
	{ //添加Main Window控件的WM_MSG消息。

	case WM_CREATE:
	{ //ToDo:Add Code Here, for WM_CREATE.
		Window_OnCreate(hWnd, (LPCREATESTRUCT)lParam);
		break;
	}
	case WM_COMMAND:
	{ //static DWORD wmCtrlID = LOWORD(wParam); static DWORD wmEvent = HIWORD(wParam);
		Window_OnCommand(hWnd, Message, wParam, lParam);
		break;
	}
	case WM_MOUSEMOVE:
	{ //ToDo:Add Code Here, for WM_MOUSEMOVE.
		Window_OnMouseMove(hWnd, (int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam), (UINT)wParam);
		break;
	}
	case WM_KEYDOWN:
	{ //ToDo:Add Code Here, for WM_KEYDOWN.
		Window_OnKeyDown(hWnd, (UINT)wParam, TRUE, (int)(short)LOWORD(lParam), (UINT)HIWORD(lParam));
		break;
	}
	case WM_DESTROY:
	{ //ToDo:Add Code Here, for WM_DESTROY(Destroy Windows).
		::PostQuitMessage(0);
		break;
	}
	default:
		return ::DefWindowProc(hWnd, Message, wParam, lParam);
	}
	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASSEX wc = {0};
	HWND hWnd;
	MSG Message;
	//#pragma region Application_Init
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.lpfnWndProc = WndProc /*自定义函数名称*/; /*default:MainWndProc() insert window procedure function here */
	wc.hInstance = hInstance;
	wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wc.lpszClassName = "WindowClass";
	wc.hIcon = ::LoadIcon(NULL, IDI_APPLICATION);	/* use "A" as icon name when you want to use the project icon */
	wc.hIconSm = ::LoadIcon(NULL, IDI_APPLICATION); /* as above */
	// INITCOMMONCONTROLSEX iccex;
	// iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
	// iccex.dwICC = ICC_LISTVIEW_CLASSES | ICC_TREEVIEW_CLASSES | ICC_BAR_CLASSES | ICC_TAB_CLASSES | ICC_UPDOWN_CLASS | ICC_PROGRESS_CLASS | ICC_USEREX_CLASSES | ICC_DATE_CLASSES;
	// InitCommonControlsEx(&iccex);
	//#pragma endregion Application_Init
	//#pragma region Application_Register
	if (!::RegisterClassEx(&wc))
	{
		::MessageBox(NULL, "Window Registration Failed!", "错误", MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}
	//#pragma endregion Application_Register
	//#pragma region Application_CreateWindow
	ghWnd = ::CreateWindowEx(WS_EX_CLIENTEDGE,
							 "WindowClass", "Just a joke.",
							 WS_VISIBLE | WS_OVERLAPPEDWINDOW,
							 CW_USEDEFAULT, CW_USEDEFAULT,
							 640, 480, NULL, NULL,
							 hInstance, NULL);
	if (hWnd == NULL)
	{
		::MessageBox(NULL, "Window Creation Failed!", "错误", MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}
	//#pragma endregion Application_CreateWindow
	//#pragma region Application_Run
	while (::GetMessage(&Message, NULL, 0, 0) > 0)
	{
		::TranslateMessage(&Message);
		::DispatchMessage(&Message);
	}
	//#pragma endregion Application_Run
	return Message.wParam;
}

//Process WM_CREATE 事件过程 for Window/Dialog/Ctrl:Form
void Window_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
{ //TODO: Message WM_CREATE Processing Code.
	;
	// (@重要信息:)CButton::Create()需创建到case WM_CREATE节中或窗体构建之后,修改类名称(WC_... OR XX_CLASS...)、标题及ControlID。如嫌“外挂”不过瘾,请使用SuperClass方式。
	// DWROD dwCtrlStyle = {0} ;
	// DWORD dwCtrlExStyle = {0} ;
	hWndButton1 = ::CreateWindowEx(0,													//Extended styles
								   WC_BUTTON,											//Button Class
								   "Button" /*自定义控件文本*/,							//Caption
								   WS_CHILD | WS_VISIBLE | WS_TABSTOP |					// window styles
									   BS_PUSHBUTTON | BS_TEXT | BS_CENTER | BS_NOTIFY, // class styles
								   250, 0,												//Left, Top
								   80, 40,												//Width, Height
								   hWnd, (HMENU)IDC_BUTTON1,							// handle of parent, control ID
								   NULL, NULL);											// handle of instance, creation parameters
	//子类化控件需要增加CButton::SubClass_Proc, Subclass the control
	::SendMessage(hWndButton1, WM_SETFONT, (WPARAM)::GetStockObject(DEFAULT_GUI_FONT), TRUE);
	//请添加CButton::SubClass_Proc()回调函数.
	::SetProp(hWndButton1, "OLDWNDPROC", (HANDLE)::SetWindowLong(hWndButton1, GWL_WNDPROC, (LONG)ButtonSubClass_Proc));
	//请添加CWnd::AddToolTip().
	AddToolTip(hWndButton1, "F");

	hWndButton2 = ::CreateWindowEx(0,													//Extended styles
								   WC_BUTTON,											//Button Class
								   "Button" /*自定义控件文本*/,							//Caption
								   WS_CHILD | WS_VISIBLE | WS_TABSTOP |					// window styles
									   BS_PUSHBUTTON | BS_TEXT | BS_CENTER | BS_NOTIFY, // class styles
								   340, 0,												//Left, Top
								   80, 40,												//Width, Height
								   hWnd, (HMENU)IDC_BUTTON2,							// handle of parent, control ID
								   NULL, NULL);											// handle of instance, creation parameters
	//子类化控件需要增加CButton::SubClass_Proc, Subclass the control
	::SendMessage(hWndButton2, WM_SETFONT, (WPARAM)::GetStockObject(DEFAULT_GUI_FONT), TRUE);
	//请添加CButton::SubClass_Proc()回调函数.
	::SetProp(hWndButton2, "OLDWNDPROC", (HANDLE)::SetWindowLong(hWndButton2, GWL_WNDPROC, (LONG)ButtonSubClass_Proc));
	//请添加CWnd::AddToolTip().
	AddToolTip(hWndButton2, "K");

	hWndButton3 = ::CreateWindowEx(0,													//Extended styles
								   WC_BUTTON,											//Button Class
								   "Button" /*自定义控件文本*/,							//Caption
								   WS_CHILD | WS_VISIBLE | WS_TABSTOP |					// window styles
									   BS_PUSHBUTTON | BS_TEXT | BS_CENTER | BS_NOTIFY, // class styles
								   430, 0,												//Left, Top
								   80, 40,												//Width, Height
								   hWnd, (HMENU)IDC_BUTTON3,							// handle of parent, control ID
								   NULL, NULL);											// handle of instance, creation parameters
	//子类化控件需要增加CButton::SubClass_Proc, Subclass the control
	::SendMessage(hWndButton3, WM_SETFONT, (WPARAM)::GetStockObject(DEFAULT_GUI_FONT), TRUE);
	//请添加CButton::SubClass_Proc()回调函数.
	::SetProp(hWndButton3, "OLDWNDPROC", (HANDLE)::SetWindowLong(hWndButton3, GWL_WNDPROC, (LONG)ButtonSubClass_Proc));
	//请添加CWnd::AddToolTip().
	AddToolTip(hWndButton3, "D");

	hWndButton4 = ::CreateWindowEx(0,													//Extended styles
								   WC_BUTTON,											//Button Class
								   "Button" /*自定义控件文本*/,							//Caption
								   WS_CHILD | WS_VISIBLE | WS_TABSTOP |					// window styles
									   BS_PUSHBUTTON | BS_TEXT | BS_CENTER | BS_NOTIFY, // class styles
								   520, 0,												//Left, Top
								   80, 40,												//Width, Height
								   hWnd, (HMENU)IDC_BUTTON4,							// handle of parent, control ID
								   NULL, NULL);											// handle of instance, creation parameters
	//子类化控件需要增加CButton::SubClass_Proc, Subclass the control
	::SendMessage(hWndButton4, WM_SETFONT, (WPARAM)::GetStockObject(DEFAULT_GUI_FONT), TRUE);
	//请添加CButton::SubClass_Proc()回调函数.
	::SetProp(hWndButton4, "OLDWNDPROC", (HANDLE)::SetWindowLong(hWndButton4, GWL_WNDPROC, (LONG)ButtonSubClass_Proc));
	//请添加CWnd::AddToolTip().
	AddToolTip(hWndButton4, "G");

	//(@重要信息:)CListBox::Create()需创建到case WM_CREATE节中或窗体构建之后,修改类名称(WC_... OR XX_CLASS...)、标题及ControlID。如嫌“外挂”不过瘾,请使用SuperClass方式。
	//DWROD dwCtrlStyle = {0} ;
	//DWORD dwCtrlExStyle = {0} ;
	hWndListBox1 = ::CreateWindowEx(WS_EX_WINDOWEDGE | WS_EX_LEFT,							//Extended styles
									WC_LISTBOX,												//ListBox Class
									"ListBox" /*自定义控件文本*/,							//Caption
									WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP |		// window styles
										LBS_NOTIFY | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT, // class styles
									0, 0,													//Left, Top
									230, 400,												//Width, Height
									hWnd, (HMENU)IDC_LISTBOX1,								// handle of parent, control ID
									NULL, NULL);											// handle of instance, creation parameters
	//子类化控件需要增加CListBox::SubClass_Proc, Subclass the control
	::SendMessage(hWndListBox1, WM_SETFONT, (WPARAM)::GetStockObject(DEFAULT_GUI_FONT), TRUE);
	//请添加CWnd::AddToolTip().
	AddToolTip(hWndListBox1, "Just a joke.");

	return;
}

//接后面代码....
ooolinux 2021-03-02
  • 打赏
  • 举报
回复
double *d[7],mind[7],maxd[7];
int i,nn,h,x,y,mx=0,my=0,idx,cc,n,r,j,L,L1,jj=0,cc2,cb;
这代码很简练,没有任何注释~
赵4老师 2021-03-02
  • 打赏
  • 举报
回复
#pragma comment(lib,"user32")
#pragma comment(lib,"gdi32")
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
double *d[7],mind[7],maxd[7];
int i,nn,h,x,y,mx=0,my=0,idx,cc,n,r,j,L,L1,jj=0,cc2,cb;
FILE *f;
char str[1024],*p;
RECT cr,vr,br;
COLORREF cj[7]={//第j列数据的颜色
	0x00FF0000,
	0x00005000,
	0x000000FF,
	0x00FF00FF,
	0x0000FFFF,
	0x00FFFFFF,
	0x00FFFF00,
};
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
	PAINTSTRUCT	ps;
	HDC	hdc;
	HFONT hfont,ohfont;
	COLORREF oc;
	HBRUSH hbrush;//,ob;
	HPEN hpen,op;
	HANDLE hData;
	LPSTR lpData;

	switch (message) {
	case WM_CLOSE://按Alt+F4退出
		PostQuitMessage(0);
		break;
	case WM_KEYUP://按Esc退出
		if (wParam==VK_ESCAPE) PostQuitMessage(0);
		break;
	case WM_LBUTTONUP://鼠标左键点击时显示附近图形对应信息
		mx=LOWORD(lParam);
		my=HIWORD(lParam);
		if (my>cr.bottom-13) {//在底部信息提示行单击
			jj=(jj+1)%cc;//轮换最后显示(最上面显示)那列数据
			InvalidateRect(hWnd,&cr,TRUE);
		} else InvalidateRect(hWnd,&vr,TRUE);
		break;
	case WM_PAINT:
		BeginPaint(hWnd, &ps);
		hdc	= ps.hdc;
		GetClientRect(hWnd,	&cr);
		br.left=cr.left;
		br.right=cr.right;
		h=(cr.bottom-13-cr.top)/(1+nn/(cr.right-cr.left));//每行像素高度
		if (h==0) h=1;
		hbrush=CreateSolidBrush((COLORREF)0x00B0B0B0);
//		ob=(HBRUSH)SelectObject(hdc,hbrush);
		for	(i=0;i<nn;i+=cr.right-cr.left) {
			if (0==i%(cr.right-cr.left)) {
				if (0==i/(cr.right-cr.left)%2) {
					br.bottom=h-1+cr.top+i/(cr.right-cr.left)*h;
					br.top=br.bottom-h;
					FillRect(hdc,&br,hbrush);
				}
			}
		}
		if (0==i/(cr.right-cr.left)%2) {
			br.bottom=h-1+cr.top+i/(cr.right-cr.left)*h;
			br.top=br.bottom-h;
			if (br.top<cr.bottom-13) {
				br.bottom=cr.bottom-13;
				FillRect(hdc,&br,hbrush);//如有必要,在最下面一行的下面填充亮灰,确保最下面一行的高度为h
			}
		}
		for	(j=cc-1;j>=0;j--) {
			if (j==jj) continue;//跳过第jj列数据
			hpen=CreatePen(PS_SOLID,0,cj[(cb+j)%7]);
			op=(HPEN)SelectObject(hdc,hpen);
			for	(i=0;i<nn;i++) {
				x=cr.left+i%(cr.right-cr.left);
				y=h-2+cr.top+i/(cr.right-cr.left)*h-((maxd[j]==mind[j])?0:((int)((d[j][i]-mind[j])/(maxd[j]-mind[j])*h)));
				if (0==i%(cr.right-cr.left)) {
					MoveToEx(hdc,x,y,NULL);
				}
				else LineTo(hdc,x,y);
			}
			SelectObject(hdc,op);
			DeleteObject(hpen);
		}
		j=jj;//将第jj列数据最后显示(最上面显示)
		hpen=CreatePen(PS_SOLID,0,cj[(cb+j)%7]);
		op=(HPEN)SelectObject(hdc,hpen);
		for	(i=0;i<nn;i++) {
			x=cr.left+i%(cr.right-cr.left);
			y=h-2+cr.top+i/(cr.right-cr.left)*h-((maxd[j]==mind[j])?0:((int)((d[j][i]-mind[j])/(maxd[j]-mind[j])*h)));
			if (0==i%(cr.right-cr.left)) {
				MoveToEx(hdc,x,y,NULL);
			}
			else LineTo(hdc,x,y);
		}
		SelectObject(hdc,op);
		DeleteObject(hpen);

		vr.top=cr.bottom-13;
		vr.bottom=cr.bottom;
		vr.left=cr.left;
		vr.right=cr.right;
		FillRect(hdc,&vr,hbrush);
		hfont =	CreateFont(12, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0,	0, "宋体");
		ohfont=(HFONT)SelectObject(hdc,hfont);
		SetBkMode(hdc, TRANSPARENT);
		oc=SetTextColor(hdc,(COLORREF)0x00000000);
		idx=(my+1)/h*(cr.right-cr.left)+mx;
		if (idx>=nn) idx=0;
		L=sprintf(str,"共%d行×%d列 各列最小,最大值=",nn,cc);
		TextOut(hdc,vr.left+8,vr.top+1,str,L);
		for	(j=0;j<cc;j++) {
			SetTextColor(hdc,cj[(cb+j)%7]);
			L1=sprintf(str,"%lg,%lg ",mind[j],maxd[j]);
			TextOut(hdc,vr.left+8+L*6,vr.top+1,str,L1);
			if (j==jj) TextOut(hdc,vr.left+8+L*6+1,vr.top+1,str,L1);
			L+=L1;
		}
		SetTextColor(hdc,(COLORREF)0x00000000);
		L1=sprintf(str,"第%d行: ",idx+1);
		TextOut(hdc,vr.left+8+L*6,vr.top+1,str,L1);
		L+=L1;
		for	(j=0;j<cc;j++) {
			SetTextColor(hdc,cj[(cb+j)%7]);
			L1=sprintf(str,"%lg ",d[j][idx]);
			TextOut(hdc,vr.left+8+L*6,vr.top+1,str,L1);
			if (j==jj) TextOut(hdc,vr.left+8+L*6+1,vr.top+1,str,L1);
			L+=L1;
		}
		if (idx>0) {
			if (OpenClipboard(hWnd)) {
				EmptyClipboard();
				hData=GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,16);
				lpData=(char *)GlobalLock(hData);
				sprintf(lpData,"%d",idx+1);//将当前行行号放入剪贴板,方便外部程序定位光标到当前行。
				GlobalUnlock(hData);
				SetClipboardData(CF_TEXT,hData);
				CloseClipboard();
			}
		}
		SetTextColor(hdc,oc);
		SelectObject(hdc,ohfont);
		DeleteObject(hfont);

//		SelectObject(hdc,ob);
		DeleteObject(hbrush);

		EndPaint(hWnd, &ps);
		break;
	default:
		return DefWindowProc(hWnd, message,	wParam,	lParam);
	}
	return 0;
}
int	WINAPI WinMain(HINSTANCE hInstance,	HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)	{
	MSG	msg				= {0};
	WNDCLASS wc			= {0};
	HBRUSH hbrh;

	if ('/'==lpCmdLine[0] && '?'==lpCmdLine[1]) {
		MessageBox(NULL,
			"·可大于32767行,最多7列\n"
			"·鼠标左键点击折线图时在底部提示行显示对应第几行和对应数值并将当前行行号放入剪贴板\n"
			"·鼠标左键点击底部提示行轮换在最上面显示某列折线并以粗体字显示其对应数值\n"
			"·可在命令行参数中用1~6另外指定第一列数据使用的颜色,默认蓝色\n"
			"·按Esc或Alt+F4键退出\n"
			"设计者:赵中 zhao4zhong1@163.com 2014-10-30",
			"全屏分行显示c:\\data.txt文件中的数据折线图",
			MB_OK
		);
		return 7;
	}
	cb=atoi(lpCmdLine);if (cb<0||6<cb) cb=0;//命令行指定第一种颜色
	f=fopen("c:\\data.txt","r");
	if (NULL==f) return	3;
	if (NULL==fgets(str,1024,f)) {fclose(f);return 5;}
	cc=0;
	p=str;
	while (1) {
		r=sscanf(p,"%lf%n",&mind[0],&n);
		if (1==r) {
			cc++;
			p+=n;
		} else if (0==r) {
			p++;
		} else break;//
	}
	cc2=0;
	if (NULL!=fgets(str,1024,f)) {
		p=str;
		while (1) {
			r=sscanf(p,"%lf%n",&mind[0],&n);
			if (1==r) {
				cc2++;
				p+=n;
			} else if (0==r) {
				p++;
			} else break;//
		}
	}
	if (0==cc && 0==cc2) {fclose(f);return 6;}//第1行有cc列数据,第2行有cc2列数据
	cc=__max(cc,cc2);
	if (cc>7) cc=7;//忽略大于7列的数据
	rewind(f);
	nn=0;
	while (1) {
		if (NULL==fgets(str,1024,f)) break;//
		nn++;
	}
	for	(j=0;j<cc;j++) {
		d[j]=(double *)malloc(nn*sizeof(double));
		if (NULL==d[j])	{fclose(f);return 4;}
	}
	rewind(f);
	for	(i=0;i<nn;i++) {
		fgets(str,1024,f);
		j=0;
		p=str;
		while (1) {
			r=sscanf(p,"%lf%n",&d[j][i],&n);
			if (1==r) {
				if (0==i) {
					mind[j]=d[j][0];
					maxd[j]=d[j][0];
				} else {
					if (d[j][i]<mind[j]) mind[j]=d[j][i];
					if (d[j][i]>maxd[j]) maxd[j]=d[j][i];
				}
				j++;
				if (j>=cc) break;//	//忽略大于cc列的数据
				p+=n;
			} else if (0==r) {
				p++;
			} else break;//
		}
		for	(;j<cc;j++)	d[j][i]=d[0][0]; //本行数据若少于cc列,将其余列填写为本文件第1个数据
	}
	fclose(f);
	hbrh=CreateSolidBrush(0x00999999);
	wc.lpfnWndProc		= WndProc;
	wc.hInstance		= hInstance;
	wc.hbrBackground	= hbrh;
	wc.lpszClassName	= "zzChart2";
	wc.hCursor			= LoadCursor(NULL,IDC_CROSS);
	if(	FAILED(RegisterClass(&wc)) ) return	1;
	if(FAILED(CreateWindow(wc.lpszClassName,
						"zzChart2",
						WS_POPUP|WS_VISIBLE,
						0,
						0,
						GetSystemMetrics(SM_CXSCREEN),
						GetSystemMetrics(SM_CYSCREEN),
						0,
						0,
						hInstance,
						NULL)))
		return 2;

	while( GetMessage( &msg, NULL, 0, 0	) >	0 )	{
		DispatchMessage( &msg );
	}
	DeleteObject(hbrh);
	for	(j=0;j<cc;j++) free(d[j]);
	return 0;
}
ooolinux 2021-03-02
  • 打赏
  • 举报
回复
引用 44 楼 赵4老师 的回复:
[quote=引用 6 楼 赵4老师 的回复:]PK是吧,谁来跟我这个纯Win32 API土造的UI的PK一下?
https://download.csdn.net/download/zhao4zhong1/7610833

没PK完就匆匆总结陈词了?![/quote]
老赵改成0分重新上传,让大家欣赏你的土造UI~
ooolinux 2021-03-02
  • 打赏
  • 举报
回复
有一点不太清楚,几十KB的程序是不是比几百KB的程序运行速度快?
  • 打赏
  • 举报
回复
老赵的资源需要积分太多~~~~
赵4老师 2021-03-02
  • 打赏
  • 举报
回复
引用 6 楼 赵4老师 的回复:
PK是吧,谁来跟我这个纯Win32 API土造的UI的PK一下? https://download.csdn.net/download/zhao4zhong1/7610833
没PK完就匆匆总结陈词了?!
  • 打赏
  • 举报
回复
简单总结一下:
认为SDK编程(简单说就是直接基于操作系统API编写程序)比使用应用程序框架(VCL/FMX或者其他框架)运行效率高是一个似是而非的迷信。
之所以说是迷信,是因为它看起来很合理:你的应用框架是包装了系统API,我直接调用API,运行效率怎么说也要比你高一点吧。
而似是而非,是因为这个论点要成立需要很多先决条件:
1. 基于SDK编程者的水平和框架设计者的水平一样高,写的程序同样优化
2. 系统API的实现都是很优化的,而且一直不断改进
3. 应用框架完全是系统API的封装,几乎没有自己实现的东西,也没有针对系统API的不足做出改进
第一条涉及到开发者的水平,属于不可控因素,就不讨论了。
而后面两条,显然不是必然成立的,甚至可以说大部分情况下都不成立。首先,操作系统是一个庞大的软件集合,出于人力、时间成本的考虑,也不可能每部分都做得一样好,只能抓主要方面。一个系统里存在大量“千年老代码”是非常现实的,很多代码可能十几、二十年,甚至更久都没动过,只是新版本build的时候更新一下版本信息、数字签名就算完工。比如你用win7,显然win7里的API至少是十几年前写的,用十几年前的编译器编译出来的,怎么敢说它比使用新编译器编译应用框架的实现运行效率高?而且应用框架的主要设计目标是使用简单、功能丰富,必然要大量扩充功能,不可能只是API的简单封装(MFC这种早就进入维护期的除外),另外,应用框架的设计者普遍都是专职的(个人搞的小框架除外),他们拥有大量的资源和时间研究底层实现,从普遍意义上来说,就是他们对底层操作系统的熟悉程度远高于我们,可以发现很多缺陷和不足,在框架中做出弥补和改进。
结论就是,小青蛙说的“SDK纯API方式编写Windows程序已经过时了”在普遍意义上是对的(当然如果钻牛角尖找出一些反例来也完全可能),不但开发效率不行,运行效率也不敢说就能超过使用应用框架编程。SDK编程唯一可以确定的优点是可以产生非常小的可执行文件,能写出几KB到几十KB的GUI程序,而相同功能使用应用框架的GUI则可能有几百KB到几MB。
qzjhjxj 2021-03-02
  • 打赏
  • 举报
回复
学习
  • 打赏
  • 举报
回复
就我的测试,LISTBOX插入10000条几乎测不出来时间,插入100000条才0.4~0.5秒之间。
代码(窗体上放一个listbox,一个label、一个button):

void __fastcall TForm1::Button2Click(TObject *Sender)
{
LARGE_INTEGER Freq, Ticks1, Ticks2;

QueryPerformanceFrequency(&Freq);
QueryPerformanceCounter(&Ticks1);
ListBox1->Items->BeginUpdate();
for (int i = 0; i < 100000; i++)
ListBox1->Items->Add(L"Item" + IntToStr(i));
ListBox1->Items->EndUpdate();
QueryPerformanceCounter(&Ticks2);
Label1->Caption = Format("%0.3f seconds", ARRAYOFCONST((
double(Ticks2.QuadPart - Ticks1.QuadPart) / Freq.QuadPart)));
}


程序截图:

  • 打赏
  • 举报
回复
首先,非常感谢IBMinfo78,这么晚还上了测试代码。虽然有点文不对题,不过#23小青蛙也说过“比较界面和消息处理的效率”问题,所以这个代码也算是比较的一个方面。
其次,关于使用应用开发框架和基于SDK编程的比较,稍后我在写一点,就结帖了。
Yx2020 2021-03-01
  • 打赏
  • 举报
回复
不会c++.0.0
「已注销」 2021-03-01
  • 打赏
  • 举报
回复
网上有个C++库,叫Rapier,估计没多少人知道。它完全就是Vcl库pascal语言的C++版本,支持MinGW32 Gcc编译器,它完全不同于owl,有兴趣的可以搜一下。 这几天耽搁了太多的工作,上面问下来了。稍后发一个典型工程的C++代码,就此打住。 后面有什么需要或我可能帮得上忙的地方,请各位高手联系我邮箱。
加载更多回复(32)

24,860

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧