2014年11月5日 星期三

(教學)Visual C++ 2005程式設計:如何實作一個Auto Number Generator的繁體中文版

//Auto Number Generator Electronic List
//ANG_Prototype.cpp
//by詹宗運
//免費授權Microsoft公司進行進一步的修改與工業化
//用來攤平記憶體缺損所造成的工業損失
//並且提供Visual C++社群做為討論與修改的使用
//version: Visual C++ 2005繁體中文版



最近科技業界常常出現科技公司老闆過勞死或是生病的新聞,
蘋果公司的iphone也常常當機而且記憶體出問題。
這是因為處理記憶體缺損是一項工業技術,
科技業老闆為了處理記憶體缺損所投入的時間與人力非常龐大,
最後都生病了。
其實筆者曾經在汐止科學園區上班,
筆者認為這些美國電腦系統的問題應該交還給美國科技業,
台灣應該做的是回報問題,
工業化以及商業化則應該交還給美國原廠去處理,
以台灣的資訊業人力數量來說並沒有美國那麼多人,
所以我們應該量力而為,
做好能力所及的事情就好,
並且要回報問題給美國原廠。

處理記憶體缺損並不是一件壞事,
使用MyErrorHandler事實上可以處理很多工業問題,
所以程式設計師有必要掌握程式設計的技術。
筆者並不缺錢,
利用這幾年空閒的時間開發小型程式,
現在正是創新與交棒給下一代2014程式設計師的時候了。
現在特別拿到網站上面公布,
這裡有AutoNumberGeneratorElectronicList的繁體中文新版,
這個程式可以產生自動號碼,
自動號碼就如同有了樂透號碼的全部組合,
如果電腦公司妥善的運用,
就可以利用這個程式開發出無限的資金,
例如樂透公司發行彩券創造收入就是一個方式。
微軟公司目前正在推廣無上限的雲端硬碟,
只要利用本程式工業化以後產生大量的自動號碼,
也可以很快的填滿微軟所有的硬碟,
歡迎公司行號推廣與利用這個程式碼。
也免費授權Microsoft微軟公司進行進一步的修改與工業化,
用來攤平記憶體缺損所造成的工業損失,
並且提供Visual C++社群做為討論與修改的使用。
version: Visual C++ 2005繁體中文版

使用方式:
建立一個Visual C++ 2005 WIN32主控台程式專案,
名稱設定成"ANG_Prototype"。
這時候會自動生成ANG_Prototype.cpp與stdafx.h
再建立一個空白標頭檔案名稱為"arrays.h"
然後把下面的ANG_Prototype.cpp與arrays.h所有文字內容,
分別拷貝貼上到你的同樣名稱的空白檔案裡面,
就可以使用了,
歡迎公司行號利用本程式提到的技術開發更高規模的工業化程式,
拼經濟救台灣。

//------------以下是stdafx.h程式碼
// stdafx.h : 可在此標頭檔中包含標準的系統 Include 檔,
// 或是經常使用卻很少變更的
// 專案專用 Include 檔案
//

#pragma once

#ifndef _WIN32_WINNT // 允許使用 Windows XP (含) 以後版本的特定功能。
#define _WIN32_WINNT 0x0501 // 將它變更為針對 Windows 其他版本的適當值。
#endif

#include <stdio.h>
#include <tchar.h>



// TODO: 在此參考您的程式所需要的其他標頭



//------------以下是arrays.h程式碼
/*
   Array Data Structure
   Chapter 2
   Data Structures for Game Developers
   Created by Allen Sherrod
*/


#include<cassert>


#ifndef _ARRAYS_H_
#define _ARRAYS_H_


template<typename T>
class UnorderedArray
{
   public:
      UnorderedArray(int size, int growBy = 1) :
                     m_array(NULL), m_maxSize(0),
                     m_growSize(0), m_numElements(0)
      {
         if(size)
            {
               m_maxSize = size;
               m_array = new T[m_maxSize];
               memset(m_array, 0, sizeof(T) * m_maxSize);

               m_growSize = ((growBy > 0) ? growBy : 0);
            }
      }

