免費論壇 繁體 | 簡體
Sclub交友聊天~加入聊天室當版主
分享
返回列表 回復 發帖

暫存

Dim Screen As Point = System.Windows.Forms.SystemInformation.PrimaryMonitorSize
      

---------------------------------------
hwnd<>hThread
FindWindow->GetWindowThreadProcessId->OpenThread->SuspendThread






VB中輕鬆實現多執行緒


"     我們在用VB寫程式的時候,可能會碰到這樣的情況,就是在一個無限的迴圈之外,我們還希望程式能完成一些其他的工作。例如,我們要編寫一個即時監視註冊表的程式,需要用到一個無限的等待迴圈來監視註冊表鍵值的變化(可以用函數WaitForSingleObject來實現),但是一旦程式進入這個無限的迴圈等待當中,就再也無法執行其他任務,也不能回應任何事件了(除非該函數監測到註冊表鍵值發生變化而退出迴圈)。到底有沒有辦法解決這個問題呢?回答當然是肯定的,只要把這個無限迴圈單獨放在一個執行緒中,問題就迎刃而解了。可是這又涉及到了一個如何創建多執行緒的問題。可能大家以為創建多個執行緒很困難吧,其實不是這樣的。

     在VB中用addressof操作符,再加上一些Windows API函數,就可以輕易地實現多執行緒。用VB做的多執行緒比用C++簡單得多,而且做出來的速度一樣快,因為它們都使用Windows API。每一個執行緒佔用大約20毫秒時間片。

     用VB寫多執行緒程式用到的第一個API函數是CreateThread,這個函數的聲明如下:

     Private Declare Function CreateThread Lib ""kernel32"" (ByVal lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long)As Long

     這個函數的返回值是執行緒的控制碼,它的參數含義如下:

     1.lpThreadAttributes:這個參數表明函數的返回控制碼是否可被子進程繼承,如果可被繼承,則指向一個SECURITY_ATTRIBUTES的結構,否則設為vbnull。

     2.dwStackSize:這個參數設置執行緒的堆疊大小。

     3.lpStartAddress:這個參數指明這個執行緒函數的起始位址。

     4.lpParameter:這個參數是傳給執行緒函數的參數。

     5.dwCreationFlags:這個參數設置當執行緒創建時的初始狀態,掛起,運行等等。

     6.lpThreadId:這個參數是待創建執行緒的ID號。

     假設創建一個管理執行緒的類clsThreads,用類的一個公用函數Initialize來初始化執行緒,用ResumeThread和SuspendThread函數來啟動執行緒,實現代碼如下:

     Private Type udtThread

     Handle As Long

     Enabled As Boolean

     End Type

     Private uThread As udtThread

     Private Const CREATE_SUSPENDED As Long = &H4

     Private Declare Function CreateThread Lib ""kernel32"" (ByVal lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long

     Private Declare Function ResumeThread Lib ""kernel32"" (ByVal hThread As Long) As Long

     Private Declare Function SuspendThread Lib ""kernel32"" (ByVal hThread As Long) As Long

     Private Declare Function TerminateThread Lib ""kernel32"" (ByVal hThread As Long, ByVal dwExitCode As Long) As Long

     Public Sub Initialize(ByVal lpfnBasFunc As Long)     '初始化執行緒

     Dim lStackSize As Long, lCreationFlags As Long, lpThreadId As Long, lNull As Long

     On Error Resume Next

     lNull = 0   '創建一個空指標

     lStackSize = 0     '0表示用exe的stack size

     lCreationFlags = CREATE_SUSPENDED     '表示初始化後先不啟動,讓別人來啟動

     uThread.Handle = CreateThread(lNull, lStackSize, lpfnBasFunc, lNull, lCreationFlags, lpThreadId)

     If uThread.Handle = lNull Then MsgBox ""Create thread failed!""

     End Sub

     Public Property Get Enabled() As Boolean

     On Error Resume Next

     Enabled = uThread.Enabled

     End Property
---------------------------------------------------------


     Public Property Let Enabled(ByVal vNewvalue As Boolean)

     On Error Resume Next

     If vNewvalue And (Not uThread.Enabled) Then

     ResumeThread uThread.Handle      '啟動執行緒

     uThread.Enabled = True

     ElseIf uThread.Enabled Then

     SuspendThread uThread.Handle

     uThread.Enabled = False

     End If

     End Property

     Private Sub Class_Terminate()     '終止執行緒

     On Error Resume Next

     Call TerminateThread(uThread.Handle, 0)

     End Sub

     以上內容在類別模組clsThreads中,有了它就可以在表單中實現多執行緒了。下面以一個簡單的例子來說明如何創建多執行緒(以2個執行緒為例)。

     在form1中添加picture1和picture2兩個圖片框,以及一個command1按鈕,在工程中添加一個bas模組,該模組的代碼如下:

     Option Explicit

     Private Declare Function GetTickCount Lib ""kernel32"" () As Long

     Public Sub FlickerTop()

     Static BgColor As Long

     Dim lTick As Long, lCounter As Long

     On Error Resume Next

     For lCounter = 0 To 60000

     BgColor = lCounter Mod 256

     Form1.Picture1.BackColor = RGB(BgColor, 0, 0)     '變化圖片框的顏色

     lTick = GetTickCount

     While GetTickCount - lTick < 10     '延遲10個毫秒時間

     Wend

     Next

     End Sub

     Public Sub FlickerBottom()

     Static BgColor As Long

     Dim lTick As Long, lCounter As Long

     On Error Resume Next

     For lCounter = 0 To 60000

     BgColor = lCounter Mod 256

     Form1.Picture2.BackColor = RGB(0, BgColor, 0)

     lTick = GetTickCount

     While GetTickCount - lTick < 10

     Wend

     Next

     End Sub

     最後在form1中用下面的代碼來創建兩個執行緒,

     Option Explicit

     Public myThreadTop As New clsThreads, myThreadBottom As New clsThreads

     Private Sub Command1_Click()

     On Error Resume Next

     With myThreadTop

     .Initialize AddressOf FlickerTop

     .Enabled = True

     End With

     With myThreadBottom

     .Initialize AddressOf FlickerBottom

     .Enabled = True

     End With

     MsgBox ""看看會有什麼...""

     Set myThreadTop = Nothing

     Set myThreadBottom = Nothing

     End Sub

代碼很簡單,程式運行的結果是出現兩個顏色不斷變化的圖片框(注意,兩個圖片框的顏色是同時變化的,而且分別各處在一個迴圈當中,即兩個迴圈同時進行),但是必須記住的一點就是程式退出之前一定要結束所創建的執行緒,不然就會出現非法操作之類的錯誤。多執行緒的應用還有很多,用途是十分廣泛的,上面舉到的一些例子只是多執行緒應用的極小一部分,更多的東西還需要大家在實踐中積累得到。(文中程式在Windows98+VB6.0下調試通過)



Option Explicit
Public Type SYSTEM_INFO
         dwOemID As Long
        dwPageSize As Long
        lpMinimumApplicationAddress As Long
         lpMaximumApplicationAddress As Long
        dwActiveProcessorMask As Long
        dwNumberOrfProcessors As Long
         dwProcessorType As Long
        dwAllocationGranularity As Long
        dwReserved As Long
End Type
Public Const STANDARD_RIGHTS_REQUIRED = &HF0000
Public Const SYNCHRONIZE = &H100000
Public Const SPECIFIC_RIGHTS_ALL = &HFFFF
Public Const STANDARD_RIGHTS_ALL = &H1F0000
Public Const PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF
Public Const PROCESS_VM_OPERATION = &H8&
Public Const PROCESS_VM_READ = &H10&
Public Const PROCESS_VM_WRITE = &H20&
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Public Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Public Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Declare Sub GetSystemInfo Lib "kernel32" (lpSystemInfo As SYSTEM_INFO)
Public Declare Function GetWindowThreadProcessId Lib "user32" _
(ByVal hWnd As Long, lpdwProcessId As Long) As Long
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
'----------------------------------------------------------------------------------------------
'以下程式在Form中
Option Explicit
Dim hProcess As Long
Dim hProcessID As Long
Dim hThreadID As Long
Dim hWndOfApp As Long
Dim hSysInfo As SYSTEM_INFO
Dim lBassAddr As Long
Private Sub Command1_Click()
List2.Clear
Dim s() As Byte, n As Long, i As Long
lBassAddr = Text2.Text
n = Text3.Text
ReDim s(n - 1)
hWndOfApp = FindWindow(vbNullString, Text1.Text)
If hWndOfApp = 0 Then
    MsgBox "無法找到該視窗"
    Exit Sub
End If
hThreadID = GetWindowThreadProcessId(hWndOfApp, hProcessID)
If hProcessID = 0 Then
    MsgBox "無法取得ProcessID"
    Exit Sub
End If
   
hProcess = OpenProcess(PROCESS_ALL_ACCESS _
, 0, hProcessID)

If hProcess = 0 Then
    MsgBox "無法開啟該Process"
    Exit Sub
End If

ReadProcessMemory hProcess, ByVal lBassAddr, s(0), n, ByVal 0&
For i = 0 To n - 1
     List2.AddItem "位址:" & (i + lBassAddr) & "= " & s(i)
Next


CloseHandle hProcess
End Sub

Private Sub Command2_Click()
Dim s() As Byte, n As Long, i As Long
Dim Data1 As Byte, Data2 As Integer, Data4 As Long
lBassAddr = Text4.Text
If Option1(0).Value Then
    n = 1
    ReDim s(0)
    Data1 = Text5.Text
     CopyMemory s(0), Data1, n
ElseIf Option1(1).Value Then
    n = 2
    ReDim s(0 To 1)
    Data2 = Text5.Text
    CopyMemory s(0), Data2, n
ElseIf Option1(2).Value Then
    n = 4
    ReDim s(0 To 3)
    Data4 = Text5.Text
    CopyMemory s(0), Data4, n
End If

hWndOfApp = FindWindow(vbNullString, Text1.Text)
hThreadID = GetWindowThreadProcessId(hWndOfApp, hProcessID)
hProcess = OpenProcess(PROCESS_ALL_ACCESS _
, 0, hProcessID)
WriteProcessMemory hProcess, ByVal lBassAddr, s(0), n, ByVal 0&
CloseHandle hProcess
End Sub

Private Sub Form_Load()
GetSystemInfo hSysInfo '取得應用程式最小及最大定址
Text2.Text = hSysInfo.lpMinimumApplicationAddress '應用程式最小定址
Text4.Text = hSysInfo.lpMinimumApplicationAddress '應用程式最小定址
Label5.Caption = "可用位址從" & hSysInfo.lpMinimumApplicationAddress & _
" 到 " & hSysInfo.lpMaximumApplicationAddress
End Sub

------------------------------------------------------------------------------

'偵測是否按下Enter 鍵,若是則執行 同Command2_Click程式
Private Sub Text1_KeyDown(ByVal eventSender As System.Object, ByVal eventArgs As System.Windows.Forms.KeyEventArgs) Handles Text1.KeyDown
                Dim KeyCode As Short = eventArgs.KeyCode
                Dim Shift As Short = eventArgs.KeyData \ &H10000
        If KeyCode = 13 Then Call Command2_Click(Command2, New System.EventArgs())

        End Sub
------------------------------------------------------------------------------------

 Private Sub Command1_Click()
   Dim hInst As Long
   Dim Thread As Long
  
   'Set up the CBT hook
   hInst = GetWindowLong(Me.hwnd, GWL_HINSTANCE)
   Thread = GetCurrentThreadId()
   hHook = SetWindowsHookEx(WH_CBT, AddressOf WinProc1, hInst, _
   Thread)
  
   'Display the message box
   MsgBox "This message box has been positioned at (0,0)."
  
   End Sub
  
   Private Sub Command2_Click()
   Dim hInst As Long
   Dim Thread As Long
  
   'Set up the CBT hook
   hInst = GetWindowLong(Me.hwnd, GWL_HINSTANCE)
   Thread = GetCurrentThreadId()
   hHook = SetWindowsHookEx(WH_CBT, AddressOf WinProc2, hInst, _
   Thread)
  
   'Display the message box
   MsgBox "This message box is centered over Form1."
   End Sub
   =============================================================================
   Type RECT
   Left As Long
   Top As Long
   Right As Long
   Bottom As Long
   End Type
  
   Public Declare Function UnhookWindowsHookEx Lib "user32" ( _
   ByVal hHook As Long) As Long
   Public Declare Function GetWindowLong Lib "user32" Alias _
   "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) _
   As Long
   Public Declare Function GetCurrentThreadId Lib "kernel32" () As Long
   Public Declare Function SetWindowsHookEx Lib "user32" Alias _
   "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, _
   ByVal hmod As Long, ByVal dwThreadId As Long) As Long
   Public Declare Function SetWindowPos Lib "user32" ( _
   ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
   ByVal x As Long, ByVal y As Long, ByVal cx As Long, _
   ByVal cy As Long, ByVal wFlags As Long) As Long
   Public Declare Function GetWindowRect Lib "user32" (ByVal hwnd _
   As Long, lpRect As RECT) As Long
  
   Public Const GWL_HINSTANCE = (-6)
   Public Const SWP_NOSIZE = &H1
   Public Const SWP_NOZORDER = &H4
   Public Const SWP_NOACTIVATE = &H10
   Public Const HCBT_ACTIVATE = 5
   Public Const WH_CBT = 5
  
   Public hHook As Long
  
   Function WinProc1(ByVal lMsg As Long, ByVal wParam As Long, _
   ByVal lParam As Long) As Long
  
   If lMsg = HCBT_ACTIVATE Then
   'Show the MsgBox at a fixed location (0,0)
   SetWindowPos wParam, 0, 0, 0, 0, 0, _
   SWP_NOSIZE Or SWP_NOZORDER Or SWP_NOACTIVATE
   'Release the CBT hook
   UnhookWindowsHookEx hHook
   End If
   WinProc1 = False
  
   End Function
  
   Function WinProc2(ByVal lMsg As Long, ByVal wParam As Long, _
   ByVal lParam As Long) As Long
  
   Dim rectForm As RECT, rectMsg As RECT
   Dim x As Long, y As Long
  
   'On HCBT_ACTIVATE, show the MsgBox centered over Form1
   If lMsg = HCBT_ACTIVATE Then
   'Get the coordinates of the form and the message box so that
   'you can determine where the center of the form is located
   GetWindowRect Form1.hwnd, rectForm
   GetWindowRect wParam, rectMsg
   x = (rectForm.Left + (rectForm.Right - rectForm.Left) / 2) - _
   ((rectMsg.Right - rectMsg.Left) / 2)
   y = (rectForm.Top + (rectForm.Bottom - rectForm.Top) / 2) - _
   ((rectMsg.Bottom - rectMsg.Top) / 2)
   'Position the msgbox
   SetWindowPos wParam, 0, x, y, 0, 0, _
   SWP_NOSIZE Or SWP_NOZORDER Or SWP_NOACTIVATE
   'Release the CBT hook
   UnhookWindowsHookEx hHook
   End If
   WinProc2 = False
  
   End Function
  前一段是 FORM 代碼
  
  後一段是 MODULE 代碼
  其實可以考慮自己寫個小窗體來實現 比較簡單(王朝網路 wangchao.net.cn)
