精华内容
下载资源
问答
  • Win10应用开发】自定义桌面壁纸 原文:【Win10应用开发】自定义桌面壁纸调用通用的API来设置桌面壁纸,是一件既简单又有趣的事情,结合XAML可以生成图像的特性,你甚至可以做一个应用,让用户用他所...
    原文:【Win10应用开发】自定义桌面壁纸

    调用通用的API来设置桌面壁纸,是一件既简单又有趣的事情,结合XAML可以生成图像的特性,你甚至可以做一个应用,让用户用他所拍的照片做成一张自定义壁纸,然后作为桌面壁纸。

    这个API是通用的,应用运行在任意Windows设备上都能使用,当然包括手机。在Windows.System.UserProfile命名空间下,有一个叫UserProfilePersonalizationSettings的类,它可以修改锁屏壁纸和桌面壁纸,调用后会返回bool值,如果成功就是true,如果人品不佳就返回false。

    在调用UserProfilePersonalizationSettings类前,先访问一下IsSupported方法,看看是否支持该操作。然后通过Current属性可以获取到一个UserProfilePersonalizationSettings实例,之后你就可以设置壁纸了。

    调用TrySetLockScreenImageAsync方法设置锁屏壁纸,调用TrySetWallpaperImageAsync方法可以设置桌面壁纸,参数都是用来作为背景的图片文件的StorageFile。

    从这也看到,用起来真的很简单,给你看个例子:

                // 设置壁纸
                if (!UserProfilePersonalizationSettings.IsSupported())
                {
                    msgbox.Content = "人品问题,不支持的操作。";
                    await msgbox.ShowAsync();
                    return;
                }
                UserProfilePersonalizationSettings settings = UserProfilePersonalizationSettings.Current;
                bool b = await settings.TrySetWallpaperImageAsync(file);
                if (b)
                {
                    msgbox.Content = "设置成功。";
                }
                else
                {
                    msgbox.Content = "操作失败。";
                }

     

    看看效果吧。在PC上运行是这样的。

     

    在手机上运行是这样的。

     

    然后以设置手机桌面壁纸为例,修改壁纸后的开始屏幕是这样的。

     

    如何,是不是很简单呢。

    示例下载地址:http://files.cnblogs.com/files/tcjiaan/CustomWallpage.zip

     

    posted on 2015-08-10 14:13 NET未来之路 阅读(...) 评论(...) 编辑 收藏

    转载于:https://www.cnblogs.com/lonelyxmas/p/4717883.html

    展开全文
  • 写在前面有过Win32编程经验的朋友都知道,使用Windows提供的API开发桌面应用是相当繁琐的,创建一个功能简单能接收并处理消息的窗口至少也得几百行代码。创建一个可视化的窗口一般要以下几个步骤: 第一步:定义入口...

    写在前面

    有过Win32编程经验的朋友都知道,使用Windows提供的API开发桌面应用是相当繁琐的,创建一个功能简单能接收并处理消息的窗口至少也得几百行代码。创建一个可视化的窗口一般要以下几个步骤:

    • 第一步:定义入口函数WinMain
    • 第二步:注册窗口类,在这一步你可以指定窗口类的菜单、光标、窗口过程函数等属性。
    • 第三步:定义窗口过程函数。
    • 第四步:创建窗口、显示窗口、更新窗口。
    • 第五步:消息循环。

    虽然这些步骤向导会为我们完成,但是由于windows系统是基于消息的,而且消息种类繁多,我们不得不通过大量的switch…case语句对不同的消息进行处理。

    为了方便程序员编写Windows应用,微软提供了一套基类库,简称MFC,使用MFC框架结合强大的集成开发工具Visual Studio,大大的简化了Windows桌面应用开发的难度。MFC对Windows API做了较深层次的封装,导致部分程序员对MFC的理解仅仅局限于工具的使用,他们只知道如何使用向导创建项目,如何使用向导添加一个消息处理函数,对MFC的消息映射、动态创建、文档视图结构等完全不了解。MFC目前在处于绝对垄断的地位,市面上绝大多数windows应用都使用MFC编写,Windows桌面应用开发第三方框架也比较少,其中Win32++是非常不错的一款。

    使用Win32++优势

    官网中提到,对于专业的开发人员来说,MFC无疑是最好的程序库,而且有微软这样强大的后盾。win32++面向的则是想使用更接近底层API编程方式的用户,对与想学习Win32 API的封装技巧以及Windows应用工作原理的新手来说,win32++也是不错的选择。

    对于新手来说Win32++有以下几方面的优势:

    • Win32++入门较为简单,MFC试图使用向导自动生成一些代码并且使用宏来隐藏一些复杂的操作,对于经验丰富的程序员来说效率非常高,但是对于新手来说他们对这些生成的代码并不能够理解,这并不是什么好事情。

    • 这套库本身是对Win32 API做了轻量级的封装,提供源码,代码相当整洁,而MFC显得过于庞大。

    • 我们无需过多学习就可以使用这套库,而MFC的学习难度远远大于Win32++.

    • 除了Visual Studio,Win32++可以使用免费的编译器编译。MFC依赖于Visual Studio,而且Visual Studio不便宜,从节省开发成本的角度考虑,Win32++也是不错的选择。Win32++集成开发工具可使用开源的Code::Blocks或Dev-C++等。

    Win32++下载与使用

    win32++官方网站:http://win32-framework.sourceforge.net/

    下载地址:http://sourceforge.net/projects/win32-framework/

    下载后解压,进入include目录,如下图所示,这便是Win32++框架的全部,相关类的声明和定义都写在头文件中,源码阅读起来较为方便,使用起来也比较方便,无需编译成lib文件,项目中直接引入这些头文件即可。

    这里写图片描述

    创建对话框应用

    1.新建Win32应用,在stdafx.h引入win32++头文件。
    2.创建对话框资源ID为IDD_DIALOG1 ,添加相应控件,如下图所示。
    这里写图片描述

    3.编写程序代码。

    // main.cpp
    #include "stdafx.h"
    #include "resource.h"
    
    // 定义CMyDialog对话框类
    class CMyDialog : public CDialog
    {
    public:
        CMyDialog(UINT nResID);
        virtual ~CMyDialog();
    
    protected:
        virtual void OnDestroy();
        virtual BOOL OnInitDialog();
        virtual INT_PTR DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
        virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
        virtual void OnOK();
    
    private:
        void OnButton();
    
        HMODULE m_hInstRichEdit;
    };
    
    
    class CDialogApp : public CWinApp
    {
    public:
        CDialogApp(); 
        virtual ~CDialogApp();
        virtual BOOL InitInstance();
        CMyDialog* GetDialog() {return &m_MyDialog;}
    
    private:
        CMyDialog m_MyDialog;
    };
    inline CDialogApp* GetDialogApp() { return static_cast<CDialogApp*>(GetApp()); }
    CDialogApp::CDialogApp() : m_MyDialog(IDD_DIALOG1)
    {
    }
    BOOL CDialogApp::InitInstance()
    {
        //显示模态对话框
        m_MyDialog.DoModal();
        return TRUE;
    }
    CDialogApp::~CDialogApp()
    {
    }
    
    CMyDialog::CMyDialog(UINT nResID) : CDialog(nResID)
    {
        m_hInstRichEdit = ::LoadLibrary(_T("RICHED32.DLL"));
        if (!m_hInstRichEdit)
            ::MessageBox(NULL, _T("CMyDialog::CRichView  Failed to load RICHED32.DLL"), _T(""), MB_ICONWARNING);
    }
    
    CMyDialog::~CMyDialog()
    {
        ::FreeLibrary(m_hInstRichEdit);
    }
    
    void CMyDialog::OnDestroy()
    {
        // 退出应用程序
        ::PostQuitMessage(0);
    }
    
    INT_PTR CMyDialog::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        return DialogProcDefault(uMsg, wParam, lParam);
    }
    
    BOOL CMyDialog::OnCommand(WPARAM wParam, LPARAM lParam)
    {
        UNREFERENCED_PARAMETER(lParam);
    
        switch (LOWORD(wParam))
        {
        case IDC_BUTTON1:   OnButton();     return TRUE;
        }
    
        return FALSE;
    }
    
    BOOL CMyDialog::OnInitDialog()
    {
        // 设置图标
        SetIconLarge(IDW_MAIN);
        SetIconSmall(IDW_MAIN);
        // 在Listbox中添加数据
        for (int i = 0 ; i < 8 ; i++)
            SendDlgItemMessage(IDC_LIST1, LB_ADDSTRING, 0, (LPARAM) _T("List Box"));
        return true;
    }
    
    void CMyDialog::OnOK()
    {
        MessageBox(_T("OK Button Pressed.  Program will exit now."), _T("Button"), MB_OK);
        CDialog::OnOK();
    }
    void CMyDialog::OnButton()
    {
        SetDlgItemText(IDC_STATIC3, _T("Button Pressed"));
        TRACE("Button Pressed\n");
    }
    
    
    int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
    {
        try
        {
            // 启动Win32++
            CDialogApp theApp;
            // 运行应用程序
            return theApp.Run();
        }
        // 捕捉异常
        catch (std::exception &e)
        {
            // 打印异常信息
            e.what();
            return -1;
        }
    }
    

    Win32++大多数类都和MFC重名,这样我们就不需要花时间去记忆这些类名。这里我们自己定义了两个类CMyDialog和CDialogApp分别从CDialog和CWinApp继承。

    在CMyDialog类中重写父类的OnInitDialog和OnCommand函数,这两个函数都是虚函数,OnInitDialog用于完成对话框的初始化工作,例如在文本框中增加文字、在ListBox中添加一些数据等操作,OnCommand函数则是用于处理对话框消息,在本例中我们將ID为IDC_BUTTON1的案例的消息交由CMyDialog类的成员函数OnButton处理。

    CDialogApp中定义了CMyDialog类型成员变量m_MyDialog。

    CDialogApp::CDialogApp() : m_MyDialog(IDD_DIALOG1)
    {
    }

    CDialogApp构造函数中,为m_MyDialog成员变量指定对话框资源ID为IDD_DIALOG1,在CDialogApp类的对象构造时同时也会初始化m_MyDialog对象。

    BOOL CDialogApp::InitInstance()
    {
        //显示模态对话框
        m_MyDialog.DoModal();
        return TRUE;
    }

    CDialogApp类重写了父类的InitInstance函数,并在InitInstance函数中调用m_MyDialog的DoModal函数显示模态对话框。

    int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
    {
        try
        {
            // 启动Win32++
            CDialogApp theApp;
            // 运行应用程序
            return theApp.Run();
        }
        // 捕捉异常
        catch (std::exception &e)
        {
            // 打印异常信息
            e.what();
            return -1;
        }
    }

    在入口函数WinMain中定义CDialogApp 对象theApp,调用父类的Run函数运行程序。

    编译运行

    效果如下:

    这里写图片描述

    展开全文
  • win32新建项目的详细代码注释 头文件及变量定义部分 //WindowsProject1.cpp: 定义应用程序的入口点。 // #include "stdafx.h" #include "WindowsProject1.h" #define MAX_LOADSTRING 100 // 全局变量: //...

    win32新建项目的详细代码注释

    头文件及变量定义部分

    //WindowsProject1.cpp: 定义应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include "WindowsProject1.h"
    
    #define MAX_LOADSTRING 100
    
    // 全局变量: 
    
    //HINSTANCE 是Windows里的一中数据类型,是用于标示(记录)一个程序的实例。
    //它与HMODULE是一样的(通用的,这两种类型最终就是32位无符号长整形)。
    //HINSTANCE,分开看就是 HANDLE(句柄) + INSTANCE(实例)
    //实例就是一个程序。用qq来举例:你可以开同时开2个qq号,但是你电脑里的qq软件只有一份。
    //这2个qq号就是qq的2个实例
    HINSTANCE hInst;                                // 当前实例x
    WCHAR szTitle[MAX_LOADSTRING] = _T("Welcome to PL0DE");                  // 标题栏文本
    WCHAR szWindowClass[MAX_LOADSTRING] = _T("PL0DE");            // 主窗口类名
    
    // 此代码模块中包含的函数的前向声明
    ATOM                MyRegisterClass(HINSTANCE hInstance);
    BOOL                InitInstance(HINSTANCE, int);
    // 如果应用程序的对话框中有“确定”按钮,那么用户单击该按钮时,
    // 操作系统会向应用程序发送一条消息,通知按钮已被单击。WndProc 负责对该事件作出响应。
    LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
    INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
    INT_PTR CALLBACK    Contact(HWND, UINT, WPARAM, LPARAM);
    
    
    
    

    程序入口部分

    // 正如每个 C/C++控制台应用程序在起始点必须具有 main 函数,每个基于 Win32 的应用程序的函数\
    也必须具有 WinMain 函数。WinMain就相当于是入口函数,并且具有固定的语法
    int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                         _In_opt_ HINSTANCE hPrevInstance,
                         _In_ LPWSTR    lpCmdLine,
                         _In_ int       nCmdShow)
    {
    	// 现在编译器在编译你的引用 hPrevInstance 的函数时便会住口,不会提示说没有使用此变量
    	// 那我们不使用为什么还需要呢,通常是因为 我们实现某个函数以满足某些API固有的署名需要
    	// 在这里就是使用了WINAPI,所以必须有这个变量的声明
        UNREFERENCED_PARAMETER(hPrevInstance);
        UNREFERENCED_PARAMETER(lpCmdLine);
    
        // TODO: 在此放置代码。
    
        // 初始化全局字符串
        LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
        LoadStringW(hInstance, IDC_WINDOWSPROJECT1, szWindowClass, MAX_LOADSTRING);
        // 创建+注册窗口类
    	if (!MyRegisterClass(hInstance)) {
    		MessageBox(NULL, _T("Call to RegisterClassEx failed!"), _T("Win32 Guided Tour"), NULL);
    		return 1;
    	}
    
        // 执行应用程序初始化: 
        if (!InitInstance (hInstance, nCmdShow))
        {
            return FALSE;
        }
    
    	// LoadAccelerators是用来加载快捷键表的
        HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT1));
    
        MSG msg;
        // 主消息循环: 
    	// 添加用于侦听操作系统所发送消息的消息循环。 
    	// 当应用程序收到一条消息时,此循环将该消息调度到 WndProc 函数以进行处理。
        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)
    {
    
    	//创建 WNDCLASSEX 类型的窗口类结构。 此结构包含关于窗口的信息
    	//例如应用程序图标、窗口背景色、标题栏中显示的名称、窗口过程函数的名称等
        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));
    
    	// 现在已创建了窗口类,必须进行注册
    	// 使用RegisterClassEx 函数,并将窗口类结构作为参数传递
        return RegisterClassExW(&wcex);
    }
    

    初始化/实例化部分

    //
    //   函数: InitInstance(HINSTANCE, int)
    //
    //   目的: 保存实例句柄并创建主窗口
    //
    //   注释: 
    //
    //        在此函数中,我们在全局变量中保存实例句柄并
    //        创建和显示主程序窗口。
    //
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
       hInst = hInstance; // 将实例句柄存储在全局变量中
    
       //  现在需要使用CreateWindow函数创建窗口
       // szWindowClass主窗口类名,szTitle是title名字
       // WS_OVERLAPPEDWINDOW:the type of window to create
       // CW_USEDEFAULT: initial position (x, y)
       // 0:initial size (width, length)
       // first nullptr:the parent of this window 
       // second nullptr:this application does not have a menu bar
       // hInstance: the first parameter from WinMain 
       // nullptr: not used in this application
       HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
    
       if (!hWnd)
       {
    	   MessageBox(NULL, _T("Call to CreateWindow failed!"), _T("Win32 Guided Tour"), NULL);
          return FALSE;
       }
    
       // 使用ShowWindow函数显示窗口
       // hWnd: CreateWindow函数返回的窗口句柄 
       // nCmdShow: the fourth parameter from WinMain 
       ShowWindow(hWnd, nCmdShow);
    
       // UpdateWindow函数用于更新窗口指定的区域
       // 如果窗口更新的区域不为空,UpdateWindow函数就发送一个WM_PAINT消息来更新指定窗口的客户区。
       // 函数绕过应用程序的消息队列,直接发送 WM_PAINT 消息给指定窗口的窗口过程
       // 如果更新区域为空,则不发送消息
       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)
    {
    	// WndProc 函数用以处理应用程序收到的消息
        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;
    			case IDM_CONTACT:
    				DialogBox(hInst, MAKEINTRESOURCE(IDD_CONTACTBOX), hWnd, Contact);
    				break;
                default:
                    return DefWindowProc(hWnd, message, wParam, lParam);
                }
            }
            break;
    	// WM_PAINT 代表收到了绘图消息
        case WM_PAINT:
    		//  WM_PAINT消息代表绘制主窗体
            {
                PAINTSTRUCT ps;
    			// 要处理 WM_PAINT 消息,首先应调用 BeginPaint
                HDC hdc = BeginPaint(hWnd, &ps);
    
    			// -----------------在这段代码对应用程序进行布局------------------------
                // TODO: 在此处添加使用 hdc 的任何绘图代码...
    			TCHAR greeting[] = _T("Hello, World!");
    			TextOut(hdc, 50, 5, greeting, _tcslen(greeting)); // TextOut 函数用于显示字符串
    			// FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
                // -----------------------布局模块结束--------------------------------
    
    			EndPaint(hWnd, &ps);
            }
            break;
        case WM_DESTROY:
    		//  WM_DESTROY消息代表投递一个退出消息并返回 
            PostQuitMessage(0);
            break;
        default:
    		//DefWindowProc缺省窗口处理函数
    		//这个函数是默认的窗口处理函数,我们可以把不关心的消息都丢给它来处理
            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;
    }
    
    // “联系”框的消息处理程序。
    INT_PTR CALLBACK Contact(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	UNREFERENCED_PARAMETER(lParam);
    	switch (message)
    	{
    	case WM_INITDIALOG:
    		return (INT_PTR)TRUE;
    	case WM_COMMAND:
    		// 这里面是框BOX内的按钮的名字
    		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
    		{
    			EndDialog(hDlg, LOWORD(wParam));
    			return (INT_PTR)TRUE;
    		}
    		break;
    	}
    	return (INT_PTR)FALSE;
    }
    
    
    展开全文
  • 本节课将简单介绍下使用C++开发Windows桌面应用的一些基础知识 目录: 准备你的开发环境 Windows 代码规范 操作字符串 什么是一个Window? WinMain:程序的入口点 1. 准备你的开发环境 安装 Windows SDK ...

    本节课将简单介绍下使用C++开发Windows桌面应用的一些基础知识

     目录:

    准备你的开发环境

    Windows 代码规范

    操作字符串

    什么是一个Window?

    WinMain:程序的入口点

    1. 准备你的开发环境

    安装 Windows SDK

           要用C或者C++开发Windows 程序,你必须安装 Microsoft Windows Software Development Kit (SDK)  或者一个包括Windows SDK的开发环境。

    这个Windows SDK 包含了头文件和编译链接你的程序所需的类库,这个Windows SDK 也包括Visual C++ 编译和链接命令行工具。

    尽管你用这个命令行工具可以编译和链接运行你的程序,但是还是建议你安装一个功能比较齐全的Microsoft Visual Studio.

    Visual C++ Express 是一个免费的可下载的Visual C++ 软件,Visual Studio Community是 Visual Studio Express 的更新替代产品。

    Windows SDK 集成IDE 下载(官方推荐):https://www.visualstudio.com/zh-hans/vs/visual-studio-express/

    Tips:

    这个Windows SDK 不支持硬件驱动的开发,在这个也不作讨论。

    如果想学习这方面的开发,请移步https://docs.microsoft.com/zh-cn/windows-hardware/drivers/gettingstarted/index

     Microsoft Visual C++ 2010 Express(已过时)是微软推出的一款免费软件,它比Microsoft Visual C++ 6.0 Enterprise Edition的兼容性和标准支持更好,比Microsoft Visual Studio 2010 Ultimate的体积更小。

     如果你对使用Visual C++ 2010 Express感兴趣,可以移步查看详细教程:https://msdn.microsoft.com/en-us/library/ff742833.aspx

    Windows代码规范

    如果你是一个开发Windows程序的新手,当你第一次看到一个WIndows程序的时候你可能会感到困惑。

    因为这个代码往往会出现像DWORD_PTR 和 LPRECT 一样充满了奇怪的类型定义和一些像hWnd 和 pwsz 变量(这称为匈牙利命名法)。学习这些代码规范是值得的。

    绝大多数Windows API由函数或 Component Object Model(COM)组件对象模型接口组成。

    很少有Windows API提供的C++类。(一个显著的例外是GDI+,一种二维图形API)

    Windows的头文件包含很多类型,这些很多都定义在头文件WinDef.h 中,下面这些是你经常会遇到的。

    你可以看到,在这些有一定数量的冗余类型。其中一些重叠仅仅是由于Windows API的历史。这里列出的类型有固定的大小,在32位和64个应用程序中的大小相同。例如,DWORD类型总是32位的

    Boolean Type

    BOOL是一个整数类型的值,用于布尔上下文定义。头文件 WinDef.h 也使用bool值定义了两个。

    BOOL is a typedef for an integer value that is used in a Boolean context. The header file WinDef.h also defines two values for use with BOOL

    #define FALSE    0 
    #define TRUE     1

    尽管布尔类型TRUE可以定义为任何一个非0的数字,但是你最好遵守规范总是TRUE设置为1

    正确的方式

    // Right way.
    BOOL result = SomeFunctionThatReturnsBoolean();
    if (result) 
    { 
        ...
    }

    错误的方式

    // Wrong!
    if (result == TRUE) 
    {
        ... 
    }

    Tips:注意BOOL是一个整数型且不可与C++ bool型互换。

    指针类型:

     Windows定义了很多表格 pointer-to-X 类型. 他们通常在名字的前面有前缀  P- or LP- .例如, LPRECT 是一个指向矩形的指针类型 , 这个矩形是一个描述了一个矩形的结构体.

    下面这样是等价的

    RECT*  rect;  // Pointer to a RECT structure.
    LPRECT rect;  // The same
    PRECT  rect;  // Also the same.

    历史上,P代表“指针”,LP代表“长指针”。长指针(也叫远指针)从16位Windows的延期,当他们需要解决内存范围以外的当前段。保留了LP前缀,使它更容易将32位Windows的16位代码移植到32位窗口中。

    但是今天没有区别——指针就是指针。

     指针精度类型

    以下数据类型始终是指针的大小,即32位应用程序中的32位宽,64位应用程序中的位宽为64位。大小是在编译时确定的。

    当32位应用程序在64位Windows上运行时,这些数据类型仍为4字节宽。(64位应用程序不能在32位Windows上运行,因此不会出现相反的情况。)

    • DWORD_PTR
    • INT_PTR
    • LONG_PTR
    • ULONG_PTR
    • UINT_PTR

     These types are used in situations where an integer might be cast to a pointer. They are also used to define variables for pointer arithmetic and to define loop counters that iterate over the full range of bytes in memory buffers. More generally, they appear in places where an existing 32-bit value was expanded to 64 bits on 64-bit Windows.

    在将整数转换为指针的情况下使用这些类型。它们还用于定义指针算术的变量,并定义循环计数器,迭代内存缓冲区中的所有字节。更一般地,它们出现在64位窗口上现有32位值被扩展到64位的地方。

    Hungarian Notation 匈牙利命名法

    匈牙利符号是将前缀添加到变量名中的实践,以便提供有关变量的附加信息。(符号的发明者查尔斯·西蒙尼是匈牙利人,因此得名)。

     操作字符串

    Windows本身支持UI元素,Unicode字符串的文件名,等等。Unicode是首选字符编码,因为它支持所有字符集和语言。Windows是Unicode字符使用UTF-16编码,其中每个字符被编码为一个16位的值。UTF-16字符称为宽字符,以区别于8位ANSI字符。Visual C++编译器支持宽字符的内置数据类型

    WinNT.h  头文件中也定义了以下类型

    typedef wchar_t WCHAR;

    你会看到在MSDN的例子代码的两个版本。若要声明宽字符文字或宽字符串文字,请将 L 置于文字之前。

    wchar_t a = L'a';
    wchar_t *str = L"hello";

    这里有一些其他的字符串相关的定义,你会看到:

    Unicode和ANSI函数

     当微软向Windows引入Unicode支持时,它通过提供两组并行API,一个用于ANSI字符串,另一组用于Unicode字符串,从而缓解了过渡。

    例如,设置窗口标题栏的文本有两个函数:

    SetWindowTextA //takes an ANSI string.
    SetWindowTextW //takes a Unicode string.

     

     实际上真正使用的时候会加上判断这样定义

    #ifdef UNICODE
    #define SetWindowText  SetWindowTextW
    #else
    #define SetWindowText  SetWindowTextA
    #endif 

     

     在MSDN中,函数的名字记录SetWindowText函数下,即使那是真的宏的名字,不是实际的函数名。

    新的应用程序应该总是调用Unicode版本。许多世界语言都需要Unicode。如果使用ANSI字符串,将不可能本地化应用程序

    ANSI版本的效率也较低,因为操作系统必须在运行时将ANSI字符串转换为Unicode。

    根据你的喜好,你可以调用Unicode功能明确,如setwindowtextw,或者使用宏。MSDN上的示例代码通常会调用宏,但两种形式是完全等价的。Windows中大多数更新的API只有Unicode版本,没有相应的ANSI版本

     当应用程序需要同时支持Windows NT以及Windows 95、Windows 98和Windows Me 时,根据目标平台编译ANSI或unicode字符串相同的代码是非常有用的。

    为此,Windows SDK提供了将字符串映射到Unicode或ANSI的宏,这取决于平台

    下面是个例子:

    SetWindowText(TEXT("My Application"));

    解析如下:

    SetWindowTextW(L"My Application"); // Unicode function with wide-character string.
    
    SetWindowTextA("My Application");  // ANSI function.

    TEXT 和 TCHAR  宏今天已经很少用了,因为所有的应用程序都应该使用Unicode ,然而你可能在MSDN看到一些这样的代码:

    然而,你可能会在旧的代码和一些MSDN代码例子看到他们。
    微软C运行时库的标题定义了一组类似的宏

    #ifdef _UNICODE
    #define _tcslen     wcslen
    #else
    #define _tcslen     strlen
    #endif 

     

     注意:有些标题使用预处理器符号Unicode,别人用_unicode使用下划线前缀。总是定义这两个符号。当你创建一个新项目,Visual C++将它们通过默认的方式设置。

     什么是Window?

     显然,Windows是Windows的中心。它们是如此重要,以至于他们在操作系统之后命名了操作系统。

    但是什么是窗口?当你想到一个窗口,你可能会想到这样的东西:

    这种类型的窗口称为应用程序窗口或主窗口。它通常有一个标题栏、最小化和最大化按钮以及其他标准UI元素的框架。

    该框架称为窗口的非客户端区域,之所以称为“窗口”,是因为操作系统负责管理窗口的那部分。框架内的区域是客户区。这是您的程序管理的窗口的一部分。

    这里是另一种类型的窗口:

    如果您是Windows编程新手,您可能会惊讶于UI控件,如按钮和编辑框本身就是Windows。UI控件和应用程序窗口之间的主要区别在于控件本身并不存在。

    相反,控件相对于应用程序窗口定位。当拖动应用程序窗口时,控件将随它移动,如您所期望的那样。另外,控件和应用程序窗口可以相互通信。

    (例如,应用程序窗口从按钮接收单击通知。)

    因此, 当你考虑window时, 不要把它简单地认为是个应用窗口,取而代之的是一种编程结构:

    占据屏幕的某一部分。
    在某一时刻可能不可见。
    知道如何画自己。
    响应来自用户或操作系统的事件。

    Parent Windows and Owner Windows 父窗口和所有者窗口

    在UI控件的情况下,控件窗口被称为应用程序窗口的子窗口。应用程序窗口是控件窗口的父窗口。父窗口提供用于定位子窗口的坐标系统。有父窗口会影响窗口外观的各个方面;例如,子窗口被裁剪,这样子窗口的任何部分都不能出现在其父窗口的边框外面。
    另一种关系是应用程序窗口和模式对话框窗口之间的关系。当应用程序显示一个模态对话框时,应用程序窗口是所有者窗口,而对话框是一个拥有窗口。拥有的窗口总是出现在它的所有者窗口前面。当所有者被最小化时,它被隐藏,并在所有者被销毁的同时被销毁。
    下图显示了一个应用程序,其中显示一个带有两个按钮的对话框:

    这个应用窗口有自己的对话框窗口,这个对话框窗口是父窗口中的两个按钮

    下面是这两者之间的关系:

    Window Handles

    窗口对象既有代码和数据,但他们都不是C++类。相反,程序使用一个称为Handle(句柄)的值引用一个窗口

    一个Handle 是一个不透明类型。本质上,它只是操作系统用来标识对象的一个数字。您可以将窗口视为创建所有窗口的大表。它使用此表通过Hanlder查找窗口。(无论是它是如何工作的内部是不重要的。)

    窗口的数据类型Hanlder是一个HWND,这通常是明显的“aitch-wind“。窗口句柄是由函数返回:CreateWindowCreateWindowEx创建窗口。

    在一个窗口进行操作,你通常会调用一些函数有一个窗口的句柄值作为参数。例如,复位窗口在屏幕上,调用MoveWindow函数:

    BOOL MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint);

     

     第一个参数是要移动的窗口的句柄。其他参数指定窗口的新位置和窗口是否应该重绘.

    记住句柄不是指针。如果窗口是一个变量,包含一个hanlder,试图引用句柄HWND  *hwnd 这样写是错误的。

    屏幕和窗口坐标

    坐标是以设备无关的像素来度量的。在讨论图形时,我们将更多地讨论与设备无关的像素的与设备无关的部分。
    根据您的任务,您可以测量相对于屏幕的坐标,相对于窗口(包括帧),或相对于窗口的客户端区域。

    例如,您将使用屏幕坐标在屏幕上定位窗口,但您将使用客户机坐标在窗口中绘图。在每种情况下,原点(0, 0)总是区域的左上角。

    WinMain: 程序入口点

    每一个Windows程序,都有一个入口函数,叫做WinMainwWinMain

    int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow);

     

    这四个参数的意义:

    hInstance :          是一种叫做“实例的句柄”或“处理模块”的操作系统使用这个值来确定可执行文件(EXE)时,在内存中加载。实例句柄是某些Windows功能-例如,加载图标或位图。

    hprevinstance:    没有意义。它在16位窗口中使用,但现在总是0。

    pcmdline:            包含命令行参数作为一个Unicode字符串。

    ncmdshow:          是一个标志,是应用程序的主窗口将被最小化,最大化,或显示正常。

    函数返回一个int类型的值。操作系统不使用该返回值,但你可以使用返回值将状态代码发送给您编写的其他程序。

    WINAPI 的调用约定。调用约定定义函数如何从调用者接收参数。例如,它定义了参数出现在堆栈上的顺序。只要确保你wWinMain函数如下声明。

    WinMain 函数和 wWinMain是相同的,唯一不同的是命令行参数作为一个ANSI字符串,Unicode 版本是首选。

    你可以使用ANSI WinMain 函数,尽管你编译的程序是以Unicode编码。要得到一个Unicode字符编码的命令行参数,可以调用 GetCommandLine 函数。

    这个函数将返回一个单一的字符串,如果你想作为一个参数式阵列的参数,通过这个字符串CommandLineToArgvW

    CRT内部主要做一些额外的工作。例如,静态初始化器是之前调用wWinMain。虽然可以告诉链接器使用不同的入口点函数,但如果链接到CRT,则使用默认值。

    否则,将跳过CRT初始化代码,结果不可预测。(例如,全局对象初始化不正确)。

    这是一个空的函数

    INT WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        PSTR lpCmdLine, INT nCmdShow)
    {
        return 0;
    }

    现在你已经拥有了入口点并理解了一些基本术语和编码约定,下篇博文我们就可以创建一个完整的窗口程序了。

     

    转载于:https://www.cnblogs.com/xingyunblog/p/7142445.html

    展开全文
  • PHP桌面应用开发思考

    2014-05-06 18:59:00
    PHP在5.3后,已经支持完整GC(垃圾回收),在桌面应用开发上,应该可以达到实用级别。WIN32的桌面开发,无非是调用WIN32API来实现,可以通过C扩展开发PHP插件来完成,但是,有一个问题不得不考虑,PHP是动态脚本语言...
  • 基于Windows平台的ATL/WTL桌面应用程序开发. 使用C/C++作为开发语言, 开发Windows本地桌面程序. WTL界面库是MFC的替代选择, 是Win32界面编程的薄封装,可以说学会WTL开发即学会了Win32界面开发。 适合中小型公司开发...
  • VS_win桌面程序开发_1

    2020-09-06 10:07:33
    // WM_COMMAND - 处理应用程序菜单 // WM_PAINT - 绘制主窗口 // WM_DESTROY - 发送退出消息并返回 // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch ...
  • Windows Store App的开发与传统的Windows桌面应用程序有着很大的不同,我们可以通过下面这个图了解一下两者的不同之处,了解这个很重要,只有了解了Windows Store App的底层机制,你才能更好地为你的应用程序设计UI...
  • 据知名编辑扎克鲍登发布的消息,微软准备重新开发PWA渐进式网络应用Monarch 来替代系统附带的邮件应用。Project Monarch是目前该产品的代号并非最终名称,消息称该应用是具有跨平台的 PWA 渐进式网络应用程序。当然...
  • 解决方法 升级.NET Framework到最新 下载地址 .NET Framework
  • WTL是对Win32窗口的薄封装,库是原微软员工开发,是MFC的替代选择。掌握了WTL表示你已经基本掌握了Win32的窗口编程. 6. 使用WTL库完全使用C++开发,不需要其他编程语言,减少学习成本和复杂度,整个WTL是开源可控的...
  • win10应用开发——如何判断应用是在手机上...在进行uwp应用开发的时候, 有时我们需要知道自己的应用是在手机端运行还是在桌面端运行,那么通过以下的api就可以进行判断: Windows.System.Profile.AnalyticsIn...
  • 另外,一些 Win RT API 还可用于在 Windows 8 上开发桌面应用,这意味着开发人员可轻松将他们的传统 Windows 应用移植至 Windows 8 桌面应用。 以下一系列文章详解了一个简单的超极本图片应用。该应用将展示开发...
  • 一番码客 : 挖掘你关心的亮点。 ... 文章目录前言安装并使用element-...操作仍然是在win10下的powershell下进行的。主要记录element-ui的安装与使用。 安装并使用element-ui 安装 在项目根目录,执行如下命令完成elem...
  • 工欲善其事,必先利其器,开发win8,我用的开发环境是win8 +vs2012,在安装VS2012时,顺便装一下...如果你开发过winform桌面应用程序,你就会感觉win8程序很熟悉,它上面也有一些控件,可以拖放,但是要创建一个漂亮的
  • 有图有真相,看来html5+js又是一种选择了,直接开发桌面运用程序,不要用浏览器 转载于:https://www.cnblogs.com/suguoqiang/archive/2012/02/28/2372633.html
  • 闲来无聊,正好小组人员讨论到桌面开发,那把笔者接触的WIndows平台下的几个主要的发展过程聊一聊。 主要从概述,参考资料,图书等几个方面说起。 所有的界面开发都会涉及如下的几个方面的内容: v 控件 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 589
精华内容 235
关键字:

win桌面应用开发