      ~UnorderedArray()
      {
         if(m_array != NULL)
            {
               delete[] m_array;
               m_array = NULL;
            }
      }

      void push(T val)
      {
         assert(m_array != NULL);

         if(m_numElements >= m_maxSize)
            {
               Expand();
            }

         m_array[m_numElements] = val;
         m_numElements++;
      }

      void pop()
      {
         if(m_numElements > 0)
            m_numElements--;
      }

      void remove(int index)
      {
         assert(m_array != NULL);

         if(index >= m_maxSize)
            {
               return;
            }

         for(int k = index; k < m_maxSize - 1; k++)
            m_array[k] = m_array[k + 1];
   
         m_maxSize--;

         if(m_numElements >= m_maxSize)
            m_numElements = m_maxSize - 1;
      }

      T& operator[](int index)
      {
         assert(m_array != NULL && index <= m_numElements);
         return m_array[index];
      }

      int search(T val)
      {
         assert(m_array != NULL);

         for(int i = 0; i < m_numElements; i++)
            {
               if(m_array[i] == val)
                  return i;
            }

         return -1;
      }

      void clear()      { m_numElements = 0; }
      int GetSize()     { return m_numElements; }
      int GetMaxSize()  { return m_maxSize; }
      int GetGrowSize() { return m_growSize; }

      void SetGrowSize(int val)
      {
         assert(val >= 0);
         m_growSize = val;
      }

   private:
      bool Expand()
      {
         if(m_growSize <= 0)
            return false;

         T *temp = new T[m_maxSize + m_growSize];
         assert(temp != NULL);

         memcpy(temp, m_array, sizeof(T) * m_maxSize);

         delete[] m_array;
         m_array = temp;

         m_maxSize += m_growSize;

         return true;
      }

   private:
      T *m_array;

      int m_maxSize;
      int m_growSize;
      int m_numElements;
};


template <typename T>
class OrderedArray
{
   public:
      OrderedArray(int size, int growBy = 1) :
                   m_array(NULL), m_maxSize(0),
                   m_growSize(0), m_numElements(0)
      {
         if(size)
            {
               m_maxSize = size;
               m_array = new T[m_maxSize];
               memset(m_array, 0, sizeof(T) * m_maxSize);

               m_growSize = ((growBy > 0) ? growBy : 0);
            }
      }

      ~OrderedArray()
      {
         if(m_array != NULL)
            {
               delete[] m_array;
               m_array = NULL;
            }
      }

      int push(T val)
      {
         assert(m_array != NULL);

         if(m_numElements >= m_maxSize)
            {
               Expand();
            }

         int i, k;

         for(i = 0; i < m_numElements; i++)
            {
               if(m_array[i] > val)
                  break;
            }

         for(k = m_numElements; k > i; k--)
            {
               m_array[k] = m_array[k - 1];
            }

         m_array[i] = val;
         m_numElements++;

         return i;
      }

      void pop()
      {
         if(m_numElements > 0)
            m_numElements--;
      }

      void remove(int index)
      {
         assert(m_array != NULL);

         if(index >= m_maxSize)
            {
               return;
            }

         for(int k = index; k < m_maxSize - 1; k++)
            m_array[k] = m_array[k + 1];
   
         m_maxSize--;

         if(m_numElements >= m_maxSize)
            m_numElements = m_maxSize - 1;
      }

      // Making this const allows for reading but not writing.
      const T& operator[](int index)
      {
         assert(m_array != NULL && index <= m_numElements);
         return m_array[index];
      }