--------------------------------------------------------------------------------
API用法暫存

GetWindow( hWnd: HWND; {指定的窗口句柄} uCmd: UINT {指定的关系选项} ): HWND; {失败返回0; 成功返回符合的窗口句柄} //uCmd
可选值:
GW_HWNDFIRST = 0; {同级别第一个}
GW_HWNDLAST = 1; {同级别最后一个}
GW_HWNDNEXT = 2; {同级别下一个}
GW_HWNDPREV = 3; {同级别上一个}
GW_OWNER = 4; {属主窗口}
GW_CHILD = 5; {子窗口}
連結

procedure TForm1.Button1Click(Sender: TObject);
var
  h: HWnd;
  p: array[0..254] of char;
begin
  h := GetWindow(Handle, GW_HWNDFIRST);
  while h <> 0 do
  begin
    if GetWindowText(h, p, 255) > 0 then Memo1.Lines.Add(p);
    h := GetWindow(h, GW_HWNDNEXT);
  end;
end;



-------------------------------------------------
GetWindow
函数功能:该函数返回与指定窗口有特定关系(如Z序或所有者)的窗口句柄。
函数原型:HWND GetWindow(HWND hWnd,UNIT nCmd);
参数:
hWnd:窗口句柄。要获得的窗口句柄是依据nCmd参数值相对于这个窗口的句柄。
nCmd:说明指定窗口与要获得句柄的窗口之间的关系。该参数值可以是下列之一:
GW_CHILD:如果指定窗口是父窗口,则获得的是在Z序顶端的子窗口的句柄,否则为NULL。函数仅检查指定父窗口的子窗口,不检查继承窗口。
GW_ENABLEDPOUP:(WindowsNT 5.0)返回的句柄标识了属于指定窗口的处于使能状态弹出式窗口(检索使用第一个由GW_HWNDNEXT 查找到的满足前述条件的窗口);如果无使能窗口,则获得的句柄与指定窗口相同。
GW_HWNDFIRST:返回的句柄标识了在Z序最高端的相同类型的窗口。如果指定窗口是最高端窗口,则该句柄标识了在Z序最高端的最高端窗口;如果指定窗口是顶层窗口,则该句柄标识了在z序最高端的顶层窗口:如果指定窗口是子窗口,则句柄标识了在Z序最高端的同属窗口。
GW_HWNDLAST:返回的句柄标识了在z序最低端的相同类型的窗口。如果指定窗口是最高端窗口,则该柄标识了在z序最低端的最高端窗口:如果指定窗口是顶层窗口,则该句柄标识了在z序最低端的顶层窗口;如果指定窗口是子窗口,则句柄标识了在Z序最低端的同属窗口。
GW_HWNDNEXT:返回的句柄标识了在Z序中指定窗口下的相同类型的窗口。如果指定窗口是最高端窗口,则该句柄标识了在指定窗口下的最高端窗口:如果指定窗口是顶层窗口,则该句柄标识了在指定窗口下的顶层窗口;如果指定窗口是子窗口,则句柄标识了在指定窗口下的同属窗口。
GW HWNDPREV:返回的句柄标识了在Z序中指定窗口上的相同类型的窗口。如果指定窗口是最高端窗口,则该句柄标识了在指定窗口上的最高端窗口;如果指定窗口是顶层窗口,则该句柄标识了在指定窗口上的顶层窗口;如果指定窗口是子窗口,则句柄标识了在指定窗口上的同属窗口。
GW_OWNER:返回的句柄标识了指定窗口的所有者窗口(如果存在)。
返回值:如果函数成功,返回值为窗口句柄;如果与指定窗口有特定关系的窗口不存在,则返回值为NULL。
若想获得更多错误信息,请调用GetLastError函数。
备注:在循环体中调用函数EnumChildWindow比调用GetWindow函数可靠。调用GetWindow函数实现该任务的应用程序可能会陷入死循环或退回一个已被销毁的窗口句柄。
速查:Windows NT:3.1以上版本;Windows:95以上版本;Windows CE:1.0以上版本;头文件:winuser.h;库文件:user32.lib。

