说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

做一个OpenGL控件-Delphi资料

HTML文档下载 WORD文档下载 PDF文档下载
做一个OpenGL控件-Delphi资料

OpenGL是一个独立于窗口的图形库,而图形最终是在窗口系统里绘制出来的,那么OpenGL的绘图命令是怎么在窗口里生成输出的呢?

这就是各个系统上的OpenGL实现者需要做的工作了。在Windows里是通过wgl库完成的,在X-Windows里是通过glx服务器来完成的,至于这些OpenGL实现具体是怎么工作的,请参考sgi发布的sample implement源码,不过那个代码是用C写的。

在MS-Windows里,wgl库负责将OpenGL的绘制设备RenderContext与GDI的DeviceContext联系起来,使得发到OpenGL的RC里的命令生成的位图能够在GDI DC里绘制出来,你可以把它想象成OpenGL在RC里有一个FrameBuffer,记录着生成的图案,而wgl则负责把FrameBuffer的内容BitBlt到DC上。当然,这并不是它实际的工作方法,如果想了解更多请参考SGI发布的SDK资料或联系MS公司。

为了使GDI DC能够接受OpenGL RC的输出,必须为DC选定特别的像素格式,然后建立RC,再用wglMakeCurrent把当前要使用的RC和DC联系起来。此后我们就可以用OpenGL命令正常工作了。在一个程序里可以创建多个RC和多个DC,程序中的OpenGL命令会发到被wglMakeCurrent指定为当前的那一组合中。

我并不认为这个初始化过程是个很有意思的工作,这个世界上有很多聪明的程序员也这么想,所以他们发明了glaux库和glut库。glaux是在著名的OpenGL Programmer Guide里提出的,这本书是OpenGL编程的官方文档,因为它的封皮是红色的,所以通常简称为RedBook。故名思意,glaux是一套输助库,它使得你无须关心在具体窗口系统里初始化、消息响应的细节,而是使用传统的c/dos程序风格编制OpenGL程序。

int main(int argc

char** argv)

{ auxInitDisplayMode( AUX_SINGLE|AUX_RGB|AUX_DEPTH16);//使用单缓冲、RGB彩色模式、16位浓度

auxInitPosition(0

0

250

250);

auxInitWindow("Title");//以上两行在(0

0)片建立了一个大小为250X250的窗口,其标题为"Title"。

myinit();//建立OpenGL透视投影环境

auxReshapeFunc(myReshape);//指定窗口大小变化的响应函数

auxMainLoop(display);//指定绘制函数

return 0; }

由于glaux是为教学目的开发的,所以实用价值很限,所以又有程序员开发了glut,这套库被广泛使用,它的工作方式与glaux极为类似,但功能完善得多,特别是对交互、全屏等的支持要理想得多,所以许多的OpenGL演示程序使用它,比如SGI网站上提供的多数演示程序都需要使用它。同时这套库已经被移植到多种平台上,所以要是想用简单的方法开发在windows/macos/os2/xwindows等系统上都能使用的程序,那么应该选择这套库。

我并不认为一个Delphi程序员会喜欢glaux或glut,因为那意味着你不能利用Delphi的可视开发能力,另外任何真正实用的Delphi程序想直接在其它操作系统上编译运行好象也不现实,即glut的跨平台能力也没有什么吸引力。我们应该开发一个VCL控件,把初始化工作封装起来。

我认为从TCustomPanel派生一个子类比较方便,让我们称它为TGLPanel吧。初始化过程要在WMCreate里完成,之所以要放在这里是因为这个时候Window Handle已经建立,但还没启用。

在WMCreate中会

①调用initDC完成DC调整工作,initDC会以本窗口使用的DC调用PreparePixelFormat,而PixelFormat则真正完成像素格式调整。

②然后WMCreate会调用InitGL完成OpenGL透视投影环境的设定。

③最后调用OnInit给用户一个调整透视投影环境的机会。

注意,如果要在MDI环境中的子窗体中使用OpenGL,还有些附加工作要做,这就是给窗口类的Params.Style加上WS_CLIPCHILDREN和WS_CLIPSIBLINGS属性,这得在Window Handle建立之前就完成,因此要写在CreateParams里。由于SDI应用并不需要该代码,所以应该定义OnPreInit事件,让用户在需要的时候自己加上,在Create里调用OnPreInit。以下代码定义了OnPreInit,但并没有定义CreateParams,如果需要自己加上吧。