      int search(T searchKey)
      {
         assert(m_array != NULL);

         int lowerBound = 0;
         int upperBound = m_numElements - 1;
         int current = 0;

         while(1)
            {
               current = (lowerBound + upperBound) >> 1;
             
               if(m_array[current] == searchKey)
                  {
                     return current;
                  }
               else if(lowerBound > upperBound)
                  {
                     return -1;
                  }
               else
                  {
                     if(m_array[current] < searchKey)
                        lowerBound = current + 1;
                     else
                        upperBound = current - 1;
                  }
            }

         return -1;
      }

      void clear()      { m_numElements = 0; }
      int GetSize()     { return m_numElements; }
      int GetMaxSize()  { return m_maxSize; }
      int GetGrowSize() { return m_growSize; }

      void SetGrowSize(int val)
      {
         assert(val >= 0);
         m_growSize = val;
      }

   private:
      bool Expand()
      {
         if(m_growSize <= 0)
            return false;

         T *temp = new T[m_maxSize + m_growSize];
         assert(temp != NULL);

         memcpy(temp, m_array, sizeof(T) * m_maxSize);

         delete[] m_array;
         m_array = temp;

         m_maxSize += m_growSize;

         return true;
      }

   private:
      T *m_array;

      int m_maxSize;
      int m_growSize;
      int m_numElements;
};


#endif
//---------------------------------------------------------------------

//---------------以下是ANG_Prototype.cpp程式碼
// ANG_prototype.cpp : 定義主控台應用程式的進入點。
//Auto Number Generator
//ANG_prototype.cpp
//by詹宗運
//免費授權Microsoft公司進行進一步的修改與工業化
//用來攤平記憶體缺損所造成的工業損失
//並且提供VC++社群做為討論與修改的使用
//version: Visual C++ 2005

#include "stdafx.h"

typedef struct a4element
{
int identity;
int a_content[3];
} A4element;



#include <windows.h>//myerrorhandler
#include <stdarg.h>//myerrorhandler
#include <stdio.h>//cout
#include <rtcapi.h>//myerrorhandler

#include <ostream>//fopen


#include <stdlib.h>//calloc
#include <iostream>//cout
#include <iomanip>//setw()






#include <fstream>
#include <memory.h>//typeinfo
#include <typeinfo>//typeinfo
#include <string.h>//string
#include <cstring>//string
#include <cstddef>//string







#define MAXQUEEN 7//定義最大堆疊容量,如果要超過10請修改switch case敘述
#define TRUE 1
#define FALSE 0
#define SOLUTION 5040//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24
#define ARRAYSIZE 8//ARRAYSIZE = MAXQUEEN+1
using namespace std;
int queen[MAXQUEEN];//存放8個皇后之列位置
int number=0;//計算總共有幾組解的總數
//決定皇后存放的位置
//輸出所需要的結果
#include "arrays.h"
UnorderedArray<int> array(4);




int SNum[SOLUTION][MAXQUEEN];//SNum = SolutionNumber
char SChar[SOLUTION][MAXQUEEN];//SChar = SolutionChar
char buf[SOLUTION*MAXQUEEN];//buf = bufferNumber

int remain;//remain = remain number

int calculate(int ,int);

#pragma runtime_checks("", off)

void print_table()
{
     int x=0,y=0;
     number+=1;


remain = SOLUTION-number;


     cout<<"自動產生"<<MAXQUEEN<<"個號碼組合的第"\
<<setw(7)<<number<<\
"組號碼,進度為剩下"<<remain<<\
"組尚未處理。"<<endl<<"\t";


int k=0;
for(x=0;x<MAXQUEEN;x++)
     {
        for(y=0;y<MAXQUEEN;y++)
           if(x==queen[y])
  {
k=y+1;
  array.push(k);
  }

     }


}