-------------------------------------------------------------------
Label1.Text = (New Random().NextDouble).ToString  '傳回0~1之間的亂數

Label1.Text = System.Windows.Forms.SystemInformation.PrimaryMonitorSize.ToString '傳回解析度

-------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace Csharp_TEST
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
         
        const int MOUSEEVENTF_MOVE = 0x0001;     //移動滑鼠
        const int MOUSEEVENTF_LEFTDOWN = 0x0002; //左鍵下
        const int MOUSEEVENTF_LEFTUP = 0x0004; //左鍵上
        const int MOUSEEVENTF_RIGHTDOWN = 0x0008; //右鍵下
        const int MOUSEEVENTF_RIGHTUP = 0x0010; //右鍵上
        const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;//中鍵下
        const int MOUSEEVENTF_MIDDLEUP = 0x0040;// 中鍵上
        const int MOUSEEVENTF_ABSOLUTE = 0x8000; //絕對座標
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
     
            mouse_event(MOUSEEVENTF_LEFTDOWN, 500, 400, 0, 0);
            mouse_event(MOUSEEVENTF_LEFTUP, 500, 400, 0, 0);
        }
    }
}




XueTr 神器 可以去除驱动级别的钩子绑定
-------------------------------------------------------------------------
series 的 DataPoints 改成用 DataBind 的方式

