0)Visual C++2017概述

2023-10-30

文章目录

一、概述

  • 编译工具:x32,x64位编译器、CLR(公共语言运行库)
  • Visual C++ 库:标准C++、活动模板库(ATL)、Microsoft基础类库(MFC)。这些库由iostream库、标准模板库(STL)、C运行时库(CRT)组成。STL/CLR 库为托管代码开发人员引入STLK
  • 开发环境

每个MFC 程序都要一个继承自CWinApp(或CWinAppEx) 的应用类,比如CTestApp 。应用类的生命期从程序开始执行到执行结束。应用类必须重载CWin 的虚函数InitInstance ,程序的初始化操作通常放在这个函数里。这里我们让程序刚运行就跳出一个消息框,因此把AfxMessageBox 放在InitInstance 里。_T 的作用与TEXT 相同,都是为了让字符串同时支持Unicode 字符和多字符环境,AfxMessageBox 是一个全局函数。

二、字符集

1、C运行时库对Unicode的支持

  1. 字符类型
    C/C++ 定义新的名为“宽字符”的数据类型,以提供对Unicode 的支持。这种数据类型为wchar_t 定义如下:
typedef unsigned short wchar_t;

该类型为无符号短整型,占用2字节,原来的char 类型仍然可以用,一个字符占用一个字节相对于wchar_t ,char 通常被称为窄字符类型

wchar_t 可以用来定义字符,也可用来定义字符数组
wchar_t arr[] = L"Style";

    L 要求编译器将其后字符串按Unicode 保存,即字符串中的每个字符占用 2 字节
    为了统一处理窄字类型和宽字类型,系统头文件tchar.h 中定义字符数据类型TCHAR 为char,定义大致如下:

#ifdef _UNICODE
#define wchar_t
#else
typedef
#endif

    该处用到了预处理器,意思是如果定义了_UNICODE 宏,则TCHAR 定义为wchar_t ,否则定义为char

TCHAR ch = 'A';			//该字符是窄字符还是宽字符取决于前面有没有定义_UNICODE
  1. 字符串处理

2、C++标准库对Unicode的支持

在C++ 标准库中的string 也有对应的宽字符版本wstring ,但未提供统一的函数形式,类似的还有fstream/wfstream,ofstream/wofstream

3、Windows API 对Unicode 的支持

两个版本,以A为结束的函数形式,针对多字节字符集,另外一个以W 为结束的函数形式,针对Unicode 字符集。

4、Visual C++ 2017对Unicode 的支持

可在工程属性中选择本工程所使用的字符集

三、SDK编程基础

1、消息的定义

一个消息是系统定义的一个32位的整数值,并用宏表示。它向Windows 发出一个通知,告诉应用程序某个事情发生了。例:单击鼠标,改变窗口尺寸等等。这会使Windows 发送消息给应用程序。产生消息的来源有3个:

  1. 由操作系统产生
  2. 由用户触发事件转换而来
  3. 由另一个消息产生

消息分为两种:

  1. 系统预定义消息
  2. 用户自定义消息
    其中用户自定义消息用一个宏来表示。在头文件winuser.h 中这些消息宏被定义为32位整数。例如:
#define WM_CREATE		//窗口创建消息
#define BM_CLICK		//按钮单击消息

消息宏分为两部分:

  1. 前缀:表示处理该消息的窗口类别
  2. 后缀:描述了该消息的目的

hwnd 是32位的窗口句柄(类指针),Win32 能够维护大多数可视对象的句柄(窗口、对话框、按钮、编辑框);message 是消息号用来存放消息常量值(消息宏)

2、预定义消息

1、窗口消息(Windows message)

窗口消息用于窗口的内部运作,窗口消息可用于一般窗口,也可以是对话框、控件,因为对话框和控件也是窗口

2、命令消息(Command Message)

    Command Message 用于处理用户请求,如用户单击菜单项或工具栏按钮或标准控件时就会产生命令消息。命令消息的格式是WM_COMMAND ,消息参数wParam 的低字节,即LOWORD(wParam)表示菜单项或工具栏。
    WM_COMMAND 除了作为命令消息外,还能作为标准控件的控件通知消息。区别是消息参数lParam 是否为NULL :如果是NULL ,则该消息是命令消息,如果lParam 是控件句柄值,则该消息是标准控件通知消息。通用控件有情况向父窗口发送消息时,并不通过WM_COMMAND,而是通过控件通知消息WM_NOTIFY 。

  • 标准控件:按钮(Button)、静态文本控件(Static)、编辑框(Edit)、组合框(ComboBox)、列表框(ListBox)、滚动块(ScrollBar)