在TGLPanel类中实际所做工作的详细说明(按成员可见性组织):

私有

1、加入DC/RC/Pal私有变量

2、定义初始化DC/RC的私有方法

保护:

3、加入FOnPaint

FOnResize

FOnInit

FOnPreInit四个事件响应变量。

4、继承/重载虚方法CreateParams

Paint

Resize

5、响应以下消息

WM_CREATE

TWMCreate

WMCreate

WM_DESTROY

TWMDestroy

WMDestroy

WM_PALETTECHANGED

TWMPaletteChanged

WMPaletteChanged

WM_QUERYNEWPALETTE

TWMQueryNewPalette

WMQueryNewPalette

WM_ERASEBKGND

TWMEraseBkgnd

WMEraseBkgnd

公开:

6、定义建构与析构方法

7、定义必要的其它方法以提供各种特性

发布:

8、以下继承来的属性

__property Alignment;

__property Align;

__property DragCursor;

__property DragMode;

__property Enabled;

__property ParentFont;

__property ParentShowHint;

__property PopupMenu;

__property ShowHint;

__property TabOrder;

__property TabStop;

__property Visible;

9、以下继承来的方法

__property OnClick;

__property OnDblClick;

__property OnDragDrop;

__property OnDragOver;

__property OnEndDrag;

__property OnEnter;

__property OnExit;

__property OnMouseDown;

__property OnMouseMove;

__property OnMouseUp;

__property OnStartDrag;

10、加入以下事件

//初始化OpenGL状态

__property TNotifyEvent OnInit = {read=FOnInit

write=FOnInit};

//专用于修改显示BPP模式

__property TNotifyEvent OnPreInit = {read=FOnPreInit

write=FOnPreInit};

11、重载以下事件

__property TNotifyEvent OnResize = {read=FOnResize

write=FOnResize};

__property TNotifyEvent OnPaint = {read=FOnPaint

write=FOnPaint};

12、将消息与其响应函数连接起来(Delphi中这一步是在定义函数时指定的)

源代码

unit GLPanel;

interface

uses

Windows

Messages

SysUtils

Classes

Graphics

Controls

Forms

Dialogs

ExtCtrls

OpenGL;

type

TGLPanel = class(TCustomPanel)

private

{ Private declarations }

DC: HDC;

RC: HGLRC;

procedure initDC;

procedure initGL;

procedure PreparePixelFormat(var DC: HDC);

protected

{ Protected declarations }

FOnPaint:TNotifyEvent;

FOnInit:TNotifyEvent;

FOnPreInit:TNotifyEvent;

FOnResize:TNotifyEvent;

procedure Paint;override;

procedure Resize;override;

procedure WMDestroy(var Msg: TWMDestroy);message WM_DESTROY;

procedure WMCreate(var Msg:TWMCreate); message WM_CREATE;

public

{ Public declarations }

constructor Create(Owner:TComponent);override;

published

{ Published declarations }

property Alignment;

property Align;

property DragCursor;

property DragMode;

property Enabled;

property ParentFont;

property ParentShowHint;

property PopupMenu;

property ShowHint;

property TabOrder;

property TabStop;

property Visible;

property OnClick;

property OnDblClick;

property OnDragDrop;

property OnDragOver;

property OnEndDrag;

property OnEnter;

property OnExit;

property OnMouseDown;

property OnMouseMove;

property OnMouseUp;

property OnStartDrag;

property OnInit:TNotifyEvent read FOnInit write FOnInit;

property OnPreInit:TNotifyEvent read FOnPreInit write FOnPreInit;

property OnResize:TNotifyEvent read FOnResize write FOnResize;

property OnPaint:TNotifyEvent read FOnPaint write FOnPaint;

end;

procedure Register;

implementation

procedure Register;

begin

RegisterComponents(’Samples’

[TGLPanel]);

end;

//---------------------------------------------

constructor TGLPanel.Create;

begin

inherited;

end;

//---------------------------------------------

procedure TGLPanel.WMDestroy(var Msg: TWMDestroy);

begin

wglMakeCurrent(0

0);

wglDeleteContext(RC);

ReleaseDC(Handle

DC);

end;

//---------------------------------------------------

procedure TGLPanel.initDC;

begin

DC := GetDC(Handle);

PreparePixelFormat(DC);

end;

//---------------------------------------------------

procedure TGLPanel.initGL;

begin

glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);

glLoadIdentity;