資料來源實作INotifyPropertyChanged
當資料來源有異動時 就會變更 UI
---------------------------------------------------------------------------
判斷是否為 null

if(b == null)

{

b = new Form();

b.Show();

}

else

{

b.activate();

}





果您用的是SQL Server資料庫, 可以使用SqlNotificationRequest類別, 以在資料庫記錄被更新時收到通知


Label1.DataBindings.Add("Text", TextBox1, "Text")




'因為原先使用下面語法進行列印,所以不管如何設定格式都跳掉
CrystalReportViewer1.PrintReport()


'後來修正列印的語法後,就可以依CrystalReport設計時所設定的印表機紙張進行列印
Dim customerReport As ReportDocument = New ReportDocument
customerReport.Load(Test.rpt)
customerReport.SetDataSource(ds) 'ds=dataset
CrystalReportViewer1.ReportSource = customerReport
   
'設定印表名稱
customerReport.PrintOptions.PrinterName = "\印表機名稱"
'列印
customerReport.PrintToPrinter(1, True, 0, 0)



物件 字首
BackgroundWorker(非同步作業)
BindingNavigator
BindingSource
Button(命令按鈕) btn
CheckBox(核取方塊) chk
CheckedListBox(核取方塊清單)
ColorDialog
ComboBox(下拉清單方塊) cbo
ContextMenuStrip
DataGridView(表格控制項) dgv
DataSet
DataTimePicker
DirectoryEntry
DirectorySearcher
DomainUpDown
ErrorProvider
EventLog
FileSystemWatcher
FlowLayoutPanel
FolderBrowserDialog
FontDialog
Form(表單) frm
GroupBox(群組框架) grp
HelpProvider
HScrollBar(水平捲軸) hsb
ImageList(影像)
Label(標籤) lbl
ListBox(清單方塊) lst
ListView lv
MaskedTextBox
MenuStrip(功能表) mun
MessageQueue
MonthCalendar
NotifyIcon
NumericUpDown
OpenFileDialog
PageSetupDialog
Panel
PerformanceCounter
PictureBox(圖片方塊) pic
PrintDialog
PrintDocument
PrintPreviewControl
PrintPreviewDialog
Process
ProgressBar(進度條) prg
PropertyGrid
RadioButton(選項按鈕) rad
RichTextBox(簡易文書編輯器)
SaveFileDialg
SerialPort
ServiceController
SplitContainer
Spiltter
StatusStrip
TabControl tab
TableLayuPanel
TextBox(文字方塊) txt
Timer(計時器) tmr
ToolStrip
ToolStripContainer
ToolTip
TrackBar
TreeView
VScrollBar(垂直捲軸) vsb
WebBrowser wb


