悄悄的显示实时股票数据
定时从腾讯股票数据接口读取实时数据,在半透明的置顶小窗口显示。
股票的代码由命令行参数输入,可以通过建立批处理文件,显示关心的几个指数。
显示效果如图:
批处理文件:在执行文件后面加上股票代码即可。
代码如下:为了尽量单个文件实现,删掉了一些模板生成的资源量。
// XStock.cpp // 读取并显示股票实时数据 // XGZ 2022-4-26 SZ // #include "stdafx.h" #include <WinInet.h> #pragma comment(lib, "Wininet.lib") #define MAX_LOADSTRING 100 // Global Variables: HINSTANCE hInst; // current instance TCHAR szTitle[MAX_LOADSTRING] = _T("X"); // The title bar text TCHAR szWindowClass[MAX_LOADSTRING] = _T("XStock20220426"); // the main window class name TCHAR szCode[16] = _T("sh000001"); // Forward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); wcscpy_s(szCode,16,lpCmdLine); // TODO: Place code here. MSG msg; MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int) msg.wParam; } ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = NULL; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL; wcex.lpszClassName = szWindowClass; wcex.hIconSm = NULL; return RegisterClassEx(&wcex); } BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE |WS_CAPTION |WS_SYSMENU, CW_USEDEFAULT, 0, 250, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } struct XSTOCK { TCHAR url[256]; float RealValue; float LastValue; float change; }; BOOL ReadStock(XSTOCK &stXStock); typedef BOOL (WINAPI *lpfn)(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags); LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HMODULE hUser32 = GetModuleHandle(_T("user32.dll")); lpfn SetLayeredWindowAttributes1; static XSTOCK stXStock; switch (message) { case WM_CREATE: SetLayeredWindowAttributes1 = (lpfn)GetProcAddress(hUser32,"SetLayeredWindowAttributes"); SetWindowLong(hWnd, GWL_EXSTYLE,GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED); SetLayeredWindowAttributes1( hWnd, RGB(255,255,255), 100, LWA_ALPHA );//设置透明度; FreeLibrary(hUser32); swprintf(stXStock.url, _T("http://qt.gtimg.cn/q=%s"),szCode ); //swprintf(stXStock.url, _T("http://qt.gtimg.cn/q=%s"),_T("sh000001") ); if(ReadStock( stXStock)) { swprintf(szTitle, _T("%s %8.2f %8.4f%%"),szCode, stXStock.RealValue, stXStock.change * 100.0 ); } else { swprintf(szTitle, _T("%s ---- ----%%"),szCode ); } SetWindowText(hWnd, szTitle); SetWindowPos(hWnd, HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED); SetTimer(hWnd, 1, 10000, NULL); //10s break; case WM_TIMER: if(ReadStock( stXStock)) { swprintf(szTitle, _T("%s %8.2f %8.4f%%"),szCode, stXStock.RealValue, stXStock.change * 100.0 ); } else { swprintf(szTitle, _T("%s ---- ----%%"),szCode ); } SetWindowText(hWnd, szTitle); SetWindowPos(hWnd, HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } BOOL ReadStock(XSTOCK &stXStock) { char strRead[1024]=""; char *token; char *next_token = NULL; DWORD strLength = 1; HINTERNET hSession = InternetOpen(_T("UrlTest"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if(hSession != NULL) { HINTERNET hHttp = InternetOpenUrl(hSession, stXStock.url, NULL, 0, INTERNET_FLAG_DONT_CACHE, 0); if (hHttp != NULL) { InternetReadFile(hHttp, strRead, 1023, &strLength); strRead[strLength] = '\0'; token = strtok_s(strRead, "~", &next_token); //交易所 token = strtok_s(NULL, "~", &next_token); //股票名字 token = strtok_s(NULL, "~", &next_token); //股票代码 token = strtok_s(NULL, "~", &next_token); //当前价格 stXStock.RealValue = atof(token); token = strtok_s(NULL, "~", &next_token); //昨收 stXStock.LastValue = atof(token); stXStock.change = (stXStock.RealValue - stXStock.LastValue)/stXStock.LastValue; return TRUE; } } return FALSE; };