glEnable(GL_LIGHTING);

glEnable(GL_LIGHT0);

glOrtho(-1

1

-1

1

-1

50);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity;

glEnable(GL_DEPTH_TEST);

//注意下面这一行是为了做练习程序时可以直接用glColor指定材质而加的,

// 可能使得光照或表面材质发生意想不到的变化,

// 如果不需要可以去掉或在程序中用glDisable(GL_COLOR_MATERIAL);关闭

glEnable(GL_COLOR_MATERIAL);

glShadeModel(GL_SMOOTH);

gluLookAt(2

4

6

0

0

0

0

1

0);

SwapBuffers(DC);

end;

//---------------------------------------------

procedure TGLPanel.PreparePixelFormat(var DC: HDC);

var

PFD : TPixelFormatDescriptor;

ChosenPixelFormat : Integer;

begin

FillChar(PFD

SizeOf(TPixelFormatDescriptor)

0);

with PFD do

begin

nSize := SizeOf(TPixelFormatDescriptor);

nVersion := 1;

dwFlags := PFD_DRAW_TO_WINDOW or

PFD_SUPPORT_OPENGL or

PFD_DOUBLEBUFFER;

iPixelType := PFD_TYPE_RGBA;

cColorBits := 16; // 16位颜色

cDepthBits := 32; // 32位深度缓冲

iLayerType := PFD_MAIN_PLANE;

{ Should be 24

but we must allow for the clunky WKU boxes }

end;

ChosenPixelFormat := ChoosePixelFormat(DC

@PFD);

if ChosenPixelFormat = 0 then

Raise Exception.Create(’ChoosePixelFormat failed!’);

SetPixelFormat(DC

ChosenPixelFormat

@PFD);

end;

procedure TGLPanel.WMCreate(var Msg:TWMCreate);

begin

//在这里做初始化工作

//修改DC的象素格式,使之支持OpenGL绘制

initDC;

RC := wglCreateContext(DC);

wglMakeCurrent(DC

RC);

//初始化GL绘制系统

initGL;

if Assigned(FOnInit) then

begin

if (wglMakeCurrent(DC

RC)=false) then

ShowMessage(’wglMakeCurrent:’ + IntToStr(GetLastError));

FOnInit(self);

end;

end;

//

procedure TGLPanel.Paint;

begin

//TCustomPanel::Paint();

if Assigned(FOnPaint) then

begin

wglMakeCurrent(DC

RC);

FOnPaint(self);

SwapBuffers(DC);

end;

end;

//

procedure TGLPanel.Resize;

begin

inherited;

if Assigned(FOnResize) then

begin

wglMakeCurrent(DC

RC);

glViewport(0

0

ClientWidth

ClientHeight);

FOnResize(self);

end;

end;

end.