void decide_position(int value)
{
   int i=0;// i=行
   while(i<MAXQUEEN)
   {
   //是否受到攻擊的判斷式
      if(calculate(i,value)!=TRUE)
      {
         queen[value]=i;//只有在未受攻擊時將計算值存入皇后陣列

         if(value==MAXQUEEN-1)//列已到末端
            print_table();//只有在未受攻擊時列已到末端時才印出結果
         else
            decide_position(value+1);//只有在未受攻擊時將計算值存入皇后陣列,
//計算完成以後,列+1遞迴重新執行函數( value=列)

      }
 //受攻擊時值不能存入陣列
      i++;//不論是否遭受攻擊都換行重新執行函數 i=行
   }  
}
//0,0 i++
//1,0 queen[0]=1
//1,1 flag=1,i++
//2,1 queen[1]=2
//2,2 flag=1,i++


//資料來源:VC++資料結構教科書
//測試在(row,col)上的皇后是否遭受攻擊
//若遭受攻擊則傳回值為1,否則傳回0
int calculate(int row,int col)
{
    int i=0,flag=FALSE;
 
    while((flag!=TRUE)&&i<col)//當未遭受攻擊與i計算值小於VALUE
    {
     
       //判斷兩皇后是否在同一列在同一對角線上
     
       if((queen[i]==row))

  flag=TRUE;//只有在未受攻擊與計算值小於VALUE,
//當皇后陣列與待求VALUE相同時,判定遭受攻擊
       i++;//逐行檢查
    }
    return flag;
}

#pragma runtime_checks("", off)
//主程式
void construct_A4element(){

int f=0;
int g=0;
int h=0;

remain=0;


A4element *a=(A4element*)calloc(SOLUTION,sizeof(A4element));

while(f<SOLUTION)
{


while(g<(ARRAYSIZE-1))
{
a->identity=f;
a->a_content[g]=array[h];

cout<<"目前核對a["<<f<<"]->a_content["<<g<<"]="<<\
(a->a_content[g])<<endl;//顯示內容

SNum[f][g]=array[h];

//如果要超過10階乘就要加大下面這個switch case敘述
switch(SNum[f][g])
{
case 10:
SChar[f][g]='0';
break;
case 1:
SChar[f][g]='1';
break;
case 2:
SChar[f][g]='2';
break;
case 3:
SChar[f][g]='3';
break;
case 4:
SChar[f][g]='4';
break;
case 5:
SChar[f][g]='5';
break;
case 6:
SChar[f][g]='6';
break;
case 7:
SChar[f][g]='7';
break;
case 8:
SChar[f][g]='8';
break;
case 9:
SChar[f][g]='9';
break;

}


buf[h]=SChar[f][g];

h++;
g++;
}
g=0;
f++;
remain=SOLUTION - f;
cout<<"核對資料結構還剩下"<<remain<<"組。"<<endl;

}

cout<<"計算完成"<<endl;
system("pause");

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

string str(SOLUTION*MAXQUEEN,' ');

cout<<"號碼產生的數量是 "<<h<<"個。"<<endl;

for(string::size_type ix=1;ix!=(string::size_type)(array.GetSize());++ix)
{
str[ix]=(char)array[ix];

}
cout<<"字串轉換完成。"<<endl;
system("pause");
//--------------------------------------------------------
//-------------make SNum----------------------------------

cout<<"計算SNum當中"<<endl;
int m=0;
int n=0;
int p=0;
    remain=0;

while(m<SOLUTION)
{
while(n<MAXQUEEN)
{
a->identity=m;
a->a_content[n]=array[p];

cout << "核對SNum[" <<m<< "]["<< n <<"]="<<(SNum[m][n])<<endl;
cout << "核對SChar["<<m<<"]["<<n<<"]="<<(SChar[m][n])<<endl;

SNum[m][n]=a->a_content[n];




p++;

n++;
}
n=0;
//---遞迴顯示自動號碼----
cout<<"這組自動號碼是:"<<endl;
for(int t=0;t<MAXQUEEN;t++)
cout<<SChar[m][t]<<" ";
cout<<endl;
//-----------------------
m++;
remain=SOLUTION-m;

cout<<"自動號碼已處理"<<m<<"組,剩下"<<remain<<"組"<<endl;

}
cout<<"自動號碼計算完成,開始輸出檔案到C硬碟。"<<endl;
cout<<"生成檔案名稱為c:\\AutoNumberGeneratorElectronicList.txt。"<<endl;
system("pause");

//--------------output------------------------------------

fstream outf(("c://AutoNumberGeneratorElectronicList.txt"),ios::out|ios::app);
//if(outf.fail())
// return;






if(buf[0]!='\0'){
outf.write(buf,sizeof(buf));
outf<<endl;

}

outf.close();

cout<<"輸出檔案完成。"<<endl;

cout<<"array的型態 = "<<typeid(array).name()<<endl;
cout<<"感謝Allen Sherrod先生的資料結構教科書,僅此致謝。"<<endl;
cout<<"Auto Number Generator: Visual C++ 2005版,"<<endl;
cout<<"詹宗運製作,"<<endl;
cout<<"免費授權Microsoft公司進行進一步的修改與工業化,"<<endl;
cout<<"用來攤平記憶體缺損所造成的工業損失,"<<endl;
cout<<"並且提供VC++社群做為討論與修改的使用。"<<endl;
system("pause");
free(a);

}




