WM_PAINT难以被触发,怎样才能够让它重绘窗口

小弟刚学VC,这是我在写一个很小的五子棋项目。现在出现了一个问题就是点击鼠标以后窗口不刷新。
网上也去查了一些原因,大致确定是说WMPAINT消息优先级低,一直被忽略。。(当然我现在还不是很确定是不是这个原因)
嗯,我写的代码看起来比较复杂,大家将就一下:

这个是含WinMain的源文件:

 #include <tchar.h>

#include "gobang.h"

#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
#define BOARD_GAP 20
#define CHESS_RADIUS 9
#define WINDOW_TITLE L"五子棋"

HDC g_hdc = NULL;
HDC g_mdc = NULL;
HBITMAP g_hBg = NULL;
HPEN g_hDrawer = NULL;
HBRUSH g_hBlkPainter = NULL;
HBRUSH g_hWhtPainter = NULL;

Processor *proc = NULL;

int g_iX = 0;
int g_iY = 0;

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
BOOL Init(HWND hwnd);
BOOL Paint(HWND hwnd);
BOOL StepPaint(HWND hwnd, Point pt, BoardPointType bpt);
BOOL CleanUp(HWND hwnd);
INT GetCenterX(Point pt);
INT GetCenterY(Point pt);
Point MouseClassify();
BOOL CheckDistance(int x, int y);
VOID CheckMate(HWND hwnd, Point bp);
VOID Win(HWND hwnd, Player player);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    WNDCLASSEX wndClass = { 0 };
    wndClass.cbSize = sizeof(WNDCLASSEX);
    wndClass.style = CS_HREDRAW | CS_VREDRAW;
    wndClass.lpfnWndProc = WndProc;
    wndClass.cbClsExtra = 0;
    wndClass.cbWndExtra = 0;
    wndClass.hInstance = hInstance;
    wndClass.hIcon = (HICON) ::LoadImage(NULL, L"src\\icon.ico", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);
    wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    wndClass.lpszMenuName = NULL;
    wndClass.lpszClassName = L"Gobang";

    if (!RegisterClassEx(&wndClass))
        return -1;

    HWND hwnd = CreateWindow(L"Gobang", WINDOW_TITLE, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);

    if (!Init(hwnd))
    {
        MessageBox(hwnd, L"资源初始化失败:计算机运行内存不足!", L"错误", 0);
        return FALSE;
    }

    if (wndClass.hIcon == NULL || g_hBg == NULL)
    {
        MessageBox(hwnd, L"资源初始化失败:素材缺失,请重新安装", L"错误", 0);
        return FALSE;
    }

    MoveWindow(hwnd, 250, 80, WINDOW_WIDTH, WINDOW_HEIGHT, true);
    ShowWindow(hwnd, nShowCmd);
    UpdateWindow(hwnd);

    MSG msg = { 0 };
    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    UnregisterClass(L"Gobang", wndClass.hInstance);
    return 0;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT paintStruct;

    switch (message)
    {
        /*case WM_TIMER:
            Paint(hwnd);
            break;*/

    case WM_PAINT:
        g_hdc = BeginPaint(hwnd, &paintStruct);
        Paint(hwnd);
        EndPaint(hwnd, &paintStruct);
        ValidateRect(hwnd, NULL);
        break;

    case WM_KEYDOWN:
        if (wParam == VK_ESCAPE)
            DestroyWindow(hwnd);
        break;

    case WM_LBUTTONDOWN: {
            /*wchar_t temp[50];
            swprintf_s(temp, L"Mouse is at (%d, %d)", g_iX, g_iY);
            MessageBox(hwnd, temp, L"提示", 0);*/
            Point clickPoint = MouseClassify();
            if (clickPoint.x != 0)
            {
                //MessageBox(hwnd, L"Mouse Point caught", L"Debug", 0);
                if (proc->getPlayer() == PLAYER_BLACK)
                {
                    if (proc->Dip(clickPoint, PLAYER_BLACK))
                    {
                        StepPaint(hwnd, clickPoint, BLACK_CHESS);
                        //CheckMate(hwnd, Point{ clickPoint.x, clickPoint.y }, BLACK_CHESS);
                    }
                }
                else if (proc->getPlayer() == PLAYER_WHITE)
                {
                    if (proc->Dip(clickPoint, PLAYER_WHITE))
                    {
                        StepPaint(hwnd, clickPoint, WHITE_CHESS );
                        //CheckMate(hwnd, clickPoint, WHITE_CHESS );
                    }
                }
            }
            break;
    }
    case WM_MOUSEMOVE:
        g_iX = LOWORD(lParam);
        if (g_iX > WINDOW_WIDTH)
            g_iX = WINDOW_WIDTH;
        else if (g_iX < 0)
            g_iX = 0;

        g_iY = HIWORD(lParam);
        if (g_iY > WINDOW_HEIGHT)
            g_iY = WINDOW_HEIGHT;
        else if (g_iY < 0)
            g_iY = 0;
        break;

    case WM_DESTROY:
        CleanUp(hwnd);
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hwnd, message, wParam, lParam);
        break;
    }

    return 0;
}