以上代码仅用来说明原理及建立一个基本的练习环境,您可以自由使用,转载请注明出处。如果使用从本人主页下载的TGLPanel请遵守内附使用说明的版权申明。如果实际做东西,建议使用Mike Lischke的GLScene控件组(http://www.lischke-online.de/)。

end

else

删除注册表项....................... end;初始化扩展是通过IShellExtInit实现的,当外壳调用IShellExtInit.Initialize时,它传递一个数据对象包含来文件对应的目录的PIDL标识符。Initialize方法需要从数据对象中提取文件名,并把文件名和PIDL标识符保存起来为了以后使用。

function TCXPropSheet.SEIInitialize(pidlFolder: PItemIDList;

lpdobj: IDataObject; hKeyProgID: HKEY): HResult;

var

StgMedium: TStgMedium;

FormatEtc: TFormatEtc;

szFile: array[0..MAX_PATH+1]of Char;

filecount: integer;begin

Result:=E_FAIL;

if(lpdobj=nil)then

begin

Result:=E_INVALIDARG;

messagebox(0

’1’

’错误’

mb_ok);

Exit;

end;

with FormatEtc do

begin

cfFormat:=CF_HDROP;

ptd:=nil;

dwAspect:=DVASPECT_CONTENT;

lindex:=-1;

tymed:=TYMED_HGLOBAL;

end;

Result:=lpdobj.GetData(FormatEtc

StgMedium);

if Failed(Result)then

Exit;

//如果只有一个文件被选中,获得文件名并保存。

filecount:=DragQueryFile(stgmedium.hGlobal

$FFFFFFFF

nil

0);

if filecount=1 then

begin

Result:=NOERROR;

DragQueryFile(stgmedium.hGlobal

0

szFile

SizeOf(szFile));

FFilename:=strpas(szFile);

end;

ReleaseStgMedium(StgMedium);end;添加页面的操作是通过IShellPropSheetExt接口来实现的。如果属性页是和文件相关联,外壳会调用IShellPropSheetExt.AddPages给属性页添加一个页面。如果属性页同控制面板程序相关联,外壳调用IShellPropSheetExt.ReplacePage来替换页面。

IShellPropSheetExt.AddPages方法有两个参数,lpfnAddPage是一个指向AddPropSheetPageProc回调函数的指针,回调函数用来提供要添加的页面信息给外壳。lParam是一个用户自定义的值,这里我们用它来返回给回调函数对象。

一般的IShellPropSheetExt.AddPages方法实现步骤是:

给PROPSHEETPAGE结构设定正确的值,特别是:

把扩展的对象引用记数变量付值给pcRefParent成员,这可以防止页面还在显示时,扩展对象被卸载。

实现PropSheetPageProc回调函数来处理页面创建和销毁的情况。

调用CreatePropertySheetPage函数来创建页面。

调用lpfnAddPage指向的函数来来添加创建好的页面。

function TCXPropSheet.AddPages(lpfnAddPage: TFNADDPROPSHEETPAGE;

lParam: LPARAM): HResult;var

PSP: TPropSheetPage;

HPSP: HPropSheetPage;begin

result:=E_FAIL;

try

psp.dwSize:=SizeOf(psp);

psp.dwFlags:=PSP_USEREFPARENT or PSP_USETITLE or PSP_USECALLBACK;

psp.hInstance:=hInstance;

//这里我们使用了事先储存在wave.res中的对话框模板

模板是用delphi5自带的

//resource workshop编辑的,使用delphi5\bin\brcc32.exe编译的。

psp.pszTemplate:=MakeIntResource(100);

//标题名

psp.pszTitle:=’波文件信息’;

//设定回调函数

psp.pfnDlgProc:=@DialogProc;

psp.pfnCallBack:=@PropCallback;

//设定对象引用记数变量

psp.pcRefParent:=@comserver.objectcount;

//用lParam向回调函数传递对象

psp.lParam:=integer(self);

HPSP:=CreatePropertySheetPage(psp);

if HPSP<>nil then begin

if not lpfnAddPage(HPSP

lParam)then begin

DestroyPropertySheetPage(HPSP);

end else begin

_addref;//增加引用记数,否则一脱离这个方法的作用域,delphi自动释放对象。

result:=S_OK;

end

end

except

on e: exception do begin

e.message:=’添加页面’+e.message;

messagebox(0

pchar(e.message)

’错误’

mb_ok);

end;

end;end;

function TCXPropSheet.ReplacePage(uPageID: UINT;

lpfnReplaceWith: TFNADDPROPSHEETPAGE; lParam: LPARAM): HResult;begin

Result:=E_NOTIMPL;//同文件关联时,外壳不调用ReplacePage

所以不用实现end;回调函数处理属性页的消息,主要要响应WM_INITDIALOG消息来初始化页面显示信息,响应WM_COMMAND消息来处理用户交互,响应WM_NOTIFY消息来处理页面切换或关闭后处理操作结果。

function DialogProc(hwndDlg: HWnd; Msg: UINT; wParam: wParam;

lParam: LPARAM): Bool; stdcall;

var

PageObj: TCXPropSheet;

filename: string;

displayName : string;

SheetHWnd: HWnd;

begin

result:=false;

try

if Msg=WM_INITDIALOG then begin//初始化界面

//获得lparam传递过来的对象

pageObj:=TCXPropSheet(PPropSheetPage(lParam)^.lParam);

//保存对象信息

SetWindowLong(hwndDlg

DWL_USER

integer(pageObj));

//设置界面显示波文件信息

SetDlgItemText(hwndDlg

100

PChar(ExtractFileName(PageObj.FFileName)));

OpenMedia(PageObj.FFileName);

SetDlgItemText(hwndDlg

101

PChar(IntToStr(GetWavStatus(MCI_WAVE_STATUS_AVGBYTESPERSEC))));

SetDlgItemText(hwndDlg

102

PChar(IntToStr(GetWavStatus(MCI_WAVE_STATUS_BITSPERSAMPLE))));

SetDlgItemText(hwndDlg

103

PChar(IntToStr(GetWavStatus(MCI_WAVE_STATUS_CHANNELS))));

CloseMedia;

SetWindowLong(hwndDlg

DWL_MSGRESULT

0);

Result:=TRUE;

end

else if(Msg=WM_COMMAND)then begin

if Lo(wParam)=110 then//用户点击了关于按钮(id=110)

MessageBox(0

’作者:hubdog’+#13#10+’email:hubdog@263.net’

’关于...’

MB_OK);

end else if(msg=WM_NOTIFY)then begin

sheetHwnd:=getparent(hwndDlg);//获得属性页的窗口句柄

case PNMHdr(lparam)^.code of

//页面失去焦点

PSN_KILLACTIVE:

begin

SetWindowLong(hwndDlg

DWL_MSGRESULT

0);

Result:=TRUE;

end;

end;

end;

except

on e: exception do begin

e.message:=’回调处理’+e.message;

messagebox(0

pchar(e.message)

’错误’

mb_ok);

end;

end;

end;

建立同驱动器相关联的属性页扩展用

同上面讲的有两点不同:

IShellExtInit.Initialize方法传递过来的数据对象包含的驱动器路径可能是CFSTR_MOUNTEDVOLUME格式而不是CF_HDROP格式的。标准驱动器是CF_HDROP格式的,而在NTFS文件系统中映射的远程设备则是CFSTR_MOUNTEDVOLUME格式的。

注册表项是HKEY_CLASSES_ROOT\Drive\Shellex\PropertySheetHandlers子键。

建立控制面板属性页扩展

同上面讲的有两点不同:

控制面板程序调用IShellPropSheetExt.ReplacePage方法来替换页面,它不调用IShellPropSheetExt。AddPages方法。

注册方式:子键可以在不同位置创建,这依赖于扩展是针对用户还是针对机器的。对用户方式子键是HKEY_CURRENT_USER\REGSTR_PATH_CONTROLPANEL,否则子键是HKEY_LOCAL_MACHINE\REGSTR_PATH_CONTROLSFOLDER。

本程序在Delphi5,Win NT 4.0,K6-233系统下调试成功。例子程序可以到http://chaozhi.com/lgc去下载

微软明日将启动第二轮裁员 涉及所有的事业部 IBM推出Watson Analytics 将人机对话带进企业决策 参与2014中国移动开发者大调查 MDCC门票等你拿 手游开发经验谈:付费体系决定游戏收成好与坏? 惠普推出全新ProLiant Gen9服务器 腾讯安全出杀手锏 搭建全国最大Wi-Fi开放平台帮助网友免费蹭网 云与数据安全实践尽在ISC 2014(免费门票) 开源的对决,MapR将Apache Drill引入企业应用 令程序员费解的10个语言特性 走进雅虎北京全球研发中心:五年光阴缔造雅虎全球创新引擎 超强集成游戏编辑器!开源跨平台引擎Wave 求别再侵犯儿童隐私!FTC狠罚Yelp和TinyCo 华为应用市场助力开发者 软硬结合造就强大生态系统 【CTO俱乐部看板研修班北京站现场速递】看板方法:渐进变革的过程 《近匠》不背单词,用“沉浸”征服英语学习 ETpl——强复用、灵活、高性能的JavaScript模板引擎 MDCC 2014大会日程概览发布 最新嘉宾议题揭秘 终于来了,微信企业号正式开启公测! 【问底】王帅:深入PHP内核(一)——弱类型变量原理探究 谷歌Kubernetes专访:未来BigTable开发只是课后习题 首届“最具价值CTO”评选来啦!我们在找你! 【CTO俱乐部走进顺丰总部】活动图文直播进行中 中国第一个云主机评测发布:天翼云性价比第一、青云质量第一 Ruby 2.1.3发布,降低内存消耗、修复众多Bug! OpenHW2014开源硬件总决赛鏖战西安 AMD力推异构计算 《坦克世界:闪电战》:PC转手游,不止免费! 【讲师】道里云毛文波:网络虚拟化与SDN实现Docker连通 性能测试:SequoiaDB vs. MongoDB vs. Cassandra vs. HBase 华云数据推运营型PaaS Plus平台,联合Tmax走出“去IOE”的云化之路 聚焦移动新势力 MDCC 2014免费展位团队名单公布 详解Google Authenticator工作原理 我刚刚开始学习B/S结构的程序设计,请问各位哪里可以下载到这方面的资料?顺便散分。 如何编程实现网络上的视频传输 知道一个模块的句柄侯怎样运行它? 中国为什么比韩国差这么多? 帮帮忙,我急需有关ERWIN的书籍资料,请能在哪里下载?急啊!先说声谢谢! 500分求助!!!如何打印MSCHART控件画出的折线图 请问网上有没有关于UI线程比较好的例子?如果有的话,发一个网址给我,在线等待,谢了! 一道选择题 局域网,一方可以ping通一方,怎么解决?? 装了WIN2K后,如何再装LIUNIX实现双启动? TQuery的简单用法,高分大放送! 如何将controls对话框中不用的控件去掉 请问怎么用coff2omf,把Strmiids.lib、Quartz.lib、Strmbase.lib转化成BCB可以接受的格式 JDBC for mysql 的使用 -------问题 偶有重回delphi修炼了,当年偶的师傅还在吗?老千,老鱼,chech,小新,老鬼,你们过的怎样?? 你现在正在看的这种页面如何实现? 我很喜欢delphi,但老板要我转学单片机,请兄弟们说几句,是福是祸?up、gz有分! vb的安装问题 请问如何在两个数据库之间进行联合查询? 迷 !!!!!! 天使的旁边是魔鬼 数据集排序问题 哪里有 MS viso 下载,谢! 用DATAREPORT设计报表,这个怎样设计? ASP写的计数器程序问题 天女散分:process basename 中文叫什么,进程什么名? 数据库句柄清除问题 请问我用JBuilder + weblogic61 编写的 EJB,在我拿到别的地方部署,是不是只拿 XEjb.jar和客户端 就行了? 如何让两个byte类型的变量a和b进行异或(^)操作,然后将结果存入另一个byte中? 我也来一个关于ACCESS的问题,高分请教。在线等待 CDC问题:怎样从屏幕尺寸转换到厘米呢?反之呢? VC中如何给动态产生的控件写事件方法?在线等! 》》怎么没有人解决这个问题呀,谁解决,我给分!!!!! 为什么快捷方式不能用? ★★★有没有像“delphi属性编辑框”一样的控件或是源码(100-1000分)★★★ 谁有RealPlay格式详细信息 500分求救! 请问大家那里有jrun 4下载 如何自己析构单文档模板? MASM32中标号的疑问 这个错误该如何改 关于在OUTLOOK中如何自创模板的问题? com系列丛书那里有卖 一个关于鼠标事件的简单问题 为什么我在JSP中能得到TEXT文本中的数据,却得不到在SELECT中的数据呢? 求救!为什么我的ACESS数据库文件会莫名其妙的达到25M,我还没输任何数据呢?而生成MDE后只有500K? 我要一个功能强大的弹出日历 Viva La Costa Rica! 我再也不看Chinese Team的比赛了! 如何做jar包呢?还有如何做bak呢?大家救救我吧。 《inside the c++ object model》问题 这句是什么意思??? 请问喝葡萄糖有什么作用?是提升记忆力还是补钙的? 秦朝灭亡后西汉建立前这段时间叫什么?为何字典上不记载这一时间段?当时是项羽的势力最大吗?为何他不改国号 化学问题H2S和NaOH反应生成什么?H2S和NaOH反应生成什么?几种情况都写下过量和不足H2Na只是一个还有什么情况 问一下有什么氧化还原剂 在KCl和CaCl2所组成的混合物中,KCl和CaCl2的物质的量的比为2比1,求1mol氯离子的该混合物的质量? H2S和氢氧化钠反应...为什么H2S和氢氧化钠反应生成的不是盐和水? 英语翻译 同学为证明NaOH溶液与稀盐酸发生了中和反应,从不同角度设计了如下方案,进行实验.方案一:先用PH试纸测定NaOH溶液的PH,再滴加盐酸,并不断振荡溶液,同时测定混合溶液的PH,如果(1)简述“强 周朝建立时,世界各国都处在什么阶段 西欧封建社会与同时期的中国有哪些异同 请大家来看看 这是个什么昆虫,叫什么名字,好漂亮哦 H2S + NAOH = 为了方便回答者准确理解,请您对问题标题或内容进行补充 谁懂越南语?帮我翻译一段文字.Vào lúc 8h ngày 26 tháng 9 cầu Cần Thơ đã bị sập các nhịp 13, 14, 15 , đã có ít nhất 50 người chết , 150 ngườ 韩国灭亡时间周朝啊 周朝是由谁所建立的啊? 467年西欧封建社会,当时中国的情况是什么? 周朝时候.“中国”指什么A是周天子的直辖地区 B中原地区 C华夏族的诸侯国 D首都 是谁建立的周朝 9-12世纪前后,西欧封建社会和中国封建社会的情况有什么不同? 周朝的建立时间回答 大禹是周朝的建立者吗 急寻电子干燥剂厂商? 在KCl和CaCl2所组成的某混合物中,K离子和Ca离子的物质的量之比为2:1,则该混合物中含CaCl2的质量分数为 只求最后一空,要详细的阶段过程. 向一定量的氢氧化钠溶液中加入一定量的稀盐酸后,混合液PH范围取混合溶液滴加酚酞试液,溶液无色,能否证明酸碱中恰好反应,理由 如要证明上述酸碱之间确实发生了反应,这混合溶液的PH值范 冰醋酸导电能力为0的理由 干燥剂哪儿有卖 在KCl和CaCl2的混合物中K离子和Ca离子物质的量之比2:1,则该混合物中含CaCl2的质量分数为___,含1molCl离子的该混合物的质量是__g(写出过程) 秦朝灭亡的时间是DC206还是DC207 干燥剂哪里有卖我是制冷维修工,在冲氟时想用干燥剂滤除冰箱管路空气中的水分;以防冰堵!在安徽泗县有卖的吗?知道的朋友请回我! kcl,cacl2组成的某种混合溶液中,k离子与ca离子物质的量之比2:1,求混合物中cacl2的质量分数? 秦朝的灭亡为什么秦朝灭亡 电子干燥剂 在KCl和CaCl2的混合溶液中K离子Ca离子的物质的量之比为2比1,KCl和CaCl2的物质的量之比为?质量之比为?还有一问,若要取出1mol氯离子的该混合物,应取该混合物的质量为? 请问烟台哪有卖助听器干燥剂的,就是那种潮湿后变颜色的干燥剂. 为什么溶液加水稀释,他的电离程度越大了加水稀释不是是反应物浓度减少吗,平衡就应该向左移啊,就右边的离子少了,而左边的分子多了啊,电离程度就应该减少啊 工地上使用生石灰时,为什么要进行熟化?熟化时,为什么必须进行陈伏? 一岁多宝宝误食水银有哪些症状 老师 请问溶液的导电性和什么有关 PH 导电性 电离程度有什么关系 中国历史上的盛世有多少个?到底哪个最“盛”?比如,仁宣之治,康乾盛世,贞观之治. 宝宝误食水银会怎样 弱电解质的电离度随溶液稀释而增大,故稀溶液比浓溶液的导电性强.为什么 盛世的内涵? 中国历史上有哪些盛世 小孩子吃了含汞的东西会怎样?有什么反应 [急]小孩误食水银怎么办?我家小孩不小心把水银温度计打破了,当我发现的时候他已经拿着含有水银的温度计咬在嘴里.这种问题要怎么办?小孩子才1岁.. 中国历史上的盛世之治有哪些?比如:贞观之治开元盛世等......只列举名称和朝代即可 西欧封建社会初期和同时期中国的情况有哪些异同 儿童误服水银怎么办?少量,而且没有什么特殊症状! 中国历史上有哪些盛世 请你试着比较西欧封建社会初期和中国当时的情况有什么不同? 小孩误食水银怎么办?给小儿测体温时,小儿不慎咬断温度计,将水银吞入,现已有6-7天时间了,拍片显示水银现滞留在小肠位置,孩子(3岁)没有不适症状,这种情况对孩子有没有问题,有没有办 生石灰熟化时为什么必须进行陈伏 西欧封建社会初期和当时的中国的情况有什么不同? 西欧封建社会初期和中国当时的情况有什么不同 请问中国历史上41个盛世是哪41个我想说的是 我只是初中生 目前我总结出来的有27个真心想不出来了 只是这次期末考试要写四个我在试题纸上写了27个在那边选 但我看到说有41个我很好奇剩 比较西欧封建社会初期和当时中国隋唐时期的情况有何不同? 一般的通讯干燥剂,哪有的卖? 如何将块状生石灰熟化成石灰膏? 秦朝怎么灭亡的,历史11课,按条答,每条一句话就行 从秦朝灭亡至西汉建立,其间到底发生了什么 H2S和NaOH如何反应如题
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