您尚未登录。

#3 Re: 计算机图形/GUI/RTOS/FileSystem/OpenGL/DirectX/SDL2 » 一个不错的LVGL Builder设计器 » 2020-01-16 22:34:01

windows下 Qt5.12 可以编译通过, 谢谢楼主推荐, 用来学习 Qt 编程也很不错.

#7 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 再来水一帖, ubuntu & win32 编译 librecad » 2020-01-07 15:10:39

windows 编译稍复杂一点, 不过也挺省心的.

1. 下载 boost sdk:
https://www.boost.org/users/download/
https://dl.bintray.com/boostorg/release/1.72.0/source/boost_1_72_0.7z

2. 解压, 我的解压路径是 D:\Downloads\boost_1_72_0

3. 设置环境变量 BOOST_DIR, 值为 D:\Downloads\boost_1_72_0

4. 克隆源码:
git clone https://github.com/LibreCAD/LibreCAD.git

5. 编译:
qtcreator.exe 打开 librecad.pro 工程, 直接按编译即可,约20分钟可以编译完成。

2020-01-07_150916.png

#11 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 再来水一帖, ubuntu & win32 编译 librecad » 2020-01-07 14:40:10

ubuntu 编译:

1.  准备工作:
sudo apt install libboost-dev qt5-default -y

2. 克隆源码:
git clone https://github.com/LibreCAD/LibreCAD.git

3. 编译:
cd LibreCAD
qmake librecad.pro
make

#14 Re: 全志 SOC » 编译、安装Windows版本sunxi-fel步骤 (32M spi flash补丁,支持W25Q256/MX25L256) » 2020-01-07 11:55:01

这个可以的: https://whycan.cn/t_444.html




以下是 2018-12-19 更新 (16楼):

为了不再给大家造成困扰,我把文件重新整理了 V3s 和 F1C100s 两个文件夹,

欢迎下载测试: sunxi-tools-win32support_f1c100s_v3s_201812219.7z

#19 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » MSVC的 NuGet 包管理器真香!首先跑个 opengl 测试程序试一试 » 2020-01-07 10:52:07

smartcar 说:

这么吊,我也学学。

互相学习!



2020-01-07_105005.png

#include <SDL.h>
#include <SDL_opengl.h>

#include <stdlib.h> //rand()

#pragma comment(lib, "OpenGL32.Lib")
#pragma comment(lib, "SDL2main.lib")

#undef main

//SDL2 flashing random color example
//Should work on iOS/Android/Mac/Windows/Linux

static bool quitting = false;
static float r = 0.0f;
static SDL_Window *window = NULL;
static SDL_GLContext gl_context;


void render() {

	SDL_GL_MakeCurrent(window, gl_context);

	r = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);

	glClearColor(r, 0.4f, 0.1f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT);

	SDL_GL_SwapWindow(window);

} //render


int SDLCALL watch(void *userdata, SDL_Event* event) {

	if (event->type == SDL_APP_WILLENTERBACKGROUND) {
		quitting = true;
	}

	return 1;
}

int main(int argc, char *argv[]) {


	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) {
		SDL_Log("Failed to initialize SDL: %s", SDL_GetError());
		return 1;
	}

	window = SDL_CreateWindow("title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 512, 512, SDL_WINDOW_OPENGL);

	gl_context = SDL_GL_CreateContext(window);

	SDL_AddEventWatch(watch, NULL);


	while (!quitting) {

		SDL_Event event;
		while (SDL_PollEvent(&event)) {
			if (event.type == SDL_QUIT) {
				quitting = true;
			}
		}

		render();
		SDL_Delay(2);

	}

	SDL_DelEventWatch(watch, NULL);
	SDL_GL_DeleteContext(gl_context);
	SDL_DestroyWindow(window);
	SDL_Quit();

	exit(0);

} //main

https://gist.github.com/underscorediscovery/46e4f5b4e3e6de7ad50d

2020-01-07_105209.png

三下五除二搞定了sdl2 demo.

#20 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » MSVC的 NuGet 包管理器真香!首先跑个 opengl 测试程序试一试 » 2020-01-07 10:30:47

2020-01-07_103011.png


也可以使用静态链接:

#pragma comment(lib, "glfw3.lib")
#pragma comment(lib, "OpenGL32.Lib")

#22 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » MSVC的 NuGet 包管理器真香!首先跑个 opengl 测试程序试一试 » 2020-01-07 10:21:29

打开 glfw 官网: https://www.glfw.org/docs/3.1/quick.html

找到那个三角形 demo 程序

#include <GLFW/glfw3.h>
#include <stdlib.h>
#include <stdio.h>
static void error_callback(int error, const char* description)
{
    fputs(description, stderr);
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);
}
int main(void)
{
    GLFWwindow* window;
    glfwSetErrorCallback(error_callback);
    if (!glfwInit())
        exit(EXIT_FAILURE);
    window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);
    glfwSetKeyCallback(window, key_callback);
    while (!glfwWindowShouldClose(window))
    {
        float ratio;
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        ratio = width / (float) height;
        glViewport(0, 0, width, height);
        glClear(GL_COLOR_BUFFER_BIT);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glRotatef((float) glfwGetTime() * 50.f, 0.f, 0.f, 1.f);
        glBegin(GL_TRIANGLES);
        glColor3f(1.f, 0.f, 0.f);
        glVertex3f(-0.6f, -0.4f, 0.f);
        glColor3f(0.f, 1.f, 0.f);
        glVertex3f(0.6f, -0.4f, 0.f);
        glColor3f(0.f, 0.f, 1.f);
        glVertex3f(0.f, 0.6f, 0.f);
        glEnd();
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwDestroyWindow(window);
    glfwTerminate();
    exit(EXIT_SUCCESS);
}

有链接错误, 所以中间添加两行:

#pragma comment(lib, "glfw3dll.lib")
#pragma comment(lib, "OpenGL32.Lib")

#23 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » MSVC的 NuGet 包管理器真香!首先跑个 opengl 测试程序试一试 » 2020-01-07 10:19:30

2020-01-07_101705.png

nuget 安装 gflw 包, 否则需要去这里下载 https://www.glfw.org/download.html

下载预编译的win32 sdk 包, 添加头文件和库文件, 手续繁琐.

#26 Re: 全志 SOC » 编译、安装Windows版本sunxi-fel步骤 (32M spi flash补丁,支持W25Q256/MX25L256) » 2020-01-07 09:09:56

去掉 ./ 就可以了, windows 的命令行解析器不支持这玩意吧。

#27 Re: 技术人生/软件使用技巧/破解经验/技术吐槽/灌水 » 从淘宝网购买时要小心 » 2020-01-06 17:34:54

@小智 保加利亚确定能单挑中国一个省?越南GDP也才和广西相当,就被吹上天了。

#34 Re: DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » 第一次见到这种急停开关, 按下急停后, 要顺时钟旋转约30度才能解锁. » 2020-01-06 16:26:15

没见过这玩意, 应该是为了安全考虑。
只记得以前公司隔壁的五金厂,听说过几起机床事故,很惨的。

#35 Re: 全志 SOC » 看f1c100s裸奔程序受到的启发 » 2020-01-06 16:24:38

现在的模式, linux 和 dtb 是单独打包的, 我记得 openwrt 是打包到一起的, 不知道f1c100s能不能这样操作?

#36 Re: 技术人生/软件使用技巧/破解经验/技术吐槽/灌水 » 从淘宝网购买时要小心 » 2020-01-06 16:23:25

@Mitko 强烈建议不要上淘宝, 也不要购买任何中国的产品, 会影响你的心情,也会影响我们的心情。

#37 Re: 全志 SOC » 关于全志H3的secure Boot » 2020-01-06 15:51:59

估计难了, 熔丝一般是一次性的, 就是 opt 一次性编程区域。

#38 Re: DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » 晕,开源版本的qcad兼容性太差了, 他的收费版本还行. » 2020-01-06 15:51:15

达克罗德 说:

已经用它给公司画了个CNC的支架了,用着还好。不兼容是指?

开源版本打不开某些 autocad 版本制作的 dxf 文件。

#44 Re: 全志 SOC » V3s buildroot 一键生成打包生成32M spi flash 镜像, jffs2 文件系统, 默认启动 Qt 模拟时钟demo, » 2020-01-06 11:54:37

yuanlwjt 说:

