句柄表和继承
句柄表和继承
句柄代表着备操作的对象
句柄的本质(handler)
句柄表可以看做一个非常大的结构体数组
句柄表的结构
索引值: 进程通过索引找到句柄表中对应的选项
内核对象地址: 通过地址直接找到对应的内核对象
访问掩码: 控制了访问权限
标志位: 标志改句柄能否被继承
句柄代表着备操作的对象
句柄表可以看做一个非常大的结构体数组
句柄表的结构
索引值: 进程通过索引找到句柄表中对应的选项
内核对象地址: 通过地址直接找到对应的内核对象
访问掩码: 控制了访问权限
标志位: 标志改句柄能否被继承
//获取控件句柄
HWND GetDlgItem(
HWND hDlg,//获得控件所处的窗口的句柄
int nIDDlgItem //控件id
);
//初始化列表的列 (listview插入新的一列
int ListView_InsertColumn(
HWNDhwnd, //控件的句柄
int iCol, //第几列 (索引 index
const LPLVCOLUMNpcol //结构体指针 (包含新列的结构体
);
//插入新的一行条目
int ListView_InsertItem(
HWND hwnd,
const LPLVITEM pitem
);
//设置条目的属性
BOOL ListView_SetItem(
HWND hwnd,
const LPLVITEM pitem
);
//删除所有项目
BOOL ListView_DeleteAllItems(
HWND hwnd
);
//标准输出格式化字符串
swprintf(buffer,L"%s,哈哈",param);
//清空
ZeroMemory(buffer);
list属性:
//获得进程所使用的堆,模块和线程的信息快照
HANDLE WINAPI CreateToolhelp32Snapshot
(
DWORD dwFlags,//标志位
DWORD th32ProcessID //进程ID
)
//dwFlags: 指定的快照中,指定需要拍的系统部分
TH32CS_INHERIT 声明快照句柄是可继承的。
TH32CS_SNAPALL 在快照中包含系统中所有的 进程和线程。
TH32CS_SNAPHEAPLIST 在快照中包含ID所指定的进程的所有的堆。
TH32CS_SNAPMODULE 在快照中包含在ID所指定的进程的所有的模块。
TH32CS_SNAPPROCESS 在快照中包含系统中所有的进程。
TH32CS_SNAPTHREAD 在快照中包含系统中所有的线程。
BOOL WINAPI Process32First(
HANDLE hSnapshot, //快照句柄
LPPROCESSENTRY32 lppe //获得的信息
);获得快照中的第一个成员的信息
BOOL WINAPI Process32Next(
HANDLE hSnapshot, //快照句柄
LPPROCESSENTRY32 lppe //获得的信息
);获得快照中后一个成员的信息
函数实现
BOOL CreateProcess(
LPCTSTR lpApplicationName, // name of executable module
LPTSTR lpCommandLine, // command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD
LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
BOOL bInheritHandles, // handle inheritance option
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // new environment block
LPCTSTR lpCurrentDirectory, // current directory name
LPSTARTUPINFO lpStartupInfo, // startup information
LPPROCESS_INFORMATION lpProcessInformation // process information
);
//中文版注释
BOOL CreateProcess(
LPCTSTR lpApplicationName, // 可执行模块名称 (全路径 必须是const字符串
LPTSTR lpCommandLine, // 命令行(字符串 可以不是const字符串
LPSECURITY_ATTRIBUTES lpProcessAttributes, // 进程安全描述符
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程描述符
BOOL bInheritHandles, // 继承标志位
DWORD dwCreationFlags, // 创建标志位 (指定控制优先级和创建过程的额外标志,除了如前说,可以在任何组合中指定下列创建标标志
LPVOID lpEnvironment, // 进程环境块
LPCTSTR lpCurrentDirectory, // 驱动目录
LPSTARTUPINFO lpStartupInfo, // 启动信息 指向一个窗体结构,该接口体表示新进程的窗口应该如何出现
LPPROCESS_INFORMATION lpProcessInformation // 进程信息
);
//启动信息参数的结构体
typedef struct _STARTUPINFO {
DWORD cb; //记录指定结构体大小,以字节为单位
LPTSTR lpReserved;
LPTSTR lpDesktop;
LPTSTR lpTitle; //对于控制台进程,日过创建了新的控制欲窗口,则会显示标题栏中的标题,如果NULL。可执行文件额名称将会用作窗口标题, This parameter must be NULL for GUI or console processes that do not create a new console window.
DWORD dwX; //控制窗口位置x
DWORD dwY; //控制窗口位置y
DWORD dwXSize; //控制窗口宽度
DWORD dwYSize; //控制窗口高度
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindow; //窗口显示方式
WORD cbReserved2;
LPBYTE lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
} STARTUPINFO, *LPSTARTUPINFO;
//进程信息结构体
typedef struct _PROCESS_INFORMATION {
HANDLE hProcess; //进程句柄
HANDLE hThread; //主线程句柄
DWORD dwProcessId; //被创建的进程id
DWORD dwThreadId; //被创建的主线程ID
} PROCESS_INFORMATION;
exp: 启动qq
运行中的
程序活在内存中
有血有肉有灵魂死在
硬盘上的 有肉没血没灵魂Windows中称为视窗,是一个程序的操作显示界面
Windows中通过什么机制将发生的一些动作和响应的响应函数连接起来
api就是一些预先定义的函数
,目的是提供应用程序与开发人员基于某软件或者硬件的一访问一组例程的能力,而又无需访问源码,或者理解内部工作机制的细节
数据类型 | 容器、模板 | |
---|---|---|
ASCII | 一个字符 | 一个字节 |
GB码(扩展了的ASCII) | 英文字符 | 一个字节 |
GB码 | 中文字符 | 两个字节 |
UNICODE字符集(unicode编码实际指的是utf-16) | 常用字符 | 两个字节 |
宽字符: 用多个字节来表示的字符称之为宽字符
(只要不是以单字节存储都可称为宽字符)
由于ASCII存在字符含量过少的缺陷,所以不但我国自己搞出了国际码。其他国家也都设计出了符合自己国情的字符集
01-09区 为特殊字符区
10-15区 为自定义区
16-87区 为汉字编码区
下面是一个针对int的冒泡排序
// _20180301.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
void Sort(int* arr,int nLength)
{
int i,k;
for (i = 0;ix > base.x && this->y > base.y;
}
private:
int x;
int y;
};
template
void Sort(T* arr,int nLength)
{
int i,k;
for (i = 0;iy)
return x;
else
return y;
}
M min()
{
相同类型间可以直接拷贝
// _20180212.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include
#include
class A
{
private:
int* a;
public:
A()
{
a = new int[10];
}
virtual ~A()
{
delete a;
printf("析构 A \n");
}
};
int main(int argc,char* argv[])
{
A a1;
A a2;
a1 = a2;
return 0;
}
//反汇编
27: A a1;
0040108D lea ecx,[ebp-14h]
00401090 call @ILT+15(B::B) (00401014)
00401095 mov dword ptr [ebp-4],0
28: A a2;
0040109C lea ecx,[ebp-1Ch]
0040109F call @ILT+15(B::B) (00401014)
004010A4 mov byte ptr [ebp-4],1
29: a1 = a2;
004010A8 lea eax,[ebp-1Ch]
004010AB push eax //a2 作为参数传递
004010AC lea ecx,[ebp-14h] //a1 作为this指针传递
004010AF call @ILT+45(A::operator=) (00401032)
30: return 0;
A::operator=:
004012E0 push ebp
004012E1 mov ebp,esp
004012E3 sub esp,44h
004012E6 push ebx
004012E7 push esi
004012E8 push edi
004012E9 push ecx
004012EA lea edi,[ebp-44h]
004012ED mov ecx,11h
004012F2 mov eax,0CCCCCCCCh
004012F7 rep stos dword ptr [edi]
004012F9 pop ecx
//eax = a1首地址
004012FA mov dword ptr [ebp-4],ecx
004012FD mov eax,dword ptr [ebp-4]
//ecx = a2首地址
00401300 mov ecx,dword ptr [ebp+8]
//ecx + 4 这里是 class A中变量a的地址(ecx 对应虚表地址)
//因为ecx是变量a2 所以这里的edx = a2.a
00401303 mov edx,dword ptr [ecx+4]
//a2.a 赋值给a1.a
00401306 mov dword ptr [eax+4],edx
//返回a1首地址
00401309 mov eax,dword ptr [ebp-4]
0040130C pop edi
0040130D pop esi
0040130E pop ebx
0040130F mov esp,ebp
00401311 pop ebp
00401312 ret 4
我们发现使用=
直接赋值对象,编译器自动生成了operator=
函数用于处理类型赋值
我们观察编译器自动生成的函数operator=
,这里赋值直接略过了虚表(ecx+4)
while
a = 10
while a > 0
puts a
a -= 1
end
until
a = 100
until a == 0
puts a
a -= 1
end
loop
a = 10
loop do
break if a 0
!~
正则匹配 是否匹配不到 匹配到返回fals 匹配不到返回true
# class_eval
class User
end
User.class_eval do
attr_accessor :name
def hello
"hello"
end
end
user = User.new
user.name = "world"
puts user.name
puts user.hello
# module"s self
module Management
def self.track
"track"
end
end
class User
include Management
end
# User.track # => error
Management.track
# class_eval in project
# requirement: we need to execute a class method when module included
module Manegement
def self.included base #Manafement模块被其他类Included的时候会执行
base.extend ClassMethods #User类注入ClassMethod
base.class_eval do #打开User类
setup_attribute
end
end
# Manegement 内部模块 当引入Management的时候 会被引用为其他类的类方法
module ClassMethods
def setup_attribute
puts "setup_attribute"
end
end
end
class User
include Manegement #目的是在include Management 的时候执行一些方法或者设置
end
# instance_eval, instance methods and class methods
# 1. as a question
class User
end
User.class_eval do
def hello
"hello"
end
end
User.instance_eval do
def hi
"hi"
end
end
puts User.hi
user = User.new
puts user.hello
# puts user.hi #报错
# instance_eval, singleton_method
a = "xxx"
a.instance_eval do
def to_hello
self.replace("hello")
end
end
puts a.to_hello
# b = "world"
# b.to_hello # => error
# class_eval as instance_eval
class User
end
User.class_eval do
def hello
"hello"
end
# works same as instance_eval
def self.hi
"hi"
end
end
puts User.new.hello
puts User.hi
# metho missing
#
# 1. how it works
# 2. ancestors
# 3. rails"s AR
class User
def hello
"hello from User"
end
def method_missing(name, *args)
"method name is #{name} ,parameters :#{args}"
end
end
user = User.new
puts user.hello
puts "-" * 30
puts user.hi("hello",19)
使用::
来访问
Array.class # => Class
Class.class # => Class
Array.superclass # =>Object
Object.superclass # =>BasicObject
BasicObject.superclass # => nil
Array.ancestors # => [Array, Enumerable, Object, Kernel, BasicObject]
# class structure, method finding
class User
def panels
@panels ||= ["Profile", "Products"]
end
end
class Admin < User
end
puts Admin.ancestors
admin = Admin.new
p admin.panels
# 从下往上查找 在admin中查找 找不到往上找User 然后Object 然后Kernel 然后 BasicObject
# 重新打开class
class User
def panels
@panels ||= ["Profile", "Products"]
end
end
class User
def panels
"overwrite"
end
end
puts User.ancestors
admin = User.new
p admin.panels
# 从下往上查找 在admin中查找 找不到往上找User 然后Object 然后Kernel 然后 BasicObject
# overwrite and re-open
class Array
def to_hello_word
"hello #{self.join(", ")}"
end
end
a = %w[cat horse dog]
puts a.to_hello_word
# overwrite and re-open
a = %w[cat horse dog]
puts a.join(",")
class Array
def join
"hello"
end
end
puts "-" * 30
puts a.join
Array.ancestors # => [Array, Enumerable, Object, Kernel, BasicObject]
Enumerable.class # => Module
Module.class # => Class
# module acts linke a class
module Management
def company_notifies
"company_notifies from management"
end
end
class User
include Management
def company_notifies
puts super
"company_notifies from user"
end
end
p User.ancestors
puts "-" * 30
user = User.new
puts user.company_notifies
# module included sequence
module Management
def company_notifies
"company_notifies from management"
end
end
module Track
def company_notifies
"company_notifies from track"
end
end
class User
include Management
include Track
def company_notifies
puts super
"company_notifies from user"
end
end
p User.ancestors
puts "-" * 30
user = User.new
puts user.company_notifies
# 1 module included in module
# 2 module acts as class
module Management
def company_notifies
"company_notifies from management"
end
end
module Track
include Management
def company_notifies
puts super
"company_notifies from track"
end
end
p Track.ancestors
puts "-" * 30
include Track
puts company_notifies
# module"s class method
module Management
def self.progress
"progress"
end
# you need to include/extend/prepend to use this metod
def company_notifies
"company_notifies from management"
end
end
puts Management.progress
后面
前面
# module include
# include
module Management
def company_notifies
"company_notifies from management"
end
end
class User
prepend Management
# include Management
def company_notifies
"company_notifies from user"
end
end
p User.ancestors
puts "-" * 30
user = User.new
puts user.company_notifies
当模块被include时会被执行,同事会传递当前作用于的self对象
# inheritance
class User
attr_accessor :name, :age
def initialize name, age
@name, @age = name, age
end
def panels
# ||= 操作符, 如果变量不存在 那么就赋值
@panels ||= ["Profile", "Products"]
end
end
class Admin < User
def panels
@panels ||= ["Profile", "Products", "Manage Users", "System Setup"]
end
end
user = User.new("user_1", 18)
p user.panels
puts "-" * 30
admin = Admin.new("admin_1", 28)
puts admin.name
p admin.panels
# 查看这个类的父类
p Admin.superclass
super关键字
调用父类的同名方法
self關鍵字
指向當前作用域實例
|
|
|
|
|
|
|
|
自己实现 attr_accessor
Demo
# 变量交换
a = 1
b = 2
b,a = a,b
puts a
puts b
puts "-" * 30
x = [1, 2, 3]
a, b = x #默认会把数组中的值依次赋值给 a ,b
puts a
puts b
puts "-" * 30
x = [1, 2, 3]
a, *b = x #这里a会接受第一个元素 b用了*号 表示接受剩下所有的元素
puts a
p b
#output
2
1
------------------------------
1
2
------------------------------
1
[2, 3]
# number
puts 1 / 10
puts 1 / 10.0
puts "-" * 30
#output
0.1
------------------------------
# string
a = "world"
b = %Q{
hello
#{a}
}
# 这里不但可以用 {} 也可以用 ()
# 但是这里的Q必须是大Q 如果是小q的话 就相当于单引号的效果
puts b
puts "-" * 30
{puts "hello"}
Demo:
# block usage
def hello
puts "hello method start"
yield
yield
puts "hello method end"
end
hello {puts "i am in block"}
#output
hello method start
i am in block
i am in block
hello method end
# yield with parameter
def hello
puts "hello method start"
yield("hello","world")
puts "hello method end"
end
hello {|x,y| puts "i am in block,#{x} #{y}"}
#output
hello method start
i am in block,hello world
hello method end
# yield with paramter
def hello name
puts "hello method start"
result = "hello " + name
yield(result)
puts "hello method end"
end
hello("world"){|x| puts "i am in block,i got #{x}"}
#output
hello method start
i am in block,i got hello world
hello method end
# build in methods
["cat", "dog","frog"].each do |animal|
puts animal
end
puts "-" * 30
["cat","dog","frog"].each{|animal| puts animal}
#output
cat
dog
frog
------------------------------
cat
dog
frog
# build in methods
10.times do |t|
puts t
end
puts "-" * 30
("a".."d").each { |char| puts char}
#output
1
2
3
4
5
6
7
8
9
------------------------------
a
b
c
d
# varibale scope
# before ruby2.0
x = 1
[1, 2, 3].each { |x| puts x}
puts x # => x will be 3,which is incorrect
#output
1
2
3
1
如果是在ruby2之前的版本 那么外部的变量x会被改变
# varibale scope
# 如果是2.0版本之后 puts x会报错
sum = 0
[1, 2, 3].each { |x| sum += x}
puts sum
# puts x
#output
6
# block return value
class Array
def find
each do |value|
return value if yield (value)
end
nil
end
end
puts [1, 2, 3].find { |x| x == 2 }
#output
2
# block as named parameter
def hello name, &block
puts "hello #{name}, from method"
block.call(name)
end
hello("world") {|x| puts "hello #{x} form block"}
#output
hello world, from method
hello world form block
# yield with parameter
def hello
puts "hello method start"
yield("hello","world")
puts "hello method end"
end
hello {|x,y| puts "i am block ,#{x},#{y}"}
#output
hello method start
i am block ,hello,world
hello method end
# block_given?
def hello
if block_given?
yield
else
puts "hello from method"
end
end
hello
puts "-" * 30
hello {puts "hello from block"}
#output
hello from method
------------------------------
hello from block
# block can be closure
def counter
sum = 0
# 代码库接收了一个参数x 如果x没有定义那么x为1 然后 sum +=x
proc {|x| x = 1 unless x; sum +=x }
end
c2 = counter
puts c2.call(1) #1
puts c2.call(2)
puts c2.call(3)
# 这里 closure 为闭包
#
#output
1
3
6
# new method to create block
# name is required
hello = -> (name){"hello #{name}"}
puts hello.call("world")
puts "-" * 30
# name is required
hello3 = lambda {|name| "hello #{name}"}
puts hello3.call("world")
puts "-" * 30
hello2 = proc {|name| "hello #{name}"}
puts hello2.call
puts hello2.call("world")
# lambda和proc区别 proc可以不传参数 lambda 更像是一个方法,必须传递参数
#output
hello world
------------------------------
hello world
------------------------------
hello
hello world
All Exception inherited from Exception Class