//主程式


#pragma runtime_checks("", off)

// RTC Error Handler
int MyErrorHandler(int errType, const char* file, int line,\
    const char* module, const char* format, ...)
{
    // 1. Prevent re-entrance
    static long IsRunning = 0;
    while ( InterlockedExchange(&IsRunning, 1) )
        Sleep(1);

    // 2. Get the RTC error number from the var_arg list
    va_list ArgList;
    va_start(ArgList, format);
    _RTC_ErrorNumber ErrorNumber = va_arg(ArgList, _RTC_ErrorNumber);
    va_end(ArgList);

    char s[1024];
    // 3. Get the error description
    const char* ErrorDesc = _RTC_GetErrDesc(ErrorNumber);
    sprintf_s(s, sizeof(s), "%s occured.\nLine: %i\
\nFile: %s\nModule: %s\nClick OK to break into debugger.",\
        ErrorDesc, line, file ? file : "Unknown",\
     module ? module : "Unknown");
 
// 4. Display message box
    MessageBoxA(NULL, s, "Run-Time Error", MB_OK);
    // 5. Go ahead and break into the debugger
    return 1;
}
#pragma runtime_checks("", restore)




int _tmain(int argc, _TCHAR* argv[])
{


cout<<"自動號碼生成器,詹宗運製作。"<<endl;
cout<<"接下來會自動運算出許多訊息,請耐心等待訊息停止以後,"<<endl;
cout<<"再按下按鍵繼續運算。"<<endl;
cout<<"開始運算,請準備。"<<endl;
system("pause");

_RTC_error_fn OldHandler;
    // Set new RTC error handler and save the old one
    OldHandler = _RTC_SetErrorFunc(&MyErrorHandler);



decide_position(0);
construct_A4element();

    _RTC_SetErrorFunc(OldHandler);
system("pause");


return 0;
}


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