-----------------------------------------------------------

Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.Text

Public Class Form1
    Const PROCESS_WM_READ As Integer = &H10
    <DllImport("kernel32.dll")>
    Public Shared Function OpenProcess(dwDesiredAccess As UInteger, bInheritHandle As Boolean, dwProcessId As Integer) As Integer
    End Function

    <DllImport("kernel32.dll")>
    Public Shared Function ReadProcessMemory(hProcess As Integer, lpBaseAddress As Integer, buffer As Byte(), size As Integer, lpNumberOfBytesRead As Integer) As Boolean
    End Function

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim notepadProcess As Process = Process.GetProcessesByName("程式名稱")(0)
        Dim processHandle As IntPtr = OpenProcess(PROCESS_WM_READ, False, notepadProcess.Id)
        Dim bytesRead As Integer = 0
        Dim buffer As Byte() = New Byte(23) {}

        ReadProcessMemory(CInt(processHandle), &HXXXXXX, buffer, buffer.Length, bytesRead)
        '&HXXXXXX是指定程式字串位置
        MsgBox(Encoding.UTF8.GetString(buffer))
    End Sub

End Class

-------------------------------------------------



http://fecbob.pixnet.net/blog/post/38606641
vb.net的委託調用



vb.net程式設計如果用多執行緒,因為無法傳遞函數指標,所以就存在了委託調用從而實現獲得函數指標的作用:

在VB.NET中,一個委派是一個型別安全、物件導向的函數指標。


委託調用程式設計如下:



'定義一個發送端‘更新進度條’的委託

Public Delegate Sub UpdateSendCallBack(ByVal msg As String, ByVal SendNum As Integer)



'發送端‘更新進度條’

Public Sub UpdateSend(ByVal msg As String, ByVal SendNum As Integer)

If frmmainsl.ProgressBar1.InvokeRequired Then



Dim d As New UpdateSendCallBack(AddressOf UpdateSend)

frmmainsl.Invoke(d, New Object() {msg, SendNum})

Else



Me.Label3.Text = msg

Me.ProgressBar1.Value = SendNum

End If



總結:delegate聲明一個委託——定義委託調用的函數。(委託和函數的參數要一致)



這樣在其他執行緒中要實現更新季度條時要這樣寫: frmmainsl.UpdateSend("第" & PacketNum + 1 & "包傳送結束!", PacketNum + 1)





正規寫法:



定義一個發送端‘更新進度條’的委託

Public Delegate Sub UpdateSendCallBack(ByVal msg As String, ByVal SendNum As Integer)



'發送端‘更新進度條’

Private Sub UpdateSend(ByVal msg As String, ByVal SendNum As Integer)

Me.Label3.Text = msg

