『壹』 d3dx9.lib(cpudetect.obj) : error LNK2001: unresolved external symbol ___security_cookie
鏈接器工具錯誤 LNK2001
錯誤消息
無法解析的外部符號「symbol」
代碼引用了鏈接器無法在庫和對象文件中找到的內容(如函數、變數或標簽)。
該錯誤信息之後為錯誤 LNK1120。
可能的原因
在將託管庫或 Web 服務項目從 Visual C++ 2003 升級到 Visual C++ 2005 時,/Zl 編譯器選項將添加到「命令行」屬性頁中。這將導致 LNK2001。請從「命令行」屬性頁中移除 /Zl,以解決此問題。有關更多信息,請參見 /Zl(省略默認庫名) 和 如何:打開項目屬性頁。或者,將 msvcrt.lib 和 msvcmrt.lib 添加到鏈接器的「附加依賴項」屬性中。
代碼請求的內容不存在(例如,符號拼寫錯誤或使用錯誤的大小寫)。
代碼請求的內容錯誤(使用的是混合版本的庫,一些庫來自產品的一個版本,而其他則來自另一個版本)。
具體原因
代碼問題
如果 LNK2001 診斷文本報告 __check_commonlanguageruntime_version 是無法解析的外部符號,則請參見 LNK2019 獲得有關如何解決該問題的信息。
成員模板的定義超出了類的范圍。Visual C++ 的一個限制是,成員模板的定義必須完全位於封閉類內。有關 LNK2001 和成員模板的更多信息,請參見知識庫文章 Q239436。
代碼或模塊定義 (.def) 文件中的大小寫不匹配會導致 LNK2001。例如,當在一個 C++ 源文件中將一個變數命名為 var1,並試圖在另一個源文件中以 VAR1 訪問該變數時。
如果項目使用函數內聯,但在 .cpp 文件而非頭文件中定義函數,則會導致 LNK2001。
從 C++ 程序調用 C 函數但不使用 extern "C"(這導致編譯器使用 C 命名約定)會導致 LNK2001。編譯器選項 /Tp 和 /Tc 使編譯器將文件分別編譯為 C++ 或 C,與文件擴展名無關。這些選項會導致函數名與您所期望的名稱不同。
試圖引用沒有外部鏈接的函數或數據會導致 LNK2001。在 C++ 中,內聯函數和 const 數據具有內部鏈接,除非被顯式指定為 extern。
缺少函數主體或變數會導致 LNK2001。如果只有函數原型或 extern 聲明,編譯器繼續運行而不會出現任何錯誤,但由於沒有保留函數代碼或變數空間,鏈接器將無法解析地址調用或變數引用。
調用參數類型與函數聲明中的參數類型不匹配的函數會導致 LNK2001。名稱修飾將函數參數合並到最終修飾函數名中。
錯誤包含的原型導致編譯器需要沒有提供的函數體,這樣會導致 LNK2001。如果同時具有函數 F 的類實現和非類實現,請注意 C++ 范圍解析規則。
在使用 C++ 時,將函數原型包含在類定義中但未能包含實現(該類的此函數的實現)會導致 LNK2001。
試圖從抽象基類的構造函數或析構函數調用純虛函數會導致 LNK2001。純虛函數沒有基類實現。
試圖在函數范圍外使用用該函數聲明的變數(局部變數)會導致 LNK2001。
在生成 ATL 項目的發布版本時,指示需要 CRT 啟動代碼。若要修復,請執行下列操作之一:
將 _ATL_MIN_CRT 從預處理器定義的列表中移除,以允許包括 CRT 啟動代碼。有關更多信息,請參見常規配置設置屬性頁。
如果可能,移除對需要 CRT 啟動代碼的 CRT 函數的調用,而是使用它們的 Win32 等效函數。例如,使用 lstrcmp,而不要使用 strcmp。需要 CRT 啟動代碼的已知函數是一些字元串和浮點函數。
編譯和鏈接問題
項目缺少對庫 (.LIB) 或對象 (.OBJ) 文件的引用。有關更多信息,請參見用作鏈接器輸入的 .lib 文件。
如果使用 /NODEFAULTLIB 或 /Zl,包含所需代碼的庫將不會鏈接到項目,除非已顯式地包括了這些庫。(在使用 /clr 或 /clr:pure 進行編譯時,您將看到對 .cctor 的引用;有關更多信息,請參見 混合程序集的初始化。)
如果正在使用 Unicode 和 MFC,如果沒有創建 wWinMainCRTStartup 的入口點,將在 _WinMain@16 上得到無法解析的外部對象;請使用 /ENTRY。請參見 Unicode 編程摘要。
有關更多信息,請參見下列位於 MSDN Library 中的知識庫文章。在 MSDN Library 中,單擊「搜索」選項卡,將文章編號或文章標題粘貼到文本框中,然後單擊「列出主題」。如果按文章編號搜索,請確保清除「僅搜索標題」選項。
Q125750 「PRB: Error LNK2001: '_WinMain@16': Unresolved External Symbol」
Q131204 「PRB: Wrong Project Selection Causes LNK2001 on _WinMain@16」
Q100639 「Unicode Support in the Microsoft Foundation Class Library」
Q291952 「PRB: Link Error LNK2001: Unresolved External Symbol _main」
將用 /MT 編譯的代碼與庫 LIBC.lib 鏈接會在 _beginthread、_beginthreadex、_endthread 和 _endthreadex 上導致 LNK2001。
鏈接需要多線程庫的代碼(任何 MFC 代碼或用 /MT 編譯的代碼)會在 _beginthread、_beginthreadex、_endthread 和 _endthreadex 上導致 LNK2001。有關更多信息,請參見下列知識庫文章:
Q126646「PRB: Error Msg: LNK2001 on __beginthreadex and __endthreadex」
Q128641「INFO: /Mx Compiler Options and the LIBC, LIBCMT, MSVCRT Libs」
Q166504「PRB: MFC and CRT Must Match in debug/release and static/dynamic」
在用 /MD 進行編譯時,因為所有的運行時現在都存放在一個 DLL 中,所以源中的「func」引用在對象中變為「__imp__func」引用。如果試圖與 LIBC.lib 或 LIBCMT.lib 靜態庫鏈接,則將在 __imp__func 上得到 LNK2001。當不用 /MD 進行編譯時,如果試圖與 MSVCxx.lib 鏈接,則並非總是得到 LNK2001,但可能會有其他問題。
在生成應用程序的調試版本時與發布模式庫鏈接會導致 LNK2001。同樣,使用 /Mxd 選項(/MTd 或 /MDd)和/或定義 _DEBUG,然後再與版本庫鏈接,將可能會產生無法解析的外部對象(同時還會出現其他問題)。將發布模式生成與調試庫鏈接同樣會導致類似問題。
將 Microsoft 庫版本和編譯器產品版本混合可能會有問題。新編譯器版本的庫可能包含早期版本的庫中沒有的新符號。可能需要更改搜索路徑中的目錄順序,或將它們更改為指向當前版本。
使用庫文件選擇下的「工具」|「選項」|「項目」|「VC++ 目錄」對話框,可以更改搜索順序。項目的「屬性頁」對話框中的「鏈接器」文件夾可能也包含可能已過期的路徑。
當安裝了新的 SDK(可能在不同的位置),但沒有將搜索順序更新為指向新位置時,可能會出現此問題。通常情況下,應將新 SDK 的 include 目錄和 lib 目錄的路徑放在默認 Visual C++ 位置的前面。另外,包含嵌入路徑的項目可能仍然指向舊路徑,這些路徑是有效的,但對於安裝到不同位置的新版本所添加的新功能已過期。
編譯器供應商之間、甚至同一編譯器的不同版本之間當前沒有 C++ 命名標准。因此,鏈接用其他編譯器編譯的對象文件可能無法生成相同的命名方案,從而導致錯誤 LNK2001。
在不同模塊上混合內聯和非內聯編譯選項會導致 LNK2001。如果創建 C++ 庫時打開了函數內聯(/Ob1 或 /Ob2),但描述函數的相應頭文件的內聯是關閉的(沒有 inline 關鍵字),則將發生此錯誤。若要防止此問題,請在要包含到其他文件中的頭文件中用 inline 定義內聯函數。
如果使用 #pragma inline_depth 編譯器指令,請確保具有 設置為 2 或更大的值,並確保使用 /Ob1 或 /Ob2 編譯器選項。
在創建純資源 DLL 時省略 LINK 選項 /NOENTRY 將導致 LNK2001。
使用不正確的 /SUBSYSTEM 或 /ENTRY 設置會導致 LNK2001。例如,如果編寫基於字元的應用程序(控制台應用程序)並指定 /SUBSYSTEM:WINDOWS,您將得到無法解析的 WinMain 外部對象。有關這些選項和入口點的更多信息,請參見 /SUBSYSTEM 和 /ENTRY 鏈接器選項。
導出問題
當將應用程序從 16 位移植到 32 位或 64 位時,會發生 LNK2001。當前的模塊定義 (.def) 文件語法要求 __cdecl、__stdcall 和 __fastcall 函數列在 EXPORTS 節中,並且不帶下劃線(不修飾)。這不同於 16 位語法,這些函數在 16 位語法中列出時必須帶下劃線(修飾)。有關更多信息,請參見模塊定義文件 EXPORTS 節的說明。
在 .def 文件中列出但未找到的任何導出將導致 LNK2001。這可能是因為導出不存在、拼寫錯誤或使用了 C++ 修飾名(.def 文件不採用修飾名)。
解釋輸出
如果符號無法解析,通過下列指南可獲得有關函數的信息:
在 x86 平台上,用 C 編譯的名稱或 C++ 中的 extern "C" 名稱的調用約定修飾是:
__cdecl
函數具有下劃線 (_) 前綴。
__stdcall
函數具有下劃線 (_) 前綴和 @ 後綴,後跟堆棧上參數的雙倍字長對齊大小。
__fastcall
函數具有 @ 前綴和 @ 後綴,後跟堆棧上參數的雙倍字長對齊大小。
使用 undname.exe 獲取修飾名的未修飾格式。
有關上面列出的某些原因的更多信息,請參見名稱修飾。
『貳』 MFC按鈕調用一程序,如何執行程序命令行參數呢
標准c庫函數不知道行不行,如果在win32環境下,調用win32 API絕對是可以的,用shellexecute函數啟動程序,命令行參數在程序名稱後按空格隔開,在調用程序main函數中使用string strLine=::AfxGetApp()->m_lpCmdLine;就可以獲取命令行參數了,在開發多進程項目的時候用的比較多,常用於進程間啟動參數傳遞。
『叄』 MFC:怎麼在顯示窗口之前顯示一個類似DOS的命令窗口
使用ShellExecute()函數。如:
ShellExecute(NULL,NULL,
"C:\\WINDOWS\\system32\\cmd.exe"/*這個參數是執行的程序的路徑和名稱*/,NULL/*這里是命令行參數*/,
NULL,
SW_HIDE/*該參數確定顯不顯示DOS窗口*/
);
具體用法見msdn
『肆』 如何用c語言在控制台彈出一個輸入對話框
#include <tchar.h>
#include <windows.h>
HINSTANCE _HInstance; // 應用程序句柄
TCHAR _Title[] = _T("簡單文本框"); // 定義窗口的標題
TCHAR _WindowClass[] = _T("MySimpleTextBoxApp");// 主窗口類名
ATOM _RegisterClass(); // 注冊主窗口類
HWND _CreateWindow(int nCmdShow); // 創建主窗口
LRESULT CALLBACK _WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // 主窗口消息處理函數
TCHAR _TextBoxClass[] = _T("MySimpleTextBox"); // 文本框的類名
ATOM _RegisterTextBoxClass(); // 注冊文本框的類
HWND _CreateTextBoxWindow(HWND hParentWnd); // 創建文本框
LRESULT CALLBACK _TextBoxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // 文本框窗口消息處理函數
void _DrawText(HDC hDC); // 繪制文本
void _SetCaretPos(HWND hWnd); // 設置游標位置
void _UpdateWindow(HWND hWnd); // 更新窗口
// 一些常量定義
#define MAINWINDOW_WIDTH 400 // 主窗口寬度
#define MAINWINDOW_HEIGHT 200 // 主窗口高度
#define TEXTBOX_WIDTH 300 // 文本框寬度
#define TEXTBOX_HEIGHT 20 // 文本框高度
#define TEXTBOX_MAXLENGTH 1024 // 文本框中文本的最大長度
TCHAR _String[TEXTBOX_MAXLENGTH + 1] = _T(""); // 文本
int _StringPosition = ::_tcslen(_String); // 游標插入點所在的位置
int APIENTRY _tWinMain(HINSTANCE hInstance, // 當前的應用程序句柄
HINSTANCE hPrevInstance, // 前一個應用程序實例的句柄(在Win32上,始終為NULL)
LPTSTR lpCmdLine, // 命令行參數
int nCmdShow // 窗口的顯示樣式
)
{
_HInstance = hInstance;
_RegisterClass(); // 注冊窗口類
if(_CreateWindow(nCmdShow) == NULL) // 創建窗口
return FALSE;
MSG msg;
while (::GetMessage(&msg, NULL, 0, 0)) // 從消息隊列中獲取消息
{
::TranslateMessage(&msg); // 轉譯一些特殊的消息
::DispatchMessage(&msg); // 執行消息處理
}
return (int)msg.wParam;
}
// 注冊應用程序窗口類
ATOM _RegisterClass()
{
WNDCLASSEX wc;
::ZeroMemory(&wc, sizeof(wc)); // 作為一步清空,是為了讓未賦值的欄位的默認值為(或NULL)
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW; // 指定當窗口橫向和縱向的尺寸發生變化時都會重繪窗口
wc.hInstance = _HInstance;
wc.hbrBackground = (HBRUSH)( COLOR_APPWORKSPACE + 1); // 指定主窗口背景為「工作區域」系統顏色
wc.lpszClassName = _WindowClass; // 此為要注冊的類名,創建窗口時要以此類名為標識符
wc.lpfnWndProc = _WndProc; // 此為處理窗口消息的函數
return ::RegisterClassEx(&wc); // 調用API函數注冊窗口類
}
// 創建窗口
HWND _CreateWindow(int nCmdShow)
{
HWND hWnd = ::CreateWindow(_WindowClass, _Title, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, MAINWINDOW_WIDTH, MAINWINDOW_HEIGHT, NULL, NULL, _HInstance, NULL);
if(hWnd == NULL)
return NULL;
::ShowWindow(hWnd, nCmdShow);
::UpdateWindow(hWnd);
return hWnd;
}
// 窗口處理過程
LRESULT CALLBACK _WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hTextBoxWnd;
switch (message)
{
case WM_CREATE: {
_RegisterTextBoxClass(); // 注冊文本框的類
hTextBoxWnd = _CreateTextBoxWindow(hWnd); // 創建文本框
} break;
case WM_ACTIVATE: // 當窗口被激活時,將焦點設置在文本框上
::SetFocus(hTextBoxWnd);
break;
case WM_SETCURSOR: { // 設置游標形狀
static HCURSOR hCursor = ::LoadCursor(NULL, IDC_ARROW);
::SetCursor(hCursor);
} break;
case WM_DESTROY: // 應用程序被關閉
::PostQuitMessage(0);
break;
default:
return ::DefWindowProc(hWnd, message, wParam, lParam);
}
return (LRESULT)0;
}
// 注冊文本框的類
ATOM _RegisterTextBoxClass()
{
WNDCLASSEX wc;
::ZeroMemory(&wc, sizeof(wc));
wc.cbSize = sizeof(wc);
wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; // 指定當窗口尺寸發生變化時重繪窗口,並且響應滑鼠雙擊事件
wc.hInstance = _HInstance;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // 指定窗口背景顏色為系統顏色「窗口背景」
wc.lpszClassName = _TextBoxClass; // 指定要注冊的窗口類名,創建窗口時要以此類名為標識符
wc.lpfnWndProc = _TextBoxWndProc; // 處理窗口消息的函數
return ::RegisterClassEx(&wc); // 調用API函數注冊文本框窗口
}
// 創建文本框
HWND _CreateTextBoxWindow(HWND hParentWnd)
{
// 之下代碼是為了讓文本框顯示在父窗口中央,而計算位置
RECT parentWndRect;
::GetClientRect(hParentWnd, &parentWndRect); // 獲取父窗口客戶區的位置
int left = (parentWndRect.right - TEXTBOX_WIDTH) / 2, top = (parentWndRect.bottom - TEXTBOX_HEIGHT) / 2;
// 創建文本框
HWND hWnd = ::CreateWindow(_TextBoxClass, NULL, WS_CHILDWINDOW | WS_VISIBLE,
left, top, TEXTBOX_WIDTH, TEXTBOX_HEIGHT,
hParentWnd, NULL, _HInstance, NULL);
return hWnd;
}
// 文本框消息的處理過程
LRESULT CALLBACK _TextBoxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT: { // 繪制這里之所以加一對大括弧,是為了讓之下定義的變數局部化
static PAINTSTRUCT ps;
static RECT rect;
HDC hDC = ::BeginPaint(hWnd, &ps); // 開始繪制操作
::GetClientRect(hWnd, &rect); // 獲取客戶區的尺寸
::DrawEdge(hDC, &rect, EDGE_SUNKEN, BF_RECT); // 繪制邊框,EDGE_SUNKEN表示繪制樣式為內嵌樣式,BF_RECT表示繪制矩形邊框
_DrawText(hDC); // 繪制文本
::EndPaint(hWnd, &ps); // 結束繪制操作
} break;
case WM_SETFOCUS: { // 獲得焦點
::CreateCaret(hWnd, (HBITMAP)NULL, 1, TEXTBOX_HEIGHT-5); // 創建游標
_SetCaretPos(hWnd); // 設置游標位置
::ShowCaret(hWnd); // 顯示游標
} break;
case WM_KILLFOCUS: // 失去焦點
::HideCaret(hWnd); // 隱藏游標
::DestroyCaret(); // 銷毀游標
break;
case WM_SETCURSOR: { // 設置游標形狀
static HCURSOR hCursor = ::LoadCursor(NULL, IDC_IBEAM);
::SetCursor(hCursor);
} break;
case WM_CHAR: { // 字元消息
TCHAR code = (TCHAR)wParam;
int len = ::_tcslen(_String);
if(code < (TCHAR)' ' || len >= TEXTBOX_MAXLENGTH)
return 0;
::MoveMemory(_String + _StringPosition + 1, _String + _StringPosition, (len - _StringPosition + 1) * sizeof(TCHAR));
_String[_StringPosition ++] = code;
_UpdateWindow(hWnd);
_SetCaretPos(hWnd);
} break;
case WM_KEYDOWN: { // 鍵按下消息
TCHAR code = (TCHAR)wParam;
switch (code)
{
case VK_LEFT: // 左游標鍵
if(_StringPosition > 0)
_StringPosition --;
break;
case VK_RIGHT: // 右游標鍵
if(_StringPosition < (int)::_tcslen(_String))
_StringPosition ++;
break;
case VK_HOME: // HOME 鍵
_StringPosition = 0;
break;
case VK_END: // END 鍵
_StringPosition = ::_tcslen(_String);
break;
case VK_BACK: // 退格鍵
if(_StringPosition > 0)
{
::MoveMemory(_String + _StringPosition - 1, _String + _StringPosition, (::_tcslen(_String)-_StringPosition + 1) * sizeof(TCHAR));
_StringPosition --;
_UpdateWindow(hWnd);
}
break;
case VK_DELETE: { // 刪除鍵
int len = ::_tcslen(_String);
if(_StringPosition < len)
{
::MoveMemory(_String + _StringPosition, _String + _StringPosition + 1, (::_tcslen(_String) - _StringPosition + 1) * sizeof(TCHAR));
_UpdateWindow(hWnd);
}
} break;
}
_SetCaretPos(hWnd);
} break;
case WM_LBUTTONDOWN: { // 滑鼠單擊,設置游標位置
int x = LOWORD(lParam);
HDC hDc = ::GetDC(hWnd);
int strLen = ::_tcslen(_String), strPos = 0;
SIZE size;
for (strPos=0; strPos<strLen; strPos++)
{
::GetTextExtentPoint(hDc, _String, strPos, &size);
if(size.cx + 4 >= x)
break;
}
_StringPosition = strPos;
::GetTextExtentPoint(hDc, _String, strPos, &size);
::SetCaretPos(size.cx + 4, 3);
::ReleaseDC(hWnd, hDc);
} break;
default:
return ::DefWindowProc(hWnd, message, wParam, lParam);
}
return (LRESULT)0;
}
// 更新窗口
void _UpdateWindow(HWND hWnd)
{
RECT rect;
::GetClientRect(hWnd, &rect);
::InvalidateRect(hWnd, &rect, TRUE);
::UpdateWindow(hWnd);
}
// 繪制文本
void _DrawText(HDC hDC)
{
int len = ::_tcslen(_String);
::TextOut(hDC, 4, 2, _String, len);
}
// 設置游標位置
void _SetCaretPos(HWND hWnd)
{
HDC hDC = ::GetDC(hWnd);
SIZE size;
::GetTextExtentPoint(hDC, _String, _StringPosition, &size);
::SetCaretPos(4 + size.cx, 3);
::ReleaseDC(hWnd, hDC);
}
『伍』 怎樣把cmd的參數傳到自己的MFC程序中並運行
像你所說的是不可能的!
給add_test.exe傳遞參數,這個很簡單!只要得到應用程序對象App,(用AfxGetApp()函數得到),App類有個成員變數m_lpCmdLine,m_lpCmdLine是個數組,他就是傳遞過來的參數!
而要給CMD傳遞回去參數,那個是不可能的!假如一個程序要接受參數,要麼就傳遞命令行參數,就像剛剛給你說的!要麼就使用消息循環,給窗口發送以個消息!而CMD是沒有消息循環也不會動態的接收命令行參數的!!
但是LZ可以考慮做以個控制台程序,就是和CMD框一樣的程序!你可以在CMD里調用,那個只是CMD暫時轉向你寫的控制台程序執行!你就在你自己寫的控制台程序里顯示結果,然後Exit就可以了!
『陸』 如何能讓打開的應用程序不在任務欄上顯示
倒是有一款工具TrayIt!.exe作用是最小化時隱藏到托盤
『柒』 請問在VC里怎麼弄命令行參數我用的是VC++6.0
在菜單欄的 工程(project)--設置(settings)打開,在debug選項卡的 程序參數(programsarguments)假如你需要添加的參數。
附加說明一下。左邊的settingfor選項。可以選擇為debug(調試)版本設置或者release(發行)版本測試。不過我想你應該算是初學者吧,就默認debug吧。
『捌』 關於主函數main()的參數問題
主函數的參數就是輸入命令行的參數,主函數不能被其他函數調用
但是,這個參數,可以傳遞給其他函數進行解析
我們完全可以利用主函數來獲取命令行的參數,然後,由另外的函數,對這些參數進解析,處理的。
做法是,我們可以定義個類似的函數,比如:
int process(int argc, char *argv[])
{
//...//如何處理的,這里從略
}
在函數中可以調用它,把參數傳遞給它,如下:
int main(int argc, char *argv[])
{
//...//略去一些代碼
process(argc,argv);//這樣,就把主函數獲取的參數,傳遞給我們自己定義的函數process了
//...//略去一些代碼
}
『玖』 Windows如何在cmd命令行中查看、修改、刪除與添加、設置環境變數
直接修改注冊表。
通過我的電腦來設置系統的環境變數。
『拾』 mfc程序怎麼接受命令行參數
三種方法:
假設我們啟動程序的時候執行的是以下命令:
D:mfcapp.exe -l -f ./1.txt
方法1,調用全局函數
::GetCommandLine();
將獲取到全部參數信息:D:mfcapp.exe -l -f ./1.txt
方法2,使用宏__argc和__argv,使用方法和命令行main(int argc,char *argv[])一樣,示例代碼:
for(inti=0;i<__argc;i++)
{
__argv[i];//依次遍歷可以得到D:mfcapp.exe-l-f./1.txt
}
方法3:使用CWinApp類的成員變數m_lpCmdLine,它裡麵包含除了第一個參數的所有信息,比如:
AfxGetApp()->m_lpCmdLine;//結果為-l -f ./1.txt