3、控件通知消息

控件有情况需要通知其父窗口,该消息有三种形式:

(1)作为窗口消息的子集

WM_XXXX 的格式

  • 控件窗口在创建或销毁前,会发送WM_PARENTNOTIFY 消息给它的父窗口
  • 控件窗口绘制自身窗口消息,如WM_CTLCOLOR 等等
  • 由滚动条控件发送,通知其父窗口滚动的消息,如WM_VSCROLL 和 WM_HSCROLL

(2)WM_COMMAND形式

    WM_COMMAND 除了作为命令消息外,还能作为标准控件的控件通知消息。区别是消息参数lParam 是否为NULL :如果是NULL ,则该消息是命令消息,如果lParam 是控件句柄值,则该消息是标准控件通知消息。通用控件有情况向父窗口发送消息时,并不通过WM_COMMAND,而是通过控件通知消息WM_NOTIFY 。

  • 标准控件:按钮(Button)、静态文本控件(Static)、编辑框(Edit)、组合框(ComboBox)、列表框(ListBox)、滚动块(ScrollBar)

lParam 用来区分是命令消息还是控件通知消息,如果为NULL ,则是命令消息,否则lParam 里面放的必然是控件的句柄,是一个控件通知消息,消息参数wParam 的低字节表示控件的ID,高字节即HIWORD(wParam)表示控件通知码,通知码标记了控件所发生的各种事件,常见标准控件的通知码和含义:

(3)WM_NOTIFY形式

    通用控件(如树型视图,列表视图)消息的消息参数wParam 和lParam 分别表示控件ID 和指向结构体NMHDR 的指针,NMHDR(Notify Message Handler) 包含控件通知消息函数的内容比如控件通知码。
    WM_NOTIFY解决了不断需要增加新消息和消息参数所带信息容量不够的问题。目前Windows 中通用控件的通知方式都是采用该消息的形式。

3、自定义消息

开发者可以自己定义消息以达到特殊功能的目的,注意不要和预定义消息的宏冲突。系统保留的消息标识符在0x0000 到0x03ff (WM_USER - 1)范围内。开发者不能使用这些值定义自己的消息。可以从WM_USER 开始,例如:

#define MY_MSG WM_USER + 1

4、消息(Message)和事件(Event)

    消息是描述某个事件发生的信息,而事件是用户操作应用程序产生的动作。事件是原因,消息是结果,事件产生消息,消息对应事件。
    消息可能是由一个事件转换而来(或者由操作系统产生),一个消息可能会产生另一个消息。事件只能由用户触发。总而言之,事件只能由用户通过外设的输入产生。

5、消息和窗口

Windows 的消息机制就是“以消息为基础,以事件为驱动”,也就是说:程序不断等待消息的形式进入系统后放入相应的队列,然后调用API 函数GetMessage 取得相应的消息并做出相应的处理。窗口就是用来接受并处理消息的,每个窗口都对应一个函数来处理消息,该函数是窗口函数(Windows Procedure 窗口过程函数)
Win32应用程序(SDK)的实现主要分为以下步骤:

  • WinMain 函数
  • MSG 结构体
  • 注册窗口
  • 创建窗口
  • 显示窗口
  • 刷新窗口
  • 消息循环
  • WindowsProc 窗口函数
        该函数是一个回调函数(Callback)就是系统无需用户调用,只需要窗口函数的函数名赋值给窗口类WNDCLASS 中的成员lpfnWndProc ,系统就知道了,利用Switch/Case 方式来判断消息种类,然后进入各分支针对某个具体消息进行处理。

    例:可以从基本的Win32 程序来理解,创建Windows 桌面应用程序,会自动生成一个Win32 的框架

// WindowsProject1.cpp : 定义应用程序的入口点。
//

#include "framework.h"
#include "WindowsProject1.h"