[1024*600分辨率RGB接口】正点原子7寸RGB电容触摸液晶屏模块  难道是这种?

对, 是这个: https://detail.tmall.com/item.htm?id=609758563397

标准 50pin 排线接口。

#45 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 用一用 dxflib 读/写 dxf 文件 » 2020-01-06 11:49:55

公司用的 dxf 解析库各种问题, 发现 qcad 用的就是 dxflib 相当完善, 所以打算强怼 dxflib 了。

#46 Re: 全志 SOC » 全志 A10/A20/A33/H3/A64/H5 等的主线Linux也可以使用 OpenGL ES, 有没有哪位朋友测试过? » 2020-01-06 11:48:57

达克罗德 说:

浏览器不是用OpenGL吗?说明跑起来了?

浏览器可以不需要opengl, 只是太慢了: https://whycan.cn/t_3287.html#p28404

#47 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 用一用 dxflib 读/写 dxf 文件 » 2020-01-06 11:47:32

找到的第一份代码 https://github.com/Luckyxcj/dxflib

是一个调用 dxflib 库写 dxf 文件,

#include <QCoreApplication>
#include <QDebug>
#include "src/dl_dxf.h"
#include "src/dl_creationadapter.h"
#include "src/dl_attributes.h"
#include "src/dl_codes.h"
#include "src/dl_entities.h"
#include "src/dl_exception.h"
#include "src/dl_global.h"
#include "src/dl_writer.h"
#include "src/dl_writer_ascii.h"
#include <QList>
#include <QString>
#include <QFile>



int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QFile file("myfile.dxf");
    if(file.exists())
    {
        file.remove();
        qDebug()<<"DEL dxf";
    }


#if 1

    DL_Dxf dxf;
    DL_Codes::version exportVersion = DL_Codes::AC1015;
    DL_WriterA* dw = dxf.out("myfile.dxf", exportVersion);
    if (dw==NULL)
    {
        printf("Cannot open file 'myfile.dxf' \
            for writing.");
        // abort function e.g. with return
    }

#if 1
    // int variable:
    //单位
    dw->dxfString(9, "$INSUNITS");
    dw->dxfInt(70, 4);
    // real (double, float) variable:
    dw->dxfString(9, "$DIMEXE");
    dw->dxfReal(40, 1.25);
    // string variable:
    dw->dxfString(9, "$TEXTSTYLE");
    dw->dxfString(7, "Standard");
    // vector variable:
    dw->dxfString(9, "$LIMMIN");
    dw->dxfReal(10, 0.0);
    dw->dxfReal(20, 0.0);
#endif
    //关闭header
    dw->sectionEnd();

    //写tablesection
    //.1 打开tables section
    dw->sectionTables();
    //.2 写viewports
    dxf.writeVPort(*dw);
    //.3写linetypes
    dw->tableLinetypes(25);

    dxf.writeLinetype(*dw, DL_LinetypeData("BYBLOCK","",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("BYLAYER","",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("CONTINUOUS","",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("ACAD_ISO02W100", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("ACAD_ISO03W100", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("ACAD_ISO04W100", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("ACAD_ISO05W100", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("BORDER", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("BORDER2", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("BORDERX2", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("CENTER", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("CENTER2", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("CENTERX2", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("DASHDOT", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("DASHDOT2", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("DASHDOTX2", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("DASHED", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("DASHED2", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("DASHEDX2", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("DIVIDE", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("DIVIDE2", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("DIVIDEX2","",0,0, 0));
    dxf.writeLinetype(*dw, DL_LinetypeData("DOT", "",0,0,0));
    dxf.writeLinetype(*dw, DL_LinetypeData("DOT2","",0,0, 0));
    dxf.writeLinetype(*dw, DL_LinetypeData("DOTX2", "",0,0,0));

    dw->tableEnd();

    //.4写layers 0不可以省略
    int numberOfLayers = 3;

    dw->tableLayers(numberOfLayers);

    dxf.writeLayer(*dw,
        DL_LayerData("0", 0),
        DL_Attributes( std::string(""),
                       DL_Codes::red,
                       -1,
                       100,
                       "BYLAYER"
                       ));     // default line style

    dxf.writeLayer(*dw,
        DL_LayerData("mainlayer", 0),
        DL_Attributes());//CONTINUOUS

    dxf.writeLayer(*dw,
        DL_LayerData("anotherlayer", 0),
        DL_Attributes());

    dw->tableEnd();
    //.5其他tables 不必要
  //  dxf.writeStyle(*dw,DL_StyleData());

    //。6写dimension styles
    dxf.writeDimStyle(*dw,
                      1,
                      1,
                      1,
                      1,
                      1);

    dxf.writeBlockRecord(*dw);
#if 1
    dxf.writeBlockRecord(*dw, "myblock1");
    dxf.writeBlockRecord(*dw, "myblock2");
#endif
    dw->tableEnd();
    //.7结束tables section
    dw->sectionEnd();
    //写blocks section
    dw->sectionBlocks();

    dxf.writeBlock(*dw,
        DL_BlockData("*Model_Space", 0, 0.0, 0.0, 0.0));
    dxf.writeEndBlock(*dw, "*Model_Space");

    dxf.writeBlock(*dw,
        DL_BlockData("*Paper_Space", 0, 0.0, 0.0, 0.0));
    dxf.writeEndBlock(*dw, "*Paper_Space");

    dxf.writeBlock(*dw,
        DL_BlockData("*Paper_Space0", 0, 0.0, 0.0, 0.0));
    dxf.writeEndBlock(*dw, "*Paper_Space0");

    dxf.writeBlock(*dw,
        DL_BlockData("myblock1", 0, 0.0, 0.0, 0.0));

    // ...
    // write block entities e.g. with dxf.writeLine(), ..
    // ...
    dxf.writeEndBlock(*dw, "myblock1");

    dxf.writeBlock(*dw,
        DL_BlockData("myblock2", 0, 0.0, 0.0, 0.0));

    // ...
    // write block entities e.g. with dxf.writeLine(), ..
    // ...
    dxf.writeEndBlock(*dw, "myblock2");

    dw->sectionEnd();

    //写entities section
    dw->sectionEntities();

    // write all your entities..

    dxf.writePoint(*dw,
        DL_PointData(10.0, 45.0, 0.0),
        DL_Attributes());//"mainlayer", 256, -1, "BYLAYER"

    dxf.writeLine(*dw,
        DL_LineData(25.0, 30.0, 0.0,   // start point
                 100.0, 120.0, 0.0),   // end point
        //DL_Attributes("mainlayer", 256, -1, "BYLAYER"));
                  DL_Attributes());
    dxf.writeArc(*dw,
                 DL_ArcData(50.0,50.0,0.0,
                            20,0.0,20),
                 DL_Attributes(std::string(""),
                               DL_Codes::red,
                               -1,
                               100,
                               "BYLAYER"
                               ));

    dxf.writeCircle(*dw,DL_CircleData(50.0,50.0,5.0,20.0),
                    DL_Attributes(std::string(""),
                                  DL_Codes::red,
                                  -1,
                                  1,
                                  "BYLAYER"
                                  ));

    dw->sectionEnd();
    //写objects section
    dxf.writeObjects(*dw);
    dxf.writeObjectsEnd(*dw);
    //结束
    dw->dxfEOF();
    dw->close();
    delete dw;
#endif
    qDebug()<< "end"<<endl;
    return a.exec();
}

2020-01-06_113858.png

#52 Re: 全志 SOC » 分享个licheepi nano镜像,支持adb调试 » 2020-01-03 19:52:50

看下用的是不是 micro usb线, usb id 有没有上拉/下拉.

#55 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 找到一个 win32 gdi & cairo 绘图引擎的 demo » 2020-01-01 23:30:36

QQ截图20200101232910.png

static void do_drawing(cairo_t *cr)
{
  cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
  cairo_set_line_width(cr, 1);

  cairo_rectangle(cr, 20, 20, 120, 80);
  cairo_rectangle(cr, 180, 20, 80, 80);
  cairo_stroke_preserve(cr);
  cairo_fill(cr);

  cairo_arc(cr, 330, 60, 40, 0, 2*M_PI);
  cairo_stroke_preserve(cr);
  cairo_fill(cr);

  cairo_arc(cr, 90, 160, 40, M_PI/4, M_PI);
  cairo_close_path(cr);
  cairo_stroke_preserve(cr);
  cairo_fill(cr);

  cairo_translate(cr, 220, 180);
  cairo_scale(cr, 1, 0.7);
  cairo_arc(cr, 0, 0, 50, 0, 2*M_PI);
  cairo_stroke_preserve(cr);
  cairo_fill(cr);
}

http://zetcode.com/gfx/cairo/shapesfills/

#58 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 找到一个 win32 gdi & cairo 绘图引擎的 demo » 2020-01-01 23:19:53

QQ截图20200101232025.png

/**
cairo-gdi-demo.cpp

Demonstrates how to get Cairo Graphics working with the Windows API and GDI.
                     
Author: Andrew Lim
Email:  danteshamest@gmail.com
Site: windrealm.com
*/
#include <windows.h>
#include <cmath>
#include "cairo-win32.h"

/**
  Gradient demonstration.
  Taken from http://cairographics.org/samples/
*/
void gradientExample( cairo_t* cr ) {
  cairo_pattern_t *pat;

  pat = cairo_pattern_create_linear (0.0, 0.0,  0.0, 256.0);
  cairo_pattern_add_color_stop_rgba (pat, 1, 0, 0, 0, 1);
  cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1);
  cairo_rectangle (cr, 0, 0, 256, 256);
  cairo_set_source (cr, pat);
  cairo_fill (cr);
  cairo_pattern_destroy (pat);

  pat = cairo_pattern_create_radial (115.2, 102.4, 25.6,
                                     102.4,  102.4, 128.0);
  cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1);
  cairo_pattern_add_color_stop_rgba (pat, 1, 0, 0, 0, 1);
  cairo_set_source (cr, pat);
  cairo_arc (cr, 128.0, 128.0, 76.8, 0.0, 2 * 3.1415);
  cairo_fill (cr);
  cairo_pattern_destroy (pat);
}

/**
  Changes the dimensions of a window's client area.
*/
void SetClientSize( HWND hwnd, int clientWidth, int clientHeight ) {
  if ( IsWindow( hwnd ) ) {
    DWORD dwStyle = GetWindowLongPtr( hwnd, GWL_STYLE ) ;
    DWORD dwExStyle = GetWindowLongPtr( hwnd, GWL_EXSTYLE ) ;
    HMENU menu = GetMenu( hwnd ) ;
    RECT rc = { 0, 0, clientWidth, clientHeight } ;
    AdjustWindowRectEx( &rc, dwStyle, menu ? TRUE : FALSE, dwExStyle );
    SetWindowPos( hwnd, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
                  SWP_NOZORDER | SWP_NOMOVE ) ;
  }
}

/**
  Handles WM_PAINT.
*/
LRESULT onPaint( HWND hwnd, WPARAM wParam, LPARAM lParam ) {
  PAINTSTRUCT ps ;
  HDC hdc = BeginPaint( hwnd, &ps );

  // Create the cairo surface and context.
  cairo_surface_t *surface = cairo_win32_surface_create (hdc);
  cairo_t *cr = cairo_create (surface);
  
  // Draw on the cairo context.
  gradientExample( cr );

  // Cleanup.
  cairo_destroy (cr);
  cairo_surface_destroy (surface);

  EndPaint( hwnd, &ps );
  return 0 ;
}

/**
  Handles WM_CLOSE.
*/
LRESULT onClose( HWND hwnd, WPARAM wParam, LPARAM lParam ) {
  PostQuitMessage( 0 );
  return 0 ;
}

/**
  Handles our window's messages.
*/
LRESULT CALLBACK WndProc( HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam ) {
  switch(msg) {
    case WM_PAINT: return onPaint( hwnd, wParam, lParam );
    case WM_CLOSE: return onClose( hwnd, wParam, lParam );
    default: return DefWindowProc(hwnd,msg,wParam,lParam);
  }
}

int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrev, LPSTR args, int nShow ) {
  MSG  msg ;
  WNDCLASS wc = {0};
  wc.lpszClassName = TEXT( "CairoGdiWndClass" );
  wc.hInstance     = hInst ;
  wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
  wc.lpfnWndProc   = WndProc ;
  wc.hCursor       = LoadCursor(0,IDC_ARROW);

  RegisterClass(&wc);
  HWND hwnd = CreateWindow( wc.lpszClassName,TEXT("Cairo & GDI Demo"),
                            WS_OVERLAPPEDWINDOW, 0,0,256,256,0,0,hInst,0);
  SetClientSize( hwnd, 256, 256 );
  ShowWindow( hwnd, SW_SHOWNORMAL );

  while( GetMessage(&msg,0,0,0) > 0 ) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return (int)msg.wParam;
}

费了九牛二虎之力才搞定的VC2017版本: cairo-gdi-demo.7z

#59 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 找到一个 win32 gdi & cairo 绘图引擎的 demo » 2020-01-01 23:06:38

原作者是用 dev-cpp 编译的, 但是我下载了这个版本,链接失败: https://whycan.cn/t_2789.html#p22710

下载地址: Dev-Cpp 5.11 TDM-GCC 4.9.2 Setup.exe

用这个版本会链接错误.

#61 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 再发一个简单的 MFC 开源 DXF 阅读器 » 2019-12-27 10:02:02

达克罗德 说:

不错,有源码可以diy

源码给大家整理好了.

我编译的Release可执行程序,应该不依赖第三方dll: DXF_Viewer_Release.7z

我修改过的VC2017源码: CadLib.7z

#62 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 再发一个简单的 MFC 开源 DXF 阅读器 » 2019-12-27 09:03:06

2019-12-27_090215.png

VC2017 编译运行 OK, 打开树莓派 dxf 文件顺利,放大/缩小也很流畅。

#63 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 再发一个简单的 MFC 开源 DXF 阅读器 » 2019-12-27 09:01:28

源码应该是 MSVC6 的版本的, 在现在的新版要修改好几处才能编译通过.

字符编码也是古老的本地编码,

看了一下作者是伊朗人, 我用 notepad++ 先选阿拉伯语 windows-1256,

然后强转为 utf-8, 就正常了。

2019-12-27_085840.png

#66 Re: 全志 SOC » 【这是一个看完你会回复握草的帖子】 开源项目,Linux名片,使用全志f1c100s » 2019-12-25 13:38:24

mango 说:

起初我以为背面会是一个极薄的电子纸。有待作者填坑。

电子纸和墨水屏是一个原理吗?

#67 Re: NXP i.MX6UL/6ULL » i.mx6ulz批量低至20元 » 2019-12-25 09:19:15

wujique 说:

不是每个人都会安卓。。。

安卓开发门槛低,一台电脑,一台手机搞定, 培训三个月就成了安卓开发攻城师,嵌入式可没那么容易,特别是软硬兼修那种。

#69 Re: 全志 SOC » LIcheepi Nano如何简单的竖屏显示? » 2019-12-14 14:47:24

那就软件按 90/270度计算好,再一次性写到 framebuffer.

#70 Re: 全志 SOC » LIcheepi Nano如何简单的竖屏显示? » 2019-12-14 13:41:31

如果上了GUI的话, 比如ucgui, 修改那个最底层的画点函数旋转 90/270度即可。

#73 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » codeproject上一个开源的 窗口设计器 和 画图板 » 2019-12-11 09:43:31

达克罗德 说:

一直想改造QT的UI builder,那个功能全

2019-12-11_094247.png

你说的是这个 Qt Designer 吧? 这个设计出来的 UI 可以用在别的 app 吗?

#78 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » MSVC 做的 SolidGraph CAD System » 2019-12-09 22:10:37

VS2017/VS2019改了好多地方还是不能通过编译链接.

#82 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 发现一个不错的 win32 api 入门教程 » 2019-12-09 14:53:58

#include "stdafx.h"

#include <stdio.h>
#include <windows.h>
#include <commctrl.h>

const wchar_t g_szClassName[] = L"myWindowClass";

HIMAGELIST g_hImageList = NULL;

#define IDM_NEW 100
#define IDM_OPEN 101
#define IDM_SAVE 102

HINSTANCE gInstance;

HWND CreateSimpleToolbar(HWND hWndParent)
{
	// Declare and initialize local constants.
	const int ImageListID = 0;
	const int numButtons = 3;
	const int bitmapSize = 16;

	const DWORD buttonStyles = BTNS_AUTOSIZE;

	// Create the toolbar.
	HWND hWndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
		WS_CHILD | TBSTYLE_WRAPABLE, 0, 0, 0, 0,
		hWndParent, NULL, gInstance, NULL);

	if (hWndToolbar == NULL)
		return NULL;

	// Create the image list.
	g_hImageList = ImageList_Create(bitmapSize, bitmapSize,   // Dimensions of individual bitmaps.
		ILC_COLOR16 | ILC_MASK,   // Ensures transparent background.
		numButtons, 0);

	// Set the image list.
	SendMessage(hWndToolbar, TB_SETIMAGELIST,
		(WPARAM)ImageListID,
		(LPARAM)g_hImageList);

	// Load the button images.
	SendMessage(hWndToolbar, TB_LOADIMAGES,
		(WPARAM)IDB_STD_SMALL_COLOR,
		(LPARAM)HINST_COMMCTRL);

	// Initialize button info.
	// IDM_NEW, IDM_OPEN, and IDM_SAVE are application-defined command constants.

	TBBUTTON tbButtons[numButtons] =
	{
		{ MAKELONG(STD_FILENEW,  ImageListID), IDM_NEW,  TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"New" },
		{ MAKELONG(STD_FILEOPEN, ImageListID), IDM_OPEN, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"Open"},
		{ MAKELONG(STD_FILESAVE, ImageListID), IDM_SAVE, 0,               buttonStyles, {0}, 0, (INT_PTR)L"Save"}
	};

	// Add buttons.
	SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
	SendMessage(hWndToolbar, TB_ADDBUTTONS, (WPARAM)numButtons, (LPARAM)&tbButtons);

	// Resize the toolbar, and then show it.
	SendMessage(hWndToolbar, TB_AUTOSIZE, 0, 0);
	ShowWindow(hWndToolbar, TRUE);

	return hWndToolbar;
}

void OnPaint(HWND hWnd)
{
	PAINTSTRUCT ps;
	HDC hdc = BeginPaint(hWnd, &ps);
	MoveToEx(hdc, 0, 0, 0);
	LineTo(hdc, 100, 100);

	Ellipse(hdc, 100, 100, 200, 200);
	EndPaint(hWnd, &ps);
	return;
}
void OnPaint2(HWND hWnd)
{
	PAINTSTRUCT ps;
	HDC hdc = BeginPaint(hWnd, &ps);
	HPEN hPen = CreatePen(PS_DASHDOTDOT, 2, NULL);
	SelectObject(hdc, hPen);
	Ellipse(hdc, 100, 200, 400, 400);
	Ellipse(hdc, 300, 300, 500, 510);

	DeleteObject(hPen);
	EndPaint(hWnd, &ps);
}

// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_CREATE:
		CreateSimpleToolbar(hwnd);
		break;
	case WM_COMMAND:
	{
		int wmId = LOWORD(wParam);
		int wmEvent = HIWORD(wParam);
		// Parse the menu selections:
		switch (wmId)
		{
		case IDM_NEW:
			MessageBox(hwnd, _TEXT("点击了new"), _TEXT("提示"), 0);
			break;
		case IDM_OPEN:
			MessageBox(hwnd, _TEXT("点击了open"), _TEXT("提示"), 0);
			break;
		default:
			return DefWindowProc(hwnd, msg, wParam, lParam);
		}
	}

		break;
	case WM_ERASEBKGND:
		printf("erase back\n");
		fflush(stdout);
		return DefWindowProc(hwnd, msg, wParam, lParam);
	case WM_MOVE:
		printf("move\n");
		fflush(stdout);
	case WM_PAINT:
		OnPaint(hwnd);
		//MessageBoxW(hwnd, L"painting ...", L"p", MB_OK);
		printf("painting...\n");
		fflush(stdout);
		//return DefWindowProc(hwnd, msg, wParam, lParam);
		break;
	case WM_LBUTTONDOWN:
		//wchar_t szFileName[MAX_PATH];
		//HINSTANCE hInstance = GetModuleHandle(NULL);
		//GetModuleFileNameW(hInstance, szFileName, MAX_PATH);
		//MessageBoxW(hwnd, szFileName, L"This program is:", MB_OK | MB_ICONINFORMATION);
		break;
	case WM_CLOSE:
		DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hwnd, msg, wParam, lParam);
	}
	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASSEXW wc;
	HWND hwnd;
	MSG Msg;
	gInstance = hInstance;
	//Step 1: Registering the Window Class
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = 0;
	wc.lpfnWndProc = WndProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = g_szClassName;
	wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

	if (!RegisterClassExW(&wc))
	{
		MessageBoxW(NULL, L"Window Registration Failed!", L"Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	// Step 2: Creating the Window
	hwnd = CreateWindowExW(
		WS_EX_CLIENTEDGE,
		g_szClassName,
		L"The title of my window",
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
		NULL, NULL, hInstance, NULL);

	if (hwnd == NULL)
	{
		MessageBoxW(NULL, L"Window Creation Failed!", L"Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);

	// Step 3: The Message Loop
	while (GetMessage(&Msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}
	return (int)Msg.wParam;
}

2019-12-09_145245.png

添加了工具栏 toolbar wm_command 消息响应代码.

#83 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 发现一个不错的 win32 api 入门教程 » 2019-12-09 14:37:30

https://docs.microsoft.com/en-us/windows/win32/controls/create-toolbars

https://docs.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-imagelist_create

HIMAGELIST g_hImageList = NULL;

HWND CreateSimpleToolbar(HWND hWndParent)
{
    // Declare and initialize local constants.
    const int ImageListID    = 0;
    const int numButtons     = 3;
    const int bitmapSize     = 16;
    
    const DWORD buttonStyles = BTNS_AUTOSIZE;

    // Create the toolbar.
    HWND hWndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, 
                                      WS_CHILD | TBSTYLE_WRAPABLE, 0, 0, 0, 0, 
                                      hWndParent, NULL, g_hInst, NULL);
        
    if (hWndToolbar == NULL)
        return NULL;

    // Create the image list.
    g_hImageList = ImageList_Create(bitmapSize, bitmapSize,   // Dimensions of individual bitmaps.
                                    ILC_COLOR16 | ILC_MASK,   // Ensures transparent background.
                                    numButtons, 0);

    // Set the image list.
    SendMessage(hWndToolbar, TB_SETIMAGELIST, 
                (WPARAM)ImageListID, 
                (LPARAM)g_hImageList);

    // Load the button images.
    SendMessage(hWndToolbar, TB_LOADIMAGES, 
                (WPARAM)IDB_STD_SMALL_COLOR, 
                (LPARAM)HINST_COMMCTRL);

    // Initialize button info.
    // IDM_NEW, IDM_OPEN, and IDM_SAVE are application-defined command constants.
    
    TBBUTTON tbButtons[numButtons] = 
    {
        { MAKELONG(STD_FILENEW,  ImageListID), IDM_NEW,  TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"New" },
        { MAKELONG(STD_FILEOPEN, ImageListID), IDM_OPEN, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"Open"},
        { MAKELONG(STD_FILESAVE, ImageListID), IDM_SAVE, 0,               buttonStyles, {0}, 0, (INT_PTR)L"Save"}
    };

    // Add buttons.
    SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
    SendMessage(hWndToolbar, TB_ADDBUTTONS,       (WPARAM)numButtons,       (LPARAM)&tbButtons);

    // Resize the toolbar, and then show it.
    SendMessage(hWndToolbar, TB_AUTOSIZE, 0, 0); 
    ShowWindow(hWndToolbar,  TRUE);
    
    return hWndToolbar;
}

借鉴微软这段代码, 自己写了一个:

#include "stdafx.h"

#include <stdio.h>
#include <windows.h>
#include <commctrl.h>

const wchar_t g_szClassName[] = L"myWindowClass";

HIMAGELIST g_hImageList = NULL;

#define IDM_NEW 100
#define IDM_OPEN 101
#define IDM_SAVE 102

HINSTANCE gInstance;

HWND CreateSimpleToolbar(HWND hWndParent)
{
	// Declare and initialize local constants.
	const int ImageListID = 0;
	const int numButtons = 3;
	const int bitmapSize = 16;

	const DWORD buttonStyles = BTNS_AUTOSIZE;

	// Create the toolbar.
	HWND hWndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
		WS_CHILD | TBSTYLE_WRAPABLE, 0, 0, 0, 0,
		hWndParent, NULL, gInstance, NULL);

	if (hWndToolbar == NULL)
		return NULL;

	// Create the image list.
	g_hImageList = ImageList_Create(bitmapSize, bitmapSize,   // Dimensions of individual bitmaps.
		ILC_COLOR16 | ILC_MASK,   // Ensures transparent background.
		numButtons, 0);

	// Set the image list.
	SendMessage(hWndToolbar, TB_SETIMAGELIST,
		(WPARAM)ImageListID,
		(LPARAM)g_hImageList);

	// Load the button images.
	SendMessage(hWndToolbar, TB_LOADIMAGES,
		(WPARAM)IDB_STD_SMALL_COLOR,
		(LPARAM)HINST_COMMCTRL);

	// Initialize button info.
	// IDM_NEW, IDM_OPEN, and IDM_SAVE are application-defined command constants.

	TBBUTTON tbButtons[numButtons] =
	{
		{ MAKELONG(STD_FILENEW,  ImageListID), IDM_NEW,  TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"New" },
		{ MAKELONG(STD_FILEOPEN, ImageListID), IDM_OPEN, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"Open"},
		{ MAKELONG(STD_FILESAVE, ImageListID), IDM_SAVE, 0,               buttonStyles, {0}, 0, (INT_PTR)L"Save"}
	};

	// Add buttons.
	SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
	SendMessage(hWndToolbar, TB_ADDBUTTONS, (WPARAM)numButtons, (LPARAM)&tbButtons);

	// Resize the toolbar, and then show it.
	SendMessage(hWndToolbar, TB_AUTOSIZE, 0, 0);
	ShowWindow(hWndToolbar, TRUE);

	return hWndToolbar;
}

void OnPaint(HWND hWnd)
{
	PAINTSTRUCT ps;
	HDC hdc = BeginPaint(hWnd, &ps);
	MoveToEx(hdc, 0, 0, 0);
	LineTo(hdc, 100, 100);

	Ellipse(hdc, 100, 100, 200, 200);
	EndPaint(hWnd, &ps);
	return;
}
void OnPaint2(HWND hWnd)
{
	PAINTSTRUCT ps;
	HDC hdc = BeginPaint(hWnd, &ps);
	HPEN hPen = CreatePen(PS_DASHDOTDOT, 2, NULL);
	SelectObject(hdc, hPen);
	Ellipse(hdc, 100, 200, 400, 400);
	Ellipse(hdc, 300, 300, 500, 510);

	DeleteObject(hPen);
	EndPaint(hWnd, &ps);
}

// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_CREATE:
		CreateSimpleToolbar(hwnd);
	case WM_ERASEBKGND:
		printf("erase back\n");
		fflush(stdout);
		return DefWindowProc(hwnd, msg, wParam, lParam);
	case WM_MOVE:
		printf("move\n");
		fflush(stdout);
	case WM_PAINT:
		OnPaint(hwnd);
		//MessageBoxW(hwnd, L"painting ...", L"p", MB_OK);
		printf("painting...\n");
		fflush(stdout);
		//return DefWindowProc(hwnd, msg, wParam, lParam);
		break;
	case WM_LBUTTONDOWN:
		//wchar_t szFileName[MAX_PATH];
		//HINSTANCE hInstance = GetModuleHandle(NULL);
		//GetModuleFileNameW(hInstance, szFileName, MAX_PATH);
		//MessageBoxW(hwnd, szFileName, L"This program is:", MB_OK | MB_ICONINFORMATION);
		break;
	case WM_CLOSE:
		DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hwnd, msg, wParam, lParam);
	}
	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASSEXW wc;
	HWND hwnd;
	MSG Msg;
	gInstance = hInstance;
	//Step 1: Registering the Window Class
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = 0;
	wc.lpfnWndProc = WndProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = g_szClassName;
	wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

	if (!RegisterClassExW(&wc))
	{
		MessageBoxW(NULL, L"Window Registration Failed!", L"Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	// Step 2: Creating the Window
	hwnd = CreateWindowExW(
		WS_EX_CLIENTEDGE,
		g_szClassName,
		L"The title of my window",
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
		NULL, NULL, hInstance, NULL);

	if (hwnd == NULL)
	{
		MessageBoxW(NULL, L"Window Creation Failed!", L"Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);

	// Step 3: The Message Loop
	while (GetMessage(&Msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}
	return (int)Msg.wParam;
}

2019-12-09_143156.png

#84 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » VS2017 从零建立一个简单的 MFC 应用 » 2019-12-09 11:30:25

一个简单的消息响应程序:

#include "stdafx.h"
#include <afxwin.h>

class FirstFrame : public CFrameWnd
{
public:
	FirstFrame()
	{
	}

	DECLARE_MESSAGE_MAP();
	afx_msg void OnLButtonDown(UINT, CPoint)
	{
		MessageBox(_TEXT("对话框内容"), _TEXT("标题"), 0);
	}

	afx_msg void OnPaint()
	{
		CPaintDC dc(this);
		LineTo(dc, 100, 200);
		LineTo(dc, 200, 300);
		LineTo(dc, 0, 0);
	}
};

BEGIN_MESSAGE_MAP(FirstFrame, CFrameWnd)
	ON_WM_LBUTTONDOWN()
	ON_WM_PAINT()
END_MESSAGE_MAP()

class FirstApp : public CWinApp
{
	virtual BOOL InitInstance()
	{
		FirstFrame* window = new FirstFrame();
		m_pMainWnd = window;
		window->Create(NULL, _TEXT("第一个 MFC 应用程序."));
		window->ShowWindow(m_nCmdShow);

		return TRUE;
	}
};

FirstApp theApp;

2019-12-09_112940.png

#85 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » VS2017 从零建立一个简单的 MFC 应用 » 2019-12-09 11:24:01

晕哥 说:

太棒了,这么好的入门教程!

感谢晕哥,在这里学到太多东西了。


#include "stdafx.h"
#include <afxwin.h>

class FirstFrame : public CFrameWnd
{
public:
	FirstFrame()
	{
	}

	DECLARE_MESSAGE_MAP();
	afx_msg void OnLButtonDown(UINT, CPoint)
	{
		MessageBox(_TEXT("对话框内容"), _TEXT("标题"), 0);
	}
};

BEGIN_MESSAGE_MAP(FirstFrame, CFrameWnd)
	ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

class FirstApp : public CWinApp
{
	virtual BOOL InitInstance()
	{
		FirstFrame* window = new FirstFrame();
		m_pMainWnd = window;
		window->Create(NULL, _TEXT("第一个 MFC 应用程序."));
		window->ShowWindow(m_nCmdShow);

		return TRUE;
	}
};

FirstApp theApp;

添加一个简单的消息响应程序。

#87 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » VS2017 从零建立一个简单的 MFC 应用 » 2019-12-09 10:22:21

2019-12-09_100908.png

MFCApp.cpp 内容:

#include "stdafx.h"
#include <afxwin.h>

class FirstApp : public CWinApp
{
	virtual BOOL InitInstance()
	{
		CFrameWnd* window = new CFrameWnd();
		m_pMainWnd = window;
		window->Create(NULL, _TEXT("第一个 MFC 应用程序."));
		window->ShowWindow(m_nCmdShow);

		return TRUE;
	}
};

FirstApp theApp;

8. 编译运行成功

#97 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 《Ivor Horton's Beginning Visual C++ 2013》 源码下载 《Visual C++ 2013 入门经典》 » 2019-12-06 09:53:56

这篇文章要收藏: MFC学习(五)常见面试题

1:应用程序类

CTestOneApp::InitInstance

可以看做是MFC程序的入口函数,main函数隐藏在这个函数中。实际开发中一般不需要对这个类进行操作,但如果要在建立主对话框之前处理一些数据或者准备工作,就可以把代码添加到这个函数中,主对话框显示之前。

这里有两个比较典型的应用:
1)启动界面之前弹出个登录界面。
2)启动界面之前,弹出一个项目配置界面。

2:对话框类

// CTestOneDlg 对话框类,继承自CDialogEx类。对话框类负责与用户交互,处理用户消息,接收用户输入。

class CTestOneDlg : public CDialogEx
{
public:
// 标准构造函数
CTestOneDlg(CWnd* pParent = NULL);
// 对话框数据
enum { IDD = IDD_TESTONE_DIALOG };
protected:
// 动态数据交换,负责控件与变量之间的关联
virtual void DoDataExchange(CDataExchange* pDX);
protected:
//应用程序句柄
HICON m_hIcon;

//重载初始化对话框
virtual BOOL OnInitDialog();
//定义消息WM_SYSCOMMAND处理函数
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
//定义消息WM_PAINT处理函数
afx_msg void OnPaint();
//定义消息ON_WM_QUERYDRAGICON处理函数
afx_msg HCURSOR OnQueryDragIcon();
//消息映射
DECLARE_MESSAGE_MAP()
};

这个类看出以下几点:
(1)控件与数据关联,可以简单的交给框架
(2)在MFC框架上开发主要是针对消息处理机制

添加一个button,并且添加一个事件后:会有如下变化

PUSHBUTTON "Button1",IDC_BTN_TEST,151,57,50,14 // RC 文件拿这个ID作为控件的标示

#define IDC_BTN_TEST 1001 /resource.h 定义一个ID号。

afx_msg void OnBnClickedBtnTest(); // 事件响应函数

BEGIN_MESSAGE_MAP(CTestOneDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTN_TEST, &CTestOneDlg::OnBnClickedBtnTest) // 把事件,响应函数, 行为三者绑定到一起
END_MESSAGE_MAP()

void CTestOneDlg::OnBnClickedBtnTest() //事件响应函数
{
// TODO: 在此添加控件通知处理程序代码
}

3 SendMessage和 postMessage 区别

SendMessage : 同步, 返回值表示处理消息后的返回值。
postMessage: 异步,只是把消息放入队列,返回值仅表示post是否正确。

同一个线程内:PostMessage只把消息放入队列,然后通过消息循环Dispatch到达窗口。SendMessage发送消息时,系统直接调用目标窗口的消息处理程序,并将结果返回。

不同线程:最好用PostThreadMessage代替PostMessage。 SendMessage发送消息到目标窗口所属线程的消息队列,然后发送的线程等待,直 到处理完。

4 onpaint() 和 ondraw()

窗口改变后,产生无效区域,需要重绘,windows会发送WM_PAINT通知客户区变化,客户区的重绘需要自己完成。

CVIew派生自CWnd, 而OnPaint()是CWnd 的类成员,同时负责响应WM_PAINT消息。OnDraw()是CVIEW的成员,没有响应消息功能。
要想在屏幕上绘图,首先要建立设备环境DC,DC是一个数据结构,包含输出设备的绘图属性的描述。MFC提供了CPaintDC 类和CWindowDC 类
实时响应,CPaintDC支持重画。

当视图无效时(大小,移动,被遮盖)Windows将WM_PAINT消息发送给它。 该视图的OnPaint处理函数通过创建CPaintDC类的DC对象来响应
该消息并调用视图的OnDraw成员函数,通常不用重写ONpaint函数。
void CView::OnPaint()
{
CPaintDC dc(this);
OnPreparDC(&dc);
OnDraw(&dc); //调用了OnDraw
}
OnPaint最后也要调用OnDraw,因此我们一般会在OnDraw函数中进行绘制。

void CMyView::OnDraw( CDC* pDC )
{
CMyDoc* pDoc = GetDocument();
CString s = pDoc->GetData(); // Returns a CString
CRect rect;
GetClientRect( &rect );
pDC->SetTextAlign( TA_BASELINE | TA_CENTER );
pDC->TextOut( rect.right / 2, rect.bottom / 2, s, s.GetLength() );
}

5 强制重画窗口

InvalidateRect(&Rect) :使得指定的区域无效。

Invalidate():使得整个窗口无效,形成无效矩形。

UpdateWindow(): 立即发送WM_PAINT,不过在它发送前,先调用GetUpdateRect(hWnd,NULL,TRUE)看有无可 绘制区域,如果没有则不发送消息。

RedrawWindow()是具有Invalidate()和UpdateWindow()的双特性。声明窗口的状态为无效,并立即更新窗口,立即调用WM_PAINT消息处理。

6  CView 与 CDcoument关系

CVIew 有一个成员变量CDocument, 指向相关的Document.
CView 与 Document交谈的过程:
A:使用者在View做动作,取得Document指针,更改资料内容。
B: View调用Document的UpdatedAllViews.
C: 其他的view的onUpdate() 被调用, 各种view的画面就更新了。
D:CVIew:Onupdate()被调用,代表通知他:document的内容已经改变了,你更新画面吧。 也可以用一种低效率的方式: invaalidate(TRUE),把窗口
整个设为重绘区,产生WM_paint,再让Cview::OnDraw()。

7 你熟悉预编译指令么?条件编译是用来做什么的?你会写么?

预编译指令: 在编译之前做一些事。
#include : 文件包含
#define: 宏替换
# if, #ifndef, #ifdef, #endif, #undef : 条件编译。
#pragma :布局控制。 主要是设定编译器的状态。 #pragma once                #pragma pack(n)

8  C++ 中的string/WString

string就是*char, wstring wchar_t, 用来处理中文,是宽字符。

9 MFC用的是Unicode

10 stdafx.h   头文件预编译

把一个工程中使用的一些MFC标准头文件(windows.h Afxwin.h)预先编译,以
后该工程编译时,不再编译这部分头文件。

11 MFC包含几种类型程序?其中MFC应用程序又包含哪几类

单文档(画图),多文档(vs 2015), 对话框.

12 MFC的消息机制

MFC使用一种消息映射机制来处理消息,一个消息与消息处理函数一一对应的消息映射表,以及消息处理
函数的声明和实现代码。当窗口接收到消息的时候,会到消息映射表中查找消息的处理函数,然后消息处理函数进行
处理

13 消息映射

Windows程序都维护有自己的消息队列,保持队列消息(当然也有非队列消息,他们直接发给窗口),并用消息循环
对消息进行处理。

消息循环首先通过GetMessage取得消息并从队列中移除,对于加速键,会调用TranslateAccelerator函数,对其进行
翻译和处理,如果处理成功就不在调用translateMessge.
否则进行消息的转换和派发。让目的窗口的窗口过程来处理消息。
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
真正处理消息的是所谓的窗口过程(LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)),这个函数的参数记录了过程对应的窗口、消息的ID以及参数,在其内部开发者可以实现。

14 自定义消息

A、自定义消息号:#define WM_CCTRY_MSG (WM_USER+100)
B、在头文件中添加消息响应函数的声明:afx_msg LRESULT OnCcTryMsg(WPARAM wParam, LPARAM lParam);
C、在CPP文件中添加消息响应函数的实现:
LRESULT CXXXDlg::OnCcTryMsg(WPARAM wParam, LPARAM lParam) {
//相关代码;
}
D、在 BEGIN_MESSAGE_MAP 与 END_MESSAGE_MAP 之间加入消息的映射代码:ON_MESSAGE(WM_CCTRY_MSG, &CDlgTestDlg::OnCcTryMsg)

然后在想触发消息的地方:sendMessage(),就可以。

15. MFC的对话框的种类,各自怎么使用?及相关函数。

模态对话框和非模态对话框。
模态对话框:工作时其父窗口无效。 DoModal();
非模态对话框: dlg.Create(;)

15 进程间通信

管道(匿名): 半双工。只适合父子进程之间通信。传输的是流。所以进程间通信必须约定好数据格式。创建管道时,
        分配一个页面作为数据缓冲区,进程对缓冲区进行读写。
有名管道:非父子进程也可以通信,有传输格式。
消息队列:放在内核中的消息链表,
信号量:
共享内存:分配一块能被其他进程访问的内存。共享的内存被映射到两个进程的虚拟空间。但是需要自己提供同步机制。
信号量,互斥锁都可以。
这个效率最高,管道和消息队列需要在内核和用户空间数据拷贝。

16 MFC程序的初始化: http://www.jizhuomi.com/software/267.html

建立MFC窗口很容易,只用两步:
从CWinApp派生一个应用程序,然后创建应用程序对象。initInstance()里面创建窗口就行。

WinMain()函数:
InitInstance 是程序入口点,是虚函数,应用程序初始化(其实也winmain函数调用它的)

注意: 全局变量的的构造函数在main函数之前执行。
基本流程:

注册窗口:注册后才能从系统中找到它,获得句柄,然后向窗口发送消息。
创建窗口:
显示更新窗口:show, update()
消息循环:
回调函数:

17  消息映射机制的原理及实现。

在每个能接收和处理消息的类中,定义一个消息和消息函数静态对照表,将消息与消息处理函数绑定。当处理消息的时候到这个表中去查就行了。
BEGIN_MESSAGE_MAP() 宏中定义。

18  ASSERT() ,是函数还是宏

预处理宏, assert(expr), 先计算表达式expr, 如果为假,那么它会输出信息并终止程序执行。
如果用if else实现同样功能的话,就会从函数开始括到函数尾。
assert是宏不是函数,定义在cassert头文件中。
使用assert的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销;
完成调试后,不必从源代码中删除assert()语句,因为宏NDEBUG有定义时,宏assert()的定义为空,
即可以通过在包含#include assert.h>或#include< csaaert >的语句之前插入 #define NDEBUG 来禁用assert调用:

assert只有在Debug版本中才有效,如果编译为Release版本则被忽略(程序一般分为Debug 版本和Release 版本,
Debug 版本用于内部调试,Release 版本发行给用户使用);

assert用法注意:
A:不要一起判断多个条件,否则不知道是哪个有问题。
B:不能改变变量的值、
C: assert语句后面空一行。

19 MFC消息三种类型

      在MFC应用程序中传输的消息有三种类型:窗口消息、命令消息和控件通知。  

(1)窗口消息:WM_XXX,除WM_COMMAND之外,所有以WM_开头的消息

      窗口消息(Window Message)一般与窗口的内部运作有关,如:创建窗口、绘制窗口和销毁窗口等。通常,消息是从系统发送到窗口,或从窗口发送到窗口。  

(2)命令消息:WM_COMMAND

      命令消息一般与处理用户请求相关,当用户单击一个菜单项或工具栏时,命令消息产生,并被发送到能处理该请求的类对象(如:装载文件、编辑文本和保存选项等)。  

(3)控件通知:有多种格式
      通常,控件通知在某些重要事件发生时,由控件窗口发送到父窗口,如打开一个组合框。控件通知为父窗口进一步控制子窗口提供了机会。例如,打开一个组合框时,父窗口可以用组合框初建时得不到的消息填充它。  

      BN_XXXX是CButton产生的消息,EN_XXXX是CEdit产生的消息,等等。

 

现在就可以知道为什么有ON_MESSAGE ,ON_COMMAND, , ON_NOTIFY了。
ON_MESSAGE是处理所有的Windows的消息的,因为所有的消息都以相同的格式传送,也就是ID, WPARAM, LPARAM.
ON_COMMAND是专门处理WM_COMMAND消息的,这样我们就不用自己解开WM_COMMAND中wParam和lParam中传送的控件ID, 事件种类…(所有的都在MFC内部解决了:),当然方便了。
ON_NOTIFY更是不用说了,看看他的处理函数,是不是把NMHDR解出来了。

20 MFC绘图有哪几类DC?各自的类名,及区别

   设备描述表(DC)是Windows中的一种数据结构,它包含GDI需要的所有关于显示界面情况的描述字段,包括相连的物理设备和各种各样的状态信息。从而提供了应用程序设计的平台无关性。

 

HDC:设备上下文句柄(可以理解为指向DC结构的指针),它指向一块描述设备的相关的内容的内存块。

 

CDC:是MFC里面的一个类,且这类封装了几乎所有关于HDC的操作,由于类的内部包含一个m_hWnd的句柄,

 

所以,CDC封装的操作(函数)与SDK平台中与关于HDC的操作都缺少一个指向设备上的句柄(不是没有,而是这个句柄在被封装起来)。

(1)、HDC到CDC的转换:
方法一: 此方法在设备结束时不会销毁原来的资源(即:hDC,hBitmap)
CDC *pDC = CDC::FromHandle(hDC);

方法二:此方法在设备结束时会销毁原来的资源(即:hDC,hBitmap)
CDC dc;
dc.Attach(hDC);

(2)、CDC到HDC的转换:

   CDC  dc;

   HDC  hDC;

   hDC = dc.GetSafeHdc();

 

CPaintDC:

CClientDC:

CWindowDC:

21:  MFC的线程有哪几类?相互有什么区别?各自的创建方法是什么

 两种:界面线程:有消息循环,能响应用户的界面操作,必须继承自CWinThread.

            工作线程:

  AfxBeginThread(RUNTIME_CLASS(MyThread));   二者的参数有区别。

22 MFC常用控件?通用对话框?

23 MFC的文件类?文件查找类?

#98 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 《Ivor Horton's Beginning Visual C++ 2013》 源码下载 《Visual C++ 2013 入门经典》 » 2019-12-05 11:56:28

#include <afxwin.h>

class COurApp : public CWinApp
{
public:	virtual BOOL InitInstance() override
	{
		CFrameWnd* wnd = new CFrameWnd();
		m_pMainWnd = wnd;
		wnd->Create(nullptr, _T("Our Dumb MFC Application"));
		wnd->ShowWindow(m_nCmdShow);
		return TRUE;
	}
};
     
COurApp AnApplication;   

再精简精简, 参考: https://blog.csdn.net/netanimals/article/details/6595467

#99 Re: 全志 SOC » bsp如何和spinand进行数据双向传输? » 2019-12-05 11:50:16

太一酱鸭 说:

外接tf卡然后从tf启动来调试这样吗,这个有些麻烦,让我想一想应该怎么做

不是还有ethernet吗?

#100 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 《Ivor Horton's Beginning Visual C++ 2013》 源码下载 《Visual C++ 2013 入门经典》 » 2019-12-05 11:28:09

Chapter 11 Code   

// Ex11_02.cpp  An elementary MFC program
#include <afxwin.h>                       // For the class library

// Window class definition
class COurWnd: public CFrameWnd
{
 public:
   // Constructor
   COurWnd()
   {
     Create(nullptr, _T("Our Dumb MFC Application"));
   }
};


// Application class definition
class COurApp : public CWinApp
{
public:
	// Function to create an instance of the main application window
	virtual BOOL InitInstance() override
	{
		m_pMainWnd = new COurWnd();               // Construct a window object...
		m_pMainWnd->ShowWindow(m_nCmdShow);     // ...and display it
		return TRUE;
	}
};

     
// Application object definition at global scope
COurApp AnApplication;                    // Define an application object

一个最简单的 MFC 应用程序.

#101 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 《Ivor Horton's Beginning Visual C++ 2013》 源码下载 《Visual C++ 2013 入门经典》 » 2019-12-05 11:02:41

晕哥 说:

感谢楼主分享!

举手之劳而已。

2019-12-05_110024.png

WM_PAINT 消息响应事件里面如果屏蔽 BeginPaint/EndPaint, 那么cpu占用率就奇高了。

#104 Re: 计算机图形/GUI/RTOS/FileSystem/OpenGL/DirectX/SDL2 » emWin中,在有背景图的对话框上绘制2D图形,2D图形无法显示,是什么原因呢?谢谢! » 2019-12-03 17:35:03

emwin 仿的是 win32 的 api,

如果想收到 WM_PAINT 消息, 那么要调用 WM_InvalidateRect() 函数才行, 这样会重绘。

#109 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 8款免费/开源的 CAD 软件 » 2019-12-02 18:58:23

用了一下, qcad 真是太棒了, 以后公司的cad重构一定优先推荐基于这个软件修改.

#110 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 8款免费/开源的 CAD 软件 » 2019-12-02 18:42:41

win32prog 说:

我编译的版本只能保存成 R15 版本的 DXF 格式, 下载的专业版可以保存成R32版本以下的多种格式:

https://whycan.cn/files/members/2532/2019-12-02_173652.png

https://qcad.org/en/qcad-documentation/qcad-features

原来官网早就列出来了, 蓝色斜体字只有专业版才有的功能.

#111 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 8款免费/开源的 CAD 软件 » 2019-12-02 18:37:58

有点意思, 油管一搜, 大把的 qcad 视频教程.

#112 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 8款免费/开源的 CAD 软件 » 2019-12-02 17:37:28

我编译的版本只能保存成 R15 版本的 DXF 格式, 下载的专业版可以保存成R32版本以下的多种格式:

2019-12-02_173652.png

#113 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 8款免费/开源的 CAD 软件 » 2019-12-02 16:21:24

两台ubuntu18.04电脑都顺利编译完成, 运行也OK,

现在问题来了, Windows 不知道怎么弄。

打开 qcad.pro 提示一堆错误:

2019-12-02T14:59:51 Clang Code Model: Error: The clangbackend executable "d:\Qt\Qt5.12.3\Tools\QtCreator\bin\clangbackend.exe" could not be started (timeout after 10000ms).
Project MESSAGE: ..\build-qcad-Desktop_Qt_5_12_3_MinGW_32_bit-Debug
Project MESSAGE: ..\build-qcad-Desktop_Qt_5_6_3_MinGW_32bit-Debug
Could not find .pro file for subdirectory "..\build-qcad-Desktop_Qt_5_12_3_MinGW_32_bit-Debug" in "F:/qcad/../build-qcad-Desktop_Qt_5_12_3_MinGW_32_bit-Debug".
Could not find .pro file for subdirectory "..\build-qcad-Desktop_Qt_5_6_3_MinGW_32bit-Debug" in "F:/qcad/../build-qcad-Desktop_Qt_5_6_3_MinGW_32bit-Debug".
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project MESSAGE: Copying imageformats\qgif.dll
Project MESSAGE: Copying imageformats\qico.dll
Project MESSAGE: Copying imageformats\qjpeg.dll
Project MESSAGE: Copying imageformats\qsvg.dll
Project MESSAGE: Copying imageformats\qtga.dll
Project MESSAGE: Copying imageformats\qtiff.dll
Project MESSAGE: Copying imageformats\qwbmp.dll
Project ERROR: Unknown module(s) in QT: script scripttools
Project MESSAGE: Copying sqldrivers\qsqlite.dll
Project MESSAGE: Copying printsupport\windowsprintersupport.dll
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Project ERROR: Unknown module(s) in QT: script scripttools
Could not find .pro file for subdirectory "FlexPainter" in "F:/qcad/scripts/Misc/Examples/MathExamples/FlexPainter"

#114 Re: 计算机图形/GUI/RTOS/FileSystem/OpenGL/DirectX/SDL2 » 谁有emwin的arm9 gcc linux版本的静态库? » 2019-12-02 14:29:06

大帅 说:

上面的大神不是说没有限制么,另外好像新塘芯片没有id,
现在只待大神解惑,
或者晚上闲了回去再试试大神说的这个版本,

感觉不太可能吧, 这样不就打开了潘多拉魔盒?

#116 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 8款免费/开源的 CAD 软件 » 2019-12-02 13:41:37

试一试ubuntu18.04 编译qcad

克隆源码: git clone https://github.com/qcad/qcad.git

安装依赖包:

sudo apt-get install -y qt5-default    \
qtbase5-dev                            \
qtmultimedia5-dev                      \
qtconnectivity5-dev                    \
libqt5opengl5-dev                      \
qtpositioning5-dev                     \
qtdeclarative5-dev                     \
qtscript5-dev                          \
libqt5sensors5-dev                     \
libqt5serialport5-dev                  \
libqt5svg5-dev                         \
qttools5-dev                           \
libqt5webkit5-dev                      \
libqt5websockets5-dev                  \
libqt5x11extras5-dev                   \
libqt5xmlpatterns5-dev                 \
qmake qcad.pro
make

正在编译了。

#122 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 上位机开发,用哪个平台好啊? » 2019-11-30 23:04:48

kekemuyu 说:

之前一直用delphi7,现在越来越发现界面开发使用web前端才是王道,做过几个比较复杂的上位机都是用go+html开发的,go负责底层交互,html5用来设计页面。开发系效率和运行速度都是刚刚的,因为前端技术太成熟了,闭着眼都能找到一堆插件,而且都是可以跨平台运行的。

delphi, 暴露年龄了

#123 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 发现一个不错的 win32 api 入门教程 » 2019-11-30 23:02:20

jiangming1399 说:

感觉现在已经很少有人裸写win32 api gui了,都是用一些界面库来实现了

为了修改公司的一个祖传MFC软件, 不得不学习一下win32 基础编程.

#124 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 发现一个不错的 win32 api 入门教程 » 2019-11-30 16:26:31

定时器调用 InvalidateRect() 使客户区域无效,gui系统会自动发出 WM_PAINT 消息,

窗口消息处理函数收到WM_PAINT消息自动显示随机颜色。

void OnTimer(HWND hWnd)
{
    printf("on timer...\n");
    fflush(stdout);
    RECT rect;
    GetClientRect(hWnd, &rect);
    InvalidateRect(hWnd, &rect, FALSE);
}
void OnPaint(HWND hWnd)
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hWnd,&ps);

    HDC memdc  = CreateCompatibleDC(hdc);
    HBITMAP membmp =CreateCompatibleBitmap(hdc, ps.rcPaint.right, ps.rcPaint.bottom);
    HGDIOBJ oldBitmap=SelectObject(memdc, membmp);


    //SetMapMode(memdc, GetMapMode(hdc));
    const RECT rect = {10, 10, 300, 100};
    //SetBkColor(memdc, RGB(0xFF, 0xFF, 0xFF));
    FillRect(memdc, &ps.rcPaint, CreateSolidBrush(RGB(255,255,255)));
    FillRect(memdc, &rect, CreateSolidBrush(RGB(rand()%0xFF, rand()%0xFF, rand()%0xFF)));
    LineTo(memdc, 100, 100);
    Ellipse(memdc, 150, 150, 250, 200);

    BitBlt(hdc,0,0,ps.rcPaint.right, ps.rcPaint.bottom,memdc,0,0,SRCCOPY);

    DeleteObject(SelectObject(memdc, oldBitmap));
    DeleteDC(memdc);
    DeleteDC(hdc);

    EndPaint(hWnd,&ps);

    return;
}

#125 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 发现一个不错的 win32 api 入门教程 » 2019-11-30 15:57:08

win32prog 说:

g++ -o test TetrisGame_zjy.c  -lgdi32 -luser32 -DUNICODE


这个编译指令要加点什么吗?

终于搞定,

g++ -o test TetrisGame_zjy.c  -lgdi32 -luser32 -DUNICODE -mwindows

这样就没有黑窗口了。


https://stackoverflow.com/questions/13100785/mingw-build-gui-application-with-console

#126 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 发现一个不错的 win32 api 入门教程 » 2019-11-30 15:52:59

#include <stdio.h>
#include <windows.h>

#define ID_TIMER	1

const wchar_t g_szClassName[] = L"myWindowClass";

void OnTimer(HWND hWnd)
{
    printf("on timer...\n");
    fflush(stdout);

}

void OnPaint(HWND hWnd)
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hWnd,&ps);

    HDC memdc  = CreateCompatibleDC(hdc);
    HBITMAP membmp =CreateCompatibleBitmap(hdc, ps.rcPaint.right, ps.rcPaint.bottom);
    HGDIOBJ oldBitmap=SelectObject(memdc, membmp);

    //SetMapMode(memdc, GetMapMode(hdc));
    const RECT rect = {10, 10, 300, 100};
    //SetBkColor(memdc, RGB(0xFF, 0xFF, 0xFF));
    FillRect(memdc, &ps.rcPaint, CreateSolidBrush(RGB(255,255,255)));
    FillRect(memdc, &rect, CreateSolidBrush(RGB(255, 0, 0)));
    LineTo(memdc, 100, 100);
    Ellipse(memdc, 150, 150, 250, 200);

    BitBlt(hdc,0,0,ps.rcPaint.right, ps.rcPaint.bottom,memdc,0,0,SRCCOPY);

    DeleteObject(SelectObject(memdc, oldBitmap));
    DeleteDC(memdc);
    DeleteDC(hdc);

    EndPaint(hWnd,&ps);


    return;

}

void OnPaint1(HWND hWnd)
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hWnd,&ps);

    const RECT rect = {10, 10, 300, 100};
    FillRect(hdc, &rect, CreateSolidBrush(RGB(255, 0, 0)));
    MoveToEx(hdc,0,0,0);
    LineTo(hdc, 100, 100);

    Ellipse(hdc, 100, 100, 200, 200);
    EndPaint(hWnd,&ps);
    return;

}
void OnPaint2(HWND hWnd)
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hWnd, &ps);
    HPEN hPen = CreatePen(PS_DASHDOTDOT, 2, NULL);
    SelectObject(hdc, hPen);
    Ellipse(hdc, 100, 200, 400, 400);
    Ellipse(hdc, 300, 300, 500, 510);

    DeleteObject(hPen);
    EndPaint(hWnd, &ps);
}

// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
    case WM_CREATE:
        //SetTimer(hwnd, ID_TIMER, 2000, NULL);
        break;
    case WM_TIMER:
        OnTimer(hwnd);
        break;
    case WM_ERASEBKGND:
        printf("erase back\n");
        fflush(stdout);
        return DefWindowProc(hwnd, msg, wParam, lParam);
    case WM_MOVE:
        printf("move\n");
        fflush(stdout);
    case WM_PAINT:
        OnPaint(hwnd);
        //MessageBoxW(hwnd, L"painting ...", L"p", MB_OK);
        printf("painting...\n");
        fflush(stdout);
        //return DefWindowProc(hwnd, msg, wParam, lParam);
        break;
    case WM_LBUTTONDOWN:
        //wchar_t szFileName[MAX_PATH];
        //HINSTANCE hInstance = GetModuleHandle(NULL);
        //GetModuleFileNameW(hInstance, szFileName, MAX_PATH);
        //MessageBoxW(hwnd, szFileName, L"This program is:", MB_OK | MB_ICONINFORMATION);
        break;
    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }

    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEXW wc;
    HWND hwnd;
    MSG Msg;

    //Step 1: Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassExW(&wc))
    {
        MessageBoxW(NULL, L"Window Registration Failed!", L"Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // Step 2: Creating the Window
    hwnd = CreateWindowExW(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        L"The title of my window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
        NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBoxW(NULL, L"Window Creation Failed!", L"Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return (int)Msg.wParam;
}

用双缓冲画图 OK

void OnPaint(HWND hWnd)
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hWnd,&ps);

    HDC memdc  = CreateCompatibleDC(hdc);
    HBITMAP membmp =CreateCompatibleBitmap(hdc, ps.rcPaint.right, ps.rcPaint.bottom);
    HGDIOBJ oldBitmap=SelectObject(memdc, membmp);

    //SetMapMode(memdc, GetMapMode(hdc));
    const RECT rect = {10, 10, 300, 100};
    //SetBkColor(memdc, RGB(0xFF, 0xFF, 0xFF));
    FillRect(memdc, &ps.rcPaint, CreateSolidBrush(RGB(255,255,255)));
    FillRect(memdc, &rect, CreateSolidBrush(RGB(255, 0, 0)));
    LineTo(memdc, 100, 100);
    Ellipse(memdc, 150, 150, 250, 200);

    BitBlt(hdc,0,0,ps.rcPaint.right, ps.rcPaint.bottom,memdc,0,0,SRCCOPY);

    DeleteObject(SelectObject(memdc, oldBitmap));
    DeleteDC(memdc);
    DeleteDC(hdc);
    
    EndPaint(hWnd,&ps);
    
    return;
}

#127 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 想看 win32 里面微软封装的那些 gdi32.dll, user32.dll 函数实现, 可以找 ReactOS » 2019-11-30 15:06:43

达克罗德 说:

ARM跑这个系统可行不

https://reactos.org/wiki/ARM_Port


搜了一下, 可以啊, 但是我不会。

这个是完全仿windows ui 和 api 的, 很早以前玩过。

#130 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 发现一个不错的 win32 api 入门教程 » 2019-11-30 11:26:46

夏雨夜寐 说:

启动了控制台调试吧?

g++ -o test TetrisGame_zjy.c  -lgdi32 -luser32 -DUNICODE


这个编译指令要加点什么吗?

#131 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 发现一个不错的 win32 api 入门教程 » 2019-11-30 11:04:03

2019-11-30_105913.png

上面代码用 mingw 编译还有点坑, 要 notepad++ 转码一下


g++ -o test TetrisGame_zjy.c  -lgdi32 -luser32 -DUNICODE

咦, 为什么背后还要启动一个黑窗口呢?

2019-11-30_110337.png

#132 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 发现一个不错的 win32 api 入门教程 » 2019-11-30 09:49:32

找到一个更精简的 俄罗斯方块: https://github.com/VincentJYZhang/tetris-game/tree/master/Source%20Code

TetrisGame_zjy.cpp

// TetrisGame_zjy.cpp
// by 张钧洋
// 2018.4.10

#include <windows.h>
#include <stdio.h>
#include <time.h>
#include "Shapes.h"

#define ID_TIMER  1
#define TIME_INTERVAL 1000   // 下落时间间隔1秒

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
VOID    CALLBACK TimerProc(HWND, UINT, UINT, DWORD);

/*---------------宏-------------------*/
#define BOARD_WIDTH 180
#define BOARD_HEIGHT 400
#define LONG_SLEEP 300

#define COLS 15  // 列数
#define ROWS 30  // 行数
#define EXTENDED_COLS 23  // 包括不显示区域的列数
#define EXTENDED_ROWS 34  // 包括不显示区域的行数

// 游戏界面实际的方格位置
#define BOARD_LEFT 4
#define BOARD_RIGHT 18
#define BOARD_TOP 0
#define BOARD_BOTTOM 29
/*-----------------------------------*/


/*-------------参数声明---------------*/
// static int shapes[7][4][4];
static int shape[4][4];
static int score = 0;

static int shape_row = 0;  // 当前形状所在行
static int shape_col = EXTENDED_COLS / 2 - 2; // 当前形状所在列

static int **gBoard;

static int lattices_top = 40;   // 上面留白
static int lattices_left = 20;  // 左侧留白
static int width = BOARD_WIDTH / COLS;                    //每个格子的宽度
static int height = (BOARD_HEIGHT - lattices_top) / ROWS; //每个格子的高度

static HBRUSH grey_brush = CreateSolidBrush(RGB(210, 210, 210));
static HBRUSH white_brush = CreateSolidBrush(RGB(255, 255, 255));
static HBRUSH red_brush = CreateSolidBrush(RGB(255, 0, 0));
static HBRUSH blue_brush = CreateSolidBrush(RGB(0, 0, 255));
static HPEN hPen = CreatePen(PS_SOLID, 1, RGB(147, 155, 166));

static bool gIsPause = false;  // 判断是否暂停
/*-----------------------------------*/

/*-------------函数声明---------------*/

void InitGame(HWND);
void InitData();

void TypeInstruction(HWND);

void RandShape();  // 随机选择一个图形

void AddScore();   // 清空一行后加100分

void UpdateShapeRect(HWND hwnd); // 更新下落形状矩形区域
void UpdateAllBoard(HWND hwnd);  // 更新游戏范围

void FallToGround();
void MoveDown(HWND hwnd);   // 下降一格
void RePaintBoard(HDC hdc); // 重绘游戏界面
void PaintCell(HDC hdc, int x, int y, int color); // 绘制指定一个格子
void ClearFullLine();       // 清空满行

void RotateShape(HWND hwnd);  // 图形变形
void MoveHori(HWND hwnd, int direction);  // 水平移动
void RotateMatrix();          // 逆时针翻转图形
void ReRotateMatrix();        // 顺时针翻转图形
bool IsLegel();               // 检测图形是否超出范围

void RespondKey(HWND hwnd, WPARAM wParam); // 响应按键

void PauseGame(HWND hwnd); // 暂停游戏
void WakeGame(HWND hwnd);  // 继续游戏


bool JudgeLose();          // 判断是否输
void LoseGame(HWND hwnd);  // 游戏输了之后处理
void ExitGame(HWND hwnd);  // 游戏结束
/*-----------------------------------*/



// 程序入口 WinMain
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	PSTR szCmdLine, int iCmdShow)
{
	static TCHAR szAppName[] = TEXT("TetrisGame_Zjy");
	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;
	}

	// 这里将窗口设置为无法调节大小并且不能最大化
	hwnd = CreateWindow(szAppName, TEXT("Tetris Game"),
		WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME ^ WS_MAXIMIZEBOX,
		CW_USEDEFAULT, CW_USEDEFAULT,
		BOARD_WIDTH + 220, BOARD_HEIGHT + 70,
		NULL, NULL, hInstance, NULL);

	ShowWindow(hwnd, iCmdShow);
	UpdateWindow(hwnd);

	// 打印说明
	TypeInstruction(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 HDC hdc;
	static HDC hdcBuffer;
	static HBITMAP hBitMap;
	static PAINTSTRUCT ps;

	switch (message)
	{
	case WM_CREATE:
		SetTimer(hwnd, ID_TIMER, TIME_INTERVAL, TimerProc);
		InitGame(hwnd);
		TypeInstruction(hwnd);
		return 0;

	// 最小化恢复后需要重绘说明
	case WM_SIZE:
		TypeInstruction(hwnd);
		return 0;

	case WM_KEYDOWN:
		RespondKey(hwnd, wParam);
		return 0;

	case WM_PAINT:
		hdc = BeginPaint(hwnd, &ps);
		RePaintBoard(hdc);
		EndPaint(hwnd, &ps);
		return 0;

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

// 计时器响应事件
VOID CALLBACK TimerProc(HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)
{
	// 计时器每秒向下移动
	MoveDown(hwnd);
}

// 初始化游戏
void InitGame(HWND hwnd) {

	gBoard = new int*[EXTENDED_ROWS];
	for (int i = 0; i < EXTENDED_ROWS; i++) {
		gBoard[i] = new int[EXTENDED_COLS];
	}

	srand(time(0));

	InitData();

	UpdateAllBoard(hwnd);
}

// 初始化游戏数据
void InitData() {

	// 将游戏面板清零
	for (int i = 0; i < EXTENDED_ROWS; i++) {
		for (int j = 0; j < EXTENDED_COLS; j++) {
			gBoard[i][j] = 0;
		}
	}

	// 将外围填充1,为了判断是否超出范围
	for (int i = 0; i < EXTENDED_ROWS; i++) {
		for (int j = 0; j < BOARD_LEFT; j++) {
			gBoard[i][j] = 1;
		}
	}
	for (int i = 0; i < EXTENDED_ROWS; i++) {
		for (int j = BOARD_RIGHT + 1; j < EXTENDED_COLS; j++) {
			gBoard[i][j] = 1;
		}
	}
	for (int i = BOARD_BOTTOM + 1; i < EXTENDED_ROWS; i++) {
		for (int j = 0; j < EXTENDED_COLS; j++) {
			gBoard[i][j] = 1;
		}
	}

	gIsPause = false;

	// 初始化分数
	score = 0;

	// 随机生成图形
	RandShape();

	return;
}

// 打印说明
void TypeInstruction(HWND hwnd) {

	TEXTMETRIC  tm;
	int cxChar, cxCaps, cyChar, cxClient, cyClient, iMaxWidth;

	HDC hdc = GetDC(hwnd);

	// 保存行高字宽信息
	GetTextMetrics(hdc, &tm);
	cxChar = tm.tmAveCharWidth;
	cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;
	cyChar = tm.tmHeight + tm.tmExternalLeading;

	int startX = 180;
	int startY = 40;

	TCHAR Instruction[100];

	// 打印说明
	wsprintf(Instruction, TEXT("INSTRUCTION "));
	TextOut(hdc, startX + 40, startY, Instruction, lstrlen(Instruction));

	wsprintf(Instruction, TEXT("↑       Change Shape"));
	TextOut(hdc, startX + 40, startY + cyChar * 3, Instruction, lstrlen(Instruction));

	wsprintf(Instruction, TEXT("←       Move Left"));
	TextOut(hdc, startX + 40, startY + cyChar * 5, Instruction, lstrlen(Instruction));

	wsprintf(Instruction, TEXT("→       Move Right"));
	TextOut(hdc, startX + 40, startY + cyChar * 7, Instruction, lstrlen(Instruction));

	wsprintf(Instruction, TEXT("↓       Move Down"));
	TextOut(hdc, startX + 40, startY + cyChar * 9, Instruction, lstrlen(Instruction));

	wsprintf(Instruction, TEXT("Space Pause the game"));
	TextOut(hdc, startX + 40, startY + cyChar * 11, Instruction, lstrlen(Instruction));

	wsprintf(Instruction, TEXT("Esc     Exit the game"));
	TextOut(hdc, startX + 40, startY + cyChar * 13, Instruction, lstrlen(Instruction));

	wsprintf(Instruction, TEXT("©   2018.4   张钧洋"));
	TextOut(hdc, startX + 40, startY + cyChar * 18, Instruction, lstrlen(Instruction));

	ReleaseDC(hwnd, hdc);
}

// 随机选中一个图形
void RandShape() {

	int shape_num = rand() % 7;

	for (int i = 0; i < 4; i++)
		for (int j = 0; j < 4; j++)
			shape[i][j] = shapes[shape_num][i][j];

}

// 更新整个游戏界面
void UpdateAllBoard(HWND hwnd) {

	static RECT rect;

	rect.left = lattices_left;
	rect.right = lattices_left + COLS * width + width;
	rect.top = lattices_top - 30;
	rect.bottom = lattices_top + ROWS * height;

	// 这个矩形包括了游戏界面方格,但不包括右侧的说明
	InvalidateRect(hwnd, &rect, false);

}

// 更新下落形状所在矩形区域内
void UpdateShapeRect(HWND hwnd) {

	static RECT rect;

	rect.left = lattices_left;
	rect.right = lattices_left + COLS * width + width;
	rect.top = lattices_top + (shape_row - 1) * height;
	rect.bottom = lattices_top + (shape_row + 4) * height;

	InvalidateRect(hwnd, &rect, false);
}

// 重绘游戏界面
void RePaintBoard(HDC hdc) {

	SetBkColor(hdc, RGB(255, 255, 255));
	SelectObject(hdc, hPen);   //选用画笔
	TCHAR score_str[50];

	// 绘制当前分数
	wsprintf(score_str, TEXT("Score: %5d "), score);
	TextOut(hdc, 20, 15, score_str, lstrlen(score_str));


	// 绘制游戏界面背景
	for (int i = BOARD_TOP; i <= BOARD_BOTTOM; i++) {
		for (int j = BOARD_LEFT; j <= BOARD_RIGHT; j++) {
			PaintCell(hdc, i, j, gBoard[i][j]);
		}
	}

	// 绘制正在下降的图形
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j<4; j++) {
			if (shape[i][j] == 1)
				PaintCell(hdc, shape_row + i, shape_col + j, shape[i][j]);
		}
	}
}

// 打印指定位置指定颜色的方格
void PaintCell(HDC hdc, int x, int y, int color) {

	// 超出范围直接结束
	if (x < BOARD_TOP || x > BOARD_BOTTOM ||
		y < BOARD_LEFT || y > BOARD_RIGHT) {
		return;
	}

	x -= BOARD_TOP;
	y -= BOARD_LEFT;

	// 将坐标换算为实际的像素点
	int _left = lattices_left + y * width;
	int _right = lattices_left + y * width + width;
	int _top = lattices_top + x * height;
	int _bottom = lattices_top + x * height + height;

	// 绘制边框
	MoveToEx(hdc, _left, _top, NULL);
	LineTo(hdc, _right, _top);
	MoveToEx(hdc, _left, _top, NULL);
	LineTo(hdc, _left, _bottom);
	MoveToEx(hdc, _left, _bottom, NULL);
	LineTo(hdc, _right, _bottom);
	MoveToEx(hdc, _right, _top, NULL);
	LineTo(hdc, _right, _bottom);


	if (color == 0) {
		SelectObject(hdc, white_brush);
	}
	else if (color == 1) {
		SelectObject(hdc, blue_brush);
	}
	else if (color == 2) {
		SelectObject(hdc, red_brush);
	}

	// 填充
	Rectangle(hdc, _left, _top, _right, _bottom);
}

// 响应按键
void RespondKey(HWND hwnd, WPARAM wParam) {

	if (wParam == VK_ESCAPE) {//ESC退出
		ExitGame(hwnd);
		return;
	}
	if (wParam == VK_SPACE) {//空格暂停
		gIsPause = !gIsPause;
		if (gIsPause == true) {
			PauseGame(hwnd);
			return;
		}
		else {
			WakeGame(hwnd);
			return;
		}
	}

	// 如果处于暂停状态下就不响应这些移动操作
	if (!gIsPause) { 
		if (wParam == VK_UP) {
			RotateShape(hwnd);
			return;
		}
		if (wParam == VK_DOWN) {
			MoveDown(hwnd);
			return;
		}
		if (wParam == VK_LEFT) {
			MoveHori(hwnd, 0);
			return;
		}
		if (wParam == VK_RIGHT) {
			MoveHori(hwnd, 1);
			return;
		}
	}
}

// 停止计数器
void PauseGame(HWND hwnd) {
	KillTimer(hwnd, ID_TIMER);
}

// 重启计数器
void WakeGame(HWND hwnd) {
	SetTimer(hwnd, ID_TIMER, TIME_INTERVAL, TimerProc);
}

// 退出游戏
void ExitGame(HWND hwnd) {

	// 先暂停游戏
	SendMessage(hwnd, WM_KEYDOWN, VK_SPACE, 0);

	// 是否退出
	int flag = MessageBox(NULL, TEXT("Do you want exit?"), TEXT("EXIT"), MB_YESNO);

	if (flag == IDYES) {
		SendMessage(hwnd, WM_DESTROY, NULL, 0);
	}
	else if (flag == IDNO) {
		return;
	}

}

// 图形变形
void RotateShape(HWND hwnd) {

	RotateMatrix();

	if (!IsLegel()) {
		ReRotateMatrix();
	}

	UpdateShapeRect(hwnd);

	return;
}

// 判断形状是否在游戏界面中
bool IsLegel() {

	for (int i = 0; i<4; i++)
		for (int j = 0; j<4; j++)
			if (shape[i][j] == 1 && 
				(gBoard[shape_row + i][shape_col + j] == 1 || 
					gBoard[shape_row + i][shape_col + j] == 2))
				return false;

	return true;
}

// 逆时针旋转当前下落的形状
void RotateMatrix() {

	int(*a)[4] = shape;

	int s = 0;

	for (int n = 4; n >= 1; n -= 2) {
		for (int i = 0; i < n - 1; i++) {
			int t = a[s + i][s];
			a[s + i][s] = a[s][s + n - i - 1];
			a[s][s + n - i - 1] = a[s + n - i - 1][s + n - 1];
			a[s + n - i - 1][s + n - 1] = a[s + n - 1][s + i];
			a[s + n - 1][s + i] = t;
		}
		s++;
	}

}

// 如果超出范围,将形状恢复(顺时针旋转)
void ReRotateMatrix() {
	int(*a)[4] = shape;
	int s = 0;
	for (int n = 4; n >= 1; n -= 2) {
		for (int i = 0; i<n - 1; i++) {
			int t = a[s + i][s];
			a[s + i][s] = a[s + n - 1][s + i];
			a[s + n - 1][s + i] = a[s + n - i - 1][s + n - 1];
			a[s + n - i - 1][s + n - 1] = a[s][s + n - i - 1];
			a[s][s + n - i - 1] = t;
		}
		s++;
	}
}

// 下落形状下降一格
void MoveDown(HWND hwnd) {

	shape_row++;

	if (!IsLegel()) {
		shape_row--;

		if (JudgeLose()) {
			LoseGame(hwnd);
			return;
		}
		FallToGround();
		ClearFullLine();
		UpdateAllBoard(hwnd);

		// 重置下落形状位置
		shape_row = 0;
		shape_col = EXTENDED_COLS / 2 - 2;

		RandShape();
	}

	UpdateShapeRect(hwnd);
}

// 判断是否输了
bool JudgeLose() {

	if (shape_row == 0)
		return true;

	return false;

}

// 游戏结束
void LoseGame(HWND hwnd) {

	SendMessage(hwnd, WM_KEYDOWN, VK_SPACE, 0);

	TCHAR words[100];
	wsprintf(words, TEXT("You lose the Game. Your score is %d. \nDo you want try again?"), score);

	int flag = MessageBox(NULL, words, TEXT("EXIT"), MB_YESNO);

	if (flag == IDYES) {
		SendMessage(hwnd, WM_CREATE, NULL, 0);
		return;
	}
	else if (flag == IDNO) {
		SendMessage(hwnd, WM_DESTROY, NULL, 0);
		return;
	}

}

// 图形落地,更新背景数组
void FallToGround() {

	for (int i = 0; i<4; i++) {
		for (int j = 0; j<4; j++) {
			gBoard[shape_row + i][shape_col + j] = shape[i][j] == 1 ? 2 : gBoard[shape_row + i][shape_col + j];
		}
	}
}

// 清除整行的方格
void ClearFullLine() {
	for (int i = shape_row; i <= shape_row + 3; i++) {
		if (i > BOARD_BOTTOM)
			continue;

		bool there_is_blank = false;

		// 判断一行是否有空格
		for (int j = BOARD_LEFT; j <= BOARD_RIGHT; j++) {
			if (gBoard[i][j] == 0) {
				there_is_blank = true;
				break;
			}
		}
		if (!there_is_blank) {
			AddScore();
			for (int r = i; r >= 1; r--) {
				for (int c = BOARD_LEFT; c <= BOARD_RIGHT; c++) {
					gBoard[r][c] = gBoard[r - 1][c];
				}
			}
		}
	}
}

// 清除一行加100分
void AddScore() {
	score += 100;
}

// 下落形状水平方向移动
void MoveHori(HWND hwnd, int direction) {

	int temp = shape_col;

	// direction 为0则左移否则右移
	if (direction == 0)
		shape_col--;
	else
		shape_col++;

	// 如果移动后位置超出边界
	if (!IsLegel()) {
		shape_col = temp;
	}

	UpdateShapeRect(hwnd);

	return;
}

Shapes.h

#ifndef SHAPES_H
#define SHAPES_H

// 存储七种形状
static int shapes[7][4][4] = {
	{
		{ 0, 0, 0, 0 },
		{ 0, 1, 0, 0 },
		{ 1, 1, 1, 0 },
		{ 0, 0, 0, 0 }
	},
	{
		{ 0, 0, 0, 0 },
		{ 0, 1, 1, 0 },
		{ 0, 1, 1, 0 },
		{ 0, 0, 0, 0 }
	},
	{
		{ 0, 1, 0, 0 },
		{ 0, 1, 0, 0 },
		{ 0, 1, 0, 0 },
		{ 0, 1, 0, 0 }
	},
	{
		{ 0, 0, 0, 0 },
		{ 1, 1, 0, 0 },
		{ 0, 1, 1, 0 },
		{ 0, 0, 0, 0 }
	},
	{
		{ 0, 0, 0, 0 },
		{ 1, 0, 0, 0 },
		{ 1, 1, 1, 0 },
		{ 0, 0, 0, 0 }
	},
	{
		{ 0, 0, 0, 0 },
		{ 0, 0, 1, 0 },
		{ 1, 1, 1, 0 },
		{ 0, 0, 0, 0 }
	},
	{
		{ 0, 0, 0, 0 },
		{ 0, 1, 1, 0 },
		{ 1, 1, 0, 0 },
		{ 0, 0, 0, 0 }
	}
};


#endif // !SHAPES_H

2019-11-30_094902.png

#133 Re: Openwrt/LEDE/AR9331/MT7688/RT5350 » MT7628DAN data? » 2019-11-30 08:08:01

这些资料我觉得 widora.io 应该有.

#134 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 发现一个不错的 win32 api 入门教程 » 2019-11-29 17:13:52

#include "Piece.h"
#include "Game.h"
#include <windows.h>
#include <iostream>

using namespace std;

const int PX_PER_BLOCK = 25;    // Cell size in pixels
const int SCREEN_WIDTH = 10;    // Level width in cells
const int SCREEN_HEIGHT = 20;   // Level height in cells
const int GAME_SPEED = 33;      // Update the game every GAME_SPEED millisecs (= 1/fps)
const int TIMER_ID = 1;

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

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
{

    static TCHAR szAppName[] = TEXT("tetris");
    HWND hwnd;
    MSG msg;
    WNDCLASSEX wc;

    // We need to repaint a lot, using CS_OWNDC is more efficient
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = szAppName;
    wc.hIconSm = NULL;

    if (!RegisterClassEx(&wc))
    {
        MessageBox(NULL, TEXT("Program requires Windows NT!"),
                   szAppName, MB_ICONERROR);
        return 0;
    }

    hwnd = CreateWindow(szAppName,
                        TEXT("Eliang's Tetris"),
                        WS_MINIMIZEBOX | WS_SYSMENU,  // No window resizing
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        SCREEN_WIDTH * PX_PER_BLOCK + 156,
                        SCREEN_HEIGHT * PX_PER_BLOCK + 25,
                        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)
{
    HDC hdc;
    PAINTSTRUCT ps;
    static Game *game;
    static DrawEngine *de;

    switch (message)
    {
        case WM_CREATE:
            hdc = GetDC(hwnd);

            de = new DrawEngine(hdc, hwnd, PX_PER_BLOCK);
            game = new Game(*de);
            SetTimer(hwnd, TIMER_ID, GAME_SPEED, NULL);

            ReleaseDC(hwnd, hdc);
            return 0;

        case WM_KEYDOWN:
            game->keyPress(wParam);
            return 0;

        case WM_TIMER:
            game->timerUpdate();
            return 0;

        case WM_KILLFOCUS:
            KillTimer(hwnd, TIMER_ID);
            game->pause(true);
            return 0;

        case WM_SETFOCUS:
            SetTimer(hwnd, TIMER_ID, GAME_SPEED, NULL);
            return 0;

        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
            game->repaint();
            EndPaint(hwnd, &ps);
            return 0;

        case WM_DESTROY:
            delete de;
            delete game;
            KillTimer(hwnd, TIMER_ID);
            PostQuitMessage(0);
            return 0;

    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

https://github.com/eliangcs/tetris-win32

https://github.com/eliangcs/tetris-win32/blob/master/src/main.cpp

68747470733a2f237265656e76e67.png

仅用 win32 api 做的俄罗斯方块。

#135 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 发现一个不错的 win32 api 入门教程 » 2019-11-29 17:07:44

手动撸的一个定时器更新 gdi 的demo:

#include <windows.h>

#define RECT_WIDTH 200
#define RECT_HEIGHT 200
// x and y are the x- and y-locations of the mouse cursor upon release
void drawRectangle(HWND hwnd, const int x, const int y)
{
    // obtain a handle to the device context
    HDC hdc = GetDC(hwnd);

    // RECT_WIDTH and RECT_HEIGHT are elsewhere defined
    // draw rectangle
    Rectangle(hdc, x - RECT_WIDTH / 2, y - RECT_HEIGHT / 2, x + RECT_WIDTH / 2, y + RECT_HEIGHT / 2);

    // release the DC
    ReleaseDC(hwnd, hdc);
}

LRESULT APIENTRY WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static int x, y;
    PAINTSTRUCT ps;

    switch (message)
    {
		case WM_CREATE:
        {
			SetTimer(hwnd, 0, 200, NULL);
			break;
        }
		case WM_TIMER:
		{
			RECT rect;

			do
			{
                x = rand();
			}
			while(x < 0 || x > 500);

			do
			{
                y = rand();
			}
			while(y < 0 || y > 500);

			GetClientRect(hwnd, &rect);
			InvalidateRect(hwnd, &rect, 1);
			break;
		}

		case WM_PAINT:
		{
            BeginPaint(hwnd, &ps);

			// draw the rectangle
			drawRectangle(hwnd, x, y);

			EndPaint(hwnd, &ps);
			return 0;
		}
		case WM_CLOSE:
			DestroyWindow(hwnd);
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

const wchar_t g_szClassName[] = L"myWindowClass";
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEXW wc;
    HWND hwnd;
    MSG Msg;

    srand(0);
    //Step 1: Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassExW(&wc))
    {
        MessageBoxW(NULL, L"Window Registration Failed!", L"Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // Step 2: Creating the Window
    hwnd = CreateWindowExW(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        L"The title of my window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
        NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBoxW(NULL, L"Window Creation Failed!", L"Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return (int)Msg.wParam;
}

win32_test2.gif

参考: https://stackoverflow.com/questions/28925178/drawing-rectangle-in-c-using-functions

#136 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 发现一个不错的 win32 api 入门教程 » 2019-11-28 17:51:43

#include <stdio.h>
#include <windows.h>

const wchar_t g_szClassName[] = L"myWindowClass";

void OnPaint(HWND hWnd)
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hWnd,&ps);
    MoveToEx(hdc,0,0,0);
    LineTo(hdc,100,100);

    Ellipse(hdc, 100, 100, 200, 200);
    EndPaint(hWnd,&ps);
    return;
}
void OnPaint2(HWND hWnd)
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hWnd, &ps);
    HPEN hPen = CreatePen(PS_DASHDOTDOT, 2, NULL);
    SelectObject(hdc, hPen);
    Ellipse(hdc, 100, 200, 400, 400);
    Ellipse(hdc, 300, 300, 500, 510);

    DeleteObject(hPen);
    EndPaint(hWnd, &ps);
}

// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
		case WM_ERASEBKGND:
            printf("erase back\n");
            fflush(stdout);
			return DefWindowProc(hwnd, msg, wParam, lParam);
        case WM_MOVE:
            printf("move\n");
            fflush(stdout);
        case WM_PAINT:
			OnPaint(hwnd);
            //MessageBoxW(hwnd, L"painting ...", L"p", MB_OK);
            printf("painting...\n");
            fflush(stdout);
            //return DefWindowProc(hwnd, msg, wParam, lParam);
        break;
        case WM_LBUTTONDOWN:
            //wchar_t szFileName[MAX_PATH];
            //HINSTANCE hInstance = GetModuleHandle(NULL);
            //GetModuleFileNameW(hInstance, szFileName, MAX_PATH);
            //MessageBoxW(hwnd, szFileName, L"This program is:", MB_OK | MB_ICONINFORMATION);
			break;
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEXW wc;
    HWND hwnd;
    MSG Msg;

    //Step 1: Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassExW(&wc))
    {
        MessageBoxW(NULL, L"Window Registration Failed!", L"Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // Step 2: Creating the Window
    hwnd = CreateWindowExW(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        L"The title of my window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
        NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBoxW(NULL, L"Window Creation Failed!", L"Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return (int)Msg.wParam;
}


mingw 编译:  gcc -o test1 test1.c -luser32 -lgdi32
msvc 编译: cl  test1.c gdi32.lib user32.lib

2019-11-28_175132.png

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn