为C++控制台加解密程序搭建GUI界面的技术求助
Hey there! Let's break this down step by step—since you're new to GUI with RAD, we'll go slow and make sure you get each part right. Your existing encryption/decryption logic is solid, so we just need to wrap it in a GUI layer using RAD Studio with C++Builder (the standard RAD tool for C++ desktop apps).
- Open RAD Studio, go to
File > New > VCL Forms Application - C++Builder - You'll see a blank form (this is the main window of your app)
Grab these components from the Tool Palette (usually on the right side of the IDE) and drag them onto your form:
- Two
TEditcomponents (for input text and encryption key) - Two
TButtoncomponents: rename theirCaptionproperties to Encrypt and Decrypt (double-click the button to edit this in the Object Inspector) - One
TMemocomponent (for displaying results—better than a single-line edit for long encrypted/decrypted text) - Three
TLabelcomponents: set their captions to Input Text:, Encryption Key:, and Result: to label each section clearly
Arrange them neatly using the alignment tools in the IDE (look for the "Align" dropdown in the toolbar) to keep things organized.
Your existing console code uses cin/cout—we need to adjust it to work with GUI inputs and outputs. Let's refactor key functions to be reusable:
First, Add Helper Functions
Add these to your project (either in the main unit file or a separate .cpp file):
#include <string> #include <cstring> #include <sstream> #include <cmath> // Prepare the key table using user input void PrepareKeyTable(const std::string& key, char tabKey[4][4][4]) { // Initialize with your default key table values char defaultKey[4][4][4] = { { {'e', 'x', 'p', 'a'}, {66, 66, 66, 66}, {66, 66, 66, 66}, {66, 66, 66, 66}}, { {66, 66, 66, 66}, {'n', 'd', ' ', '3'}, {'a', 'b', 'c', 'd'}, {'a', 'b', 'c', 'd'}}, { {66, 66, 66, 66}, {66, 66, 66, 66}, {'2', '-', 'b', 'y'}, {66, 66, 66, 66}}, { {66, 66, 66, 66}, {66, 66, 66, 66}, {66, 66, 66, 66}, {'t', 'e', ' ', 'k'}} }; memcpy(tabKey, defaultKey, sizeof(char)*4*4*4); char lineKey[18] = {}; strncpy(lineKey, key.c_str(), 17); // Limit to 17 chars (matches your original code) lineKey[17] = '\0'; put_linekey_into_table(tabKey[0][0], lineKey); hash_salsa(tabKey[0][0]); } // Encrypt input text and return ASCII-formatted result std::string EncryptText(const std::string& inputText, char tabKey[4][4][4]) { char text[512] = {}; strncpy(text, inputText.c_str(), 511); text[511] = '\0'; char tabText[4][4][4] = {}; text_insert_into_table(tabText, text); char tabEncrypted[4][4][4] = {}; XOR_function(tabKey, tabText, tabEncrypted); // Build the ASCII string (instead of printing to console) std::string result; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { for (int k = 0; k < 4; k++) { result += std::to_string((int)tabEncrypted[i][j][k]) + ":"; } } } if (!result.empty()) result.pop_back(); // Remove trailing colon return result; } // Decrypt ASCII-formatted text and return plain text std::string DecryptText(const std::string& encryptedAscii, char tabKey[4][4][4]) { char text[512] = {}; std::string line = encryptedAscii; int counter = 0; std::string ascii_code = ""; for (char c : line) { if (c != ':') { ascii_code += c; } else { int ascii_val = std::stoi(ascii_code); text[counter] = (char)ascii_val; ascii_code = ""; counter++; } } char tabText[4][4][4] = {}; text_insert_into_table(tabText, text); char tabDecrypted[4][4][4] = {}; XOR_function(tabKey, tabText, tabDecrypted); // XOR is symmetric for decryption char tabOutput[65] = {}; merge_tables_into_string(tabDecrypted, tabOutput); return std::string(tabOutput); }
Link Buttons to Functions
Double-click the Encrypt button—RAD will generate an OnClick event handler. Add this code:
void __fastcall TForm1::ButtonEncryptClick(TObject *Sender) { // Check if inputs are empty if (EditInput->Text.IsEmpty() || EditKey->Text.IsEmpty()) { ShowMessage("Please enter both input text and encryption key!"); return; } char tabKey[4][4][4]; PrepareKeyTable(EditKey->Text.c_str(), tabKey); std::string encrypted = EncryptText(EditInput->Text.c_str(), tabKey); MemoResult->Text = encrypted; }
Double-click the Decrypt button and add:
void __fastcall TForm1::ButtonDecryptClick(TObject *Sender) { if (EditInput->Text.IsEmpty() || EditKey->Text.IsEmpty()) { ShowMessage("Please enter both encrypted text and encryption key!"); return; } char tabKey[4][4][4]; PrepareKeyTable(EditKey->Text.c_str(), tabKey); std::string decrypted = DecryptText(EditInput->Text.c_str(), tabKey); MemoResult->Text = decrypted; }
Note: Replace component names (like EditInput, EditKey) with whatever names you gave your components in the IDE.
- Make sure all your original functions (
text_insert_into_table,hash_salsa, etc.) are included in your project (copy them into your unit file or link their header) - Add necessary headers to the top of your unit file:
#include <vcl.h> #pragma hdrstop #include "Unit1.h" #include <string> #include <cstring> // Include your original function definitions here
- Click the green play button in RAD to run your app
- Enter test text and a key, click Encrypt—you'll see the ASCII encrypted result in the memo
- Copy that encrypted text back into the input, use the same key, click Decrypt—you should get your original text back
- Input Limits: Your original code handles up to 64 characters of input. Add a check to warn users if their text is too long (use
EditInput->Text.Length()to check) - Key Length: Your code expects a 16-character key. Add a check to ensure the key is the right size, or pad shorter keys with spaces
- Debugging: If something breaks, use RAD's debugger (set breakpoints in your functions to see where things go wrong)
内容的提问来源于stack exchange,提问作者Graga61