#define MAX_LOADSTRING 100

// 全局变量:
HINSTANCE hInst;                                // 当前实例
WCHAR szTitle[MAX_LOADSTRING];                  // 标题栏文本
WCHAR szWindowClass[MAX_LOADSTRING];            // 主窗口类名

// 此代码模块中包含的函数的前向声明:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: 在此处放置代码。

    // 初始化全局字符串
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_WINDOWSPROJECT1, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // 执行应用程序初始化:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT1));

    MSG msg;

    // 主消息循环:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}



//
//  函数: MyRegisterClass()
//
//  目标: 注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT1));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT1);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}

//
//   函数: InitInstance(HINSTANCE, int)
//
//   目标: 保存实例句柄并创建主窗口
//
//   注释:
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // 将实例句柄存储在全局变量中

   HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目标: 处理主窗口的消息。
//
//  WM_COMMAND  - 处理应用程序菜单
//  WM_PAINT    - 绘制主窗口
//  WM_DESTROY  - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 分析菜单选择:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: 在此处添加使用 hdc 的任何绘图代码...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}

定义一个窗口类

  在上面的程序中操作系统要求在调用API 函数CreateWindow 创建窗口之前,要求开发者必须定义一个窗口类(不是C++ 传统意义上的类)来规定所要创建窗口的各种信息,包括函数处理名、窗口风格、图标、鼠标、菜单等,通过一个结构体WNDCLASSEXW (末尾的W 表示是Unicode 下的版本,如果是多字节下的版本为WNDCLASSEXW ,关于该名称的解释在MFC 常见变量解析中有所提及)来定义窗口类,定义如下:

创建窗口

Create Window 函数声明如下:

显示窗口、刷新窗口

窗口创建完毕后就要显示窗口,使用Show Window 来显示窗口,再使用Update Window 来刷新窗口。所谓刷新窗口就是发送一个WM_PAINT 消息给窗口,在窗口函数WndProc 中会做WM_PAINT 处理。

消息循环

  其中,GetMessage 从主线程消息队列中获取一个消息并将它复制到MSG 结构中。
  GetMessage 函数将等待一个消息的到来以后才返回。
MSDN中介绍 MSG 定义如下:

typedef struct tagMSG {
HWND hwnd;		//1、hwnd表示消息所属的窗口。我们通常开发的程序都是窗口应用程序,一个消息一般都是与某个窗口相关联的。
UINT message;	//2、指定了消息的标识符
WPARAM wParam;	//3、用于指定消息的附加信息
LPARAM lParam;	//4、用于指定消息的附加信息
DWORD time;		//5、消息投递到消息队列中的时间
POINT pt;		//6、鼠标的当前位置
} MSG;

参考微软官方文档Microsoft MSG structure

窗口函数

WIN32 编程中最重要的函数,窗口(过程)函数,WndProc 函数和 About 函数和都是窗口过程函数,分别处理各自窗口的消息。
窗口函数的声明(该函数为回调函数):

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);
//1、LRESULT 表示会返回多种long 型值
//2、HWND 窗口句柄,一个整形值
//3、UINT unsigned int
//4、typedef UINT_PTR WPARAM
		//就是unsigned int,因为typedef unsigned int UINT_PTR
//5、typedef LONG_PTR LPARAM
		//就是unsigned LONG,因为typedef unsigned LONG ULONG_PTR

窗口过程是一个用于处理所有发送到这个窗口的消息的函数。任何一个窗口类都有一个窗口过程。同一个类(窗口类名相同)使用相同的窗口过程来响应消息

画出字符串

  1. 函数GetClientRect 是获取窗口客户区(暂时认为空白区域)的坐标和大小,存入Rect 类型变量中。Rect 是一个结构体,定义如下:
typedef struct tagRECT{
	LONG left;
	LONG top;
	LONG right;
	LONG bottom;
}RECT;
  1. 用SetTextColor 函数设置要画的字符串颜色,SetBkColor 设置背景色,最后用DrawText 画出文本字符串,声明如下:
int DrawText(
	HDC hDC, // 设备描述表句柄
	LPCTSTR lpString, // 将要绘制的字符串
	int nCount, // 字符串的长度
	LPRECT lpRect, // 指向矩形结构RECT的指针
	UINT uFormat // 正文的绘制选项
);