11 則留言:

  1. 我提供一下資料來源:
    這個程式實作的遞迴部份程式碼,
    可以參考 金禾資訊 吳燦銘先生 資料結構使用C++ 4-2-4 八皇后問題
    arrays.h則是來自 charles river media書店,
    Allen Sherrod先生的
    Data Structure and Algorithms for Game Developers.
    這些都是已公開的教學用程式碼,
    實作程式碼只要把MyErrorHandler的#pragma關掉的敘述寫到程式裡面,
    就可以正確的在電腦執行。
    利用現有的教科書open source程式碼,
    就可以完成auto Number Generator的實作了。

    資料來源:
    金禾資訊 吳燦銘先生 資料結構使用C++ , ISBN 9789861492575
    Allen Sherrod先生 Data Structure and Algorithms for Game Developers ISBN-10 1584504951
    僅此致謝,
    希望工業化以後,
    2014版可以推出更進步的VC++教科書。

    回覆刪除
  2. Auto Number Generator是一項超越時代的程式。
    這裡的A4element已經電腦化,不需要實體,
    也不需要遵守舊電腦使用印表機的規則。
    他可以自動算出1234567的所有排列組合,
    並且儲存成一個檔案放在電腦的C硬碟。
    不需要用紙,不需要人力,也不需要印表機。
    想想看在工業界可以節省多少費用,
    可是當初倚天中文電腦雜誌居然停辦了,
    可見越高的獲利就代表著越高的風險。
    事實上依照電腦本身的規則就可以生成數字組合,
    非常方便。
    如果可以把這項技術工業化,
    電腦就可以算出所有的數字組合,
    甚至是更高層次的運算,都有可能辦到。
    這裡提供的是Visual C++繁體中文版。
    只要是符合Visual C++2005電腦本身規則的電腦,
    都可以使用這項計算程式。
    在工業界有很多意見是反對電腦讓使用者這樣算的,
    工廠也想盡辦法推銷紙、人力與印表機,
    所以發表這項程式有很大的阻力。
    不過我認為這些反對的意見常常阻止Visual C++語言進步。
    現在特別提出這個程式,
    希望引起業界的重視。
    越高的風險,就代表著越高的獲利。
    真正有價值的運算,
    都是有工業化的必要,
    而且應該由程式員一代接著一代的寫出來。
    人的生命是很短暫的,
    電腦工業界如果阻止人類產生新版免費程式,
    人類更應該寫出更多程式,
    取回電腦應該有的硬體免費價格,
    節省紙張人力,
    寫程式讓硬體計算更多,
    硬體才會變成好用而且不用付錢的硬體。
    這才是程式員努力工業化的正確方向。

    回覆刪除
  3. 2014/11/11
    組合語言相關文章:
    http://stackoverflow.com/questions/9824448/optimizations-by-compiler-in-a-recursive-program

    感謝ozzy123大大的分享,
    最佳化與工業化的細節就留給筆電工廠的程式員,
    這方面的技術細節跟組合語言有關。
    相信透過組合語言方面的技術,
    可以有效提升未來筆電的效能,
    就可以增加台灣筆電的銷售量了。

    回覆刪除
  4. 作者已經移除這則留言。

    回覆刪除
  5. 作者已經移除這則留言。

    回覆刪除
  6. 2014/11/14
    已經修改檔案儲存部份的程式碼,已確定可以正常生成檔案。
    如果你希望獲得7階乘的AutoNumberGeneratorElectronicList.txt,
    建議你以系統管理員身分執行這個程式,
    就可以正確生成AutoNumberGeneratorElectronicList.txt。
    請勿在硬碟空間已經快要用完的硬碟上面生成檔案,
    以免硬碟空間不足,造成電腦錯誤。
    使用者如果修改程式碼故意造成電腦空間用完,
    本文作者不負任何責任,特此聲明。
    請使用者注意。
    如果使用者已經有這項技術,
    想修改程式碼要造成電腦空間用完,
    請你趕快拿新版擴充版程式技術去填滿微軟公司的無上限雲端硬碟,
    微軟公司的無上限雲端硬碟現在缺人,謝謝。

    回覆刪除
  7. 2014/11/14
    ccy19640710(scott.chiang)的問題:

    程式有用到 Microsoft.ACE.OLEDB.12.0 然後用安裝和部署的專案,

    在另一台電腦上安裝完成,

    執行時出現 Microsoft.ACE.OLEDB.12.0 提供者並未登錄於本機電腦上,

    那應該是沒有資料庫引擎的關係.

    那我要如何在安裝部署中加入資料庫引擎套件在安裝時一起安裝?

    不知 VB.NET 有沒有像 VB6 一樣,用封裝暨部署精靈就可以將資料庫引擎包進來的!


    答案:

    安裝部署中加入資料庫引擎可以簡單解釋成下面幾個步驟:

    1.輸出友善的訊息顯示到螢幕上面,
    判斷使用者確定要安裝資料庫引擎。

    2.使用電腦程式碼停止電腦系統阻止安裝引擎的安全碼,
    讓資料庫引擎可以安裝。
    對現在的電腦來說也很簡單,
    就是把停止阻止安裝的程式碼寫好,
    然後以系統管理員的身分執行就可以了。

    3.執行安裝部分的電腦程式碼,
    這個程式碼可能是一長串的遞迴程式或是解壓縮程式,
    因此一般來說不會用VB寫這部份的程式碼,
    通常是微軟公司自己用Visual C++在寫的,
    所以你可以試著聯絡微軟公司看看。
    一般的程式員並不會有權限來設計這種安裝程式,
    請你向微軟公司反應情況,
    他們可能可以開放給你一些VB權限或是VB文件來進行VB的開發。

    4.程式解壓縮完或是算完遞迴式以後就要執行程式碼恢復電腦系統的安全碼。
    這樣就完成了。

    請參考: C++論壇的教學: 如何實作一個Auto Number Generator
    http://www.programmer-club.com.tw/ShowSameTitleN/c/45953.html

    這是一個利用遞迴程式求出1234567所有排列組合的Visual C++程式,
    你可以把程式裡面的遞迴程式當作是一個迷你的資料庫引擎,
    然後把算出來的組合數字當作是一個迷你的資料庫安裝部署。

    Auto Number Generator裡面的步驟如下:


    int _tmain(int argc, _TCHAR* argv[])
    {
    ...
    }


    int _tmain()函式的內容如下:

    1.輸出友善的訊息顯示到螢幕上面,
    判斷使用者是要確定執行或是按下關閉按鈕跳出。

    2.使用電腦程式碼停止電腦系統阻止安裝引擎的安全碼,
    讓資料庫引擎可以安裝。
    這裡VC++的實作是使用MyErrorHandler。

    3.執行安裝部分的電腦程式碼,
    這個程式碼可能是一長串的遞迴程式或是解壓縮程式,
    在這個程式裡面是執行decide_position(0) 和build_A4element()這兩個函式。

    4.程式解壓縮完或是算完遞迴式以後就要執行程式碼恢復電腦系統的安全碼。
    這裡VC++的實作是使用MyErrorHandler。
    這樣就完成了。

    最後再強調一次:
    一般來說不會用VB寫這部份的程式碼,
    通常是微軟公司自己的主管用Visual C++在寫的,
    所以你可以試著聯絡微軟公司看看。
    一般的程式員並不會有權限來設計這種安裝程式,
    請你向微軟公司反應情況,
    他們可能可以開放給你一些VB權限或是VB文件來進行VB的開發。


    回覆刪除
  8. 2014/11/21 關於延伸閱讀
    有部份的英文單字已經因為21世紀所以有了不同的稱呼名稱。
    維基百科有下列英文單字的延伸閱讀:


    1.airplane generator, vortex generator
    http://en.wikipedia.org/wiki/Vortex_generator

    2.automobile industry, automotive industry
    http://en.wikipedia.org/wiki/Automotive_industry

    3.automobile generator, Automotive_thermoelectric_generator
    http://en.wikipedia.org/wiki/Automotive_thermoelectric_generator

    4.electric generator
    http://en.wikipedia.org/wiki/Electric_generator

    5.number generator, Lamborghini
    http://en.wikipedia.org/wiki/Lamborghini

    回覆刪除
  9. 2015/8/29 網誌已經更新,加上了我本人的簽名。

    回覆刪除
  10. 2016/11/7 網誌已經更新,
    參考了美國大選的英文用法,
    把build_A4element()改名成較為正確的construct_A4element()。

    回覆刪除
  11. 千萬不要過勞死!過勞死是不值得的。
    過勞死最新新聞專輯的網址:

    https://zh.cn.nikkei.com/china/ccompany/23578-2017-02-06-15-40-25.html

    回覆刪除