Me.ProgressBar1.Value = SendNum

End If



這樣在其他執行緒中要實現更新季度條時要這樣寫: frmmainsl.Invoke(New UpdateSendCallBack(AddressOf UpdateSend), New Object() {"第" & PacketNum + 1 & "包傳送結束!", PacketNum + 1})

----------------------------------------------------------------------------------------------------------

標籤說明:
<summary>:說明文字。
<remarks>:可加入型別相關資訊,補充 <summary>資訊。

<param>:傳入的參數加上說明。
<returns>:傳回值加上描述。
<value>:說明屬性。


-------------------------------------------------------------------------
大家好,
我弄不清楚在子類別(sub class)的意思是甚麼? 在參考書上的問題程式碼是這樣的。

Class 1

Public Class TextLine
     Public Line As String
     ' 建構子(1)
     Public Sub New()
         Line = ""
     End Sub
     ' 建構子(2)
     Public Sub New(text As String)
         Line = text
     End Sub
     ' 物件方法
    Public Function GetWord() As String
         Dim arrWords() As String = Split(Line, " ")
         Return (arrWords(0))
     End Function
     ' 可覆寫的方法
    Public Overridable Sub ShowText()
         Console.WriteLine(LCase(Line))
     End Sub
End Class


Class 2

Public Class MyLine
     Inherits TextLine
     ' 建構子
    Public Sub New()
         MyBase.New()
     End Sub
     ' 新增屬性
    ReadOnly Property Length() As Long
         Get
             Return Len(MyBase.Line)
         End Get
     End Property
     ' 新增方法
    Public Function InStr(str As String) As Integer
         Dim arrWords() As String =
                           Split(MyBase.Line, " ")
         Dim i As Integer
         For i = 0 To UBound(arrWords)
             If arrWords(i) = str Then
                 Exit For
             End If
         Next i
         If i < UBound(arrWords) Then
             Return i + 1
         End If
         Return -1
     End Function
     ' 覆寫方法
    Public NotOverridable Overrides Sub ShowText()
         Console.WriteLine(MyBase.Line)
     End Sub