Win32 编程最重要的概念和要点(窗口和消息)

需要理解的要点如下:

  • 消息的组成:一个消息由消息名称message(UINT)
    和两个参数(WPARAM,LPARAM)组成。当用户输入或窗口状态发生改变时系统都会发送消息到某一窗口。用户可以自定义消息名称(自定义消息的宏),也可以利用自定义消息来发送通知和传送数据。
  • 消息的接收者:一个消息必须由一个窗口接收。在窗口的过程(WNDPROC)中可以对消息进行分析,对自己感兴趣的消息进行处理。
  • 消息的默认处理:如果用户没有对某个消息进行处理,通常窗口会对消息进行默认处理。微软为窗口编写了默认窗口处理过程。该窗口负责处理我们未处理的消息。因此我们可以不用去理睬我们未处理的消息,例如,窗口拖动会产生大量的消息。
  • 窗口句柄:系统通过窗口句柄在整个系统中唯一标识一个窗口。发送消息时必须指定一个窗口句柄表明该消息由哪个窗口接收。而每个窗口有自己的窗口过程,所以用户的输入就会被正确的处理。

6、工程目录结构

  • 工程、项目(project)
  • 每个Project 都存在于Solution(解决方案)中
  • Text.rc 是资源文件
  • .vcxproj 是工程文件
  • small.ico 和Test.ico 是两个图标文件

7、Win32 控件编程

控件名称 预定义窗口类名 功能
按钮控件 Button 提供单击和选择
静态文本控件 Static 显示文本字符串
编辑框控件 Edit 显示和输入文本字符串
列表框 Listbox 列表显示字符串
组合框 combobox 供用户选择或编辑字符串
  • 创建窗口
    控件也是窗口,因此创建窗控件和创建窗口一样,使用CreateWindow 或CreateWindowEx函数,并在窗口样式上使用WS_CHILD 这个样式(或WS_CHILDWINDOW 效果一样),表示控件放在其他窗口上,作为其他窗口的子窗口。创建控件的地方一般放在父窗口WM_CREATE消息处理中
  • WS_VISIBLE 表示创建按钮的同时显示出来,如果没有该风格,则创建成功后不会显示。
  • 每个控件必须有唯一ID(其实是一个整数值)
  • 控件和父窗口之间的信息交互
    用户对某窗口的控件进行操作时,操作产生的事件会被控件转换为消息,然后发送给父窗口,消息的名字系统预定义为WM_COMMAND ,消息参数wParam 的低字节部分LOWORD(wParam)表示控件ID ,wParam 的高字节部分HIWORD(wParam)表示通知码,通知码表示某种操作的宏,定义在winuser.h中;lParam 表示控件句柄。WM_COMMAND 只是告诉父窗口控件产生消息了,但具体是什么操作由通知码来获得,不同的控件通知码不同。
  • 控件大小、位置、使能、可见性和销毁
    控件也是窗口,调整窗口大小和位置函数是MoveWindow 或SetWindowPos ,函数也可用于控件。如果要让控件不可用可以使用EnableWindow 。销毁控件可以使用DestroyWindow,但一般主窗口销毁的时候,其拥有的子窗口(包括控件)都会自动销毁,所以不用显式地去调用DestroyWindow

1)按钮控件

常用按钮通知码,表2为常见按钮通知消息


_tcscpy_s 是strcpy 的Unicode 和非Unicode 的通用版本,结尾加了_s是表示该函数的安全版本。同样的还有_stprintf_s

四、MFC编程基础

1、MFC类库概述

MFC类库的类别层次结构:

重要类之间的继承关系:

