0

Error info

I have tried to read the examples of others' LNK2019 error, but they doesn't match my case. It troubled me for 2 hours and have no idea what to do.

The kbam_emu and pixel_check are the namespaces of mine. The names behind are my functions. They are declared in "kbam_emu.h", "kbam_emu.cpp", "pixel_check.h" and "pixel_check.cpp" respectively:

"kbam_emu.h"

/*
  Name: keyboard and mouse emulation
  Copyright: -
  Author: Samuel YKC
  Date: 15/11/14 20:17
  Description: This header file is designed for creating bots. The essential codes for keyboard and mouse input are written by 
  a programmer on the Internet with the user name 'Muted'. Thanks, Muted. Here is the address for his original post: 
               http://forum.codecall.net/topic/45292-c-keyboardmouse-emulation/
*/

#ifndef _KBAM_EMU_H_
#define _KBAM_EMU_H_

#include <string>
#include <sstream>
#include <ctype.h>
#include <windows.h>
#include <winable.h>

using namespace std;

namespace kbam_emu
{
    enum mouse_button{ left, middle, right };

    void GenerateKey(int vk, BOOL bExtended);
    void GenerateLine(string line);
    void Click(const int X, const int Y, mouse_button button = left);
    void Drag(const int X, const int Y, const int X2, const int Y2);
}

#endif

"kbam_emu.cpp"

#include <kbam_emu.h>

/* This is a function to simplify usage of sending keys */
void kbam_emu::GenerateKey(int vk, BOOL bExtended)
{
    KEYBDINPUT  kb = {0};
    INPUT       Input = {0};

    /* Generate a "key down" */
    if (bExtended) { kb.dwFlags  = KEYEVENTF_EXTENDEDKEY; }
    kb.wVk  = vk;
    Input.type  = INPUT_KEYBOARD;
    Input.ki  = kb;
    SendInput(1, &Input, sizeof(Input));

    /* Generate a "key up" */
    ZeroMemory(&kb, sizeof(KEYBDINPUT));
    ZeroMemory(&Input, sizeof(INPUT));
    kb.dwFlags  =  KEYEVENTF_KEYUP;
    if (bExtended) { kb.dwFlags |= KEYEVENTF_EXTENDEDKEY; }
    kb.wVk = vk;
    Input.type = INPUT_KEYBOARD;
    Input.ki = kb;
    SendInput(1, &Input, sizeof(Input));

    return;
}

/* This is a function to send a line containing English alphabets, numbers and spaces
   It assumes that the user does not have the Caps Lock turned on initailly */
void kbam_emu::GenerateLine(string line)
{
     stringstream is(line);
     char c;
     while(is.get(c))
     {
         if(isupper(c))
         {
             GenerateKey(VK_CAPITAL, TRUE); //Caps Lock on
             GenerateKey(c, FALSE);
             GenerateKey(VK_CAPITAL, TRUE); //Caps Lock off
         }
         else
         {
             GenerateKey(toupper(c), FALSE);
         }
     }
     return;
}

/* This is a function to click somewhere on the screen */
void kbam_emu::Click(const int X, const int Y, mouse_button button)
{
    SetCursorPos(X, Y);

    DWORD down;
    DWORD up;

    switch(button)
    {
        case left:
            down = MOUSEEVENTF_LEFTDOWN;
            up = MOUSEEVENTF_LEFTUP;
            break;
        case middle:
            down = MOUSEEVENTF_MIDDLEDOWN;
            up = MOUSEEVENTF_MIDDLEUP;
            break;
        case right:
            down = MOUSEEVENTF_RIGHTDOWN;
            up = MOUSEEVENTF_RIGHTUP;
            break;
    }

    INPUT Input[2];
    ZeroMemory(Input, sizeof(INPUT) * 2);
    Input[0].type = INPUT_MOUSE;
    Input[0].mi.dwFlags = down;

    Input[1].type = INPUT_MOUSE;
    Input[1].mi.dwFlags = up;
    SendInput(2, Input, sizeof(INPUT));

    return;
}