End Class

Module 1

Module Module1
     Sub Main()
         Dim line As MyLine = New MyLine()
         Dim txtline As TextLine =
                        New TextLine("THIS IS A BOOK.")
         txtline.ShowText()
         Console.WriteLine("第1個字: " & txtline.GetWord())
         line.Line = "That is a pen."
         line.ShowText()
         Console.WriteLine("字串長度: " & line.Length)
         Console.WriteLine("第1個字: " & line.GetWord())
         Console.WriteLine("找尋is: " & line.InStr("is"))
         line = Nothing
         txtline = Nothing
         Console.Read()
     End Sub
End Module

我發覺在class 2中把MyBase關鍵字刪去後,結果還是一樣的。是否說MyBase其實沒有實際作用呢?




因為如果你不寫,編譯器會在編譯的時候幫你加回去。不過他不會加在你的原始碼,而是加在編譯後的 IL Code 裡面。

建構式的預設行為就是呼叫父類別的無參數建構式。你可以把父類別的無參數建構式刪掉,只留下那個有一個參數的建構式 , 子類別的建構式也不要加  MyBase.New(),

正常來說,編譯應該會失敗。因為會找不到父類別的無參數建構式。

----------------------------------------------------------------
關於第二點,就如 .Net Framework 的許多對話盒一樣.這些對話盒是給很多程式,表單使用.
如果你沒有降偶,就是表單A跟表單B關係很緊的話,你這樣你整個系統就會有多的這種子表單,非常難維護.
第三點.程式跟程式間是傳資料而不要傳控制項.資料物件跟控制項用DataBinding的方式.二個控制項蓮到同一個DataBinding 時當某個控件轉換某個資料狀態,她會回寫到原來的DataSource,然後DataBinding 就會通知所有UI,控制項...去更新顯示.而你在操作時只要修改資料來源UI就變化,這樣妳就不用為了一個值去找某個控件了.
比如說(討論區最常見的) DataGridView 裡包 DataGridView 包 ListBox 再包ComboBox.今天我要找 ComboBox 的值. 告訴你你要找到這個值,寫到哭你都還不一定取的出.


1.寫Class or form 要有封裝的效果,所謂封裝就是該對外面通訊才Public,不然就用Private.為什麼,你有看過一隻Class有好幾千個屬性,方法嗎?,你開的越多越難用,而每個Public 是 Property 而不要是  Field,而每個輸入都要有Check的動作.

2.Class or Form 之間要低偶合,所謂低偶合就是 A跟B之間的關係越小越好.怎麼將偶那?就是你在設計門面(方法),介面的通道越小越好.比如我今天要FormB 去修改 FormA的TextBoxA ,我今天設計 FormB去接收 FormA,那我真的只能改 FormA裡的TextBoxA. 如果我今天改一下 FormB去接TextBox的參數,我FormB就可以去改 FormA的TextBoxA,TextBoxB 或 FormC的TextBox.
接著第二個降偶的方式,是用第三方物件去傳參數.(範例還在思考中).
第三個比較複雜一點.比如說我 FormB 要執行 FormA 裡面三個方法.這個你就要將這三個方法去抽象化或介面化後當成參數去傳.
Exp: 我FormB 是做列印對話盒的動作.功能是要做印表機參數設定,列印的內容取自FormA的三個方法.所以你將三個方法取出並產生IPrint的介面,你列印時只要將IPrint 參數傳到 FormB就可以列印.而今天我要列印FormC,我也只要FormC實作IPrint 就可以列印FormC.

3.2個Control間內容要同步,動 ControlA ,ControlB連動,底層商業物件內容連動.這個你們要去學DataBinding 的物件及IPropertyChange.ICollectionChange(上面二個介面名稱可能不很正確,你們要在驗證一下).
有了這些,你就可以將資料庫或其它來源的資料Binding 到 Control 呈現,你在UI的修改會自動更新其他的畫面,及底層的資料來源.
返回列表