记录将C语言编写的Windows程序转换为python语言编写,演示具体效果在最后,这对初学者理解Windows消息机制及框架有一定参考作用

主要思路 由于C语言的数组定义使用名字加中括号及括号内数字定义,但是在python中【】已经被作为列表 元组等序列类型分片、存取元素,因此我们不能像C语言那样定义数组

例如C语言    int  a[10]  是声明定义一个含有10个int类型的数组a,而在执行语句部分,比如a[1]

表示使用索引号为1的元素 但是在python中 我们不需要声明语句 所以无法像C语言这样声明,于是我转换思路 我将其定义为类,那么声明中的数字就在类初始化中完成。在引用具体元素时,我想保持C语言风格 我使用字典来做类似C语言的引用,比如C语言中引用a[1]元素 我在python中使用a['1']来引用 使用字典方式,所以C语言的声明语句可以考虑使用python字典来初始化,元素引用使用字典形式,保证二者相似性,这样做的目的就是为了我转换C语言为python时候,尽量保持C语言的语法形式。同时注意,C语言中switch case结构在python中是match case 但是该语法似乎需要python3.10及以后的新版本才支持。我的是3.10所以运行测试通过

我初步定义一个二维数组版的python类

class pythonArrayD2():def __init__(self,rows,columns):assert isinstance(rows,int),"参数必须是正整数"assert isinstance(rows, int), "参数必须是正整数"self.rows=rowsself.columns=columnsself.Values={}self.Values=self.initValues()def initValues(self):for i in range(self.rows):for j in range(self.columns):self.Values[str(i)+','+str(j)]=0return self.Values

比如C语言定义一个二维数组   a[10][15]

使用我的类定义类似     a=pythonArrayD2(10,15)

而在引用元素时 比如 C语言  a[2][3]  ,在python中就为 a['2,3'] 使用字符串,并且用逗号分开。

基于此 我转换C语言程序为python就简单得多

为了区分 我在自己定义的文件名都加了数字1为后缀,其中一个定义Windows常量的文件,没有使用的原因主要给大家展示自己可以定义常量替换库文件中的常量 但是为了与C语言风格统一 我没有使用自己定义的常量 ,同时python中大家注意一件事 ,就是常量尽量定义在一个单独的文件中 然后使用全称引用,比如在const.py文件中定义常量 WM_SETFOCUS=7,我们在引用的时候使用全称

const.WM_SETFOCUS来引用,为什么要这样中 虽然C语言中可以直接使用WM_SETFOCUS来引用,那是因为编译性语言,在pyhong解释语言在 我们无法判断WM_SETFOCUS是常量还是变量,python通常解释为变量 容易变成局部变量受到回收机制影响 我给出C语言的Windows源码 和我自己转换后python代码 供初学者参考  记住我们要研究编程者是如何思考的 ,而不是抄其代码,知道其思想后 我们可以随时使用任何语言编写程序 只是语法不同而已 但是思路不变 同时我们理解程序作用后 我们可以参考其代码增加更多功能为自己使用, 提到效率 ,当我们熟悉很多语言的语法后 就练习使用正则表达式转换任何语言 ,同时程序更为精炼,无须对大量常量或者固定语法变量手动转换,这就是编程的作用。下面分别给出python与C语言源码

该程序涉及几个文件  

1,主文件                                                    main.py

2、定义C语言结构 Windows类型的文件    structure1.py

3、定义宏的文件                                         microDefine1.py

4、定义Windows常量的文件  未用             win32con1.py

1. main.py

