从数据库中获取VARCHAR会返回一个空的和/或已损坏的字符串

时间:2014-06-04 08:27:17

标签: c++ mysql winapi mysql-connector

经过多次试验和错误,谷歌和stackoverflow的帮助,我终于设法让我的大部分代码工作。除了从数据库中获取正确的字符串。我怀疑并且几乎肯定它与编码有关。但作为一个新手,我现在还不知道到底出了什么问题。此代码与我自己的试验和错误,谷歌和stackoverflow一起打补丁。如果我在主要问题之外做了其他事情,请告诉我,因为我只知道我在做什么 - 我已经在这个项目上工作了一个半星期,几乎学习了WinApi,MySQL c ++连接器和C ++从头开始。

问题中的数据库使用UTF-8(mb4)编码。在我的项目中启用了Unicode。

对于上下文,我将在此处粘贴大部分代码。 前面的代码

//===========================================================================
//Global variables
//===========================================================================
HWND g_hMnDialog = NULL;
int  g_iFieldCount = 5;

sql::Driver *driver;
sql::Connection *con;
sql::Statement *stmt;
sql::PreparedStatement *prep_stmt;
sql::ResultSet  *res;

//===========================================================================
//Converting string to wstring
//===========================================================================
std::wstring s2ws(const std::string& s)
{
    int len;
    int slength = (int)s.length() + 1;
    len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
    wchar_t* buf = new wchar_t[len];
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
    wstring r(buf);
    delete[] buf;
    return r;
}

//===========================================================================
//Function for refreshing ID list
//===========================================================================
void fRefreshListID(HWND hwnd)
{
    HWND hList = GetDlgItem(hwnd, IDC_lbList);
    if (hList == NULL) MessageBox(NULL, L"we got a problem", L"error", 0);
    string query = "SELECT `ID` FROM `tremreg` ORDER BY `ID` DESC";
    res = stmt->executeQuery(query.c_str());
    while (res->next())
    {
        int i = res->getInt("ID");
        string str = boost::lexical_cast<std::string>(i);
        wstring stemp = s2ws(str);
        SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)stemp.c_str());
    }
    delete res;
}

//===========================================================================
//Function for fetching edit control data into a buffer
//===========================================================================
LPWSTR fGetEditControlData(HWND hwnd, INT iEditBoxID) 
{
    HWND hEditControlHandle = GetDlgItem(hwnd, iEditBoxID);
    DWORD dwBufferSize = GetWindowTextLength(hEditControlHandle) + 1;
    LPWSTR pszEditControlData = (LPWSTR)GlobalAlloc(GPTR, dwBufferSize);
    GetWindowText(hEditControlHandle, pszEditControlData, dwBufferSize);
    LPWSTR pszReturn = pszEditControlData;
    pszEditControlData = NULL; GlobalFree(pszEditControlData);
    return pszReturn;
}

//===========================================================================
//The confirmation dialog function.
//===========================================================================
void fConfirmWindow(HWND hwnd)
{
    INT iConfirmWin = MessageBox(NULL, L"Are you sure you want to quit?", L"Comfirmation", MB_OKCANCEL);
    if (iConfirmWin == 1) DestroyWindow(hwnd);
} 

//===========================================================================
//Dialog message processing
//===========================================================================
BOOL CALLBACK MnDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
    switch (Message)
    {
    case WM_INITDIALOG:
    {                 
        fRefreshListID(hwnd);
    }
        break;

    case WM_COMMAND:
        switch (LOWORD(wParam)) 
//===========================================================================
//Inserts the edit box content into the DB      
//===========================================================================
       {
            case IDC_bSave:
            {
                prep_stmt = con->prepareStatement("INSERT INTO tremreg(client, telnr, atnrem, papatn, gedapr) VALUES (?, ?, ?, ?, ?)");
                for (int i = 1; i <= g_iFieldCount; i++)
                {
                    DWORD dwBuffer = GetWindowTextLength(GetDlgItem(hwnd, 1000 + i)) + 1;
                    LPSTR buf = (LPSTR)GlobalAlloc(GPTR, dwBuffer);
                    WideCharToMultiByte(CP_UTF8, 0, fGetEditControlData(hwnd, 1000 + i), -1, buf, dwBuffer, NULL, NULL);
                    prep_stmt->setString(i, buf);
                    buf = NULL; GlobalFree(buf);
                }   
            prep_stmt->execute();
            }
            break;
    //===========================================================================
    //Listbox stuff
    //===========================================================================
    case IDC_lbList:
        switch (HIWORD(wParam))
        {
        case LBN_SELCHANGE:
        {
            //===========================================================================
            //Trying to fill the edit boxes with data fetched from DB
            //===========================================================================
            int index = SendMessage(GetDlgItem(hwnd, IDC_lbList), LB_GETCURSEL, 0, 0);
            string sint = boost::lexical_cast<std::string>(index);
            string smt = "SELECT `client`, `telnr`, `atnrem`, `papatn`, `gedapr` FROM `tremreg` WHERE `ID` =";
            string query = smt + sint;
            res = stmt->executeQuery(query.c_str());
            string str; 
            while (res->next())
            {
                for (int i = 1; i <= g_iFieldCount; i++)
                {
                    string s = res->getString(i);
                    wstring str = s2ws(s);
                    SetDlgItemText(hwnd, 1000 + i, str.c_str());
                }
            }
            delete res;

        }
            break;
        }
        break;
    }
    break;

case WM_CLOSE:
    fConfirmWindow(hwnd);
    break;
case WM_DESTROY:
    delete prep_stmt;
    delete stmt;
    delete con;
    PostQuitMessage(0);
    break;
default:
    return FALSE;
}
return TRUE;
}

//===========================================================================
//The core
//===========================================================================
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, INT nCmdShow)
{
    MSG msg;

    driver = get_driver_instance();
    con = driver->connect("tcp://127.0.0.1:3306", "root", "");
    con->setSchema("registracija");
    stmt = con->createStatement();

    g_hMnDialog = CreateDialog(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_MAINFORM), NULL, MnDlgProc);
    if (g_hMnDialog != NULL) ShowWindow(g_hMnDialog, SW_SHOWMAXIMIZED);
    UpdateWindow(g_hMnDialog);

    while (GetMessage(&msg, g_hMnDialog, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }


    return msg.wParam;
}

0 个答案:

没有答案