BOOL Init(HWND hwnd)
{
    g_hdc = GetDC(hwnd);
    g_mdc = CreateCompatibleDC(g_hdc);
    g_hBg = (HBITMAP)LoadImage(NULL, L"src\\bg.bmp", IMAGE_BITMAP, WINDOW_WIDTH, WINDOW_HEIGHT, LR_LOADFROMFILE | LR_DEFAULTSIZE);
    g_hDrawer = CreatePen(PS_SOLID, 2, RGB(0, 0, 0));   // black pen
    g_hBlkPainter = CreateSolidBrush(RGB(0, 0, 0)); // black brush
    g_hWhtPainter = CreateSolidBrush(RGB(255, 255, 255));

    proc = new Processor(9, 9);

    if (g_hdc == NULL || g_mdc == NULL || g_hBlkPainter == NULL || g_hWhtPainter == NULL || proc == NULL)
    {
        return FALSE;
    }

    //SetTimer(hwnd, 1, 100, NULL);

    //Game_Paint(hwnd);
    return TRUE;
}

BOOL Paint(HWND hwnd)
{
    SelectObject(g_mdc, g_hBg);
    BitBlt(g_hdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_mdc, 0, 0, SRCCOPY);

    SelectObject(g_hdc, g_hDrawer);
    for (int i = 1; i < proc->getBoardWidth() + 1; i++)
    {
        MoveToEx(g_hdc, GetCenterX(Point{1, i}), GetCenterY(Point{1, i}), NULL);
        LineTo(g_hdc, GetCenterX(Point{ proc->getBoardHeight(), i}), GetCenterY(Point{ proc->getBoardHeight(), i }));
    }
    for (int i = 1; i < proc->getBoardWidth() + 1; i++)
    {
        MoveToEx(g_hdc, GetCenterX(Point{ i, 1}), GetCenterY(Point{ i, 1}), NULL);
        LineTo(g_hdc, GetCenterX(Point{i, proc->getBoardWidth() }), GetCenterY(Point{i, proc->getBoardHeight() }));
    }

    for (int i = 0; i < proc->getBoardWidth(); i++)
    {
        for (int j = 0; j < proc->getBoardHeight(); j++)
        {
            StepPaint(hwnd, Point{ i+1, j+1 }, proc->getBoardPointType(Point{i+1, j+1}));
        }
    }
    return TRUE;
}

BOOL StepPaint(HWND hwnd, Point pt, BoardPointType bpt)
{
    if (bpt== NO_CHESS)
    {
        return FALSE;
    }

    if (bpt == WHITE_CHESS)
    {
        SelectObject(g_hdc, g_hDrawer);
        SelectObject(g_hdc, g_hWhtPainter);
        Ellipse(g_hdc, GetCenterX(pt) - CHESS_RADIUS, GetCenterY(pt) - CHESS_RADIUS, GetCenterX(pt) + CHESS_RADIUS, GetCenterY(pt) + CHESS_RADIUS);
    }
    else
    {
        SelectObject(g_hdc, g_hDrawer);
        SelectObject(g_hdc, g_hBlkPainter);
        Ellipse(g_hdc, GetCenterX(pt) - CHESS_RADIUS, GetCenterY(pt) - CHESS_RADIUS, GetCenterX(pt) + CHESS_RADIUS, GetCenterY(pt) + CHESS_RADIUS);
    }
    return TRUE;
}

BOOL CleanUp(HWND hwnd)
{
    //KillTimer(hwnd, 1);
    DeleteDC(g_mdc);
    ReleaseDC(hwnd, g_hdc);
    return TRUE;
}

INT GetCenterX(Point pt)
{
    int scrctrx = WINDOW_WIDTH / 2;
    int midx = proc->getBoardWidth() / 2;
    return scrctrx - (midx - pt.x) * BOARD_GAP;
}

INT GetCenterY(Point pt)
{
    int scrctry = WINDOW_HEIGHT / 2;
    int midy = proc->getBoardHeight() / 2;
    return scrctry - (midy - pt.y) * BOARD_GAP;
}

Point MouseClassify()
{
    for (int i = 1; i < proc->getBoardWidth() + 1; i++)
    {
        for (int j = 1; j < proc->getBoardHeight() + 1; j++)
        {
            if (CheckDistance(GetCenterX(Point{ i, j}), GetCenterY(Point{i, j})))
            {
                return Point{i, j};
            }
        }
    }
    return Point{0, 0};
}

BOOL CheckDistance(int x, int y)
{
    int dx = g_iX - x;
    int dy = g_iY - y;
    return dx * dx + dy * dy < CHESS_RADIUS * CHESS_RADIUS;
}

VOID CheckMate(HWND hwnd, Point bp)
{
    /*if (Board_Check(g_board,bp))
    {
        Win(hwnd, currentPlayer);
    }*/
    MessageBox(hwnd, L"CheckMate not completed", L"Warning", 0);
}

VOID Win(HWND hwnd, Player player)
{
    //wchar_t msg[20] = (player == PLAYER_BLACK) ? L"Black Win!" : L"White Win!";
    if (player == PLAYER_BLACK)
    {
        MessageBox(hwnd, L"Black Win!", L"结束", 0);
    }
    else {
        MessageBox(hwnd, L"White Win!", L"结束", 0);
    }

    exit(0);
}

这个是引用的自己写的一个文件gobang.h:

 #ifndef _GOBANG_H_
#define _GOBANG_H_

#include <windows.h>