void kbam_emu::Drag(const int X, const int Y, const int X2, const int Y2)
{
    SetCursorPos(X, Y);

    INPUT Input[1];
    ZeroMemory(Input, sizeof(INPUT));
    Input[0].type = INPUT_MOUSE;
    Input[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
    SendInput(1, Input, sizeof(INPUT));

    SetCursorPos(X2, Y2);

    INPUT Input2[1];
    ZeroMemory(Input2, sizeof(INPUT));
    Input2[0].type = INPUT_MOUSE;
    Input2[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;
    SendInput(1, Input2, sizeof(INPUT));

    return;
}

"pixel_check.h"

/*
  Name: pixel check
  Copyright: -
  Author: Samuel YKC
  Date: 16/11/14 00:26
  Description: This header file is designed for checking pixels. The essential codes for retrieving the color of a pixel 
  on screen are written by a programmer on the Internet with the user name 'templatetypedef'. Thanks, templatetypedef. Here 
  is the address for his original post: 
               http://stackoverflow.com/questions/4839623/getting-pixel-color-in-c
*/

#ifndef _PIXEL_CHECK_H_
#define _PIXEL_CHECK_H_

#include <windows.h>
#include "kbam_emu.h"

using namespace std;
using namespace kbam_emu;

namespace pixel_check
{
    COLORREF GetPixelColor(int x, int y);
    bool ComparePixelWithColor(int x, int y, COLORREF color);

    void SleepOnColor(int x, int y, COLORREF color, int interval=100);
    void SleepUntilColor(int x, int y, COLORREF color, int interval=100);

    void ClickUntilColor(int click_x, int click_y, int pixel_x, int pixel_y, COLORREF color, int interval=1000);
}

#endif

"pixel_check.cpp"

#include "pixel_check.h"

COLORREF pixel_check::GetPixelColor(int x, int y)
{
    HDC dc = GetDC(NULL);
    COLORREF color = GetPixel(dc, x, y);
    ReleaseDC(NULL, dc);

    return color;
}

bool pixel_check::ComparePixelWithColor(int x, int y, COLORREF color)
{
    HDC dc = GetDC(NULL);
    COLORREF pixel_color = GetPixel(dc, x, y);
    ReleaseDC(NULL, dc);

    return (pixel_color==color);
}

void pixel_check::SleepOnColor(int x, int y, COLORREF color, int interval)
{
    while(ComparePixelWithColor(x,y,color)) Sleep(interval);
}

void pixel_check::SleepUntilColor(int x, int y, COLORREF color, int interval)
{
    while(!ComparePixelWithColor(x,y,color)) Sleep(interval);
}

void pixel_check::ClickUntilColor(int click_x, int click_y, int pixel_x, int pixel_y, COLORREF color, int interval)
{
    while(!ComparePixelWithColor(pixel_x,pixel_y,color))
    {
        Click(click_x, click_y);
        Sleep(interval);
    }
}

And in my project, I put the #include like this (I placed the .h & .cpp in the default include directory so <> is fine to use):

#include <kbam_emu.h>
#include <pixel_check.h>

and uses the functions this way:

kbam_emu::Click(0, 0);

Lastly, in the .pro file I added this line:

LIBS += -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32

I supposed everything I have done is logical. Still, the linker bet a differ. I tried to post the full codes here so that I won't miss anything. Does anyone know what is wrong?

Samuel
  • 113
  • 2
  • 8
  • There are C style API function defintions missing. Some problems with name-mangling because of compiling parts using `g++` instead of `gcc`? – πάντα ῥεῖ Feb 08 '15 at 16:41
  • I tried to read a lot and still don't know how to fix... I actually have no idea what `g++` or `gcc` is until just then. I don't know where to look for these compilers so I tried to install them from [here](http://mingw-w64.sourceforge.net/download.php#mingw-builds). Then I tried to add the compiler to Qt and created a kit with this compiler, I don't know if I was doing it wrong but it just won't work. I means it simply won't compile at all. – Samuel Feb 09 '15 at 02:46

1 Answers1

0

After I keep randomly trying things for days, I accidentally find the solution.

I placed my files into the project instead of the default \include directory this time. Then, I clicked the button "run qmake" in Qt and those kbam_emu.obj & pixel_check.obj that haven't been created before are finally being created. No more linker problem now!

I think this might be about the makefile is not updated automatically so I need to manually give the run qmake instruction to Qt. Hope my case would help some of you.

Samuel
  • 113
  • 2
  • 8