精华内容
下载资源
问答
  • 广义上讲,IME是微软提供的Windows平台的一套输入法编程规范,依照这套规范(框架),你不需要处理太多输入法特性相关的操作(光标跟随,输入捕获,字码转换后输出到应用程序等),你只需要使用IME规范里面提供的...

    应该也有人会遇到这样的困扰:就是在edit或是richedit控件中输入时,输入法的提示框位置不正确。

    何为HIMC

    什么是IME (Input Method Editors)?广义上讲,IME是微软提供的Windows平台的一套输入法编程规范,依照这套规范(框架),你不需要处理太多输入法特性相关的操作(光标跟随,输入捕获,字码转换后输出到应用程序等),你只需要使用IME规范里面提供的工具函数(imm32库),实现规范所指定必须导出的接口即可。实际上你要做的就是写一个导出函数包含IME规范规定的接口的dll,所以,狭义上讲IME就是你写的这个dll。

    HIMC实际上是个DWORD类型,一般在启动或关闭输入法时用到。
    头文件和库:

    #include   <imm.h> 
    #pragma   comment(lib, "imm32.lib ")

    如何获取HIMC

    通过函数:ImmGetContext
    Returns the input context associated with the specified window.

    An application should routinely use this function to retrieve the current input context before attempting to access information in the context.
    The application must call ImmReleaseContext when it is finished with the input context.

    重要的是看返回值:
    Returns the handle to the input context.

    结构体COMPOSITIONFORM 是干什么的?
    作用:
    Contains style and position information for a composition window.
    原型:

    typedef struct tagCOMPOSITIONFORM {
      DWORD dwStyle;
      POINT ptCurrentPos;
      RECT  rcArea;
    } COMPOSITIONFORM, *PCOMPOSITIONFORM;
    

    GetCaretPos函数就不需要再解释了:
    该函数将插入标记的位置(按客户区坐标)信息拷贝到指定的POINT结构中

    ImmSetCompositionWindow函数怎样设置的?
    作用:
    Sets the position of the composition window.
    原型:

    BOOL ImmSetCompositionWindow(
      _In_ HIMC              hIMC,
      _In_ LPCOMPOSITIONFORM lpCompForm
    );

    等等,我们还没有完。

    就像获得设备描述表一样,有获取,就要有释放.

    ImmReleaseContext函数来释放:
    作用:
    此函数释放输入上下文和解锁相关联的内存。应用程序必须调用ImmReleaseContext为对应每一个ImmGetContext。
    原型:

    BOOL ImmReleaseContext(
    HWND hWnd,
    HIMC hIMC
    );

    有了以上的储备,工作变得简单。

    if (uMsg == WM_IME_COMPOSITION)
    {
            HIMC hIMC = ImmGetContext(m_hWnd);//获取
            if (hIMC)
            {
                // Set composition window position near caret position
                POINT point;
                GetCaretPos(&point);//获取输入光标位置,存入point结构体
    
                COMPOSITIONFORM Composition;
                Composition.dwStyle = CFS_POINT;
                Composition.ptCurrentPos.x = point.x;
                Composition.ptCurrentPos.y = point.y;
                ImmSetCompositionWindow(hIMC, &Composition);//设置
    
                ImmReleaseContext(m_hWnd, hIMC);//释放
            }
    }

    good job!

    展开全文
  • 桌面客户端开发框架技术选型

    千次阅读 2021-02-14 23:00:35
    C/S 架构是软件产品的主流,后面渐渐地被 B/S 架构所取代(因为不需要配置客户端),但由于浏览器有刷新机制,服务器的负载等因素,C/S 架构的响应速度和流畅性是好于 B/S 架构的,所以现在软件开发的趋势是两者的...

    https://static001.infoq.cn/resource/image/ac/06/acd31d24679f4f819153aafdaa7b0506.jpg

    互联网出现之前,C/S 架构是软件产品的主流,后面渐渐地被 B/S 架构所取代(因为不需要配置客户端),但由于浏览器有刷新机制,服务器的负载等因素,C/S 架构的响应速度和流畅性是好于 B/S 架构的,所以现在软件开发的趋势是两者的融合,一般是 B/S 架构开发的产品可以非常方便地转移到 C/S 架构下。客户端(client)是 C/S 架构软件产品中重要的一部分,除了和用户交互、本地处理数据的强大功能,顺畅的体验和美观的样式也是客户端技术追求的目标。这里和大家介绍桌面版应用程序的一些历史和现在比较流行的 electron 技术。

    桌面版应用程序历史

    桌面应用程序,又称为 GUI 程序。可以分为以下几个阶段:

    • VB,上古程序员的开发工具,曾经全球第一的开发语言,拖拽式的图形化开发让它成为极佳的桌面开发工具。微软依靠其操作系统的优势,一直压制同时期的竞争对手 delphi。微策略早期应用该技术,开发了管理智能商务平台的大杀器 developer。
    • C++、win32API 的 MFC 方案是基于窗口中组合控件和消息传递机制。这也是 20 多年前的技术,所以 API 设计的不是很友好。几年前微软已经停止维护,简单来说它已经过时了。
    • Winform 微策略几年前基于该技术研发第一代的 Desktop 版本,但是从开发体验角度来说自定义、美化控件会比较麻烦。
    • C# .net framework,代表就是 WPF,它的原生特性是其他类库无法比拟的:High DPI、Split Screen 以及对 DirectX 的天然优势。但是并不开源,需要依赖.net 框架,还有就是启动会比较慢。Workstation Windows 的新客户端就是基于该技术研发。
    • Java swing/javaFx,这是一类比较大的阵营,优势是跨平台和流行开发语言 Java 的天然结合,但开发出来的界面作者个人认为并不美观。
    • C++ Qt,这是很多客户端跨平台的首选,因为开源、UI 库和各种功能的类库非常丰富,但是学习成本比较高。
    • C++ duilib,这是 windows 下开源的 directUI(微软提出的分离 UI 和逻辑的思想)库,它是迎合互联网桌面软件小而美的趋势发展起来的,可能大家对它的关注度比较少。但是用它开发出的产品大名鼎鼎,比如 QQ、微信、爱奇艺等很多知名度高的软件。
    • Objective-c/swift cocoa,这是 mac 平台下的方案。可以方便调用底层的 API,缺点是不跨平台,文档不友好,UI 库并不丰富。现在这种方式开发的越来越少了。

    基于 Web 技术的桌面应用开发

    从 B/S 和 C/S 架构逐渐融合的角度来说,基于 Web 技术进行桌面程序的开发渐渐变成了主流。因为对界面的代码部分可以做到复用。

    这类技术早期的方案是用 vb 内嵌 webBrowser 控件,基于 IE 内核,正好很多网页开发也有用 activeX 的需求,但这种方式具有明显的缺陷——非常依赖于用户的环境,会因为组件缺失导致程序各种崩溃。第二类是嵌入式网页框架,这类技术主要是基于浏览器引擎实现 UI 渲染。比较典型的就是 appkit 上面 UIWebView 和 CEF(chro-mium embeded framework)。这种方法可以使用网页 HTML5+CSS 实现各种酷炫的效果,但是缺点也比较明显,就是桌面程序里面嵌入了一个类似 Chrome 的浏览器,内存的开销会比较大。

    后面出现了 nwjs 和 electron,electron 相比 CEF 有了单独执行 js 的 v8 引擎,可以运行 NodeJS 来完成服务器端功能,通过和内部浏览器的 v8 引擎交互可以实现一个独立的客户端,这不同于 CEF 需要寄宿在其他程序内部。

    Electron

    https://static001.infoq.cn/resource/image/82/71/8230406c39089c55996ec023fc553871.png

    用 Electron 来做桌面程序开发的优势明显,相当于是完全的网页编程,有 Web 开发经验的前端开发上手非常容易。Web 开发生态广泛,开发成本低,可扩展性强,一些流行的前端框架例如 React、Angular、Vue 都可以和 electron 结合进行开发。另外它也具备和 Qt 一样跨平台的优良特性。对性能要求不高的桌面版程序来说,一份代码同时得到网页版和各个平台的桌面版,开发的效率是其他方案无法比的。可以说,这是大部分人看好的趋势。

    和 Web 开发的区别

    前端开发的一个痛点就是经常需要考虑多种浏览器之间的兼容,但是使用 electron 开发则不存在这样的问题,它只需要考虑 electron 中对应 Chrome 的版本。另一个使用 electron 解决的痛点是跨域,它可以绕过客户端直接通过 NodeJS 里的 request 通信模块发出请求,这样就无需被跨域所困扰。

    扩展能力

    node-ffi 可以在 NodeJS 环境中调用动态链接库接口。通过这种方式,我们可以把 JavaScript 方法映射到动态链接库接口,从而实现 C++ 类库的接入。

    Electron 运行原理

    https://static001.infoq.cn/resource/image/39/47/39c7055c50f9ec4e2918c74e60f12c47.png

    Electron 的运行机制可以从两种进程说起:主进程和渲染进程。运行 package.json 的称为主进程,它可以负责创建渲染进程(多个)。下图是一段主进程代码,主进程负责创建一个浏览器实例来加载网页。每个创建的浏览器实例都在它自己的渲染进程内返回一个 Web 页面。当 BrowserWindow 实例销毁时,相应的渲染进程也会终止。主进程负责掌管所有的 Web 页面和它们相应的渲染进程。每个渲染进程都是相互独立的,它们只关心自己所运行的 Web 页面。

    const electron = require('electron');const app = electron.app;const BrowserWindow = electron.BrowserWindow;var window = null;app.on('ready', function() { window = new BrowserWindow({width: 800, height: 600}); window.loadURL('<https://microstrategy.com>');});

    复制代码

    主进程还负责应用程序的生命周期(app 打开退出)和一些 app 事件的监听,同时负责系统底层 API 的调用。创建的渲染进程用来展示 HTML + CSS 技术编写的 Web 页面, 同时可以运行 JavaScript 实现交互,可以把渲染进程简单理解为 Chrome 上打开的一个浏览器进程。

    <html> <body> <script> const remote = require('electron').remote; console.log(remote.app.getVersion()); </script> </body></html>

    复制代码

    在渲染进程中是不允许调用原生 GUI 相关的 API,那是因为在网页中掌管原生 GUI 很危险,易造成内存泄露。如果你想在网页中进行 GUI 的操作,渲染进程必须向主进程传达请求,然后在主进程中完成操作。

    Electron 封装了一系列自己的 API 可供主进程和渲染进程调用。可以通过如下方式获取:

    const {app, BrowserWindow, ipcMain, ... } = require('electron'); // 仅主进程可用const {ipcRender, remote, ... } = require('electron'); // 仅渲染进程可用

    复制代码

    主进程和渲染进程均可直接调用 NodeJS 的 API:

    node1.addEventListener('click', () => { console.log(os.path.basename('xxxx');})

    复制代码

    进程通信

    渲染进程如何向主进程发送消息

    通信本质上基于 nodeJS 的事件基础类 Event-Emitter,ipcMain 和 ipcRender 都是该类的实例,通过事件模型需要的接口方法,采用了发布 / 订阅的方式来发送和监听消息。

    异步方式:

    import { ipcRender } from 'electron'; // 在渲染进程引入 ipcRender,它是 EventEmitter 的一个实例ipcRender.send('async', 'I am from webview'); // 可以异步发送

    复制代码

    同步方式:

    import { ipcRender } from 'electron'; // 在渲染进程引入 ipcRenderipcRender.sendSync('sync', 'I am sync sent from webview'); // 同步方式

    复制代码

    通过同步方式发送会 block 整个渲染进程,直到主进程响应。

    主进程会加载 ipcMain 来进行监听。

    import { ipcMain } from 'electron'; // 在主进程引入 ipcMainipcMain.on('async', (event, info) { console.log(info);});

    复制代码

    除此以外, electron 还提供了一种简单的方案(remote 模块)来实现渲染进程和主进程的通信。这样就可以不必显示地发送消息。

    import { remote } from 'electron'; // 在渲染进程引入 remoteremote.mainProcessObject.invokeMethod(); // 调用主进程才有的方法});

    复制代码

    主进程如何向渲染进程发送消息

    主进程通过找到渲染进程对应的 browserWindow 就可以发送消息。

    constant window = BrowserWindow.fromId(global.id); // 通过 id 来进行对应window.webContents.send('msg', 'hello world');

    复制代码

    渲染进程监听:

    ipcRender.on('msg', (event, info) => { console.log(info)});

    复制代码

    渲染进程之间共享数据

    一种可行的方案是在主进程实现消息的转发。还有比较简单的方案是通过浏览器实现的 HTML API,比如 localStorage, sessionStorage 或者 IndexedDB,或者通过主进程创建全局变量 sharedObject 来实现渲染进程的数据共享。

    以上是一些 electron 技术的初步介绍,有兴趣的读者可以继续阅读详细的官方文档来深入学习。目前来看 electron 不能算一个年轻的开源项目, 还有不少新的桌面替代技术在涌现(比如 miniblink)。

    作者介绍:

    徐瑞青,高级软件工程师,毕业于鲁汶大学电子工程系。2014 年加入微策略,目前在数据 gateway 部门参与数据建模、清洗的开发工作,也参与过 Workstation 数据导入的早期开发。

    本文转载自微信公众号:微策略 商业智能

    展开全文
  • Delphi 三层框架开发客户端开发

    千次阅读 2014-10-24 15:04:14
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, DB, DBClient, MConnect, SConnect, Grids, DBGrids, ExtCtrls, ActnList,ufrmCreate; type TfrmMain = ...

    新建一个application

    如图 添加以下控件


     先启动scktsrvr.exe   此 在dephi程序的bin目录下  ) 然后   启动服务端 


    再进行属性设置


    代码如下

    <pre name="code" class="delphi">unit ufrmMain;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, DB, DBClient, MConnect, SConnect, Grids, DBGrids,
      ExtCtrls, ActnList,ufrmCreate;
    
    type
      TfrmMain = class(TForm)
        sconn: TSocketConnection;
        btnInit: TButton;
        dbgrdDep: TDBGrid;
        ds3: TDataSource;
        dsTemp: TClientDataSet;
        pnl1: TPanel;
        btnNew: TButton;
        btnModify: TButton;
        btnSave: TButton;
        btnCancel: TButton;
        btn2: TButton;
        actlst1: TActionList;
        actCreate: TAction;
        actModify: TAction;
        actSave: TAction;
        actCancel: TAction;
        actDelete: TAction;
        btnPostData: TButton;
        procedure btnInitClick(Sender: TObject);
        procedure actSaveExecute(Sender: TObject);
        procedure btnSaveClick(Sender: TObject);
        procedure btnCancelClick(Sender: TObject);
        procedure actCancelExecute(Sender: TObject);
        procedure btn2Click(Sender: TObject);
        procedure actDeleteExecute(Sender: TObject);
        procedure btnModifyClick(Sender: TObject);
        procedure btnNewClick(Sender: TObject);
        procedure actCreateExecute(Sender: TObject);
        procedure actModifyExecute(Sender: TObject);
        procedure btnPostDataClick(Sender: TObject);
        procedure dsTempAfterInsert(DataSet: TDataSet);
      private
        procedure EnableControl(Flag:Boolean);
      public
        { Public declarations }
      end;
    
    var
      frmMain: TfrmMain;
    
    implementation
    
    {$R *.dfm}
    //添加函数
    function GetGUID: string;        //add lgm
    var
      LTep: TGUID;
    begin
      CreateGUID(LTep);
      Result := GUIDToString(LTep);
    end;
    
    
    
    procedure TfrmMain.btnInitClick(Sender: TObject);
    var
      a:OleVariant;
    begin
      sconn.Open;
      sconn.AppServer.GetData('tb_Department','1=1',a);
      dsTemp.Data:=a;
      sconn.Close;
    end;
    
    procedure TfrmMain.actSaveExecute(Sender: TObject);
    begin
       if dsTemp.State in [dsEdit,dsInsert] then
       begin
         dsTemp.Post;
         EnableControl(False);
       end;
    end;
    
    procedure TfrmMain.btnSaveClick(Sender: TObject);
    begin
      actSave.Execute;
    end;
    
    procedure TfrmMain.btnCancelClick(Sender: TObject);
    begin
      actCancel.Execute;
    end;
    
    procedure TfrmMain.actCancelExecute(Sender: TObject);
    begin
      if dsTemp.State in [dsEdit,dsInsert] then
      begin
        dsTemp.Cancel;
        EnableControl(False);
      end;
    end;
    
    procedure TfrmMain.btn2Click(Sender: TObject);
    begin
    
      actDelete.Execute;
    end;
    
    procedure TfrmMain.actDeleteExecute(Sender: TObject);
    begin
      if dsTemp.eof and dsTemp.bof then exit;
      if MessageDlg('是否删除?',mtWarning,[mbYes,mbNo],-1)=mrYes then
      begin
        dsTemp.Delete;
      end;
    end;
    
    procedure TfrmMain.btnModifyClick(Sender: TObject);
    begin
      if dsTemp.Active then
      if dsTemp.eof and dsTemp.bof then exit;
      actModify.Execute;
    end;
    
    procedure TfrmMain.btnNewClick(Sender: TObject);
    begin
      if dsTemp.Active then
      actCreate.Execute;
    end;
    
    procedure TfrmMain.actCreateExecute(Sender: TObject);
    begin
      frmCreate:=TfrmCreate.Create(self);
      try
        frmCreate.IsCreate:=True;
        if  frmCreate.ShowModal=mrOK then
        begin
          EnableControl(true);
        end;
      finally
        frmCreate.Free;
      end;
    end;
    
    procedure TfrmMain.actModifyExecute(Sender: TObject);
    begin
      frmCreate:=TfrmCreate.Create(self);
      try
        frmCreate.IsCreate:=False;
        if  frmCreate.ShowModal=mrOK then
        begin
          EnableControl(true);
        end;
      finally
        frmCreate.Free;
      end;
    end;
    
    procedure TfrmMain.EnableControl(Flag: Boolean);
    begin
      btnCancel.Enabled:=Flag;
      btnSave.Enabled:=Flag;
      btnNew.Enabled:=not Flag;
      btnModify.Enabled:=not Flag;
    end;
    
    procedure TfrmMain.btnPostDataClick(Sender: TObject);
    var
      b:OleVariant;
    begin
      //先进行保存
      actSave.Execute;
      sconn.Open;
      sconn.AppServer.PostData('tb_Department',dstemp.Data,b);
      sconn.AppServer.GetData('tb_Department','1=1',b);
      dsTemp.Data:=b;
      sconn.Close;    
    end;
    
    procedure TfrmMain.dsTempAfterInsert(DataSet: TDataSet);
    begin
      dsTemp.FieldByName('FKey').AsString:=GetGUID;
    end;
    
    end.C


    dfm代码
    object frmMain: TfrmMain
      Left = 724
      Top = 400
      Width = 588
      Height = 369
      Caption = 'frmMain'
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'MS Sans Serif'
      Font.Style = []
      OldCreateOrder = False
      PixelsPerInch = 96
      TextHeight = 13
      object btnInit: TButton
        Left = 88
        Top = 285
        Width = 75
        Height = 25
        Caption = #21152#36733#25968#25454
        TabOrder = 0
        OnClick = btnInitClick
      end
      object dbgrdDep: TDBGrid
        Left = 0
        Top = 41
        Width = 572
        Height = 204
        Align = alTop
        DataSource = ds3
        Options = [dgTitles, dgIndicator, dgColumnResize, dgColLines, dgRowLines, dgTabs, dgRowSelect, dgConfirmDelete, dgCancelOnExit]
        TabOrder = 1
        TitleFont.Charset = DEFAULT_CHARSET
        TitleFont.Color = clWindowText
        TitleFont.Height = -11
        TitleFont.Name = 'MS Sans Serif'
        TitleFont.Style = []
      end
      object pnl1: TPanel
        Left = 0
        Top = 0
        Width = 572
        Height = 41
        Align = alTop
        TabOrder = 2
        object btnNew: TButton
          Left = 15
          Top = 7
          Width = 75
          Height = 25
          Caption = #26032#24314
          TabOrder = 0
          OnClick = btnNewClick
        end
        object btnModify: TButton
          Left = 107
          Top = 7
          Width = 75
          Height = 25
          Caption = #20462#25913
          TabOrder = 1
          OnClick = btnModifyClick
        end
        object btnSave: TButton
          Left = 198
          Top = 7
          Width = 75
          Height = 25
          Caption = #20445#23384
          Enabled = False
          TabOrder = 2
          OnClick = btnSaveClick
        end
        object btnCancel: TButton
          Left = 290
          Top = 7
          Width = 75
          Height = 25
          Caption = #21462#28040
          Enabled = False
          TabOrder = 3
          OnClick = btnCancelClick
        end
        object btn2: TButton
          Left = 411
          Top = 7
          Width = 75
          Height = 25
          Caption = #21024#38500
          TabOrder = 4
          OnClick = btn2Click
        end
      end
      object btnPostData: TButton
        Left = 225
        Top = 284
        Width = 144
        Height = 25
        Caption = #25552#20132#25968#25454#21040#26381#21153#22120
        TabOrder = 3
        OnClick = btnPostDataClick
      end
      object sconn: TSocketConnection
        ServerGUID = '{82AEC5B8-E53F-4725-A24D-456FD570E355}'
        ServerName = 'Project1.TestService'
        Host = '10.10.60.3'
        Left = 107
        Top = 143
      end
      object ds3: TDataSource
        DataSet = dsTemp
        Left = 255
        Top = 151
      end
      object dsTemp: TClientDataSet
        Aggregates = <>
        Params = <>
        RemoteServer = sconn
        AfterInsert = dsTempAfterInsert
        Left = 191
        Top = 147
      end
      object actlst1: TActionList
        Left = 289
        Top = 264
        object actCreate: TAction
          Caption = 'actCreate'
          OnExecute = actCreateExecute
        end
        object actModify: TAction
          Caption = 'actModify'
          OnExecute = actModifyExecute
        end
        object actSave: TAction
          Caption = 'actSave'
          OnExecute = actSaveExecute
        end
        object actCancel: TAction
          Caption = 'actCancel'
          OnExecute = actCancelExecute
        end
        object actDelete: TAction
          Caption = 'actDelete'
          OnExecute = actDeleteExecute
        end
      end
    end
    

    新建记录修改和新增窗体 如下图

    代码如下

    unit ufrmCreate;
    
    interface
    
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,DBClient,DB;
    
    
    type
      TfrmCreate = class(TForm)
        edtName: TEdit;
        edtSex: TEdit;
        edtAge: TEdit;
        edtMobile: TEdit;
        mmoRemark: TMemo;
        lbl1: TLabel;
        lbl2: TLabel;
        lbl3: TLabel;
        lbl4: TLabel;
        lbl5: TLabel;
        btnSave: TButton;
        btnCancel: TButton;
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure FormShow(Sender: TObject);
        procedure btnSaveClick(Sender: TObject);
      private
        FIsCreate: Boolean;
        FcdsDep: TClientDataSet;
        procedure SetIsCreate(const Value: Boolean);
        procedure init;
        { Private declarations }
      public
        property IsCreate:Boolean  read FIsCreate write SetIsCreate;
        property cdsDep:TClientDataSet  read FcdsDep write  FcdsDep;
      end;
    
    
    var
      frmCreate: TfrmCreate;
    
    
    implementation
        uses ufrmMain;
    {$R *.dfm}
    
    
    { TfrmCreate }
    
    
    procedure TfrmCreate.SetIsCreate(const Value: Boolean);
    begin
      FIsCreate := Value;
      if IsCreate then
        Caption:='Create'
      else
        Caption:='Modify';
    end;
    
    
    procedure TfrmCreate.FormCreate(Sender: TObject);
    begin
      cdsDep:=TClientDataSet.Create(Self);
    end;
    
    
    procedure TfrmCreate.FormDestroy(Sender: TObject);
    begin
      cdsDep.Free;
    end;
    
    
    procedure TfrmCreate.FormShow(Sender: TObject);
    begin   
      if IsCreate then
      begin
        frmMain.dsTemp.Insert;
      end else
      begin
        init;
        frmMain.dsTemp.Edit;
      end;
    end;
    
    
    procedure TfrmCreate.btnSaveClick(Sender: TObject);
    begin
      if edtName.Text=''  then
      begin
        ShowMessage('姓名不能为空');
        Exit;
      end;
      if edtMobile.Text='' then
      begin
         ShowMessage('电话号码不能为空');
         exit;
      end;
      if frmMain.dsTemp.State in [dsEdit,dsInsert] then
      begin
        frmMain.dsTemp.fieldbyName('FName').AsString:=edtName.Text;
        frmMain.dsTemp.fieldbyName('FSex').AsString:=edtSex.Text;
        frmMain.dsTemp.fieldbyName('FAge').AsString:=edtAge.Text;
        frmMain.dsTemp.fieldbyName('FMobile').AsString:=edtMobile.Text;
        frmMain.dsTemp.fieldbyName('FRemark').AsString:=mmoRemark.Text;
        ModalResult:=mrOk;
      end else
        ModalResult:=mrCancel;
    end;
    
    
    procedure TfrmCreate.init;
    begin
      edtName.Text:=frmMain.dsTemp.fieldbyName('FName').AsString;
      edtSex.Text:=frmMain.dsTemp.fieldbyName('FSex').AsString;
      edtAge.Text:=frmMain.dsTemp.fieldbyName('FAge').AsString;
      edtMobile.Text:=frmMain.dsTemp.fieldbyName('FMobile').AsString;
      mmoRemark.Text:=frmMain.dsTemp.fieldbyName('FRemark').AsString;
    end;
    
    
    end.
    

    运行客户端程序 进行测试如下


    点击加载数据 显示数据

    最后只有提交到服务器 才能真正的保存数据到数据库
    此 基本结束 如有问题 请留言

    项目源码下载 —— http://download.csdn.net/detail/gykthh/8077801

    展开全文
  • 客户端开发设计总结

    万次阅读 多人点赞 2016-09-19 16:01:04
    1 基础设施程序最基本的处理就是数据IO以及为了并行计算所做的操作,它们通常会作为程序的底层框架,供上层使用。2 交互从PC到现在的移动设备还有VR,人机交互中的输入设备在不断自然化,可是展示界面的元素仍然还是...

    1 基础设施

    程序最基本的处理就是数据IO以及为了并行计算所做的操作,它们通常会作为程序的底层框架,供上层使用。

    基础框架

    2 交互

    从PC到现在的移动设备还有VR,人机交互中的输入设备在不断自然化,可是展示界面的元素仍然还是这几种:静态文本、按钮、列表、输入框、选择菜单、进度提示、滚动条、标签页。每种UI框架都提供这些基本组件,可以说掌握它们就等于对这个框架入门了。高级的交互会跨越窗口、跨越程序,并能更智能化地响应输入。

    interaction

    3 硬件设备

    PC上的硬件大都需要通过统一的接口来操作,开发者需要做好繁复的参数设置才能正确使用。移动系统则对很多硬件做了封装,为开发者提供定制的简单API。有时候开发者并不需要直接操控硬件,但需要获取硬件的信息,根据可用的资源数来执行不同的策略。

    硬件设备

    4 程序设计

    现在的程序流行快速迭代,没过几天就发布一个新版本。新的app还要越快上线越好,尽早占据制高点。如此匆忙的节奏,让传统软件的架构设计退居二线,程序往往都是技术债务多到影响开发速度或新功能才执行大的重构优化。不过我们至少可以提前根据功能分出一些模块,让后面的重构稍微轻松些。

    design

    5 后勤

    如果说需求开发是前线,那么产品经理无暇关心的东西都算后勤了。这部分工作需要技术经理主导来开展。对程序员来说这部分工作可能没那么刺激,但却是深入学习系统和各种工具原理的好机会。

    logistics

    6 其它

    关于编程语言、开发工具、操作系统的总结在这:
    http://blog.csdn.net/hursing/article/details/45603483

    7 一些感想

    客户端开发有界面,能图形化反馈编程结果,所以比服务器端开发更“刺激”一些。因为和操作系统紧密结合,知识具有针对性,所以即使是做UI也比做前端的难度大些。

    现在做移动开发其实和当年做Windows程序没有差别,只是系统比较新且更新快,文档多数是英文的,又少有中文图书积累,所以门槛稍高。再过几年当供过于求,应该会回归编程平台这一基础属性,不再带有什么光环。

    客户端开发的尽头就是熟悉了所有的API。然而API在演变,还得继续跟随。Windows的API多到没人能完全记住或用过,但三年前的iOS是可以的,现在也不行了,苹果在不断地添加。看Android,到现在已经演化了24个版本,很难去跟踪了。

    无论哪种系统,不断有API被标记为Deprecated,也有部分在新操作系统上不可用,需要在代码里判断操作系统版本或SDK的版本。这些历史,对新手来说直接就是不知道。随着人员也跟着更新换代,更多人就忘了,于是文档成了这种混乱的救命稻草,会查文档真的非常重要。

    如果让我编制一个学习路径,应该是这样的:

    1. 编程语言,代码规范,格式化工具
    2. IDE环境,快捷键
    3. UI框架,学会查SDK文档,掌握文档的整体结构
    4. 网络、磁盘等IO
    5. 更多系统SDK的模块
    6. 调试技巧
    7. 工程文件组织,命令行操作
    8. 流行的第三方库
    9. 打包,自动化
    10. 测试方法、工具、自动化
    11. 优化方法
    12. 学习系统原理
    13. 反编译,hack
    14. 发布渠道和流程
      • 官方:Google Play、Apple Store
      • 厂商:小米、华为、魅族、vivo、oppo……
      • 第三方商店: 豌豆荚、PP助手、安卓市场……
      • 渠道:友盟+……
    15. 写博客总结。像这样 http://blog.csdn.net/hursing

    有空再写写调试和优化总结吧。

    展开全文
  • 首先是简单的自我介绍,由面试官先介绍,然后说了一下腾讯视频windows客户端开发的相关要求,win32编程,c++基础,主要是维护开发相关。 然后后面就是让我先介绍一下,我做的项目,后面我也简单的说了一下,做的项目...
  • 跨平台客户端开发经验总结

    万次阅读 热门讨论 2015-09-22 16:25:21
    1 前言因为《猫科动物和企鹅在窗口外看机器人吃苹果》这出戏太美,很多公司都希望能全平台同时发布新版本app,还要...革命总会出新知,今天已有一些开源框架能应对同时在5大平台Mac OS X、Linux、Windows、Android、iO
  • 因为现在我现在开发主要在自己的笔记本(windows)上,然后写的后端都要部署到实验室的台式机(windows)上,这样一来,我一改点东西的话,还得去实验室,在台式机上操作把项目pull下来然后再部署到Tomcat上(仅仅是一...
  • 针对 .NET 客户端开发,Microsoft 正在开发一些革命性的工具和一个易于实现的应用程序框架(代号"Acropolis"),以便开发人员能够更快速地创建、管理和部署 Microsoft Windows 客户端应用程序。Microsoft Code ...
  • 对于Qt跨平台客户端开发的一些看法

    千次阅读 多人点赞 2021-07-23 19:15:47
    Qt能跨平台开发,这是大家都知道的,但是,真的做起来不是那么容易,很多公司的客户端也没也完全用跨平台框架开发,而是在windows, macOS,linux上各搞一套,比如windows用DuiLlib、Qt、或者自己写的UI框架;...
  • 1.前言: 网上已经有很多关于ONVIF开发的资料,这里概括介绍一下ONVIF协议以及介绍一下我自己在开发...《ONVIF网络摄像头(IPC)客户端开发—ONVIF介绍》《ONVIF网络摄像头(IPC)客户端开发—最简RTSP客户端实现》《...
  • gsoap 客户端 开发实例

    千次阅读 2017-01-05 14:36:42
     gSOAP是一个跨平台的,用于开发Web Service服务端和客户端的工具,在Windows、Linux、MAC OS和UNIX下使用C和C++语言编码,集合了SSL功能。   下载最新gSoap程序包,解压后在\gsoap\bin目录下找到 编译器soapcpp2...
  • 原文地址:Mina基础(Apache user guide Chapter2 basics)1.1.1... 从这里,我们可以看到Mina是介于应用层与底层网络层之间的,底层网络层基于TCP、UDP、in-VM通信,甚至作为RS-232C串口通信的客户端。你只需在Mina上
  • 客户端UI统一框架

    千次阅读 2012-12-12 11:18:41
    规划的时候,首先从Android入手,Android开发完毕后,再开发WindowsMobile,随后是IOS平台, 带来的问题是:关注某个平台而忽略其他平台, 导致设计上,缺乏系统考虑和整体考虑。2. 各种平台的操作方式
  • 岗位职责:1、负责坚果云在Windows 10平台上WPF应用的开发与维护;2、负责基于WPF的Windows平台核心客户端产品开发,维护与测试;3、WPF桌面应用将具备丰富的文件展示和...
  • 桌面客户端框架技术选型

    千次阅读 2020-04-10 22:47:34
    2.客户端能够跨平台,同时适应Windows和Mac平台 3.用户界面友好,满足用户对界面的苛求 4.能够与快速与第三方的C++应用、Web应用集成 5.客户端安装包大小适中,减少用户的下载和安装时间 6.支持XP系统(国内还有近10%...
  • 什么是RIA? RIA(Rich Interface Applications)富界面应用,俗称胖客户端或者富客户端。 RIA的优势 RIA 具有的桌面应用程序的特点包括:在消息确认和格式编排方面提供互动用户界面;在无刷新页面之下提供快捷的...
  • windows系统(window 中选择zip)下要下载的内容: 2.解压apache-cxf-3.1.15.zip包,并进入这个apache-cxf-3.1.15目录下面的bin,进入cmd wsdl2java -p [生成代码的包目录] -d [代码生成的路径] -client -encoding ...
  • Apache MINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可靠性的网络应用程序。它提供了一个通过Java NIO在不同的传输例如TCP/IP和UDP/IP上抽象的事件驱动的异步API。  Apache MINA 也称为: ...
  • DWZ富客户端框架使用手册

    万次阅读 2014-10-19 15:40:16
    DWZ 富客户端框架(jQuery RIA framework), 是中国人自己开发的基于 jQuery 实现的 Ajax RIA 开源框架. DWZ 富客户端框架设计目标是 简单实用、扩展方便、快速开发、RIA 思路、轻量级 DWZ 框架支持用 html 扩展的...
  • EasyClient是EasyDarwin开源流媒体团队开发的一款功能丰富的开源PC客户端项目,目前支持Windows、Android版本,后续将支持ios版本,其中Windows版本的EasyClient支持多种源接入,包括Windows摄像头、麦克风、RTSP...
  • 《ONVIF协议网络摄像机(IPC)客户端程序开发》专栏,学ONVIF,跟我来!!!
  • OPC通讯开发说明--基于WTOPCSVR的OPC服务器端和基于WTCLIENT的OPC客户端开发说明一、OPC技术介绍二、OPC通讯的流程三、OPC标准官方文件部分变量说明1.OPCBROWSETYPE枚举2.OPC读写标志宏定义3.OPCSERVERSTATE枚举4....
  • 我建议大家 还是安装 anaconda ,然后用这个安装这个包,记得以前用这个安装过 scrapy 爬虫框架,就是用它搞定的。 anaconda 的 具体使用方法可参考 ...
  • 准备一个用来存放 truffle 环境的空文件夹也就是开发合约文件所放位置 新建完成后,在此文件夹 运行powershell(我使用cmd报错),输入 npm -g install truffle 全局安装 truffle 然后输入 truffle init 会在此...
  • Duilib是windows平台下的一款轻量级directUI开源库(遵循BSD协议),完全免费,可用于商业软件开发,只需在软件包里附上协议文件即可。Duilib可以简单方便地实现大多数界面需求,包括换肤、换色,透明等功能,支持...
  • 需要使用到的内容: Gsoap XML Schemas Specifications 1、下载Gsoap 从Gsoap官网下载最新版gsoap(博主用的是gsoap_2.8.36)。gsoap有三个版本:Open Source gSOAP、Commercial gSOAP Edition、Commercial ...
  • 《ONVIF协议网络摄像机(IPC)客户端程序开发》专栏,学ONVIF,跟我来!!!
  • http://www.gameres.com/654759.html ...设计思想/框架 客户端  编程语言:   引擎/SDK: Unity3D/2D   GameRes游资网授权发布 文 / 吴秦
  • ET框架的目标就是简化客户端开发,简化分布式服务端开发,但是功能非常强大,完全可以作为一个大型分布式服务端使用。ET框架有很多创造性的设计: 1.可用VS单步调试的分布式服务端,N变1 一般来说
  • ET框架服务端环境部署服务端环境部署,包括安装.NET Core运行库、MongoDB数据库1、确定.NET Core运行库版本,下载并安装2、安装MongoDB数据库和Studio 3T服务端程序编译与运行1、服务端程序编译2、资源服务器编译3、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 94,470
精华内容 37,788
关键字:

windows客户端开发需要什么框架