#define DEFAULT_BOARD_WIDTH 19
#define DEFAULT_BOARD_HEIGHT 19

enum BoardPointType
{
    NO_CHESS, BLACK_CHESS, WHITE_CHESS
};

enum Player
{
    PLAYER_BLACK, PLAYER_WHITE
};

typedef struct S_Point
{
    int x;
    int y;
} Point;

class Board
{
private:
    int w;
    int h;
    BoardPointType **bp;

public:
    Board();
    Board(int w, int h);

    int getW();
    int getH();

    BoardPointType getBoardPointType(Point pt);
};

class Processor
{
private:
    Board *board = NULL;
    bool vsCom;
    Player currentPlayer;

public:
    Processor();
    Processor(int bw, int bh);
    Processor(bool vsCom);
    Processor(int bw, int bh, bool vsCom);

    int getBoardWidth();
    int getBoardHeight();
    Player getPlayer();
    BoardPointType getBoardPointType(Point pt);

    BOOL Dip(Point pt, Player pl);
};

#endif // gobang.h

为什么运行之后不能够正常点一个点在上面。特别是调用了Ellipse(...)函数前后我看了,各项参数都是很正常的。。
每个参数是什么意思应该很好理解吧,我就不多解释了。proc是我定义的一个全局变量,用于对每个步骤进行响应。g_iX, g_iY是用来记录鼠标的位置。

编程环境:VS 2013

3个回答

下棋是鼠标点击事件不是窗体重绘事件

谢谢一楼的回答,虽然不是这个问题。我已经搞定了,只需要把WinMain里的Move, Show, Update函数放在Init函数之前就可以了。这一点我也没有想到为什么,不过还是谢谢了