详细参考:Microsoft Docs MFC Hierarchy Chart
几个重要的类:

  1. 类CObject
    大多数MFC类的基类,主要提供四方面的功能:串行化数据、运行时提供类的信息、对象诊断输出和收集类兼容
  2. 类CCmdTarget
    “大内总管”,消息映射的一个基类。消息映射把命令或消息引导给用户为之编写的响应函数。
  3. 类CWinApp
    主要封装程序初始化、运行和结束等功能。如其中含有一个InitInstance ,在这个函数中实现程序主窗口的创建。在其中可以加入自己的代码,在程序刚运行时执行某些功能。如果需要在程序结束时加入一些功能,可在ExitInstance中加入一些功能
  4. 类CWnd
    举足轻重,几乎所有的窗口都从它派生而来。通常的三种MFC程序:单个文档程序、多个文档程序和基于对话框的程序。这3种程序的主窗口由CFrameWnd、CMDIFrameWnd、CDialog来实现,这三个类都由该类直接或间接派生
  5. 类CFrameWnd
    框架窗口(构造应用程序或部分程序的窗口),通常包含视图窗口(通常和文档数据打交道,用来显示文档中的数据,是框架窗口的客户区,用来显示文档中的数据,是框架窗口的客户区,用来显示数据的子窗口)、工具栏、状态栏等元素的窗口。
      创建框架窗口三种方法:直接通过CFrameWnd 的成员函数Create 来创建、通过成员函数LoadFrame 来创建、通过文档模板来间接构造
  6. 类CMDIFrameWnd
    继承于CFrameWnd ,主要用来实现多文档程序(MDI)的框架窗口
  7. 类CDialog
    用来实现程序中各种对话框的功能,包括模态对话框和非模态对话框
  8. CCommonDialog
    各通用对话框的父类,通用对话框:颜色选取对话框(CColorDialog)、字体设置对话框(CFontDialog)、文件打开对话框(CFileDialog)、搜索替换对话框(CFindReplaceDialog)、打印对话框(CPrintDialog)等。Windows 标准对话框类(CCommonDialog)继承自CDIalog
  9. 类CView
    视图类,也是一种窗口,是框架窗口的客户区(显示数据的子窗口)。作用是为文档数据提供一个视图。视图就是显示数据、接收用户输入、编辑或选择数据的窗口。CView 派生出很多不同显示数据方式的视图子类,如让视图以列表显示的CLIstView 、让数据以树型方式显示的CTreeView 、支持用户编辑功能的视图CEditView、让数据以超文本方式显示的CHtmlView
  10. 类CDocTemplate
    文档模板类主要用来整合文档、视图和框架窗口的创建
  11. 类CDocument
    管理程序中的数据

以上为程序大框架方面的几个类。其他的是针对某些功能的,如CSocket 是针对网络功能的实现、CMenu 是针对菜单功能的实现、CException 是针对异常功能的实现、CFile 是针对文件功能的实现等等。

2、MFC应用程序类型

  • 单文档程序就是一个程序中只有一个视图窗口和一个文档对象
  • 多文档程序就是一个程序中有多个视图窗口和多个文档对象
  • 对话框程序没有视图窗口和文档对象等概念,通常是在对话框上放置控件,然后通过控件的操作和用户交互。

3、窗口客户区

  在Win32 程序中,窗口客户区比较简单,通常指除去菜单栏、滚动条后的中间区域部分。
  MFC程序的窗口客户区,文档程序主窗口的客户区和视图窗口的客户区是不同的,通常画图程序是在视图窗口的客户区上进行。
  单文档程序的工具栏和状态栏是显示在客户区内的,即主窗口客户区是包括工具栏和状态栏区域的白色区域是视图窗口的客户区。

CRect 是一个MFC 类,用于表示一个矩形的大小,常见成员函数:

五、键盘

  键盘的硬件原理是用户每次按下或释放某个键,键盘都会产生扫描码,以确定相应的键,并且按下的时候,扫描码最高位是0,释放的时候最高位是1,因此每个键能产生两个不同的扫描码。
  物理键盘产生扫描码,不同键盘产生的扫描码不同。为屏蔽不同物理键盘差异,Windows 系统通过虚拟键盘来提供与设备无关的键盘操作。上层应用只需要和虚拟键盘打交道
  虚拟键盘上的键码通过宏定义来表示,它们在winuser.h 中定义:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