import sysimport structure1
from structure1 import *
import win32gui
import win32con
import ctypes
import ctypes.wintypes
from random import randint
from microDefine1 import *
from const1 import *
from win32con1 import *
import win32con1
debug=True
user32 = ctypes.windll.user32
gdi32=ctypes.windll.gdi32
#------全局变量----------------
className = 'MyWindowClass'
hwnd=0
msg = ctypes.wintypes.MSG()
wParam=None
lparam=None
idFocus=0  #由于python是解释型语言 所以在函数或者过程内使用全局变量要声明是全局变量 否则视为新建的局部变量
#可能你觉得不用在过程开头声明为全局变量也没事 但是因为程序不再时自上而下执行 但是有时希望更改全局变量值 而在另外过程中使用
szChildClass="checkChild"szAppName="CheckWindwo"
hwndChild=structure1.pythonArrayD2(win32con1.DIVISIONS_CONST,win32con1.DIVISIONS_CONST)
def childWndproc(hwnd,msg,wParam,lParam):global idFocus#C语言结构类型在python中定义为类ps=structure1.PAINTSTRUCT()rect=structure1.RECT()hdc=0   #实际就是指针 但是python变量功能上相当于宏 变量类型自动检测 所以对应简单类型定义直接使用变量match msg:case win32con.WM_CREATE:#SetWindowLong第二个参数0对于子窗口有效 这里是子窗口的过程win32gui.SetWindowLong(hwnd,0,0)return 0case win32con.WM_KEYDOWN:#发生大多数消息给父窗口 自己只处理很少的消息if wParam!=win32con.VK_RETURN and wParam!=win32con.VK_SPACE:user32.SendMessageW(user32.GetParent(hwnd),msg,wParam,lParam)return 0case win32con.WM_LBUTTONDOWN:user32.SetWindowLongA(hwnd,0,1 ^ user32.GetWindowLongA(hwnd,0))user32.SetFocus(hwnd)user32.InvalidateRect(hwnd,win32con.NULL,False)return 0#作用就是窗口获得焦点后 发生一个重绘消息给窗口过程 那么就执行wm_paint消息下的代码case win32con.WM_SETFOCUS:idFocus=user32.GetWindowLongA(hwnd,win32con.GWL_ID)case win32con.WM_KILLFOCUS:user32.InvalidateRect(hwnd,win32con.NULL,True)return 0case win32con.WM_PAINT:hdc=user32.BeginPaint(hwnd,ctypes.byref(ps))user32.GetClientRect(hwnd,ctypes.byref(rect))gdi32.Rectangle(hdc,0,0,rect.right,rect.bottom)#再绘制X标记if user32.GetWindowLongA(hwnd,0):gdi32.MoveToEx(hdc,0,0,win32con.NULL)gdi32.LineTo(hdc,rect.right,rect.bottom,win32con.NULL)gdi32.MoveToEx(hdc,0,rect.bottom,win32con.NULL)gdi32.LineTo(hdc,rect.right,0)#绘制具有焦点时显示的虚线边框if hwnd==user32.GetFocus():#左坐标往前增加1/10rect.left +=rect.right//10rect.right -=rect.right//10rect.top +=rect.bottom//10rect.bottom -=rect.bottom//10#不填充区域gdi32.SelectObject(hdc,gdi32.GetStockObject(win32con.NULL_BRUSH))gdi32.SelectObject(hdc,gdi32.CreatePen(win32con.PS_DASH,0,0))gdi32.Rectangle(hdc,rect.left,rect.top,rect.right,rect.bottom)gdi32.DeleteObject(gdi32.SelectObject(hdc,gdi32.GetStockObject(win32con.BLACK_PEN)))user32.EndPaint(hwnd,ctypes.byref(ps))return 0return win32gui.DefWindowProc(hwnd,msg,wParam,lParam)#----------------主窗口回调函数------------------------
def windowProc(hwnd, msg, wParam, lParam):# cxBlock = 0# cyBlock = 0# x = 0# y = 0global idFocusmatch msg:case win32con.WM_CREATE:print("第一时间收到创建消息")for x in range(win32con1.DIVISIONS_CONST):for y in range(win32con1.DIVISIONS_CONST):hwndChild.Values[str(x) + "," + str(y)] = win32gui.CreateWindow(szChildClass, NULL,win32con.WS_CHILDWINDOW | win32con.WS_VISIBLE, 0, 0, 0, 0,hwnd, (y << 8) | x,user32.GetWindowLongA(hwnd, win32con.GWL_HINSTANCE),NULL)# x += 1# y += 1print("字典元素数量:",len(hwndChild.Values))case win32con.WM_SIZE:cxBlock = LOWORD(lParam) // win32con1.DIVISIONS_CONSTcyBlock = HOWORD(lParam) // win32con1.DIVISIONS_CONSTfor x in range(win32con1.DIVISIONS_CONST):for y in range(win32con1.DIVISIONS_CONST):user32.MoveWindow(hwndChild.Values[str(x) + "," + str(y)], x * cxBlock, y * cyBlock, cxBlock, cyBlock, True)return 0case win32con1.WM_LBUTTONDOWN:print("点击了鼠标左键")user32.MessageBeep(0)return 0case win32con1.WM_SETFOCUS:user32.SetFocus(user32.GetDlgItem(hwnd, idFocus))return 0case win32con.WM_KEYDOWN:x = idFocus & 0xffy = idFocus >> 8match wParam:case win32con.VK_UP:y -= 1case win32con.VK_DOWN:y += 1case win32con.VK_LEFT:x -= 1case win32con.VK_RIGHT:x += 1case win32con.VK_HOME:x = y = 0case win32con.VK_END:x = y = DIVISIONS_CONST - 1case _:return 0x = (x + DIVISIONS_CONST) % DIVISIONS_CONSTy = (y + DIVISIONS_CONST) % DIVISIONS_CONSTidFocus = y << 8 | xuser32.SetFocus(user32.GetDlgItem(hwnd, idFocus))return 0case win32con.WM_DESTROY:user32.PostQuitMessage(0)return 0return win32gui.DefWindowProc(hwnd, msg, wParam, lParam)#定义主窗口类
def defineClass01(wndClass):#---------第一步   初始化类结构-python版本和C语言版本有一定的不同 某些域没有cbClsExtra-----------------------------------------#---------窗口类的作用就是定义窗口的一般性特征 或者通用特征wndClass.style = win32con.CS_HREDRAW | win32con.CS_VREDRAW | win32con.CS_DBLCLKS  #每当窗口水平方向或垂直方向尺寸发生改变后 要完全刷新窗口wndClass.lpfnWndProc = windowProc                           #这个过程要处理基于这个窗口类创建的所有窗口的全部消息  使用函数名 实际引用提供指向函数的指针# wndClass.cbClsExtra=0wndClass.cbWndExtra = 0wndClass.hInstance = win32gui.GetModuleHandle(None)         #程序的实例句柄wndClass.hIcon=win32gui.LoadIcon(None,win32con.IDI_APPLICATION)wndClass.hCursor = win32gui.LoadCursor(None, win32con.IDC_ARROW)    #使用预定义图标 第一个参数为None  使用自定义图片 第一个参数为程序的实例句柄wndClass.hbrBackground =  win32con.COLOR_WINDOW     #win32gui.GetStockObject(win32con.WHITE_BRUSH) 或者获取图像对象#将窗口客户区边界设置为指定颜色wndClass.lpszClassName =szAppNamereturn wndClassdef registerClass02(wndClass):#--------第二步  注册类---------------------------------------------wndClassAtom = win32gui.RegisterClass(wndClass)   #因为python中变量名就是结构体的地址 无须像C语言使用取地址运算符&if(wndClassAtom==0):print("注册失败")sys.exit(0)
def createWindow03(szAppName):hwnd = win32gui.CreateWindow(szAppName, "我的窗口", win32con.WS_OVERLAPPEDWINDOW | 0x00100000 |0x00200000,100, 100, 500, 500, None, None, win32gui.GetModuleHandle(None), None)return hwnd#定义子窗口类
def registerChildClass02(ChildwndClass):ChildwndClass.lpfnWndProc=childWndprocChildwndClass.cbWndExtra =ctypes.sizeof(ctypes.c_long)ChildwndClass.hIcon=0ChildwndClass.lpszClassName=szChildClasswin32gui.RegisterClass(ChildwndClass)def displayAndUpdateWindow04(hwnd):user32.ShowWindow(hwnd, win32con.SW_SHOW)  # 产生一个WM_SIZE消息user32.UpdateWindow(hwnd)  # 产生一个WM_PAINT消息def createMessageStrunctAndSendIntInfo05(hwnd,msg,wParam,lparam):
#-------第五步 创建消息结构体并建立消息循环 -------------------------------user32.SendMessageA(hwnd,win32con.WM_CREATE,wParam,lparam)#发送按键消息 并且按键的虚拟码为0x01=VK_LBUTTONuser32.SendMessageA(hwnd,win32con.WM_KEYDOWN,0X01,lparam)def drawRectangle(hwnd):rect=RECT()user32.SetRect(ctypes.byref(rect),randint(1,500),randint(2,500),randint(1,500),randint(1,500))hBrush=gdi32.CreateSolidBrush(RGB(randint(0,255),randint(0,255),randint(0,255)))hdc=user32.GetDC(hwnd)user32.FillRect(hdc,ctypes.byref(rect),hBrush)user32.ReleaseDC(hwnd,hdc)gdi32.DeleteObject(hBrush)def main():wndClass = win32gui.WNDCLASS()msg = ctypes.wintypes.MSG()wndClass=defineClass01(wndClass)registerClass02(wndClass)hwnd=createWindow03(szAppName)registerChildClass02(wndClass)displayAndUpdateWindow04(hwnd)createMessageStrunctAndSendIntInfo05(hwnd,msg,wParam,lparam)# def mainLoop(msg,):#第六步 自动执行消息队列  msg由操作系统自动生成 传递给你的程序while user32.GetMessageW(ctypes.byref(msg), None, wParam, lparam) != 0:#PeekMessageA在没有消息时返回0  有消息是返回非零if(user32.PeekMessageA(ctypes.byref(msg),None,wParam,lparam,win32con.PM_NOREMOVE)):print("检测自己应用程序收到消息", msg.message, "十六进制", hex(msg.message))match msg.message:case 0x83f1:# match(wParam):#     case win32con.VK_LBUTTON:print("按下有窗口最大化最小化按钮的消息-- -----------")case 0x113:print("收到定时器消息", msg.message, "十六进制", hex(msg.message))passelse:  #没有消息时处理# # print("heoll 这是空闲时间")# drawRectangle(hwnd)# # user32.UpdateWindow(hwnd)passuser32.TranslateMessage(ctypes.byref(msg))user32.DispatchMessageW(ctypes.byref(msg))if __name__ == '__main__':main()