单击鼠标并没有使窗口DC失效啊,所以当然不会触发了,你可以用鼠标左键按下的消息啊

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
求教WM_PAINT消息和非WM_PAINT消息下绘图的区别
小弟新学WIN32下的编程。对WM_PAINT消息下绘制图形和非WM_PAINT下绘图感到很困惑。不知道什么时候需要在WM_PAINT下绘图,什么时候收到消息后直接绘图。求教。
我是初学者想请教win32 api 关于使用WM_PAINT 谢谢
通过WM_LBUTTONDOWN WM_LBUTTONUP WM_PAINT 做出线段,怎么才能让他每次做出来之后不会刷新能保留下来?
direct2d怎么实现相对固定的时间 刷新游戏场景 而不是被迫接收到wm_paint消息后刷
比如gdi 可以写在消息循环里面 然后用gettickcount函数实现相对固定的时间刷新 但是direct2d貌似只能写在wm_paint消息里面 怎么实现这个功能呢 各位大神 谢谢
怎么强制其他程序的控件重绘。
我在做一个帮助程序,需要在其他程序的窗口上绘图(Graphics),但是只要这个窗口不重绘,我画的东西就一直在上面,所以我想强制他重绘,但是UpdateWindow,InvalIDAteRect,SendMessage(WM_PAINT)都没有用啊,有大佬知道怎么解决吗?
windows编程关闭窗口时进程还在后台运行
代码如下: ``` #include <Windows.h> #include <stdio.h> /* * 窗口的回调函数 */ LRESULT CALLBACK WindowProc(HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam) // second message parameter { HDC hDC; PAINTSTRUCT ps; switch (uMsg) { case WM_PAINT: /* * 窗口重绘时调用 * 只有在WM_PAINT消息中才可以使用BeginPaint、EndPaint * 其他消息使用GetDC、ReleaseDC */ hDC = BeginPaint(hwnd, &ps); TextOut(hDC, 0, 50, "这是在WM_PAINT消息中重绘的文字", strlen("这是在WM_PAINT消息中重绘的文字")); EndPaint(hwnd, &ps); break; case WM_CHAR: MessageBox(hwnd, "WM_CHAR消息触发了", "提示", MB_OK); break; case WM_LBUTTONDOWN: hDC = GetDC(hwnd); TextOut(hDC, 0, 70, "这是在WM_LBUTTONDOWN消息中重绘的文字", strlen("这是在WM_LBUTTONDOWN消息中重绘的文字")); ReleaseDC(hwnd, hDC); break; case WM_CLOSE: if (IDYES == MessageBox(hwnd, "确定要退出吗?", "提示", MB_YESNO)) { //确定退出,销毁窗口,抛出一个WM_DESTYRY的消息 DestroyWindow(hwnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0; } int WINAPI WinMain(HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // command line int nCmdShow) // show state { //第一步、设计窗口类 WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; //设置水平竖直重绘,发送WM_PAINT消息 wndclass.lpfnWndProc = WindowProc; //指定窗口的回调函数 wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; //两个额外数据 wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_CROSS); wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "myWindowClass"; //第二步、注册窗口类 RegisterClass(&wndclass); //第三步、创建窗口 HWND hWnd = CreateWindow( "myWindowClass", //窗口类的名字 "my first window", //窗口标题 WS_OVERLAPPEDWINDOW, //样式 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, //左上角坐标,宽高 NULL, //父窗口 NULL, //菜单 hInstance, //实例 NULL); //附加参数 //第四部、显示更新窗口 ShowWindow(hWnd, SW_SHOWNORMAL); //正常显示窗口 UpdateWindow(hWnd); //更新窗口 //第五步、消息循环 MSG msg; while (GetMessageA(&msg, hWnd, 0, 0)) { TranslateMessage(&msg); //翻译消息 DispatchMessageA(&msg); //将消息传入窗口的回调函数 } return 0; } ```
求救!python3 pywin32 创建窗体没有 WM_CREATE 信息!
求救!python3 pywin32 创建窗体没有 WM_CREATE 信息! ``` def createPropertyWin(hWndParent = None): def wndProc(hWnd, message, wParam, lParam): print(message) if message == win32con.WM_PAINT: print("WM_PAINT") hdc, paintStruct = win32gui.BeginPaint(hWnd) dpiScale = win32ui.GetDeviceCaps(hdc, win32con.LOGPIXELSX) / 60.0 fontSize = 80 lf = win32gui.LOGFONT() lf.lfFaceName = "Times New Roman" lf.lfHeight = int(round(dpiScale * fontSize)) hf = win32gui.CreateFontIndirect(lf) win32gui.SelectObject(hdc, hf) rect = win32gui.GetClientRect(hWnd) win32gui.DrawText( hdc, '测试', -1, rect, win32con.DT_CENTER | win32con.DT_NOCLIP | win32con.DT_SINGLELINE | win32con.DT_VCENTER ) win32gui.EndPaint(hWnd, paintStruct) return 0 elif message == win32con.WM_CREATE: print("WM_CREATE") return 0 else: return win32gui.DefWindowProc(hWnd, message, wParam, lParam) hInstance = win32api.GetModuleHandle() className = 'MyCreatePropertyWin' wndClass = win32gui.WNDCLASS() wndClass.style = win32con.CS_HREDRAW | win32con.CS_VREDRAW | win32con.CS_DBLCLKS wndClass.lpfnWndProc = wndProc wndClass.hInstance = hInstance wndClass.hCursor = win32gui.LoadCursor(None, win32con.IDC_ARROW) wndClass.hbrBackground = win32gui.GetStockObject(win32con.WHITE_BRUSH) wndClass.lpszClassName = className wndClassAtom = win32gui.RegisterClass(wndClass) exStyle = win32con.WS_EX_COMPOSITED | win32con.WS_EX_LAYERED | win32con.WS_EX_CLIENTEDGE style = win32con.WS_OVERLAPPEDWINDOW | win32con.CW_USEDEFAULT hWindow = win32gui.CreateWindowEx( exStyle, wndClassAtom, "属性", style, 0, 0, 300, 500, hWndParent, None, hInstance, None ) win32gui.ShowWindow(hWindow, win32con.SW_SHOWNORMAL) win32gui.UpdateWindow(hWindow) win32gui.PumpMessages() ```
Invalidate重绘那个窗口的问题?
一个对话框dlg里面有一个自定义的Cmybutton类,请问下如果在Cmybutton的类下使用Invalidate函数,会发出WM_PAINT消息,这个消息能被主对话框捕获到吗?我理解是 invalidate是在Cmybuntton里面被调用的是不是就只有Cmybutton这个按钮才重绘呢? 对这些消息机制不是很懂,希望大神能讲下
处理WM_NCPAINT消息,用GetWindowDC获取窗口DC,为什么得到的窗口形状是圆角矩形
如图, ![图片说明](https://img-ask.csdn.net/upload/201703/27/1490626391_502.png) 我想处理WM_NCPAINT,实现自绘窗口边框。就算把整个窗口填满,得到的窗口形状为什么不是矩形,而是上面有两个圆角。如果让win8系统来绘制窗口,为什么又是没有圆角的矩形窗口? 求高手指点
WIN32编程断点无法命中WM_TIMER消息
在WIN32编程中,设置了定时器,我在WM_Timer消息中打上断点,却无法命中断点,是怎么回事? 大家看看我的代码有没有问题? ``` LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rect; int TIMER1 = 1; SYSTEMTIME st; static TCHAR str[50]; switch (message) { case WM_CREATE:SetTimer(hwnd, TIMER1, 100, NULL); return 0; case WM_PAINT: hdc = GetDC(hwnd); TextOut(hdc, 0, 0, str, 50); ReleaseDC(hwnd, hdc); return 0; case WM_TIMER: GetLocalTime(&st); GetTimeFormat(LOCALE_SYSTEM_DEFAULT, TIME_FORCE24HOURFORMAT, &st, "hh':'mm':'ss", str, 50); return 0; case WM_DESTROY: KillTimer(hwnd, TIMER1); PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } ```
我是初学者想问win32 api的问题谢谢
用WM_LBUTTONDOWN与WM_LBUTTONUP 通过WM_PAINT如何画出一条线段 能具体点吗谢谢!
Win32消息,子窗口如何接受WM_KEYDOWN消息
我有一个主窗口,里面创建了一个子窗口。所有的操作其实都是为了对子窗口里的图片进行处理。但是一些控件如Button等放在主窗口。现在我想要这个子窗口处理我的PAGEUP和PAGEDOWN键盘消息,但是在主窗口的消息处理函数中可以接收到WM_KEYDOWN消息,而在子窗口中却不能接收到。我知道可以通过主窗口主动POST消息给子窗口实现,但是我想知道能不能直接在子窗口里接收消息。比如,主窗口放弃处理这个消息,并传递给子窗口。我对Windows的消息传递机制一直不是很清楚,希望有懂的大神简单讲解一下这个问题,非常感谢。 case WM_KEYDOWN: switch (wParam) { case VK_LEFT: // LEFT ARROW MessageBox(hWnd,"Left","Left", MB_YESNO); break; case VK_RIGHT: // RIGHT ARROW MessageBox(hWnd,"Right","Right", MB_YESNO); break; case VK_UP: // UP ARROW MessageBox(hWnd,"UP","UP", MB_YESNO); break; case VK_DOWN: // DOWN ARROW MessageBox(hWnd,"DOWN","DOWN", MB_YESNO); break; case VK_HOME: // HOME MessageBox(hWnd,"HOME","HOME", MB_YESNO); break; case VK_END: // END MessageBox(hWnd,"END","END", MB_YESNO); break; case VK_PRIOR: // PAGE UP MessageBox(hWnd,"PAGEUP","PAGEUP",MB_YESNO); break; case VK_NEXT: // PAGE DOWN MessageBox(hWnd,"PAGEDOWN","PAGEDOWN",MB_YESNO); break; default: break; } break;
WM_WINDOWPOSCHANGING消息中的WINDOWPOS->flags成员怎么清除相应位SWP_DRAWFRAME???
**WM_WINDOWPOSCHANGING消息备注:** 对于具有WS_OVERLAPPED或WS_THICKFRAME样式的窗口,DefWindowProc函数将WM_GETMINMAXINFO消息发送到窗口。 这样做是为了验证窗口的新大小和位置,并强制执行CS_BYTEALIGNCLIENT和CS_BYTEALIGNWINDOW客户端样式。 通过不将WM_WINDOWPOSCHANGING消息传递给DefWindowProc函数,应用程序可以覆盖这些默认值。 在处理此消息时,修改WINDOWPOS中的任何值会影响窗口在Z顺序中的新大小,位置或位置。应用程序可以通过设置或清除WINDOWPOS的flags成员中的相应位来阻止对窗口的更改。 **WINDOWPOS结构成员flags描述** flags 类型:UINT 该成员可以是以下一个或多个值。 值 含义 SWP_DRAWFRAME 0×0020 在窗口周围绘制一个框架(在窗口的类描述中定义)。与SWP_FRAMECHANGED标志相同。 SWP_FRAMECHANGED 0×0020 即使窗口的大小未更改,也会向窗口 发送WM_NCCALCSIZE消息。如果未指定此标志,则仅在更改窗口大小时发送WM_NCCALCSIZE。 ``` case WM_NCCALCSIZE:return 0; case WM_WINDOWPOSCHANGING: { WINDOWPOS *pos = (LPWINDOWPOS)lParam; pos->flags;//怎么清除相应位SWP_DRAWFRAME??? return 0; } ``` WM_NCCALCSIZE消息返回0后可以无边框,但是最大化时会发生位移 不正常(-8, -8)-(1374, 776), 1382x784 (最大化) 正常(0,0)-(1366,768)(最大化) 清除相应位SWP_DRAWFRAME后应该就可以实现正常,但怎么实现???
为什么win32在WM_CLOSE消息中直接调用PostQuitMessage(0)窗口无法退出?在拖动窗口后点击又可以退出了?
我知道直接用PostQuitMessage结束消息循环会导致内存泄漏,应该在WM_CLOSE中用DestroyWindow发送WM_DESTROY之后再用PostQuitMessage, 但我想知道为什么我在使用消息循环1时直接在WM_CLOSE下用PostQuitMessage(0)窗口为什么无法退出,并且在拖动窗口后再点击退出就行了。而在使用消息循环2时点击能直接退出。 消息循环1: while (bRet = GetMessage(&msg, MainWnd, 0, 0)) { if (-1 == bRet) break; TranslateMessage(&msg); DispatchMessage(&msg); } 消息循环2: while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } (使用的编译器是vs2017)
计时器消息会因为重绘消息停止?
不知道为什么拖动边框或者最大最小化会使定时器停止,求解释消息的机制,萌新求解释┭┮﹏┭┮ LRESULT CALLBACK wndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { PAINTSTRUCT paintStruct; switch (message) { case WM_TIMER: Game_Paint(hwnd); return 0; case WM_PAINT: g_hdc = BeginPaint(hwnd,&paintStruct); Game_Paint(hwnd); EndPaint(hwnd,&paintStruct); ValidateRect(hwnd,NULL); return 0; case WM_KEYDOWN: if (wparam == VK_ADD) { DestroyWindow(hwnd); }return 0; case WM_DESTROY: Game_Cleanup(hwnd); PostQuitMessage(0); return 0; default: return DefWindowProc(hwnd,message,wparam,lparam); } } ``` ```
MFC向其他程序发送wm_command消息失败
MFC 点击按钮向其他程序发送wm_command消息, _点击按钮发送后,要移动一下鼠标或键盘按一下键,才会发出消息,目标窗口才会做出响应, 请问是怎么回事,要怎么解决. 如果鼠标不动,消息发不出来.目标窗口没反应 ``` HWND hwnd_sj = ::FindWindow(NULL,L"数据下载"); SendMessage(hwnd_sj,WM_COMMAND,0x0abe1, 0); return; ``` 用网上下载的消息调试器发送成功
新手用MFC求教,在咋们CSDN上搜到一个程序刚好我要用,收拾了一堆出错后剩下这个求教。
{WM_NULL,"WM_NULL"}, {WM_CREATE,"WM_CREATE"}, {WM_DESTROY,"WM_DESTROY"}, {WM_MOVE,"WM_MOVE"}, {WM_SIZE,"WM_SIZE"}, {WM_ACTIVATE,"WM_ACTIVATE"}, {WM_SETFOCUS,"WM_SETFOCUS"}, {WM_KILLFOCUS,"WM_KILLFOCUS"}, {WM_ENABLE,"WM_ENABLE"}, {WM_SETREDRAW,"WM_SETREDRAW"}, {WM_SETTEXT,"WM_SETTEXT"}, {WM_GETTEXT,"WM_GETTEXT"}, {WM_GETTEXTLENGTH,"WM_GETTEXTLENGTH"}, {WM_PAINT,"WM_PAINT"}, {WM_CLOSE,"WM_CLOSE"}, {WM_QUERYENDSESSION,"WM_QUERYENDSESSION"}, {WM_QUIT,"WM_QUIT"}, 后半部分全是波浪线 出错提示: 1>e:\pjb\messagetip\messagetip\stdafx.h(71): error C2440: “初始化”: 无法从“const char [8]”转换为“LPCTSTR” 1> 与指向的类型无关;转换要求 reinterpret_cast、C 样式转换或函数样式转换 1>e:\pjb\messagetip\messagetip\stdafx.h(72): error C2440: “初始化”: 无法从“const char [10]”转换为“LPCTSTR” 1> 与指向的类型无关;转换要求 reinterpret_cast、C 样式转换或函数样式转换 1>e:\pjb\messagetip\messagetip\stdafx.h(73): error C2440: “初始化”: 无法从“const char [11]”转换为“LPCTSTR” 1> 与指向的类型无关;转换要求 reinterpret_cast、C 样式转换或函数样式转换 1>e:\pjb\messagetip\messagetip\stdafx.h(74): error C2440: “初始化”: 无法从“const char [8]”转换为“LPCTSTR”
使用wm_concat导致的性能问题
sql类似如下 select a.name wm_concat(a.c1), wm_concat(a.c2), wm_concat(a.c3) from table a group by a.name 这里要按名称分组将其他三个值都拼接起来,返回的都是clob类型,导致查询非常慢 而且占用相当大的表空间。。。请教大神,这要如何优化?a.c1等拼接的值很容易超过 4000。。。
结构体定义的问题,求大神帮忙解释下第二个结构体的含义,谢谢了!
struct MSGMAP_ENTRY { UINT nMessage; LONG (*pfn)(HWND,UINT,WPARAM,LPARAM); }; struct MSGMAP_ENTRY _messageEntries[] = { WM_CREATE, OnCreate, WM_PAINT, OnPaint, WM_SIZE, OnSize, WM_COMMAND, OnCommand, WM_SETFOCUS, OnSetFocus, WM_CLOSE, OnClose, WM_DESTROY, OnDestroy, } ; 求大神帮我解释下第二个结构体的含义吗?谢谢了!
SetWindowsHookEx 截获不到WM_COPYDATA
SetWindowsHookEx 截获不到WM_COPYDATA 代码是写在DLL中的,钩子也成功了,但截不到 LRESULT CALLBACK MYWNDPROC(int code, WPARAM wParam, LPARAM lParam) { COPYDATASTRUCT * pCopyData; if(code==HC_ACTION) { CWPSTRUCT *pMsg = (CWPSTRUCT *)lParam; if(pMsg->message==WM_COPYDATA) 截不到WM_COPYDATA,但SPY++可以,求教。
Java学习的正确打开方式
在博主认为,对于入门级学习java的最佳学习方法莫过于视频+博客+书籍+总结,前三者博主将淋漓尽致地挥毫于这篇博客文章中,至于总结在于个人,实际上越到后面你会发现学习的最好方式就是阅读参考官方文档其次就是国内的书籍,博客次之,这又是一个层次了,这里暂时不提后面再谈。博主将为各位入门java保驾护航,各位只管冲鸭!!!上天是公平的,只要不辜负时间,时间自然不会辜负你。 何谓学习?博主所理解的学习,它是一个过程,是一个不断累积、不断沉淀、不断总结、善于传达自己的个人见解以及乐于分享的过程。
程序员必须掌握的核心算法有哪些?
由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是零散的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过...
有哪些让程序员受益终生的建议
从业五年多,辗转两个大厂,出过书,创过业,从技术小白成长为基层管理,联合几个业内大牛回答下这个问题,希望能帮到大家,记得帮我点赞哦。 敲黑板!!!读了这篇文章,你将知道如何才能进大厂,如何实现财务自由,如何在工作中游刃有余,这篇文章很长,但绝对是精品,记得帮我点赞哦!!!! 一腔肺腑之言,能看进去多少,就看你自己了!!! 目录: 在校生篇: 为什么要尽量进大厂? 如何选择语言及方...
大学四年自学走来,这些私藏的实用工具/学习网站我贡献出来了
大学四年,看课本是不可能一直看课本的了,对于学习,特别是自学,善于搜索网上的一些资源来辅助,还是非常有必要的,下面我就把这几年私藏的各种资源,网站贡献出来给你们。主要有:电子书搜索、实用工具、在线视频学习网站、非视频学习网站、软件下载、面试/求职必备网站。 注意:文中提到的所有资源,文末我都给你整理好了,你们只管拿去,如果觉得不错,转发、分享就是最大的支持了。 一、电子书搜索 对于大部分程序员...
linux系列之常用运维命令整理笔录
本博客记录工作中需要的linux运维命令,大学时候开始接触linux,会一些基本操作,可是都没有整理起来,加上是做开发,不做运维,有些命令忘记了,所以现在整理成博客,当然vi,文件操作等就不介绍了,慢慢积累一些其它拓展的命令,博客不定时更新 free -m 其中:m表示兆,也可以用g,注意都要小写 Men:表示物理内存统计 total:表示物理内存总数(total=used+free) use...
比特币原理详解
一、什么是比特币 比特币是一种电子货币,是一种基于密码学的货币,在2008年11月1日由中本聪发表比特币白皮书,文中提出了一种去中心化的电子记账系统,我们平时的电子现金是银行来记账,因为银行的背后是国家信用。去中心化电子记账系统是参与者共同记账。比特币可以防止主权危机、信用风险。其好处不多做赘述,这一层面介绍的文章很多,本文主要从更深层的技术原理角度进行介绍。 二、问题引入 假设现有4个人...
程序员接私活怎样防止做完了不给钱?
首先跟大家说明一点,我们做 IT 类的外包开发,是非标品开发,所以很有可能在开发过程中会有这样那样的需求修改,而这种需求修改很容易造成扯皮,进而影响到费用支付,甚至出现做完了项目收不到钱的情况。 那么,怎么保证自己的薪酬安全呢? 我们在开工前,一定要做好一些证据方面的准备(也就是“讨薪”的理论依据),这其中最重要的就是需求文档和验收标准。一定要让需求方提供这两个文档资料作为开发的基础。之后开发...
网页实现一个简单的音乐播放器(大佬别看。(⊙﹏⊙))
今天闲着无事,就想写点东西。然后听了下歌,就打算写个播放器。 于是乎用h5 audio的加上js简单的播放器完工了。 演示地点演示 html代码如下` music 这个年纪 七月的风 音乐 ` 然后就是css`*{ margin: 0; padding: 0; text-decoration: none; list-...
Python十大装B语法
Python 是一种代表简单思想的语言,其语法相对简单,很容易上手。不过,如果就此小视 Python 语法的精妙和深邃,那就大错特错了。本文精心筛选了最能展现 Python 语法之精妙的十个知识点,并附上详细的实例代码。如能在实战中融会贯通、灵活使用,必将使代码更为精炼、高效,同时也会极大提升代码B格,使之看上去更老练,读起来更优雅。
数据库优化 - SQL优化
以实际SQL入手,带你一步一步走上SQL优化之路!
2019年11月中国大陆编程语言排行榜
2019年11月2日,我统计了某招聘网站,获得有效程序员招聘数据9万条。针对招聘信息,提取编程语言关键字,并统计如下: 编程语言比例 rank pl_ percentage 1 java 33.62% 2 cpp 16.42% 3 c_sharp 12.82% 4 javascript 12.31% 5 python 7.93% 6 go 7.25% 7 p...
通俗易懂地给女朋友讲:线程池的内部原理
餐盘在灯光的照耀下格外晶莹洁白,女朋友拿起红酒杯轻轻地抿了一小口,对我说:“经常听你说线程池,到底线程池到底是个什么原理?”
《奇巧淫技》系列-python!!每天早上八点自动发送天气预报邮件到QQ邮箱
将代码部署服务器,每日早上定时获取到天气数据,并发送到邮箱。 也可以说是一个小型人工智障。 知识可以运用在不同地方,不一定非是天气预报。
经典算法(5)杨辉三角
杨辉三角 是经典算法,这篇博客对它的算法思想进行了讲解,并有完整的代码实现。
英特尔不为人知的 B 面
从 PC 时代至今,众人只知在 CPU、GPU、XPU、制程、工艺等战场中,英特尔在与同行硬件芯片制造商们的竞争中杀出重围,且在不断的成长进化中,成为全球知名的半导体公司。殊不知,在「刚硬」的背后,英特尔「柔性」的软件早已经做到了全方位的支持与支撑,并持续发挥独特的生态价值,推动产业合作共赢。 而对于这一不知人知的 B 面,很多人将其称之为英特尔隐形的翅膀,虽低调,但是影响力却不容小觑。 那么,在...
腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹?
昨天,有网友私信我,说去阿里面试,彻底的被打击到了。问了为什么网上大量使用ThreadLocal的源码都会加上private static?他被难住了,因为他从来都没有考虑过这个问题。无独有偶,今天笔者又发现有网友吐槽了一道腾讯的面试题,我们一起来看看。 腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹? 在互联网职场论坛,一名程序员发帖求助到。二面腾讯,其中一个算法题:64匹...
面试官:你连RESTful都不知道我怎么敢要你?
干货,2019 RESTful最贱实践
为啥国人偏爱Mybatis,而老外喜欢Hibernate/JPA呢?
关于SQL和ORM的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行了一番讨论,感触还是有一些,于是就有了今天这篇文。 声明:本文不会下关于Mybatis和JPA两个持久层框架哪个更好这样的结论。只是摆事实,讲道理,所以,请各位看官勿喷。 一、事件起因 关于Mybatis和JPA孰优孰劣的问题,争论已经很多年了。一直也没有结论,毕竟每个人的喜好和习惯是大不相同的。我也看...
白话阿里巴巴Java开发手册高级篇
不久前,阿里巴巴发布了《阿里巴巴Java开发手册》,总结了阿里巴巴内部实际项目开发过程中开发人员应该遵守的研发流程规范,这些流程规范在一定程度上能够保证最终的项目交付质量,通过在时间中总结模式,并推广给广大开发人员,来避免研发人员在实践中容易犯的错误,确保最终在大规模协作的项目中达成既定目标。 无独有偶,笔者去年在公司里负责升级和制定研发流程、设计模板、设计标准、代码标准等规范,并在实际工作中进行...
SQL-小白最佳入门sql查询一
不要偷偷的查询我的个人资料,即使你再喜欢我,也不要这样,真的不好;
redis分布式锁,面试官请随便问,我都会
文章有点长并且绕,先来个图片缓冲下! 前言 现在的业务场景越来越复杂,使用的架构也就越来越复杂,分布式、高并发已经是业务要求的常态。像腾讯系的不少服务,还有CDN优化、异地多备份等处理。 说到分布式,就必然涉及到分布式锁的概念,如何保证不同机器不同线程的分布式锁同步呢? 实现要点 互斥性,同一时刻,智能有一个客户端持有锁。 防止死锁发生,如果持有锁的客户端崩溃没有主动释放锁,也要保证锁可以正常释...
项目中的if else太多了,该怎么重构?
介绍 最近跟着公司的大佬开发了一款IM系统,类似QQ和微信哈,就是聊天软件。我们有一部分业务逻辑是这样的 if (msgType = "文本") { // dosomething } else if(msgType = "图片") { // doshomething } else if(msgType = "视频") { // doshomething } else { // doshom...
Nginx 原理和架构
Nginx 是一个免费的,开源的,高性能的 HTTP 服务器和反向代理,以及 IMAP / POP3 代理服务器。Nginx 以其高性能,稳定性,丰富的功能,简单的配置和低资源消耗而闻名。 Nginx 的整体架构 Nginx 里有一个 master 进程和多个 worker 进程。master 进程并不处理网络请求,主要负责调度工作进程:加载配置、启动工作进程及非停升级。worker 进程负责处...
Python 编程开发 实用经验和技巧
Python是一门很灵活的语言,也有很多实用的方法,有时候实现一个功能可以用多种方法实现,我这里总结了一些常用的方法和技巧,包括小数保留指定位小数、判断变量的数据类型、类方法@classmethod、制表符中文对齐、遍历字典、datetime.timedelta的使用等,会持续更新......
YouTube排名第一的励志英文演讲《Dream(梦想)》
Idon’t know what that dream is that you have, I don't care how disappointing it might have been as you've been working toward that dream,but that dream that you’re holding in your mind, that it’s po...
“狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作
一、垃圾文字生成器介绍 最近在浏览GitHub的时候,发现了这样一个骨骼清奇的雷人项目,而且热度还特别高。 项目中文名:狗屁不通文章生成器 项目英文名:BullshitGenerator 根据作者的介绍,他是偶尔需要一些中文文字用于GUI开发时测试文本渲染,因此开发了这个废话生成器。但由于生成的废话实在是太过富于哲理,所以最近已经被小伙伴们给玩坏了。 他的文风可能是这样的: 你发现,...
程序员:我终于知道post和get的区别
是一个老生常谈的话题,然而随着不断的学习,对于以前的认识有很多误区,所以还是需要不断地总结的,学而时习之,不亦说乎
《程序人生》系列-这个程序员只用了20行代码就拿了冠军
你知道的越多,你不知道的越多 点赞再看,养成习惯GitHub上已经开源https://github.com/JavaFamily,有一线大厂面试点脑图,欢迎Star和完善 前言 这一期不算《吊打面试官》系列的,所有没前言我直接开始。 絮叨 本来应该是没有这期的,看过我上期的小伙伴应该是知道的嘛,双十一比较忙嘛,要值班又要去帮忙拍摄年会的视频素材,还得搞个程序员一天的Vlog,还要写BU...
加快推动区块链技术和产业创新发展,2019可信区块链峰会在京召开
11月8日,由中国信息通信研究院、中国通信标准化协会、中国互联网协会、可信区块链推进计划联合主办,科技行者协办的2019可信区块链峰会将在北京悠唐皇冠假日酒店开幕。   区块链技术被认为是继蒸汽机、电力、互联网之后,下一代颠覆性的核心技术。如果说蒸汽机释放了人类的生产力,电力解决了人类基本的生活需求,互联网彻底改变了信息传递的方式,区块链作为构造信任的技术有重要的价值。   1...
Java世界最常用的工具类库
Apache Commons Apache Commons有很多子项目 Google Guava 参考博客
相关热词 c# clr dll c# 如何orm c# 固定大小的字符数组 c#框架设计 c# 删除数据库 c# 中文文字 图片转 c# 成员属性 接口 c#如何将程序封装 16进制负数转换 c# c#练手项目
立即提问