0)Visual C++2017概述 的相关文章

  • 混合 MFC 和 WPF:模态对话框

    我使用 C CLI 界面层将 C WPF 对话框添加到现有的 C MFC 应用程序 我一切正常 只是我遇到了形式问题 例如 MFC 应用程序使用 ShowDialog 显示 WPF 对话框 按预期工作 该 WPF 对话框显示使用 DoMod
  • 没有强命名的代码签名是否会让您的应用程序容易被滥用?

    尝试了解authenticode代码签名和强命名 我是否正确地认为 如果我对引用一些 dll 非强命名 的 exe 进行代码签名 恶意用户就可以替换我的 DLL 并以看似由我签名但正在运行的方式分发应用程序他们的代码 假设这是真的 那么您似
  • 通过 CMIS (dotCMIS) 连接到 SP2010:异常未经授权

    我正在使用 dotCMIS 并且想要简单连接到我的 SP2010 服务器 我尝试用 C 来做到这一点 如下所示http chemistry apache org dotnet getting started with dotcmis htm
  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • 嵌套接口:将 IDictionary> 转换为 IDictionary>?

    我认为投射一个相当简单IDictionary
  • 使用实体框架模型输入安全密钥

    这是我今天的完美想法 Entity Framework 中的强类型 ID 动机 比较 ModelTypeA ID 和 ModelTypeB ID 总是 至少几乎 错误 为什么编译时不处理它 如果您使用每个请求示例 DbContext 那么很
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • SolrNet连接说明

    为什么 SolrNet 连接的容器保持静态 这是一个非常大的错误 因为当我们在应用程序中向应用程序发送异步请求时 SolrNet 会表现异常 在 SolrNet 中如何避免这个问题 class P static void M string
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • 如何在Xamarin中删除ViewTreeObserver?

    假设我需要获取并设置视图的高度 在 Android 中 众所周知 只有在绘制视图之后才能获取视图高度 如果您使用 Java 有很多答案 最著名的方法之一如下 取自这个答案 https stackoverflow com a 24035591
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • 测试用例执行完成后,无论是否通过,如何将测试用例结果保存在变量中?

    我正在使用 NUNIT 在 Visual Studio 中使用 Selenium WebDriver 测试用例的代码是 我想在执行测试用例后立即在变量中记录测试用例通过或失败的情况 我怎样才能实现这一点 NUnit 假设您使用 NUnit
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags

随机推荐

  • I.MX6U开发板交叉编译Qt项目(什么是交叉编译器;如何搭建Qt交叉编译环境;WinSCP将Windows中的文件传到Ubuntu中;如何将编译好的执行文件拷到开发板上)

    文章目录 1 关于嵌入式学习的一些思考 1 1 使用imx6 还是stm32mp 1 2 关于是否需要买板子 2 I MX6U开发板交叉编译Qt项目 2 1 什么是交叉编译器 2 2 安装交叉编译器 2 2 1 下载交叉编译器和资料 2 2
  • 用FLEX实现屏幕快照及下载 flex导出excel文件

    用FLEX实现屏幕快照及下载 Flex Flash Flex2 Flex3 GgNET 01月 31st 2008 2 53am 这种方式 在服务器端不会在磁盘上生成图片FLEX代码public function printMap void
  • 分析脚本搭建docker环境:python, R

    1 搭建Anaconda Python3 6 FROM nvidia cuda 8 0 cudnn6 devel ubuntu16 04 MAINTAINER Tyan
  • TP-Link-IPC使用rtsp推流

    文章目录 1 安装 2 使用 3 RTSP 1 安装 电源 WIFI 2 使用 扫码或官网下载APP 登录绑定查看IP 登录IE浏览器 输入账号密码默认admin 123456 3 RTSP 注意 通过RTSP可以取视频流 但不支持控制云台
  • Linux samba网络传输服务

    Linux samba网络传输服务 本文章适合的读者 Linux初 中级用户 开源软件爱好者 大中专院校的学生 社会培训学生 Linux下的开发人员 samba 使用smb协议的应用程序 主要用于文件共享 SMB service messa
  • 实验七-卷积编码的MATLAB实现

    信息论编码实验3 9连载 更多看专栏 实验七 卷积编码的MATLAB实现 一 卷积码原理介绍 1 1 基本概念 1 2 n k N 卷积编码 1 2 1 编码 1 2 2 译码 Viterbi 译码算法 二 代码展示及运行结果 2 1 2
  • Mybatis处理一对多关系时的性能考虑

    Mybatis对于处理一对多的情况有三种解决方案 查询的时候join子表 然后交由mybatis拼装 查询的时候不join子表 另外发起select去抓取子表数据 和第二种类似 只不过利用fetchType lazy来延缓抓取的时机 这三种
  • JWT——Token认证的两种实现和安全详解

    前言 最近因为项目中需要解决跨域取值的问题 所有考虑到用Token认证做技术支撑点 自己看了许多与之相关的文章 从中总结出了以下两个要点 签名和token时间 在说这两个要点之前先大概简单说一下与之有关的一些问题 首先 如果你对token认
  • 【IT之路】连接MySQL遇到ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using passwor:yes)问题

    一般这个错误是由密码错误引起 解决的办法自然就是重置密码 假设我们使用的是root账户 1 重置密码的第一步就是跳过MySQL的密码认证过程 方法如下 vim etc my cnf 注 windows下修改的是my ini 在文档内搜索my
  • DenseNet网络详解及Pytorch实现

    DenseNet网络详解及Pytorch实现 DenseNet网络简介 DenseNet Densely Connected Convolutional Networks 是由Gao Huang等研究人员于2017年提出的一种深度神经网络架
  • dva.js 知识导图

    JavaScript语言 JavaScript语言 不要用 var 而是用 const 和 let 分别表示常量和变量 不同于 var 的函数作用域 const 和 let 都是块级作用域 模板字符串 模板字符串提供了另一种做字符串组合的方
  • HTTP与TCP的区别和联系

    相信不少初学应用网络程序开发的朋友都想知道Http与Socket连接究竟有什么区别 希望通过自己的浅显理解能对初学者有所帮助 一 基本概念 1 TCP连接 手机能够使用联网功能是因为手机底层实现了TCP IP协议 可以使手机终端通过无线网络
  • Java中常用的一种时间格式的转换方法

    有时需要将一种格式的时间转化成其他格式的时间 这里列举了一种常用的转换方法 将从控件获得类似于 Thu Jan 01 00 00 00 CST 2009 的时间格式转化称 yyyy MM dd 格式 DateFormat format1 n
  • Java基础16--面向对象:抽象类

    Java基础16 面向对象 抽象类 文章目录 Java基础16 面向对象 抽象类 概述 抽象类 继承抽象类 抽象方法 抽象类总结规定 概述 在面向对象的概念中 所有的对象都是通过类来描绘的 但是反过来 并不是所有的类都是用来描绘对象的 如果
  • 带你知道如何在Flask中集成支付宝第三方支付模块并进行联调?

    支付宝沙箱 支付宝沙箱基础配置 支付宝开放平台 如果从www alipay com访问 选择我是开发者 支付宝扫码登录 身份 自研开发者 控制台 gt 开发服务 gt 沙箱 gt 沙箱应用 沙箱 协助开发者进行接口开发及主要功能联调的模拟环
  • vue2.0 关于 vue.config.js配置项详解

    const CompressionPlugin require compression webpack plugin 引入gzip压缩插件 const TerserPlugin require terser webpack plugin 代
  • 基于Selenium+Python的web自动化测试框架详解

    目录 一 什么是Selenium 二 自动化测试框架 三 自动化框架的设计和实现 四 需要改进的模块 五 总结 一 什么是Selenium Selenium是一个基于浏览器的自动化测试工具 它提供了一种跨平台 跨浏览器的端到端的web自动化
  • iOS之LLVM编译流程和Clang插件开发集成

    LLVM 简介 一 什么是 LLVM LLVM 是构架编译器 compiler 的框架系统 以 C 编写而成 用于优化以任意程序语言编写的程序的编译时间 compile time 链接时间 link time 运行时间 runtime 以及
  • 读书:《少即是多》

    少即时多 是本田直之的一本书 他还写过 杠杆阅读术 杠杆时间术 杠杆思考术 等 现在社会 物质财富的获得变得相对容易 但并没有让人更幸福 或者快乐持续的时间很短 随之而来的是担心 忧虑和负担 真正带来幸福的反而是减法 如何做减法 断舍离 L
  • 0)Visual C++2017概述

    文章目录 一 概述 二 字符集 1 C运行时库对Unicode的支持 2 C 标准库对Unicode的支持 3 Windows API 对Unicode 的支持 4 Visual C 2017对Unicode 的支持 三 SDK编程基础 1