線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3739
推到 Plurk!
推到 Facebook!

關於"Unresolved external '__stdcall _com_issue_error(long)'"的錯誤

答題得分者是:dllee
huntfox
一般會員


發表:11
回覆:13
積分:4
註冊:2006-10-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-09-15 06:42:08 IP:203.79.xxx.xxx 訂閱
各位大大
我想要去取得CPU的使用率, 所以在網路上蒐尋相關的資訊
結果在VC6.0下可以正確執行
但是在BCB下卻出現下列的問題
請問該怎麼解決呢
[Linker Error] Unresolved external '__stdcall _com_issue_error(long)' referenced from C:\DOCUMENTS AND SETTINGS\FOX\桌面\CPUUSAGE_SRC\新資料夾\BCBATL.LIB|comutil
程式碼如下
<textarea class="cpp" rows="10" cols="60" name="code">cpuUsage.cpp #include "stdafx.h" #include // for CRegKey use #include "CpuUsage.h" #pragma pack(push,8) #include "PerfCounters.h" #pragma pack(pop) #define SYSTEM_OBJECT_INDEX 2 // 'System' object #define PROCESS_OBJECT_INDEX 230 // 'Process' object #define PROCESSOR_OBJECT_INDEX 238 // 'Processor' object #define TOTAL_PROCESSOR_TIME_COUNTER_INDEX 240 // '% Total processor time' counter (valid in WinNT under 'System' object) #define PROCESSOR_TIME_COUNTER_INDEX 6 // '% processor time' counter (for Win2K/XP) /////////////////////////////////////////////////////////////////// // // GetCpuUsage uses the performance counters to retrieve the // system cpu usage. // The cpu usage counter is of type PERF_100NSEC_TIMER_INV // which as the following calculation: // // Element Value // ======= =========== // X CounterData // Y 100NsTime // Data Size 8 Bytes // Time base 100Ns // Calculation 100*(1-(X1-X0)/(Y1-Y0)) // // where the denominator (Y) represents the total elapsed time of the // sample interval and the numerator (X) represents the time during // the interval when the monitored components were inactive. // // // Note: // ==== // On windows NT, cpu usage counter is '% Total processor time' // under 'System' object. However, in Win2K/XP Microsoft moved // that counter to '% processor time' under '_Total' instance // of 'Processor' object. // Read 'INFO: Percent Total Performance Counter Changes on Windows 2000' // Q259390 in MSDN. // /////////////////////////////////////////////////////////////////// typedef enum { WINNT, WIN2K_XP, WIN9X, UNKNOWN }PLATFORM; PLATFORM GetPlatform() { OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (!GetVersionEx(&osvi)) return UNKNOWN; switch (osvi.dwPlatformId) { case VER_PLATFORM_WIN32_WINDOWS: return WIN9X; case VER_PLATFORM_WIN32_NT: if (osvi.dwMajorVersion == 4) return WINNT; else return WIN2K_XP; } return UNKNOWN; } CCpuUsage::CCpuUsage() { m_bFirstTime = true; m_lnOldValue = 0; memset(&m_OldPerfTime100nSec, 0, sizeof(m_OldPerfTime100nSec)); } CCpuUsage::~CCpuUsage() { } BOOL CCpuUsage::EnablePerformaceCounters(BOOL bEnable) { if (GetPlatform() != WIN2K_XP) return TRUE; CRegKey regKey; if (regKey.Open(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\PerfOS\\Performance") != ERROR_SUCCESS) return FALSE; regKey.SetValue(!bEnable, "Disable Performance Counters"); regKey.Close(); if (regKey.Open(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\PerfProc\\Performance") != ERROR_SUCCESS) return FALSE; regKey.SetValue(!bEnable, "Disable Performance Counters"); regKey.Close(); return TRUE; } // // GetCpuUsage returns the system-wide cpu usage. // Since we calculate the cpu usage by two samplings, the first // call to GetCpuUsage() returns 0 and keeps the values for the next // sampling. // Read the comment at the beginning of this file for the formula. // int CCpuUsage::GetCpuUsage() { static PLATFORM Platform = GetPlatform(); if (m_bFirstTime) EnablePerformaceCounters(); // Cpu usage counter is 8 byte length. CPerfCounters PerfCounters; char szInstance[256] = {0}; // Note: // ==== // On windows NT, cpu usage counter is '% Total processor time' // under 'System' object. However, in Win2K/XP Microsoft moved // that counter to '% processor time' under '_Total' instance // of 'Processor' object. // Read 'INFO: Percent Total Performance Counter Changes on Windows 2000' // Q259390 in MSDN. DWORD dwObjectIndex; DWORD dwCpuUsageIndex; switch (Platform) { case WINNT: dwObjectIndex = SYSTEM_OBJECT_INDEX; dwCpuUsageIndex = TOTAL_PROCESSOR_TIME_COUNTER_INDEX; break; case WIN2K_XP: dwObjectIndex = PROCESSOR_OBJECT_INDEX; dwCpuUsageIndex = PROCESSOR_TIME_COUNTER_INDEX; strcpy(szInstance,"_Total"); break; default: return -1; } int CpuUsage = 0; LONGLONG lnNewValue = 0; PPERF_DATA_BLOCK pPerfData = NULL; LARGE_INTEGER NewPerfTime100nSec = {0}; lnNewValue = PerfCounters.GetCounterValue(&pPerfData, dwObjectIndex, dwCpuUsageIndex, szInstance); NewPerfTime100nSec = pPerfData->PerfTime100nSec; if (m_bFirstTime) { m_bFirstTime = false; m_lnOldValue = lnNewValue; m_OldPerfTime100nSec = NewPerfTime100nSec; return 0; } LONGLONG lnValueDelta = lnNewValue - m_lnOldValue; double DeltaPerfTime100nSec = (double)NewPerfTime100nSec.QuadPart - (double)m_OldPerfTime100nSec.QuadPart; m_lnOldValue = lnNewValue; m_OldPerfTime100nSec = NewPerfTime100nSec; double a = (double)lnValueDelta / DeltaPerfTime100nSec; double f = (1.0 - a) * 100.0; CpuUsage = (int)(f 0.5); // rounding the result if (CpuUsage < 0) return 0; return CpuUsage; } int CCpuUsage::GetCpuUsage(LPCTSTR pProcessName) { static PLATFORM Platform = GetPlatform(); if (m_bFirstTime) EnablePerformaceCounters(); // Cpu usage counter is 8 byte length. CPerfCounters PerfCounters; char szInstance[256] = {0}; DWORD dwObjectIndex = PROCESS_OBJECT_INDEX; DWORD dwCpuUsageIndex = PROCESSOR_TIME_COUNTER_INDEX; strcpy(szInstance,pProcessName); int CpuUsage = 0; LONGLONG lnNewValue = 0; PPERF_DATA_BLOCK pPerfData = NULL; LARGE_INTEGER NewPerfTime100nSec = {0}; lnNewValue = PerfCounters.GetCounterValue(&pPerfData, dwObjectIndex, dwCpuUsageIndex, szInstance); NewPerfTime100nSec = pPerfData->PerfTime100nSec; if (m_bFirstTime) { m_bFirstTime = false; m_lnOldValue = lnNewValue; m_OldPerfTime100nSec = NewPerfTime100nSec; return 0; } LONGLONG lnValueDelta = lnNewValue - m_lnOldValue; double DeltaPerfTime100nSec = (double)NewPerfTime100nSec.QuadPart - (double)m_OldPerfTime100nSec.QuadPart; m_lnOldValue = lnNewValue; m_OldPerfTime100nSec = NewPerfTime100nSec; double a = (double)lnValueDelta / DeltaPerfTime100nSec; CpuUsage = (int) (a*100); if (CpuUsage < 0) return 0; return CpuUsage; } int CCpuUsage::GetCpuUsage(DWORD dwProcessID) { static PLATFORM Platform = GetPlatform(); if (m_bFirstTime) EnablePerformaceCounters(); // Cpu usage counter is 8 byte length. CPerfCounters PerfCounters; DWORD dwObjectIndex = PROCESS_OBJECT_INDEX; DWORD dwCpuUsageIndex = PROCESSOR_TIME_COUNTER_INDEX; int CpuUsage = 0; LONGLONG lnNewValue = 0; PPERF_DATA_BLOCK pPerfData = NULL; LARGE_INTEGER NewPerfTime100nSec = {0}; lnNewValue = PerfCounters.GetCounterValueForProcessID(&pPerfData, dwObjectIndex, dwCpuUsageIndex, dwProcessID); NewPerfTime100nSec = pPerfData->PerfTime100nSec; if (m_bFirstTime) { m_bFirstTime = false; m_lnOldValue = lnNewValue; m_OldPerfTime100nSec = NewPerfTime100nSec; return 0; } LONGLONG lnValueDelta = lnNewValue - m_lnOldValue; double DeltaPerfTime100nSec = (double)NewPerfTime100nSec.QuadPart - (double)m_OldPerfTime100nSec.QuadPart; m_lnOldValue = lnNewValue; m_OldPerfTime100nSec = NewPerfTime100nSec; double a = (double)lnValueDelta / DeltaPerfTime100nSec; CpuUsage = (int) (a*100); if (CpuUsage < 0) return 0; return CpuUsage; } </textarea>
<textarea class="cpp" rows="10" cols="60" name="code">cpuUsage.h #ifndef _CPUUSAGE_H #define _CPUUSAGE_H #include class CCpuUsage { public: CCpuUsage(); virtual ~CCpuUsage(); // Methods int GetCpuUsage(); int GetCpuUsage(LPCTSTR pProcessName); int GetCpuUsage(DWORD dwProcessID); BOOL EnablePerformaceCounters(BOOL bEnable = TRUE); // Attributes private: bool m_bFirstTime; LONGLONG m_lnOldValue ; LARGE_INTEGER m_OldPerfTime100nSec; }; #endif </textarea>
<textarea class="cpp" rows="10" cols="60" name="code">perfCounters.h #include #include #include // for using bstr_t class #include #define TOTALBYTES 100*1024 #define BYTEINCREMENT 10*1024 template class CPerfCounters { public: CPerfCounters() { } ~CPerfCounters() { } T GetCounterValue(PERF_DATA_BLOCK **pPerfData, DWORD dwObjectIndex, DWORD dwCounterIndex, LPCTSTR pInstanceName = NULL) { QueryPerformanceData(pPerfData, dwObjectIndex, dwCounterIndex); PPERF_OBJECT_TYPE pPerfObj = NULL; T lnValue = {0}; // Get the first object type. pPerfObj = FirstObject( *pPerfData ); // Look for the given object index for( DWORD i=0; i < (*pPerfData)->NumObjectTypes; i ) { if (pPerfObj->ObjectNameTitleIndex == dwObjectIndex) { lnValue = GetCounterValue(pPerfObj, dwCounterIndex, pInstanceName); break; } pPerfObj = NextObject( pPerfObj ); } return lnValue; } T GetCounterValueForProcessID(PERF_DATA_BLOCK **pPerfData, DWORD dwObjectIndex, DWORD dwCounterIndex, DWORD dwProcessID) { QueryPerformanceData(pPerfData, dwObjectIndex, dwCounterIndex); PPERF_OBJECT_TYPE pPerfObj = NULL; T lnValue = {0}; // Get the first object type. pPerfObj = FirstObject( *pPerfData ); // Look for the given object index for( DWORD i=0; i < (*pPerfData)->NumObjectTypes; i ) { if (pPerfObj->ObjectNameTitleIndex == dwObjectIndex) { lnValue = GetCounterValueForProcessID(pPerfObj, dwCounterIndex, dwProcessID); break; } pPerfObj = NextObject( pPerfObj ); } return lnValue; } protected: class CBuffer { public: CBuffer(UINT Size) { m_Size = Size; m_pBuffer = (LPBYTE) malloc( Size*sizeof(BYTE) ); } ~CBuffer() { free(m_pBuffer); } void *Realloc(UINT Size) { m_Size = Size; m_pBuffer = (LPBYTE) realloc( m_pBuffer, Size ); return m_pBuffer; } void Reset() { memset(m_pBuffer,NULL,m_Size); } operator LPBYTE () { return m_pBuffer; } UINT GetSize() { return m_Size; } public: LPBYTE m_pBuffer; private: UINT m_Size; }; // // The performance data is accessed through the registry key // HKEY_PEFORMANCE_DATA. // However, although we use the registry to collect performance data, // the data is not stored in the registry database. // Instead, calling the registry functions with the HKEY_PEFORMANCE_DATA key // causes the system to collect the data from the appropriate system // object managers. // // QueryPerformanceData allocates memory block for getting the // performance data. // // void QueryPerformanceData(PERF_DATA_BLOCK **pPerfData, DWORD dwObjectIndex, DWORD dwCounterIndex) { // // Since i want to use the same allocated area for each query, // i declare CBuffer as static. // The allocated is changed only when RegQueryValueEx return ERROR_MORE_DATA // static CBuffer Buffer(TOTALBYTES); DWORD BufferSize = Buffer.GetSize(); LONG lRes; char keyName[32]; sprintf(keyName,"%d",dwObjectIndex); Buffer.Reset(); while( (lRes = RegQueryValueEx( HKEY_PERFORMANCE_DATA, keyName, NULL, NULL, Buffer, &BufferSize )) == ERROR_MORE_DATA ) { // Get a buffer that is big enough. BufferSize = BYTEINCREMENT; Buffer.Realloc(BufferSize); } *pPerfData = (PPERF_DATA_BLOCK) Buffer.m_pBuffer; } // // GetCounterValue gets performance object structure // and returns the value of given counter index . // This functions iterates through the counters of the input object // structure and looks for the given counter index. // // For objects that have instances, this function returns the counter value // of the instance pInstanceName. // T GetCounterValue(PPERF_OBJECT_TYPE pPerfObj, DWORD dwCounterIndex, LPCTSTR pInstanceName) { PPERF_COUNTER_DEFINITION pPerfCntr = NULL; PPERF_INSTANCE_DEFINITION pPerfInst = NULL; PPERF_COUNTER_BLOCK pCounterBlock = NULL; // Get the first counter. pPerfCntr = FirstCounter( pPerfObj ); for( DWORD j=0; j < pPerfObj->NumCounters; j ) { if (pPerfCntr->CounterNameTitleIndex == dwCounterIndex) break; // Get the next counter. pPerfCntr = NextCounter( pPerfCntr ); } if( pPerfObj->NumInstances == PERF_NO_INSTANCES ) { pCounterBlock = (PPERF_COUNTER_BLOCK) ((LPBYTE) pPerfObj pPerfObj->DefinitionLength); } else { pPerfInst = FirstInstance( pPerfObj ); // Look for instance pInstanceName _bstr_t bstrInstance; _bstr_t bstrInputInstance = pInstanceName; for( int k=0; k < pPerfObj->NumInstances; k ) { bstrInstance = (wchar_t *)((PBYTE)pPerfInst pPerfInst->NameOffset); if (!stricmp((LPCTSTR)bstrInstance, (LPCTSTR)bstrInputInstance)) { pCounterBlock = (PPERF_COUNTER_BLOCK) ((LPBYTE) pPerfInst pPerfInst->ByteLength); break; } // Get the next instance. pPerfInst = NextInstance( pPerfInst ); } } if (pCounterBlock) { T *lnValue = NULL; lnValue = (T*)((LPBYTE) pCounterBlock pPerfCntr->CounterOffset); return *lnValue; } return -1; } T GetCounterValueForProcessID(PPERF_OBJECT_TYPE pPerfObj, DWORD dwCounterIndex, DWORD dwProcessID) { int PROC_ID_COUNTER = 784; BOOL bProcessIDExist = FALSE; PPERF_COUNTER_DEFINITION pPerfCntr = NULL; PPERF_COUNTER_DEFINITION pTheRequestedPerfCntr = NULL; PPERF_COUNTER_DEFINITION pProcIDPerfCntr = NULL; PPERF_INSTANCE_DEFINITION pPerfInst = NULL; PPERF_COUNTER_BLOCK pCounterBlock = NULL; // Get the first counter. pPerfCntr = FirstCounter( pPerfObj ); for( DWORD j=0; j < pPerfObj->NumCounters; j ) { if (pPerfCntr->CounterNameTitleIndex == PROC_ID_COUNTER) { pProcIDPerfCntr = pPerfCntr; if (pTheRequestedPerfCntr) break; } if (pPerfCntr->CounterNameTitleIndex == dwCounterIndex) { pTheRequestedPerfCntr = pPerfCntr; if (pProcIDPerfCntr) break; } // Get the next counter. pPerfCntr = NextCounter( pPerfCntr ); } if( pPerfObj->NumInstances == PERF_NO_INSTANCES ) { pCounterBlock = (PPERF_COUNTER_BLOCK) ((LPBYTE) pPerfObj pPerfObj->DefinitionLength); } else { pPerfInst = FirstInstance( pPerfObj ); for( int k=0; k < pPerfObj->NumInstances; k ) { pCounterBlock = (PPERF_COUNTER_BLOCK) ((LPBYTE) pPerfInst pPerfInst->ByteLength); if (pCounterBlock) { int processID = 0; processID = *(T*)((LPBYTE) pCounterBlock pProcIDPerfCntr->CounterOffset); if (processID == dwProcessID) { bProcessIDExist = TRUE; break; } } // Get the next instance. pPerfInst = NextInstance( pPerfInst ); } } if (bProcessIDExist && pCounterBlock) { T *lnValue = NULL; lnValue = (T*)((LPBYTE) pCounterBlock pTheRequestedPerfCntr->CounterOffset); return *lnValue; } return -1; } /***************************************************************** * * * Functions used to navigate through the performance data. * * * *****************************************************************/ PPERF_OBJECT_TYPE FirstObject( PPERF_DATA_BLOCK PerfData ) { return( (PPERF_OBJECT_TYPE)((PBYTE)PerfData PerfData->HeaderLength) ); } PPERF_OBJECT_TYPE NextObject( PPERF_OBJECT_TYPE PerfObj ) { return( (PPERF_OBJECT_TYPE)((PBYTE)PerfObj PerfObj->TotalByteLength) ); } PPERF_COUNTER_DEFINITION FirstCounter( PPERF_OBJECT_TYPE PerfObj ) { return( (PPERF_COUNTER_DEFINITION) ((PBYTE)PerfObj PerfObj->HeaderLength) ); } PPERF_COUNTER_DEFINITION NextCounter( PPERF_COUNTER_DEFINITION PerfCntr ) { return( (PPERF_COUNTER_DEFINITION)((PBYTE)PerfCntr PerfCntr->ByteLength) ); } PPERF_INSTANCE_DEFINITION FirstInstance( PPERF_OBJECT_TYPE PerfObj ) { return( (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfObj PerfObj->DefinitionLength) ); } PPERF_INSTANCE_DEFINITION NextInstance( PPERF_INSTANCE_DEFINITION PerfInst ) { PPERF_COUNTER_BLOCK PerfCntrBlk; PerfCntrBlk = (PPERF_COUNTER_BLOCK)((PBYTE)PerfInst PerfInst->ByteLength); return( (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfCntrBlk PerfCntrBlk->ByteLength) ); } }; </textarea>
<textarea class="cpp" rows="10" cols="60" name="code">main.cpp // Main.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include #include #include "CpuUsage.h" int main(int argc, char* argv[]) { int processID=0; CCpuUsage usageA; CCpuUsage usageB; CCpuUsage usageC; printf("SystemWide Cpu Usage Explorer cpu usage Cpu Usage for processID 0\n"); printf("==================== ================== ========================\n"); while (true) { // Display the system-wide cpu usage and the "Explorer" cpu usage int SystemWideCpuUsage = usageA.GetCpuUsage(); int ProcessCpuUsageByName = usageB.GetCpuUsage("explorer"); int ProcessCpuUsageByID = usageC.GetCpuUsage(processID); printf("d%%"d%%%\r",SystemWideCpuUsage, ProcessCpuUsageByName, ProcessCpuUsageByID); Sleep(1000); } return 0; } </textarea>
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-09-15 08:06:57 IP:59.105.xxx.xxx 訂閱
在 CPU 使用率的取得上,本站也可以找到許多的資料,可能大部分都是 Delphi 的,讓您覺得不知道如何去改它。
我在本站一直宣導各位 BCB/CCB 的使用者,一定要善用 BCB/CCB 可直接使用 Delphi Unit 的觀念,
很多時候,別人已寫好多年的 Delphi code 至今仍可使用(也許部分 uses Unit 名稱要修改或去除,
但大部分都是可以直接使用的。

以取得 CPU 使用率來說,有免費的 VCL AdCpuUsage 1.02[註] 可以作到,它連多處理器的狀況都處理了,
也可以分別取得每個處理器的使用率。在這個 VCL 中有提供 BCB4/BCB5 的 Project 範例,如果您用
BCB6 或更高的版本,可直接開 BCB5 的專案試試看。開啟後,您可以看到,就是在 Project 中直接加
入 Delphi 的 Unit(.pas) compile 後就會產生 .hpp 檔,在程式中 include 此 .hpp 檔,就可以叫用 .hpp
內的函式或元件了。

如果您想要取得單一應用程式占用 CPU 的狀況,在本站也可以找到相關的討論,如:
如何取得某一PORCESS的CPU佔用使用率?
說真的,對同一問題,如果我由網路找到 Delphi 及 VC 的 code,我會把 Delphi 加到我的專案,
因為這比去修改 VC 的 code 要快 N 多倍,因為 VC 可能 include 的 header 檔在 BCB/CCB 中可能
不存在,還需要安裝最新或某年的 MicroSoft PlatForm SDK 才能順利 compile。

註:原作者網站:http://www.aldyn.ru/index.html 提供兩個免費好用的 Delphi 元件(應該都可以在 BCB 下使用)
AdCpuUsage 可以取得 CPU Usage 的元件
PerfUtils 使用 Windows NT/2K/XP(or Up) 系統本身的 Performance API 可取得 CPU Usage 及其他系統相關資源


強力推薦 ShareMe 免費網路硬碟VMASKVMIO-Server/SECS/GEMdllee's blogdllee's StatPlus
------
http://www.ViewMove.com
編輯記錄
dllee 重新編輯於 2007-09-15 08:16:34, 註解 增加 AdCpuUsage 作者網站連結及其提供的免費元件連結‧
huntfox
一般會員


發表:11
回覆:13
積分:4
註冊:2006-10-23

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-09-15 11:51:10 IP:218.165.xxx.xxx 訂閱
感謝大大的回答
說真的我還是第一次知道可以這樣加入.pas的程式碼
只是關於"Unresolved external '__stdcall _com_issue_error(long)' referenced from C:\CPUUSAGE_SRC\BCBATL.LIB|comutil"的錯誤
似乎常常會遇到
只知道可能是某個DLL未加入專案
所以才會想知道
遇到相同的問題
怎樣解決比較好囉

不管怎樣
還是感謝大大的回答
也讓我得到了新的知識
雖然這是大大推很久的東西囉
編輯記錄
huntfox 重新編輯於 2007-09-15 11:53:29, 註解 無‧
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-09-15 13:32:34 IP:59.105.xxx.xxx 訂閱
也許是您比較常使用 VC/VB 轉過來的 Code 所以比較常遇到吧。
以 BCBATL.LIB 其中的 ATL 應該指的是 Active Template Library,
也表示可能在您的 Project 中有使用或引用到 Active 相關的元件或資源,
才會需要 BCBATL。

這篇與 請問這個錯誤訊息是什麼意思? 您有相同的問題,以當時
pwipwi 版主的回應看來,pwipwi 版主也是沒遇到過(我也沒遇到過)。

BCB 在使用 ActiveX 元件時,是常常發生問題的,我是使用 BCB5,
不知道最新的 CB 是否有比較好,BCB6 好像也是差不多。
所以我通常不在 BCB 中使用 ActiveX 元件,減少麻煩。



強力推薦 ShareMe 免費網路硬碟VMASKVMIO-Server/SECS/GEMdllee's blogdllee's StatPlus
------
http://www.ViewMove.com
系統時間:2024-04-16 13:40:46
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!