2.    structure1.py

import ctypesHANDLE = ctypes.c_void_pHDC = HANDLEHWND=ctypes.c_void_p
LONG = ctypes.c_long
BOOL = ctypes.c_long
BYTE = ctypes.c_byte
WCHAR = ctypes.c_wchar
UINT = ctypes.c_uint
INT=ctypes.c_int
if ctypes.sizeof(ctypes.c_long) == ctypes.sizeof(ctypes.c_void_p):WPARAM = ctypes.c_ulongLPARAM = ctypes.c_long
elif ctypes.sizeof(ctypes.c_longlong) == ctypes.sizeof(ctypes.c_void_p):WPARAM = ctypes.c_ulonglongLPARAM = ctypes.c_longlongclass RECT(ctypes.Structure):_fields_ = [("left", LONG),("top", LONG),("right", LONG),("bottom", LONG)]
tagRECT = _RECTL = RECTL = RECTclass PAINTSTRUCT(ctypes.Structure):_fields_=[("hdc",HDC),("fErase",BOOL),("rcPaint",RECT),("fRestore",BOOL),("fIncUpdate",BOOL),("rgbReserved",BYTE * 32)]
tagPAINTSTRUCT=PAINTSTRUCTclass TEXTMETRIC(ctypes.Structure):_fields_=[("tmHeight",LONG),("tmAscent",LONG),('tmDescent',LONG),('tmInternalLeading', LONG),('tmExternalLeading',LONG ),('tmAveCharWidth',LONG ),('tmMaxCharWidth',LONG ),('tmWeight',LONG ),('tmOverhang',LONG ),('tmDigitizedAspectX',LONG ),('tmDigitizedAspectY',LONG),('tmFirstChar',WCHAR),('tmLastChar',WCHAR),('tmDefaultChar', WCHAR),('tmBreakChar',WCHAR ),('tmItalic',BYTE ),('tmUnderlined',BYTE ),('tmStruckOut', BYTE ),('tmPitchAndFamily',BYTE),('tmCharSet',BYTE)]
TEXTMETRICW=PTEXTMETRICW=NPTEXTMETRICW=LPTEXTMETRICW=TEXTMETRICclass SCROLLINFO(ctypes.Structure):_fields_=[('cbSize',UINT),   #set to sizeof(SCROLLINFO)('fMask',UINT),    #value to set or get('nMin',INT),      #minimum range value('nMax',INT),      #maximum range value('nPage',UINT),    #page size('nPos',INT),      #current position('nTrackPos',INT)  #current track position]
tagSCROLLINFO=PSCROLLINFO=SCROLLINFOclass WNDPROC(ctypes.Structure):_fields_=[("unnamedParam1",HWND),("namedParam2",UINT),("unnamedParam3",WPARAM),("unnamedParam4",LPARAM)]HINSTANCE=HANDLE
HICON=HANDLE
HCURSOR=HANDLE
HBRUSH=HANDLE
LPCWSTR=HANDLE
class WNDCLASS(ctypes.Structure):_fields_=[("style",UINT),("lpfnWndProc",WNDPROC),("cbClsExtra",ctypes.c_int),("cbWndExtra",ctypes.c_int),("hInstance",HINSTANCE),("hIcon",HICON),("hCursor",HCURSOR),('hbrBackground',HBRUSH),('lpszMenuName',LPCWSTR),('lpszClassName',LPCWSTR)]class POINT(ctypes.Structure):_fields_ = [("x", LONG),("y", LONG)]tagPOINT = _POINTL = POINTL = POINT#演示 验证初始化后是否正确打印每个域的值
p=PAINTSTRUCT(1111,1)COLORREF=ctypes.c_uint32
class LOGPEN(ctypes.Structure):_fields_=[('lopnStyle',UINT),('lopnWidth',POINT),('lopnColor',COLORREF)]
PLOGPEN=NPLOGPEN=LPLOGPEN=LOGPENprint(p.hdc,p.fErase)
print(ctypes.sizeof(SCROLLINFO))class pythonArrayD2():def __init__(self,rows,columns):assert isinstance(rows,int),"参数必须是正整数"assert isinstance(rows, int), "参数必须是正整数"self.rows=rowsself.columns=columnsself.Values={}self.Values=self.initValues()def initValues(self):for i in range(self.rows):for j in range(self.columns):self.Values[str(i)+','+str(j)]=0return self.Values

3.   microDefine1.py

def LOWORD(x):return x & 0xffff
def HOWORD(x):return (x>>16) & 0xffff
def MAX(a,b):if a>b:return aelse:return b
def MIN(a,b):if a<b:return aelse:return b
def RGB(red,green,blue):assert isinstance(red,(int,float)),"必须输入整数"assert isinstance(green, (int, float)), "必须输入整数"assert isinstance(green, (int, float)), "必须输入整数"red=int(red)green=int(green)blue=int(blue)if red>255:red=min(red,255)if red<0:red=max(0,red)if green>255:green=min(green,255)if green<0:green=max(0,green)if blue>255:blue=min(blue,255)if blue<0:blue=max(0,blue)return blue*(1<<16)+green*(1<<8)+red

4  这个文件只是给出一种思路 ,可以不用 仅供参考   win32con1.py

DIVISIONS_CONST=5
WM_CREATE=1
DIVISIONS_CONST=5
NULL=None
WS_CHILDWINDOW=1073741824
WS_VISIBLE=268435456
GWL_HINSTANCE=-6
WM_SIZE=5
WM_LBUTTONDOWN=513
WM_SETFOCUS=7

以下是Windows源码  世界著名技术作家Charles Petzold编写的 所以参考价值极高

/*-------------------------------------------------
   CHECKER4.C -- Mouse Hit-Test Demo Program No. 4
                 (c) Charles Petzold, 1998
  -------------------------------------------------*/

#include <windows.h>

#define DIVISIONS 5

LRESULT CALLBACK WndProc   (HWND, UINT, WPARAM, LPARAM) ;
LRESULT CALLBACK ChildWndProc (HWND, UINT, WPARAM, LPARAM) ;

int   idFocus = 0 ;
TCHAR szChildClass[] = TEXT ("Checker4_Child") ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("Checker4") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;
     
     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;
     
     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("Program requires Windows NT!"), 
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }
     
     wndclass.lpfnWndProc   = ChildWndProc ;
     wndclass.cbWndExtra    = sizeof (long) ;
     wndclass.hIcon         = NULL ;
     wndclass.lpszClassName = szChildClass ;
     
     RegisterClass (&wndclass) ;
     
     hwnd = CreateWindow (szAppName, TEXT ("Checker4 Mouse Hit-Test Demo"),
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;
     
     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;
     
     while (GetMessage (&msg, NULL, 0, 0))
     {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
     }
     return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     static HWND hwndChild[DIVISIONS][DIVISIONS] ;
     int         cxBlock, cyBlock, x, y ;
     
     switch (message)
     {
     case WM_CREATE :
          for (x = 0 ; x < DIVISIONS ; x++)
               for (y = 0 ; y < DIVISIONS ; y++)
                    hwndChild[x][y] = CreateWindow (szChildClass, NULL,
                              WS_CHILDWINDOW | WS_VISIBLE,
                              0, 0, 0, 0,
                              hwnd, (HMENU) (y << 8 | x),
                              (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE),
                              NULL) ;
          return 0 ;
               
     case WM_SIZE :
          cxBlock = LOWORD (lParam) / DIVISIONS ;
          cyBlock = HIWORD (lParam) / DIVISIONS ;
          
          for (x = 0 ; x < DIVISIONS ; x++)
                for (y = 0 ; y < DIVISIONS ; y++)
                    MoveWindow (hwndChild[x][y],
                                x * cxBlock, y * cyBlock,
                                cxBlock, cyBlock, TRUE) ;
          return 0 ;
                       
     case WM_LBUTTONDOWN :
          MessageBeep (0) ;
          return 0 ;

          // On set-focus message, set focus to child window

     case WM_SETFOCUS:
          SetFocus (GetDlgItem (hwnd, idFocus)) ;
          return 0 ;

          // On key-down message, possibly change the focus window

     case WM_KEYDOWN:
          x = idFocus & 0xFF ;
          y = idFocus >> 8 ;

          switch (wParam)
          {
          case VK_UP:    y-- ;                    break ;
          case VK_DOWN:  y++ ;                    break ;
          case VK_LEFT:  x-- ;                    break ;
          case VK_RIGHT: x++ ;                    break ;
          case VK_HOME:  x = y = 0 ;              break ;
          case VK_END:   x = y = DIVISIONS - 1 ;  break ;
          default:       return 0 ;
          }

          x = (x + DIVISIONS) % DIVISIONS ;
          y = (y + DIVISIONS) % DIVISIONS ;

          idFocus = y << 8 | x ;

          SetFocus (GetDlgItem (hwnd, idFocus)) ;
          return 0 ;

     case WM_DESTROY :
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}

LRESULT CALLBACK ChildWndProc (HWND hwnd, UINT message, 
                               WPARAM wParam, LPARAM lParam)
{
     HDC         hdc ;
     PAINTSTRUCT ps ;
     RECT        rect ;
     
     switch (message)
     {
     case WM_CREATE :
          SetWindowLong (hwnd, 0, 0) ;       // on/off flag
          return 0 ;

     case WM_KEYDOWN:
               // Send most key presses to the parent window
          
          if (wParam != VK_RETURN && wParam != VK_SPACE)
          {
               SendMessage (GetParent (hwnd), message, wParam, lParam) ;
               return 0 ;
          }
               // For Return and Space, fall through to toggle the square
          
     case WM_LBUTTONDOWN :
          SetWindowLong (hwnd, 0, 1 ^ GetWindowLong (hwnd, 0)) ;
          SetFocus (hwnd) ;
          InvalidateRect (hwnd, NULL, FALSE) ;
          return 0 ;

               // For focus messages, invalidate the window for repaint
          
     case WM_SETFOCUS:
          idFocus = GetWindowLong (hwnd, GWL_ID) ;

               // Fall through

     case WM_KILLFOCUS:
          InvalidateRect (hwnd, NULL, TRUE) ;
          return 0 ;
          
     case WM_PAINT :
          hdc = BeginPaint (hwnd, &ps) ;
          
          GetClientRect (hwnd, &rect) ;
          Rectangle (hdc, 0, 0, rect.right, rect.bottom) ;

               // Draw the "x" mark
          
          if (GetWindowLong (hwnd, 0))
          {
               MoveToEx (hdc, 0,          0, NULL) ;
               LineTo   (hdc, rect.right, rect.bottom) ;
               MoveToEx (hdc, 0,          rect.bottom, NULL) ;
               LineTo   (hdc, rect.right, 0) ;
          }

               // Draw the "focus" rectangle
          
          if (hwnd == GetFocus ())
          {
               rect.left   += rect.right / 10 ;
               rect.right  -= rect.left ;
               rect.top    += rect.bottom / 10 ;
               rect.bottom -= rect.top ;

               SelectObject (hdc, GetStockObject (NULL_BRUSH)) ;
               SelectObject (hdc, CreatePen (PS_DASH, 0, 0)) ;
               Rectangle (hdc, rect.left, rect.top, rect.right, rect.bottom) ;
               DeleteObject (SelectObject (hdc, GetStockObject (BLACK_PEN))) ;
          }

          EndPaint (hwnd, &ps) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}
 

最后是python和C语言演示效果图

python 

c语言效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/217560.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为OD机试真题B卷 Java 实现【统计大写字母个数】,附详细解题思路

一、题目描述 找出给定字符串中大写字符(即’A’-‘Z’)的个数。 数据范围&#xff1a;字符串长度&#xff1a;1≤∣s∣≤250 字符串中可能包含空格或其他字符 二、输入描述 对于每组样例&#xff0c;输入一行&#xff0c;代表待统计的字符串。 三、输出描述 输出一个整…

【css】css实现文字两端对齐效果:

文章目录 一、方法1&#xff1a;二、方法2&#xff1a;三、注意&#xff1a; 一、方法1&#xff1a; 给元素设置 text-align: justify;text-align-last: justify;并且加上text-justify: distribute-all-line; 目的是兼容ie浏览器 p{width: 130px;text-align: justify;text-alig…

飞天使-linux操作的一些技巧与知识点3-http的工作原理

文章目录 http工作原理nginx的正向代理和反向代理的区别一个小技巧dig 命令巧用 http工作原理 http1.0 协议 使用的是短连接&#xff0c;建立一次tcp连接&#xff0c;发起一次http的请求&#xff0c;结束&#xff0c;tcp断开 http1.1 协议使用的是长连接&#xff0c;建立一次tc…

Network 灰鸽宝典【目录】

目前已有文章 21 篇 Network 灰鸽宝典专栏主要关注服务器的配置&#xff0c;前后端开发环境的配置&#xff0c;编辑器的配置&#xff0c;网络服务的配置&#xff0c;网络命令的应用与配置&#xff0c;windows常见问题的解决等。 文章目录 服务配置环境部署GitNPM 浏览器编辑器系…

GEE:重分类

作者:CSDN @ _养乐多_ 本文记录了在 Google Earth Engine(GEE)平台上对一副类别图像进行重分类的代码。并以 COPERNICUS/Landcover/100m/Proba-V-C3/Global 数据集中的土地利用数据为例。 结果如下图所示, 文章目录 一、核心函数二、示例代码三、代码链接一、核心函数 核…

文件操作及函数

什么是文件&#xff1f; 在程序设计中&#xff0c;文件有两种&#xff1a;程序文件和数据文件。 程序文件 包括源程序文件&#xff08;.c&#xff09;&#xff0c;目标文件&#xff08;.obj&#xff09;&#xff0c;可执行程序(.exe)。 数据文件 文件的内容不一定是程序&…

linux下部署frp客户端服务端-内网穿透

简介 部署在公司内部局域网虚拟机上的服务需要在外网能够访问到&#xff0c;这不就是内网穿透的需求吗&#xff0c;之前通过路由器实现过&#xff0c;现在公司这块路由器不具备这个功能了&#xff0c;目前市面上一些主流的内网穿透工具有&#xff1a;Ngrok&#xff0c;Natapp&…

Docker镜像构建:深入Dockerfile创建自定义镜像

Docker的强大之处在于其能够通过Dockerfile定义和构建自定义镜像&#xff0c;为应用提供独立、可移植的运行环境。在这篇博客文章中&#xff0c;将深入探讨Docker镜像构建的核心概念&#xff0c;通过更加丰富的示例代码&#xff0c;帮助大家全面理解和掌握构建自定义镜像的技术…

深度学习在人体动作识别领域的应用:开源工具、数据集资源及趋动云GPU算力不可或缺

人体动作识别检测是一种通过使用计算机视觉和深度学习技术&#xff0c;对人体姿态和动作进行实时监测和分析的技术。该技术旨在从图像或视频中提取有关人体姿态、动作和行为的信息&#xff0c;以便更深入地识别和理解人的活动。 人体动作识别检测的基本步骤包括&#xff1a; 数…

关于MySQL的bigint问题

MySQL的bigint(8)能存多大数值&#xff1f; MySQL的BIGINT(8)可以存储的数值范围是从-9,223,372,036,854,775,808到9,223,372,036,854,775,807。这是因为BIGINT数据类型在MySQL中使用8字节进行存储&#xff0c;每个字节有8位&#xff0c;所以总共可以表示2^64个不同的整数。 …

IDEA 出现问题:git提交commit时Perform code analysis卡住解决方案

问题 git提交commit时Perform code analysis卡住很久 解决方案一 1、打开 IntelliJ IDEA&#xff0c;进入 File -> Settings&#xff08;或者使用快捷键 CtrlAltS&#xff09;。 2、在弹出的 Settings 窗口中&#xff0c;找到 Version Control -> Commit Dialog 选项…

什么是数字化营销?如何进行数字化营销?数字化有多重要?

引言 数字化营销是一种利用数字技术和在线平台来促进产品或服务销售的策略。它包括利用各种数字渠道&#xff0c;如社交媒体、搜索引擎优化、内容营销和数据分析等&#xff0c;与目标受众建立联系并推动销售。 在当今商业环境中&#xff0c;数字化营销扮演着至关重要的角色。…

阿里云国际版无法远程连接Windows服务器的排查方法

如果您遇到紧急情况&#xff0c;需要尽快登录Windows实例&#xff0c;请参见以下操作步骤&#xff0c;先检查ECS实例的状态&#xff0c;然后通过云助手向Windows实例发送命令或通过VNC登录实例&#xff0c;具体步骤如下&#xff1a; 步骤一&#xff1a;检查ECS实例状态 无论何…

SpringBoot之请求的详细解析

1. 请求 在本章节呢&#xff0c;我们主要讲解&#xff0c;如何接收页面传递过来的请求数据。 1.1 Postman 之前我们课程中有提到当前最为主流的开发模式&#xff1a;前后端分离 在这种模式下&#xff0c;前端技术人员基于"接口文档"&#xff0c;开发前端程序&…

智能优化算法应用:基于萤火虫算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于萤火虫算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于萤火虫算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.萤火虫算法4.实验参数设定5.算法结果6.参考文…

Unity检测AssetBundle是否循环依赖

原理&#xff1a;bundle的依赖关系构建一个二维的矩阵图&#xff0c;如果对角线相互依赖&#xff08;用1标记&#xff09;则表示循环依赖。 using PlasticGui; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; public cl…

单变量线性回归的机器学习代码

本文为学习吴恩达版本机器学习教程的代码整理&#xff0c;使用的数据集为https://github.com/fengdu78/Coursera-ML-AndrewNg-Notes/blob/f2757f85b99a2b800f4c2e3e9ea967d9e17dfbd8/code/ex1-linear%20regression/ex1data1.txt 将数据集和py代码放到同一目录中&#xff0c;使…

如何合理运用蚂蚁SEO蜘蛛池

蜘蛛池是一种搜索引擎优化&#xff08;SEO&#xff09;技术&#xff0c;它通过将多个网站连接到一个池子中&#xff0c;从而提高这些网站的搜索引擎排名。然而&#xff0c;合理运用蜘蛛池需要一定的技巧和策略&#xff0c;否则可能会适得其反。 如何联系蚂蚁seo&#xff1f; …

Java+SSM+MySQL基于微信的在线协同办公小程序(附源码 调试 文档)

基于微信的在线协同办公小程序 一、引言二、系统设计三、技术架构四、管理员功能设计五、员工功能设计六、系统实现七、界面展示八、源码获取 一、引言 随着科技的飞速发展&#xff0c;移动互联网已经深入到我们生活的各个角落。在这个信息时代&#xff0c;微信作为全球最大的…

电子学会C/C++编程等级考试2022年09月(五级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:城堡问题 1 2 3 4 5 6 7 ############################# 1 # | # | # | | # #####---#####---#---#####---# 2 # # | # # # # # #---#####---#####---#####---# 3 # | | # # # # # #---#########---#####---#---# 4 # # | | | …